From d3b944046ad059f1aad09427cee39080f8ad6872 Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Sun, 8 Nov 2020 12:53:11 -0600 Subject: [PATCH] [Ldap] Ldap Entry case-sensitive attribute key option --- src/Symfony/Component/Ldap/CHANGELOG.md | 5 ++ src/Symfony/Component/Ldap/Entry.php | 54 ++++++++++++++++--- .../Component/Ldap/Tests/EntryTest.php | 42 +++++++++++++++ 3 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/Symfony/Component/Ldap/Tests/EntryTest.php diff --git a/src/Symfony/Component/Ldap/CHANGELOG.md b/src/Symfony/Component/Ldap/CHANGELOG.md index f54a3e8241..b232f657db 100644 --- a/src/Symfony/Component/Ldap/CHANGELOG.md +++ b/src/Symfony/Component/Ldap/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.3.0 +----- + +* Added caseSensitive option for attribute keys in the Entry class. + 5.1.0 ----- diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index da3b8bb74e..60253f69a9 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -13,16 +13,23 @@ namespace Symfony\Component\Ldap; /** * @author Charles Sarrazin + * @author Karl Shea */ class Entry { private $dn; private $attributes; + private $lowerMap; public function __construct(string $dn, array $attributes = []) { $this->dn = $dn; - $this->attributes = $attributes; + $this->attributes = []; + $this->lowerMap = []; + + foreach ($attributes as $key => $attribute) { + $this->setAttribute($key, $attribute); + } } /** @@ -38,13 +45,21 @@ class Entry /** * Returns whether an attribute exists. * - * @param string $name The name of the attribute + * @param string $name The name of the attribute + * @param bool $caseSensitive Whether the check should be case-sensitive * * @return bool */ - public function hasAttribute(string $name) + public function hasAttribute(string $name/* , bool $caseSensitive = true */) { - return isset($this->attributes[$name]); + $caseSensitive = 2 > \func_num_args() || true === func_get_arg(1); + $attributeKey = $this->getAttributeKey($name, $caseSensitive); + + if (null === $attributeKey) { + return false; + } + + return isset($this->attributes[$attributeKey]); } /** @@ -53,13 +68,21 @@ class Entry * As LDAP can return multiple values for a single attribute, * this value is returned as an array. * - * @param string $name The name of the attribute + * @param string $name The name of the attribute + * @param bool $caseSensitive Whether the attribute name is case-sensitive * * @return array|null */ - public function getAttribute(string $name) + public function getAttribute(string $name/* , bool $caseSensitive = true */) { - return isset($this->attributes[$name]) ? $this->attributes[$name] : null; + $caseSensitive = 2 > \func_num_args() || true === func_get_arg(1); + $attributeKey = $this->getAttributeKey($name, $caseSensitive); + + if (null === $attributeKey) { + return null; + } + + return $this->attributes[$attributeKey] ?? null; } /** @@ -78,6 +101,7 @@ class Entry public function setAttribute(string $name, array $value) { $this->attributes[$name] = $value; + $this->lowerMap[strtolower($name)] = $name; } /** @@ -86,5 +110,21 @@ class Entry public function removeAttribute(string $name) { unset($this->attributes[$name]); + unset($this->lowerMap[strtolower($name)]); + } + + /** + * Get the attribute key. + * + * @param string $name The attribute name + * @param bool $caseSensitive Whether the attribute name is case-sensitive + */ + private function getAttributeKey(string $name, bool $caseSensitive = true): ?string + { + if ($caseSensitive) { + return $name; + } + + return $this->lowerMap[strtolower($name)] ?? null; } } diff --git a/src/Symfony/Component/Ldap/Tests/EntryTest.php b/src/Symfony/Component/Ldap/Tests/EntryTest.php new file mode 100644 index 0000000000..7185db1040 --- /dev/null +++ b/src/Symfony/Component/Ldap/Tests/EntryTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Ldap\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Ldap\Entry; + +class EntryTest extends TestCase +{ + public function testCaseSensitiveAttributeAccessors() + { + $mail = 'fabpot@symfony.com'; + $givenName = 'Fabien Potencier'; + + $entry = new Entry('cn=fabpot,dc=symfony,dc=com', [ + 'mail' => [$mail], + 'givenName' => [$givenName], + ]); + + $this->assertFalse($entry->hasAttribute('givenname')); + $this->assertTrue($entry->hasAttribute('givenname', false)); + + $this->assertNull($entry->getAttribute('givenname')); + $this->assertSame($givenName, $entry->getAttribute('givenname', false)[0]); + + $firstName = 'Fabien'; + + $entry->setAttribute('firstName', [$firstName]); + $this->assertSame($firstName, $entry->getAttribute('firstname', false)[0]); + $entry->removeAttribute('firstName'); + $this->assertFalse($entry->hasAttribute('firstname', false)); + } +}