예제 #1
0
 public static function setUser(SHUserAdapter $adapter, $JUser)
 {
     if (is_numeric($JUser)) {
         $id = $JUser;
     } elseif ($JUser instanceof JUser) {
         $id = $JUser->id;
     } else {
         //TODO: lang string
         throw new RuntimeException('Invalid User ID', 101);
     }
     $link = null;
     // Check if we can retrieve link from cache
     if (isset(self::$userCache[$adapter->loginuser]) && is_array(self::$userCache[$adapter->loginuser])) {
         foreach (self::$userCache[$adapter->loginuser] as $links) {
             if ($links['joomla_id'] === $id) {
                 $link = self::$userCache[$adapter->loginuser];
                 break;
             }
         }
     }
     if (empty($link)) {
         $link = self::lookupFromJoomlaId(self::TYPE_USER, $id);
     }
     if ($link) {
         // Check if we actually need to update
         if ($link[0]['adapter'] == $adapter->getName() && $link[0]['domain'] == $adapter->getDomain() && $link[0]['username'] == $adapter->getId(false) && $link[0]['joomla_id'] == $id) {
             return;
         }
         // Commit the link update
         self::update($link[0]['id'], $adapter->getName(), $adapter->getDomain(), $adapter->getId(false), $id);
     } else {
         // Commit the link insert
         self::insert(self::TYPE_USER, $adapter->getName(), $adapter->getDomain(), $adapter->getId(false), $id);
     }
     unset(self::$userCache['U_' . $adapter->loginuser]);
     unset(self::$userCache['I_' . $id]);
 }
예제 #2
0
	/**
	 * Save the users profile to the database.
	 *
	 * @param   integer        $userId    Joomla user ID to save.
	 * @param   string         $username  Joomla username to save.
	 * @param   SHUserAdapter  $adapter   User adapter of LDAP user.
	 * @param   array          $options   An optional set of options.
	 *
	 * @return  boolean  True on success
	 *
	 * @since   2.0
	 */
	protected function saveProfile($userId, $username, $adapter, $options = array())
	{
		$xml = $this->getXMLFields($adapter->getDomain());

		SHLog::add(JText::sprintf('PLG_LDAP_PROFILE_DEBUG_12221', $username), 12221, JLog::DEBUG, 'ldap');

		$addRecords		= array();
		$updateRecords 	= array();
		$deleteRecords	= array();

		$db = JFactory::getDBO();
		$query = $db->getQuery(true);

		// Lets get a list of current SQL entries
		if (is_null($current = $this->queryProfile($userId, true)))
		{
			return false;
		}

		/* We want to process each attribute in the XML
		* then find out if it exists in the LDAP directory.
		* If it does, then we compare that to the value
		* currently in the SQL database.
		*/
		$attributes = $this->getAttributes($xml);

		foreach ($attributes as $attribute)
		{
			// Lets check for a delimiter (this is the indicator that multiple values are supported)
			$delimiter = null;
			$xmlField = $xml->xpath("fieldset/field[@name='$attribute']");
			$value = null;

			if ($delimiter = (string) $xmlField[0]['delimiter'])
			{
				// These are potentially multiple values

				if (strToUpper($delimiter) == 'NEWLINE')
				{
					$delimiter = "\n";
				}

				$value = '';

				if ($v = $adapter->getAttributes($attribute))
				{
					if (is_array($v[$attribute]))
					{
						foreach ($v[$attribute] as $values)
						{
							$value .= $values . $delimiter;
						}
					}
				}
			}
			else
			{
				// These are single values
				if ($v = $adapter->getAttributes($attribute))
				{
					if (isset($v[$attribute][0]))
					{
						$value = $v[$attribute][0];
					}
				}
			}

			// Get the action status required against the SQL table
			$status = $this->checkSqlField($current, $attribute, $value);

			switch ($status)
			{
				case 1:
					$updateRecords[$attribute] = $value;
					break;

				case 2:
					$addRecords[$attribute] = $value;
					break;

				case 3:
					$deleteRecords[] = $attribute;
					break;
			}
		}

		/* Lets commit these differences to the database
		 * in steps (delete, add, update) and return the
		 * result.
		 */
		$results = array();

		if (count($deleteRecords))
		{
			$results[] = $this->deleteRecords($userId, $deleteRecords);
		}

		if (count($addRecords))
		{
			$results[] = $this->addRecords($userId, $addRecords, count($current) + 1);
		}

		if (count($updateRecords))
		{
			$results[] = $this->updateRecords($userId, $updateRecords);
		}

		$return = (!in_array(false, $results, true));

		if (count($results))
		{
			// Changes occurred so lets log it
			SHLog::add(
				JText::sprintf(
					'PLG_LDAP_PROFILE_DEBUG_12225',
					$username,
					$return == 1 ? JText::_('PLG_LDAP_PROFILE_SUCCESS') : JText::_('PLG_LDAP_PROFILE_FAIL')
				), 12225, JLog::DEBUG, 'ldap'
			);

			if (!$return)
			{
				// There was an error
				return false;
			}

			// Everything went well - we have updated both LDAP and the J! database.
			SHLog::add(JText::sprintf('PLG_LDAP_PROFILE_INFO_12224', $username), 12224, JLog::INFO, 'ldap');

			// Return this was successful and something was updated
			return true;
		}
		else
		{
			// No changes occurred so log that the profile was up to date
			SHLog::add(
				JText::sprintf('PLG_LDAP_PROFILE_DEBUG_12226', $username), 12226, JLog::DEBUG, 'ldap'
			);

			return;
		}
	}
예제 #3
0
 /**
  * Called after a user LDAP read to gather extra ldap attribute values that
  * were not included in the initial read.
  *
  * @param   SHUserAdapter  $adapter      The current user adapter.
  * @param   array          &$attributes  Discovered User Ldap attribute keys=>values.
  * @param   array          $options      Array holding options.
  *
  * @return  void
  *
  * @since   2.0
  */
 public function onLdapAfterRead($adapter, &$attributes, $options = array())
 {
     if (!$this->doSetup()) {
         return;
     }
     $details = array();
     $return = array();
     $groups = array();
     /* Firstly, we need to check if there are any initial groups discovered
      * if a forward lookup is being used. If not then we need to find these
      * initial groups first.
      */
     if ($this->lookup_type === self::LOOKUP_FORWARD) {
         /*
          * Attempt to do a forward lookup if the Ldap user group attributes are
          * not present. Though in most cases, they should be present.
          */
         if (!isset($attributes[$this->memberof_attribute])) {
             // We cannot get any more information if there is no source user DN
             if (is_null($adapter->getId(false))) {
                 return false;
             }
             // Add to the user attribute request for an Ldap read
             $details[] = $this->memberof_attribute;
             $return = $details;
         } else {
             if (!count($attributes[$this->memberof_attribute])) {
                 // There are no groups to process for this user (or the parameter was set incorrectly)
                 return true;
             }
             // Yes we have groups already, we just need to check for recursion if required laters
             $groups = $attributes[$this->memberof_attribute];
         }
     } else {
         // Attempt to do a reverse lookup
         $return[] = $this->member_attribute;
         // The following will only execute if the attributes doesnt have what is required for reverse lookup
         if (!isset($attributes[$this->member_dn]) || is_null($this->member_dn)) {
             // We cannot get any more information if there is no source user DN
             if (is_null($adapter->getId(false))) {
                 return false;
             }
             // This will indicate another ldap read later
             $details[] = $this->member_dn;
         }
     }
     // Lets get our result ready
     $return = array_fill_keys($return, null);
     $result = null;
     if (count($details)) {
         // Get our ldap user attributes and check we have a valid result
         $result = $adapter->client->read($adapter->getId(false), null, $details);
     }
     if (!count($groups)) {
         // Need to process first level user groups from the ldap result
         if ($this->lookup_type === self::LOOKUP_FORWARD) {
             // Forward lookup: all we need is the user group values
             $groups = $result->getAttribute(0, $this->memberof_attribute, array());
         } else {
             // Reverse lookup: have to find the groups with the user dn present
             $lookupValue = is_null($result) ? $attributes[$this->member_dn][0] : $result->getValue(0, $this->member_dn, 0);
             // Build the search filter for this
             $search = $this->member_attribute . '=' . $lookupValue;
             $search = SHLDAPHelper::buildFilter(array($search));
             // Find all the groups that have this user present as a member
             if (($reverse = $adapter->client->search(null, $search, array('dn'))) !== false) {
                 for ($i = 0; $i < $reverse->countEntries(); ++$i) {
                     // Extract the group distinguished name from the result
                     $groups[] = $reverse->getDN($i);
                 }
             }
         }
     }
     // Need to process the recursion using the initial groups as a basis
     if ($this->recursion && count($groups)) {
         // Check if the Adapter is LDAP based
         if ($adapter::getType('LDAP')) {
             $outcome = array();
             if ($this->lookup_type === self::LOOKUP_REVERSE) {
                 // We need to override the lookup attribute for reverse recursion
                 self::getRecursiveGroups($adapter->client, $groups, $this->recursion_depth, $outcome, 'dn', $this->member_attribute);
             } else {
                 self::getRecursiveGroups($adapter->client, $groups, $this->recursion_depth, $outcome, $this->memberof_attribute, $this->dn_attribute);
             }
             // We need to merge them back together without duplicates
             $groups = array_unique(array_merge($groups, $outcome));
         }
     }
     // Lets store the groups
     $groups = array_values($groups);
     $attributes[$this->lookup_type === self::LOOKUP_FORWARD ? $this->memberof_attribute : $this->member_attribute] = $groups;
     return true;
 }
예제 #4
0
 /**
  * Returns the domain or the configuration ID used for this specific user.
  *
  * @return  string  Domain or Configuration ID.
  *
  * @since   2.0
  */
 public function getDomain()
 {
     if (is_null($this->domain)) {
         // Lets pull the domain from the SHLdap object
         $this->getId(false);
         $this->domain = $this->client->domain;
     }
     return parent::getDomain();
 }