From 32743c850f901b77b81232b9239b2128d5c6f041 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Mon, 3 Dec 2018 20:31:09 -0600 Subject: [PATCH] [Ldap] Entry move support --- .../Ldap/Adapter/EntryManagerInterface.php | 2 ++ .../Ldap/Adapter/ExtLdap/EntryManager.php | 25 +++++++++++++++++++ src/Symfony/Component/Ldap/CHANGELOG.md | 5 ++++ .../Tests/Adapter/ExtLdap/LdapManagerTest.php | 18 +++++++++++++ 4 files changed, 50 insertions(+) diff --git a/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php b/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php index 82c023d5ec06d..34b879a6f0204 100644 --- a/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php +++ b/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php @@ -21,6 +21,8 @@ * @author Charles Sarrazin * @author Bob van de Vijver * @author Kevin Schuurmans + * + * @method void move(Entry $entry, string $newParent) Moves an entry on the Ldap server */ interface EntryManagerInterface { diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php index f80601b3baa45..68778cb42dc10 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -110,6 +110,22 @@ public function rename(Entry $entry, $newRdn, $removeOldRdn = true) } } + /** + * Moves an entry on the Ldap server. + * + * @throws NotBoundException if the connection has not been previously bound. + * @throws LdapException if an error is thrown during the rename operation. + */ + public function move(Entry $entry, string $newParent) + { + $con = $this->getConnectionResource(); + $rdn = $this->parseRdnFromEntry($entry); + // deleteOldRdn does not matter here, since the Rdn will not be changing in the move. + if (!@ldap_rename($con, $entry->getDn(), $rdn, $newParent, true)) { + throw new LdapException(sprintf('Could not move entry "%s" to "%s": %s.', $entry->getDn(), $newParent, ldap_error($con))); + } + } + /** * Get the connection resource, but first check if the connection is bound. */ @@ -139,4 +155,13 @@ public function applyOperations(string $dn, iterable $operations): void throw new UpdateOperationException(sprintf('Error executing UpdateOperation on "%s": "%s".', $dn, ldap_error($this->getConnectionResource()))); } } + + private function parseRdnFromEntry(Entry $entry) + { + if (!preg_match('/^([^,]+),/', $entry->getDn(), $matches)) { + throw new LdapException(sprintf('Entry "%s" malformed, could not parse RDN', $entry->getDn())); + } + + return $matches[1]; + } } diff --git a/src/Symfony/Component/Ldap/CHANGELOG.md b/src/Symfony/Component/Ldap/CHANGELOG.md index 7dc0c81b3dfda..ef189219dcbca 100644 --- a/src/Symfony/Component/Ldap/CHANGELOG.md +++ b/src/Symfony/Component/Ldap/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.3.0 +----- + + * added `EntryManager::move`, not implementing it is deprecated + 4.2.0 ----- diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php index 70723515559d3..7b557eee7ef6b 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php @@ -341,4 +341,22 @@ public function testUpdateOperationsThrowsExceptionWhenAddedDuplicatedValue() $entryManager->applyOperations($entry->getDn(), $duplicateIterator); } + + /** + * @group functional + */ + public function testLdapMove() + { + $result = $this->executeSearchQuery(1); + + $entry = $result[0]; + $this->assertNotContains('ou=Ldap', $entry->getDn()); + + $entryManager = $this->adapter->getEntryManager(); + $entryManager->move($entry, 'ou=Ldap,ou=Components,dc=symfony,dc=com'); + + $result = $this->executeSearchQuery(1); + $movedEntry = $result[0]; + $this->assertContains('ou=Ldap', $movedEntry->getDn()); + } }