From f8c4395c34008d8b5cff41d83c156a6a80e4ba0e Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Sun, 8 Nov 2020 12:53:11 -0600 Subject: [PATCH 1/7] Ldap Entry case-sensitive attribute key option --- src/Symfony/Component/Ldap/CHANGELOG.md | 1 + src/Symfony/Component/Ldap/Entry.php | 50 +++++++++++++++++-- .../Component/Ldap/Tests/EntryTest.php | 42 ++++++++++++++++ 3 files changed, 88 insertions(+), 5 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 f54a3e824184e..235a0ffe0363e 100644 --- a/src/Symfony/Component/Ldap/CHANGELOG.md +++ b/src/Symfony/Component/Ldap/CHANGELOG.md @@ -16,6 +16,7 @@ CHANGELOG ----- * Added the "extra_fields" option, an array of custom fields to pull from the LDAP server + * Added caseSensitive option for attribute keys in the Entry class. 4.3.0 ----- diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index da3b8bb74ef41..aa45b9d0d41b1 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -13,16 +13,23 @@ /** * @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->lowerMap = []; + + foreach ($attributes as $key => $attribute) + { + $this->setAttribute($key, $attribute); + } } /** @@ -39,12 +46,19 @@ public function getDn() * Returns whether an attribute exists. * * @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, $caseSensitive = true) { - return isset($this->attributes[$name]); + $attributeKey = $this->getAttributeKey($name, $caseSensitive); + + if (!$attributeKey) { + return false; + } + + return isset($this->attributes[$attributeKey]); } /** @@ -54,12 +68,19 @@ public function hasAttribute(string $name) * this value is returned as an array. * * @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, $caseSensitive = true) { - return isset($this->attributes[$name]) ? $this->attributes[$name] : null; + $attributeKey = $this->getAttributeKey($name, $caseSensitive); + + if (!$attributeKey) { + return null; + } + + return isset($this->attributes[$attributeKey]) ? $this->attributes[$attributeKey] : null; } /** @@ -78,6 +99,7 @@ public function getAttributes() public function setAttribute(string $name, array $value) { $this->attributes[$name] = $value; + $this->lowerMap[strtolower($name)] = $name; } /** @@ -86,5 +108,23 @@ public function setAttribute(string $name, array $value) 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 + * + * @return string|null + */ + private function getAttributeKey(string $name, $caseSensitive = true) + { + if ($caseSensitive) { + return $name; + } + + return isset($this->lowerMap[strtolower($name)]) ? $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 0000000000000..940646765bc40 --- /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', true)); + $this->assertTrue($entry->hasAttribute('givenname', false)); + + $this->assertSame(null, $entry->getAttribute('givenname', true)); + $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)); + } +} From 4ed0b884b4aa7be16ff8580ba7970857a7c61b36 Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Sun, 8 Nov 2020 12:57:57 -0600 Subject: [PATCH 2/7] Coding standard patch --- src/Symfony/Component/Ldap/Entry.php | 15 +++++++-------- src/Symfony/Component/Ldap/Tests/EntryTest.php | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index aa45b9d0d41b1..c89f585086d9a 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -26,8 +26,7 @@ public function __construct(string $dn, array $attributes = []) $this->dn = $dn; $this->lowerMap = []; - foreach ($attributes as $key => $attribute) - { + foreach ($attributes as $key => $attribute) { $this->setAttribute($key, $attribute); } } @@ -45,8 +44,8 @@ public function getDn() /** * Returns whether an attribute exists. * - * @param string $name The name of the attribute - * @param bool $caseSensitive Whether the check should be case-sensitive + * @param string $name The name of the attribute + * @param bool $caseSensitive Whether the check should be case-sensitive * * @return bool */ @@ -67,8 +66,8 @@ public function hasAttribute(string $name, $caseSensitive = true) * 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 bool $caseSensitive Whether the attribute name is case-sensitive + * @param string $name The name of the attribute + * @param bool $caseSensitive Whether the attribute name is case-sensitive * * @return array|null */ @@ -114,8 +113,8 @@ public function removeAttribute(string $name) /** * Get the attribute key. * - * @param string $name The attribute name - * @param bool $caseSensitive Whether the attribute name is case-sensitive + * @param string $name The attribute name + * @param bool $caseSensitive Whether the attribute name is case-sensitive * * @return string|null */ diff --git a/src/Symfony/Component/Ldap/Tests/EntryTest.php b/src/Symfony/Component/Ldap/Tests/EntryTest.php index 940646765bc40..24a16c4b12190 100644 --- a/src/Symfony/Component/Ldap/Tests/EntryTest.php +++ b/src/Symfony/Component/Ldap/Tests/EntryTest.php @@ -29,7 +29,7 @@ public function testCaseSensitiveAttributeAccessors() $this->assertFalse($entry->hasAttribute('givenname', true)); $this->assertTrue($entry->hasAttribute('givenname', false)); - $this->assertSame(null, $entry->getAttribute('givenname', true)); + $this->assertNull($entry->getAttribute('givenname', true)); $this->assertSame($givenName, $entry->getAttribute('givenname', false)[0]); $firstName = 'Fabien'; From dc942bedb0e2a866074fd9c7e219e4b246835a4e Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Sun, 8 Nov 2020 20:55:56 -0600 Subject: [PATCH 3/7] Ensure that the default caseSensitive case is tested. --- src/Symfony/Component/Ldap/Tests/EntryTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Ldap/Tests/EntryTest.php b/src/Symfony/Component/Ldap/Tests/EntryTest.php index 24a16c4b12190..7185db1040281 100644 --- a/src/Symfony/Component/Ldap/Tests/EntryTest.php +++ b/src/Symfony/Component/Ldap/Tests/EntryTest.php @@ -26,10 +26,10 @@ public function testCaseSensitiveAttributeAccessors() 'givenName' => [$givenName], ]); - $this->assertFalse($entry->hasAttribute('givenname', true)); + $this->assertFalse($entry->hasAttribute('givenname')); $this->assertTrue($entry->hasAttribute('givenname', false)); - $this->assertNull($entry->getAttribute('givenname', true)); + $this->assertNull($entry->getAttribute('givenname')); $this->assertSame($givenName, $entry->getAttribute('givenname', false)[0]); $firstName = 'Fabien'; From 161ad7a0ca5070a1c5be1e88d73cbf3582a3b17f Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Fri, 13 Nov 2020 17:15:33 -0600 Subject: [PATCH 4/7] Initialize attributes to an empty array --- src/Symfony/Component/Ldap/Entry.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index c89f585086d9a..9471265537e34 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -24,6 +24,7 @@ class Entry public function __construct(string $dn, array $attributes = []) { $this->dn = $dn; + $this->attributes = []; $this->lowerMap = []; foreach ($attributes as $key => $attribute) { From bbb1ba171e2a6018b8c66fa3f49f4bde5edc0cbf Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Fri, 13 Nov 2020 17:34:12 -0600 Subject: [PATCH 5/7] Remove 4.x changelog entry --- src/Symfony/Component/Ldap/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Component/Ldap/CHANGELOG.md b/src/Symfony/Component/Ldap/CHANGELOG.md index 235a0ffe0363e..f54a3e824184e 100644 --- a/src/Symfony/Component/Ldap/CHANGELOG.md +++ b/src/Symfony/Component/Ldap/CHANGELOG.md @@ -16,7 +16,6 @@ CHANGELOG ----- * Added the "extra_fields" option, an array of custom fields to pull from the LDAP server - * Added caseSensitive option for attribute keys in the Entry class. 4.3.0 ----- From fe9b8c40642efc8699e2a80bc821b09579869421 Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Fri, 13 Nov 2020 17:54:40 -0600 Subject: [PATCH 6/7] Code style --- src/Symfony/Component/Ldap/Entry.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index 9471265537e34..9396f3b9afab6 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -54,7 +54,7 @@ public function hasAttribute(string $name, $caseSensitive = true) { $attributeKey = $this->getAttributeKey($name, $caseSensitive); - if (!$attributeKey) { + if (null === $attributeKey) { return false; } @@ -76,11 +76,11 @@ public function getAttribute(string $name, $caseSensitive = true) { $attributeKey = $this->getAttributeKey($name, $caseSensitive); - if (!$attributeKey) { + if (null === $attributeKey) { return null; } - return isset($this->attributes[$attributeKey]) ? $this->attributes[$attributeKey] : null; + return $this->attributes[$attributeKey] ?? null; } /** @@ -119,12 +119,12 @@ public function removeAttribute(string $name) * * @return string|null */ - private function getAttributeKey(string $name, $caseSensitive = true) + private function getAttributeKey(string $name, bool $caseSensitive = true): ?string { if ($caseSensitive) { return $name; } - return isset($this->lowerMap[strtolower($name)]) ? $this->lowerMap[strtolower($name)] : null; + return $this->lowerMap[strtolower($name)] ?? null; } } From f885afc3eba4178ab0bb11e320d3e11dc3be4fc7 Mon Sep 17 00:00:00 2001 From: Karl Shea Date: Fri, 13 Nov 2020 17:57:03 -0600 Subject: [PATCH 7/7] Code style --- src/Symfony/Component/Ldap/Entry.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index 9396f3b9afab6..1a156e5f2280c 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -116,8 +116,6 @@ public function removeAttribute(string $name) * * @param string $name The attribute name * @param bool $caseSensitive Whether the attribute name is case-sensitive - * - * @return string|null */ private function getAttributeKey(string $name, bool $caseSensitive = true): ?string {