feature #17817 [Ldap] Add write support for the Ldap component (csarrazi)
This PR was merged into the 3.1-dev branch.
Discussion
----------
[Ldap] Add write support for the Ldap component
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | yes
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #17679
| License | MIT
| Doc PR | no
This PR implements write support for the Ldap component.
Commits
-------
dfd04ff
Added support for adding / removing / updating Ldap entries
This commit is contained in:
commit
e837b34c34
@ -34,6 +34,13 @@ interface AdapterInterface
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
43
src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php
Normal file
43
src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <charles@sarraz.in>
|
||||
*/
|
||||
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);
|
||||
}
|
@ -21,6 +21,7 @@ class Adapter implements AdapterInterface
|
||||
{
|
||||
private $config;
|
||||
private $connection;
|
||||
private $entryManager;
|
||||
|
||||
public function __construct(array $config = array())
|
||||
{
|
||||
@ -43,6 +44,18 @@ class Adapter implements AdapterInterface
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEntryManager()
|
||||
{
|
||||
if (null === $this->entryManager) {
|
||||
$this->entryManager = new EntryManager($this->connection);
|
||||
}
|
||||
|
||||
return $this->entryManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
67
src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php
Normal file
67
src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <charles@sarraz.in>
|
||||
*/
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
@ -59,4 +59,25 @@ class Entry
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,14 @@ final class Ldap implements LdapInterface
|
||||
return $this->adapter->createQuery($dn, $query, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEntryManager()
|
||||
{
|
||||
return $this->adapter->getEntryManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user