Ldap\Connection: Add query alias support

refs #8826
This commit is contained in:
Johannes Meyer 2015-05-04 11:32:03 +02:00
parent 5baa0590b1
commit 664017573f

View File

@ -315,7 +315,7 @@ class Connection implements Selectable
$count += 1; $count += 1;
if ($offset === 0 || $offset < $count) { if ($offset === 0 || $offset < $count) {
$entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes( $entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes(
ldap_get_attributes($this->ds, $entry) ldap_get_attributes($this->ds, $entry), array_flip($fields)
); );
} }
} while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry))); } while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry)));
@ -412,7 +412,7 @@ class Connection implements Selectable
$count += 1; $count += 1;
if ($offset === 0 || $offset < $count) { if ($offset === 0 || $offset < $count) {
$entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes( $entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes(
ldap_get_attributes($this->ds, $entry) ldap_get_attributes($this->ds, $entry), array_flip($fields)
); );
} }
} while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry))); } while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry)));
@ -447,20 +447,48 @@ class Connection implements Selectable
return $entries; // TODO(7693): Sort entries post-processed return $entries; // TODO(7693): Sort entries post-processed
} }
protected function cleanupAttributes($attrs) protected function cleanupAttributes($attributes, array $requestedFields)
{ {
$clean = (object) array(); // In case the result contains attributes with a differing case than the requested fields, it is
for ($i = 0; $i < $attrs['count']; $i++) { // necessary to create another array to map attributes case insensitively to their requested counterparts.
$attr_name = $attrs[$i]; // This does also apply the virtual alias handling. (Since an LDAP server does not handle such)
if ($attrs[$attr_name]['count'] === 1) { $loweredFieldMap = array();
$clean->$attr_name = $attrs[$attr_name][0]; foreach ($requestedFields as $name => $alias) {
$loweredFieldMap[strtolower($name)] = is_string($alias) ? $alias : $name;
}
$cleanedAttributes = array();
for ($i = 0; $i < $attributes['count']; $i++) {
$attribute_name = $attributes[$i];
if ($attributes[$attribute_name]['count'] === 1) {
$attribute_value = $attributes[$attribute_name][0];
} else { } else {
for ($j = 0; $j < $attrs[$attr_name]['count']; $j++) { $attribute_value = array();
$clean->{$attr_name}[] = $attrs[$attr_name][$j]; for ($j = 0; $j < $attributes[$attribute_name]['count']; $j++) {
$attribute_value[] = $attributes[$attribute_name][$j];
} }
} }
$requestedAttributeName = isset($loweredFieldMap[strtolower($attribute_name)])
? $loweredFieldMap[strtolower($attribute_name)]
: $attribute_name;
$cleanedAttributes[$requestedAttributeName] = $attribute_value;
} }
return $clean;
// The result may not contain all requested fields, so populate the cleaned
// result with the missing fields and their value being set to null
foreach ($requestedFields as $name => $alias) {
if (! is_string($alias)) {
$alias = $name;
}
if (! array_key_exists($alias, $cleanedAttributes)) {
$cleanedAttributes[$alias] = null;
Logger::debug('LDAP query result does not provide the requested field "%s"', $name);
}
}
return (object) $cleanedAttributes;
} }
public function testCredentials($username, $password) public function testCredentials($username, $password)
@ -608,30 +636,22 @@ class Connection implements Selectable
*/ */
protected function discoverCapabilities($ds) protected function discoverCapabilities($ds)
{ {
$query = $this->select()->from( $fields = array(
'*', 'defaultNamingContext',
array( 'namingContexts',
'defaultNamingContext', 'vendorName',
'namingContexts', 'vendorVersion',
'vendorName', 'supportedSaslMechanisms',
'vendorVersion', 'dnsHostName',
'supportedSaslMechanisms', 'schemaNamingContext',
'dnsHostName', 'supportedLDAPVersion', // => array(3, 2)
'schemaNamingContext', 'supportedCapabilities',
'supportedLDAPVersion', // => array(3, 2) 'supportedControl',
'supportedCapabilities', 'supportedExtension',
'supportedControl', '+'
'supportedExtension',
'+'
)
);
$result = @ldap_read(
$ds,
'',
$query->create(),
$query->listFields()
); );
$result = @ldap_read($ds, '', (string) $this->select()->from('*', $fields), $fields);
if (! $result) { if (! $result) {
throw new LdapException( throw new LdapException(
'Capability query failed (%s:%d): %s. Check if hostname and port of the' 'Capability query failed (%s:%d): %s. Check if hostname and port of the'
@ -641,6 +661,7 @@ class Connection implements Selectable
ldap_error($ds) ldap_error($ds)
); );
} }
$entry = ldap_first_entry($ds, $result); $entry = ldap_first_entry($ds, $result);
if ($entry === false) { if ($entry === false) {
throw new LdapException( throw new LdapException(
@ -651,9 +672,7 @@ class Connection implements Selectable
); );
} }
$ldapAttributes = ldap_get_attributes($ds, $entry); return new Capability($this->cleanupAttributes(ldap_get_attributes($ds, $entry), array_flip($fields)));
$result = $this->cleanupAttributes($ldapAttributes);
return new Capability($result);
} }
/** /**