From dfd04ff3a619d07aca77adbc3606b5fd952a8531 Mon Sep 17 00:00:00 2001 From: Charles Sarrazin Date: Wed, 17 Feb 2016 20:52:41 +0100 Subject: [PATCH] Added support for adding / removing / updating Ldap entries --- .../Ldap/Adapter/AdapterInterface.php | 7 ++ .../Ldap/Adapter/EntryManagerInterface.php | 43 +++++++ .../Ldap/Adapter/ExtLdap/Adapter.php | 13 ++ .../Ldap/Adapter/ExtLdap/EntryManager.php | 67 ++++++++++ src/Symfony/Component/Ldap/Entry.php | 21 ++++ src/Symfony/Component/Ldap/Ldap.php | 8 ++ src/Symfony/Component/Ldap/LdapInterface.php | 6 + .../Tests/Adapter/ExtLdap/LdapManagerTest.php | 116 ++++++++++++++++++ 8 files changed, 281 insertions(+) create mode 100644 src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php create mode 100644 src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php create mode 100644 src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php diff --git a/src/Symfony/Component/Ldap/Adapter/AdapterInterface.php b/src/Symfony/Component/Ldap/Adapter/AdapterInterface.php index 1e2f72d5bddff..cc9a7a63e986f 100644 --- a/src/Symfony/Component/Ldap/Adapter/AdapterInterface.php +++ b/src/Symfony/Component/Ldap/Adapter/AdapterInterface.php @@ -34,6 +34,13 @@ public function getConnection(); */ public function createQuery($dn, $query, array $options = array()); + /** + * Fetches the entry manager instance. + * + * @return EntryManagerInterface + */ + public function getEntryManager(); + /** * Escape a string for use in an LDAP filter or DN. * diff --git a/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php b/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php new file mode 100644 index 0000000000000..b53e2e0662b3b --- /dev/null +++ b/src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Ldap\Adapter; + +use Symfony\Component\Ldap\Entry; + +/** + * Entry manager interface. + * + * @author Charles Sarrazin + */ +interface EntryManagerInterface +{ + /** + * Adds a new entry in the Ldap server. + * + * @param Entry $entry + */ + public function add(Entry $entry); + + /** + * Updates an entry from the Ldap server. + * + * @param Entry $entry + */ + public function update(Entry $entry); + + /** + * Removes an entry from the Ldap server. + * + * @param Entry $entry + */ + public function remove(Entry $entry); +} diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Adapter.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Adapter.php index 4bf0303df0574..545d5d69a75d4 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Adapter.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Adapter.php @@ -21,6 +21,7 @@ class Adapter implements AdapterInterface { private $config; private $connection; + private $entryManager; public function __construct(array $config = array()) { @@ -43,6 +44,18 @@ public function getConnection() return $this->connection; } + /** + * {@inheritdoc} + */ + public function getEntryManager() + { + if (null === $this->entryManager) { + $this->entryManager = new EntryManager($this->connection); + } + + return $this->entryManager; + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php new file mode 100644 index 0000000000000..18043ccc9919a --- /dev/null +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Ldap\Adapter\ExtLdap; + +use Symfony\Component\Ldap\Adapter\EntryManagerInterface; +use Symfony\Component\Ldap\Entry; +use Symfony\Component\Ldap\Exception\LdapException; + +/** + * @author Charles Sarrazin + */ +class EntryManager implements EntryManagerInterface +{ + private $connection; + + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * {@inheritdoc} + */ + public function add(Entry $entry) + { + $con = $this->connection->getResource(); + + if (!@ldap_add($con, $entry->getDn(), $entry->getAttributes())) { + throw new LdapException(sprintf('Could not add entry "%s": %s', $entry->getDn(), ldap_error($con))); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function update(Entry $entry) + { + $con = $this->connection->getResource(); + + if (!@ldap_modify($con, $entry->getDn(), $entry->getAttributes())) { + throw new LdapException(sprintf('Could not update entry "%s": %s', $entry->getDn(), ldap_error($con))); + } + } + + /** + * {@inheritdoc} + */ + public function remove(Entry $entry) + { + $con = $this->connection->getResource(); + + if (!@ldap_delete($con, $entry->getDn())) { + throw new LdapException(sprintf('Could not remove entry "%s": %s', $entry->getDn(), ldap_error($con))); + } + } +} diff --git a/src/Symfony/Component/Ldap/Entry.php b/src/Symfony/Component/Ldap/Entry.php index f4da743742b57..3248d96d999eb 100644 --- a/src/Symfony/Component/Ldap/Entry.php +++ b/src/Symfony/Component/Ldap/Entry.php @@ -59,4 +59,25 @@ public function getAttributes() { return $this->attributes; } + + /** + * Sets a value for the given attribute. + * + * @param $name + * @param array $value + */ + public function setAttribute($name, array $value) + { + $this->attributes[$name] = $value; + } + + /** + * Removes a given attribute. + * + * @param $name + */ + public function removeAttribute($name) + { + unset($this->attributes[$name]); + } } diff --git a/src/Symfony/Component/Ldap/Ldap.php b/src/Symfony/Component/Ldap/Ldap.php index 82a443ca57f77..514f51d22c21a 100644 --- a/src/Symfony/Component/Ldap/Ldap.php +++ b/src/Symfony/Component/Ldap/Ldap.php @@ -46,6 +46,14 @@ public function query($dn, $query, array $options = array()) return $this->adapter->createQuery($dn, $query, $options); } + /** + * {@inheritdoc} + */ + public function getEntryManager() + { + return $this->adapter->getEntryManager(); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Ldap/LdapInterface.php b/src/Symfony/Component/Ldap/LdapInterface.php index 8f89bd60dfd99..767aa83dd1143 100644 --- a/src/Symfony/Component/Ldap/LdapInterface.php +++ b/src/Symfony/Component/Ldap/LdapInterface.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Ldap; +use Symfony\Component\Ldap\Adapter\EntryManagerInterface; use Symfony\Component\Ldap\Adapter\QueryInterface; /** @@ -33,4 +34,9 @@ interface LdapInterface extends BaseLdapInterface * @return QueryInterface */ public function query($dn, $query, array $options = array()); + + /** + * @return EntryManagerInterface + */ + public function getEntryManager(); } diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php new file mode 100644 index 0000000000000..6bf1003de173a --- /dev/null +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php @@ -0,0 +1,116 @@ + + * + * 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 Symfony\Component\Ldap\Adapter\ExtLdap\Adapter; +use Symfony\Component\Ldap\Adapter\ExtLdap\Collection; +use Symfony\Component\Ldap\Entry; +use Symfony\Component\Ldap\Exception\LdapException; + +/** + * @requires extension ldap + */ +class LdapManagerTest extends \PHPUnit_Framework_TestCase +{ + /** @var Adapter */ + private $adapter; + + protected function setUp() + { + $this->adapter = new Adapter(array('host' => 'localhost', 'port' => 3389)); + $this->adapter->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony'); + } + + /** + * @group functional + */ + public function testLdapAddAndRemove() + { + $this->executeSearchQuery(1); + + $entry = new Entry('cn=Charles Sarrazin,dc=symfony,dc=com', array( + 'sn' => array('csarrazi'), + 'objectclass' => array( + 'inetOrgPerson', + ), + )); + + $em = $this->adapter->getEntryManager(); + $em->add($entry); + + $this->executeSearchQuery(2); + + $em->remove($entry); + $this->executeSearchQuery(1); + } + + /** + * @group functional + */ + public function testLdapAddInvalidEntry() + { + $this->setExpectedException(LdapException::class); + $this->executeSearchQuery(1); + + // The entry is missing a subject name + $entry = new Entry('cn=Charles Sarrazin,dc=symfony,dc=com', array( + 'objectclass' => array( + 'inetOrgPerson', + ), + )); + + $em = $this->adapter->getEntryManager(); + $em->add($entry); + } + + /** + * @group functional + */ + public function testLdapUpdate() + { + $result = $this->executeSearchQuery(1); + + $entry = $result[0]; + $this->assertNull($entry->getAttribute('email')); + + $em = $this->adapter->getEntryManager(); + $em->update($entry); + + $result = $this->executeSearchQuery(1); + + $entry = $result[0]; + $this->assertNull($entry->getAttribute('email')); + + $entry->removeAttribute('email'); + $em->update($entry); + + $result = $this->executeSearchQuery(1); + $entry = $result[0]; + $this->assertNull($entry->getAttribute('email')); + } + + /** + * @return Collection|Entry[] + */ + private function executeSearchQuery($expectedResults = 1) + { + $results = $this + ->adapter + ->createQuery('dc=symfony,dc=com', '(objectclass=person)') + ->execute() + ; + + $this->assertCount($expectedResults, $results); + + return $results; + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy