Skip to content

Commit

Permalink
Adapter map link logic implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
ShMaunder committed Mar 1, 2014
1 parent 14d0e54 commit 7fe95f6
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 22 deletions.
15 changes: 15 additions & 0 deletions administrator/components/com_shconfig/sql/install.mysql.utf8.sql
Expand Up @@ -10,6 +10,21 @@ CREATE TABLE IF NOT EXISTS `#__sh_config` (
UNIQUE KEY `uk_name` (`name`)
);

--
-- Table structure for table `jos_sh_config`
--

CREATE TABLE IF NOT EXISTS `#__sh_adapter_map` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` int(3) NOT NULL,
`adapter_name` varchar(255) NOT NULL,
`domain` varchar(45) NOT NULL,
`adapter_id` varchar(255) NOT NULL,
`joomla_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_entry` (`type`, `adapter_name`, `domain`, `adapter_id`)
);

--
-- Default table data for `jos_sh_config`
--
Expand Down
3 changes: 3 additions & 0 deletions cli/ldap_cron.php
Expand Up @@ -204,6 +204,9 @@ public function doExecute()
// Even if the sync does not need a save, do it anyway as Cron efficiency doesnt matter too much
SHUserHelper::save($instance);

// Update the user map linker
SHAdapterMap::setUser($adapter, $instance->id);

// Above should throw an exception on error so therefore we can report success
$this->out(JText::sprintf('CLI_SHMANIC_LDAP_INFO_13029', $username));
++$success;
Expand Down
40 changes: 29 additions & 11 deletions libraries/shmanic/adapter/event/bouncer.php
Expand Up @@ -40,9 +40,21 @@ class SHAdapterEventBouncer extends JEvent
*/
public function __construct(&$subject)
{
// Gets the user adapter name for the curernt session user
$userLink = SHAdapterLink::getUserLink();
$this->adapterUser = $userLink['name'];
// Gets the user adapter name for the current session user
$session = JFactory::getSession();

$user = $session->get('user');

if (($user instanceof JUser) && $user->id > 0)
{
if (!($session->get('shuseradaptername', false)))
{
$userLink = SHAdapterMap::lookupFromJoomlaId(SHAdapterMap::TYPE_USER, $user->id);
$session->set('shuseradaptername', $userLink['adapter']);
}

$this->adapterUser = $session->get('shuseradaptername');
}

parent::__construct($subject);
}
Expand Down Expand Up @@ -192,9 +204,9 @@ public function onContentPrepareForm($form, $data)
*/
public function onUserBeforeDelete($user)
{
if ($userLink = SHAdapterLink::getUserLink($user) && $userLink['adapter'])
if (($userLink = SHAdapterMap::lookupFromJoomlaId(SHAdapterMap::TYPE_USER, $user['id'])) && $userLink['adapter'])
{
SHAdapterEventHelper::triggerEvent($userLink['name'], 'onUserBeforeDelete', array($user));
SHAdapterEventHelper::triggerEvent($userLink['adapter'], 'onUserBeforeDelete', array($user));
}
}

Expand All @@ -211,9 +223,9 @@ public function onUserBeforeDelete($user)
*/
public function onUserAfterDelete($user, $success, $msg)
{
if ($userLink = SHAdapterLink::getUserLink($user) && $userLink['adapter'])
if (($userLink = SHAdapterMap::lookupFromJoomlaId(SHAdapterMap::TYPE_USER, $user['id'])) && $userLink['adapter'])
{
SHAdapterEventHelper::triggerEvent($userLink['name'], 'onUserAfterDelete', array($user, $success, $msg));
SHAdapterEventHelper::triggerEvent($userLink['adapter'], 'onUserAfterDelete', array($user, $success, $msg));
}
}

Expand Down Expand Up @@ -331,6 +343,9 @@ public function onUserAfterSave($user, $isNew, $success, $msg)

// Silently resave the user without calling the onUserSave events
SHUserHelper::save($instance, false);

// Update the user map linker
SHAdapterMap::setUser($adapter, $instance->id);
}

SHAdapterEventHelper::triggerEvent($this->adapterUser, 'onUserAfterSave', array($user, $isNew, $success, $msg));
Expand Down Expand Up @@ -412,6 +427,9 @@ public function onUserLogin($user, $options = array())
}
}

// Update the user map linker
SHAdapterMap::setUser($adapter, $instance->id);

// Allow user adapter events to be called
$this->adapterUser = $adapterName;

Expand All @@ -430,9 +448,9 @@ public function onUserLogin($user, $options = array())
*/
public function onUserLogout($user, $options = array())
{
if ($userLink = SHAdapterLink::getUserLink($user['username']) && $userLink['adapter'])
if ($userLink = SHAdapterMap::getUserLink($user['username']) && $userLink['adapter'])
{
return SHAdapterEventHelper::triggerEvent($userLink['name'], 'onUserLogout', array($user, $options));
return SHAdapterEventHelper::triggerEvent($userLink['adapter'], 'onUserLogout', array($user, $options));
}
}

Expand All @@ -453,9 +471,9 @@ public function onUserLoginFailure($response)
if ($id = JUserHelper::getUserId($username))
{
// Check if the attempted login was an adapter user, if so then fire the event
if ($userLink = SHAdapterLink::getUserLink($id) && $userLink['adapter'])
if ($userLink = SHAdapterMap::getUserLink($id) && $userLink['adapter'])
{
SHAdapterEventHelper::triggerEvent($userLink['name'], 'onUserLoginFailure', array($response));
SHAdapterEventHelper::triggerEvent($userLink['adapter'], 'onUserLoginFailure', array($response));
}
}
}
Expand Down
173 changes: 170 additions & 3 deletions libraries/shmanic/adapter/map.php
@@ -1,17 +1,184 @@
<?php

abstract class SHAdapterLink
abstract class SHAdapterMap
{
const TYPE_USER = 1;

const TYPE_GROUP = 2;

const TYPE_CONTACT = 3;

/**
* Instance based cache to prevent double lookups for same user.
*
* @var array
* @since 2.1
*/
protected static $userCache = array();

public static function getUserLink($username = null)
{
return self::getUser($username);
}

public static function getUser($username = null)
{
if (isset(self::$userCache[$username]))
{
return self::$userCache[$username];
}

if ($link = self::lookupFromAdapterId(self::TYPE_USER, $username))
{
self::$userCache[$username] = $link;

return self::$userCache[$username];
}

// TODO: currently is badly inefficient
// BC for 2.0
if ($type = SHUserHelper::getTypeParam($username))
{
$domain = SHUserHelper::getDomainParam($username);

return array('adapter' => true, 'name' => $type, 'domain' => $domain);
return array('adapter' => $type, 'domain' => $domain);
}

return array('adapter' => false, 'domain' => null);
}

public static function setUser(SHUserAdapter $adapter, $JUser)
{
if (is_numeric($JUser))
{
$id = $JUser;
}
elseif ($JUser instanceof JUser)
{
$id = $JUser->id;
}
else
{
$id = JUserHelper::getUserId($JUser);
}

if (!is_numeric($id))
{
//TODO: lang string
throw new RuntimeException('Invalid User ID', 101);
}

// Check if we can retrieve link from cache
if (isset(self::$userCache[$adapter->loginuser]) && (self::$userCache[$adapter->loginuser]['joomla_id'] === $id))
{
$link = self::$userCache[$adapter->loginuser];
}
else
{
$link = self::lookupFromJoomlaId(self::TYPE_USER, $id);
}

if ($link)
{
// Check if we actually need to update
if (($link['adapter'] == $adapter->getName())
&& ($link['domain'] == $adapter->getDomain())
&& ($link['username'] == $adapter->loginuser)
&& ($link['joomla_id'] == $id))
{
return;
}

// Commit the link update
self::update($link['id'], $adapter->getName(), $adapter->getDomain(), $adapter->loginuser, $id);

}
else
{
// Commit the link insert
self::insert(self::TYPE_USER, $adapter->getName(), $adapter->getDomain(), $adapter->loginuser, $id);
}

unset(self::$userCache[$adapter->loginuser]);
}

public static function update($id, $adapterName, $domain, $adapterId, $joomlaId)
{
$db = JFactory::getDbo();

$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__sh_adapter_map'))
->set($db->quoteName('adapter_name') . ' = ' . $db->quote($adapterName))
->set($db->quoteName('domain') . ' = ' . $db->quote($domain))
->set($db->quoteName('adapter_id') . ' = ' . $db->quote($adapterId))
->set($db->quoteName('joomla_id') . ' = ' . $db->quote($joomlaId))
->where($db->quoteName('id') . ' = ' . $db->quote($id))
);

return $db->execute();
}

public static function insert($type, $adapterName, $domain, $adapterId, $joomlaId)
{
$db = JFactory::getDbo();

$db->setQuery(
$db->getQuery(true)
->insert($db->quoteName('#__sh_adapter_map'))
->columns(
array(
$db->quoteName('type'),
$db->quoteName('adapter_name'),
$db->quoteName('domain'),
$db->quoteName('adapter_id'),
$db->quoteName('joomla_id')
)
)
->values(
$db->quote($type) . ', ' .
$db->quote($adapterName) . ', ' .
$db->quote($domain) . ', ' .
$db->quote($adapterId) . ', ' .
$db->quote($joomlaId)
)
);

return $db->execute();
}

public static function lookup($key, $type, $value)
{
$db = JFactory::getDbo();

$db->setQuery(
$db->getQuery(true)
->select('*')
->from($db->quoteName('#__sh_adapter_map'))
->where($db->quoteName('type') . ' = ' . $db->quote($type))
->where($db->quoteName($key) . ' = ' . $db->quote($value))
);

if ($results = $db->loadAssoc())
{
$results['adapter'] = $results['adapter_name'];

if ($type === self::TYPE_USER)
{
$results['username'] = $results['adapter_id'];
}

return $results;
}
}

return array('adapter' => false, 'name' => null, 'domain' => null);
public static function lookupFromJoomlaId($type, $joomlaId)
{
return self::lookup('joomla_id', $type, $joomlaId);
}

public static function lookupFromAdapterId($type, $adapterId)
{
return self::lookup('adapter_id', $type, $adapterId);
}
}
14 changes: 6 additions & 8 deletions libraries/shmanic/factory.php
Expand Up @@ -185,28 +185,26 @@ public static function getUserAdapter($user, $type = null, $options = array())
}
}

// If the JUser ID has been specified then use it (more efficient)
if ($id = isset($credentials['id']) ? (int) $credentials['id'] : JUserHelper::getUserId($username))
// Attempts to get the user linking entry to determine domain and type of user
if (($link = SHAdapterMap::getUser($username)) && $link['adapter'])
{
$jUser = JFactory::getUser($id);

if ((boolean) $config->get('user.usedomain', true))
{
if (!isset($credentials['domain']))
{
// Attempt to get the domain for this user
$credentials['domain'] = SHUserHelper::getDomainParam($jUser);
$credentials['domain'] = $link['domain'];
}
}
else
{
unset($credentials['domain']);
}

if (!isset($credentials['type']))
if (!isset($credentials['type']) && is_null($type))
{
// Attempt to get the User Adapter type
$type = SHUserHelper::getTypeParam($jUser);
// Attempt to get the User Adapter name
$type = $link['adapter'];
}
}

Expand Down

0 comments on commit 7fe95f6

Please sign in to comment.