Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[Ldap] Always have a valid connection when using the EntryManager
  • Loading branch information
bobvandevijver authored and fabpot committed Jan 12, 2017
1 parent 027d588 commit 7775ec2
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 7 deletions.
12 changes: 12 additions & 0 deletions src/Symfony/Component/Ldap/Adapter/EntryManagerInterface.php
Expand Up @@ -12,32 +12,44 @@
namespace Symfony\Component\Ldap\Adapter;

use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

/**
* Entry manager interface.
*
* @author Charles Sarrazin <charles@sarraz.in>
* @author Bob van de Vijver <bobvandevijver@hotmail.com>
*/
interface EntryManagerInterface
{
/**
* Adds a new entry in the Ldap server.
*
* @param Entry $entry
*
* @throws NotBoundException
* @throws LdapException
*/
public function add(Entry $entry);

/**
* Updates an entry from the Ldap server.
*
* @param Entry $entry
*
* @throws NotBoundException
* @throws LdapException
*/
public function update(Entry $entry);

/**
* Removes an entry from the Ldap server.
*
* @param Entry $entry
*
* @throws NotBoundException
* @throws LdapException
*/
public function remove(Entry $entry);
}
2 changes: 1 addition & 1 deletion src/Symfony/Component/Ldap/Adapter/ExtLdap/Adapter.php
Expand Up @@ -50,7 +50,7 @@ public function getConnection()
public function getEntryManager()
{
if (null === $this->entryManager) {
$this->entryManager = new EntryManager($this->connection);
$this->entryManager = new EntryManager($this->getConnection());
}

return $this->entryManager;
Expand Down
21 changes: 18 additions & 3 deletions src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php
Expand Up @@ -14,9 +14,11 @@
use Symfony\Component\Ldap\Adapter\EntryManagerInterface;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

/**
* @author Charles Sarrazin <charles@sarraz.in>
* @author Bob van de Vijver <bobvandevijver@hotmail.com>
*/
class EntryManager implements EntryManagerInterface
{
Expand All @@ -32,7 +34,7 @@ public function __construct(Connection $connection)
*/
public function add(Entry $entry)
{
$con = $this->connection->getResource();
$con = $this->getConnectionResource();

if (!@ldap_add($con, $entry->getDn(), $entry->getAttributes())) {
throw new LdapException(sprintf('Could not add entry "%s": %s', $entry->getDn(), ldap_error($con)));
Expand All @@ -46,7 +48,7 @@ public function add(Entry $entry)
*/
public function update(Entry $entry)
{
$con = $this->connection->getResource();
$con = $this->getConnectionResource();

if (!@ldap_modify($con, $entry->getDn(), $entry->getAttributes())) {
throw new LdapException(sprintf('Could not update entry "%s": %s', $entry->getDn(), ldap_error($con)));
Expand All @@ -58,10 +60,23 @@ public function update(Entry $entry)
*/
public function remove(Entry $entry)
{
$con = $this->connection->getResource();
$con = $this->getConnectionResource();

if (!@ldap_delete($con, $entry->getDn())) {
throw new LdapException(sprintf('Could not remove entry "%s": %s', $entry->getDn(), ldap_error($con)));
}
}

/**
* Get the connection resource, but first check if the connection is bound.
*/
private function getConnectionResource()
{
// If the connection is not bound, throw an exception. Users should use an explicit bind call first.
if (!$this->connection->isBound()) {
throw new NotBoundException('Query execution is not possible without binding the connection first.');
}

return $this->connection->getResource();
}
}
8 changes: 5 additions & 3 deletions src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php
Expand Up @@ -13,13 +13,15 @@

use Symfony\Component\Ldap\Adapter\AbstractQuery;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

/**
* @author Charles Sarrazin <charles@sarraz.in>
* @author Bob van de Vijver <bobvandevijver@hotmail.com>
*/
class Query extends AbstractQuery
{
/** @var Connection */
/** @var Connection */
protected $connection;

/** @var resource */
Expand Down Expand Up @@ -53,9 +55,9 @@ public function __destruct()
public function execute()
{
if (null === $this->search) {
// If the connection is not bound, then we try an anonymous bind.
// If the connection is not bound, throw an exception. Users should use an explicit bind call first.
if (!$this->connection->isBound()) {
$this->connection->bind();
throw new NotBoundException('Query execution is not possible without binding the connection first.');
}

$con = $this->connection->getResource();
Expand Down
6 changes: 6 additions & 0 deletions src/Symfony/Component/Ldap/Adapter/QueryInterface.php
Expand Up @@ -12,9 +12,12 @@
namespace Symfony\Component\Ldap\Adapter;

use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

/**
* @author Charles Sarrazin <charles@sarraz.in>
* @author Bob van de Vijver <bobvandevijver@hotmail.com>
*/
interface QueryInterface
{
Expand All @@ -27,6 +30,9 @@ interface QueryInterface
* Executes a query and returns the list of Ldap entries.
*
* @return CollectionInterface|Entry[]
*
* @throws NotBoundException
* @throws LdapException
*/
public function execute();
}
21 changes: 21 additions & 0 deletions src/Symfony/Component/Ldap/Exception/NotBoundException.php
@@ -0,0 +1,21 @@
<?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\Exception;

/**
* NotBoundException is thrown if the connection with the LDAP server is not yet bound.
*
* @author Bob van de Vijver <bobvandevijver@hotmail.com>
*/
class NotBoundException extends \RuntimeException implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/AdapterTest.php
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\Ldap\Adapter\ExtLdap\Adapter;
use Symfony\Component\Ldap\Adapter\ExtLdap\Collection;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\NotBoundException;
use Symfony\Component\Ldap\LdapInterface;

/**
Expand Down Expand Up @@ -65,4 +66,15 @@ public function testLdapQueryIterator()
$this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn'));
$this->assertEquals(array('fabpot@symfony.com', 'fabien@potencier.com'), $entry->getAttribute('mail'));
}

/**
* @group functional
*/
public function testLdapQueryWithoutBind()
{
$ldap = new Adapter($this->getLdapConfig());
$this->setExpectedException(NotBoundException::class);
$query = $ldap->createQuery('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))', array());
$query->execute();
}
}
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\Ldap\Adapter\ExtLdap\Collection;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

/**
* @requires extension ldap
Expand Down Expand Up @@ -98,6 +99,39 @@ public function testLdapUpdate()
$this->assertNull($entry->getAttribute('email'));
}

/**
* @group functional
*/
public function testLdapUnboundAdd()
{
$this->adapter = new Adapter($this->getLdapConfig());
$this->setExpectedException(NotBoundException::class);
$em = $this->adapter->getEntryManager();
$em->add(new Entry(''));
}

/**
* @group functional
*/
public function testLdapUnboundRemove()
{
$this->adapter = new Adapter($this->getLdapConfig());
$this->setExpectedException(NotBoundException::class);
$em = $this->adapter->getEntryManager();
$em->remove(new Entry(''));
}

/**
* @group functional
*/
public function testLdapUnboundUpdate()
{
$this->adapter = new Adapter($this->getLdapConfig());
$this->setExpectedException(NotBoundException::class);
$em = $this->adapter->getEntryManager();
$em->update(new Entry(''));
}

/**
* @return Collection|Entry[]
*/
Expand Down

0 comments on commit 7775ec2

Please sign in to comment.