Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e837b34

Browse files
committed
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
2 parents 45caae4 + dfd04ff commit e837b34

File tree

8 files changed

+281
-0
lines changed

8 files changed

+281
-0
lines changed

src/Symfony/Component/Ldap/Adapter/AdapterInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ public function getConnection();
3434
*/
3535
public function createQuery($dn, $query, array $options = array());
3636

37+
/**
38+
* Fetches the entry manager instance.
39+
*
40+
* @return EntryManagerInterface
41+
*/
42+
public function getEntryManager();
43+
3744
/**
3845
* Escape a string for use in an LDAP filter or DN.
3946
*
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Ldap\Adapter;
13+
14+
use Symfony\Component\Ldap\Entry;
15+
16+
/**
17+
* Entry manager interface.
18+
*
19+
* @author Charles Sarrazin <[email protected]>
20+
*/
21+
interface EntryManagerInterface
22+
{
23+
/**
24+
* Adds a new entry in the Ldap server.
25+
*
26+
* @param Entry $entry
27+
*/
28+
public function add(Entry $entry);
29+
30+
/**
31+
* Updates an entry from the Ldap server.
32+
*
33+
* @param Entry $entry
34+
*/
35+
public function update(Entry $entry);
36+
37+
/**
38+
* Removes an entry from the Ldap server.
39+
*
40+
* @param Entry $entry
41+
*/
42+
public function remove(Entry $entry);
43+
}

src/Symfony/Component/Ldap/Adapter/ExtLdap/Adapter.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class Adapter implements AdapterInterface
2121
{
2222
private $config;
2323
private $connection;
24+
private $entryManager;
2425

2526
public function __construct(array $config = array())
2627
{
@@ -43,6 +44,18 @@ public function getConnection()
4344
return $this->connection;
4445
}
4546

47+
/**
48+
* {@inheritdoc}
49+
*/
50+
public function getEntryManager()
51+
{
52+
if (null === $this->entryManager) {
53+
$this->entryManager = new EntryManager($this->connection);
54+
}
55+
56+
return $this->entryManager;
57+
}
58+
4659
/**
4760
* {@inheritdoc}
4861
*/
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Ldap\Adapter\ExtLdap;
13+
14+
use Symfony\Component\Ldap\Adapter\EntryManagerInterface;
15+
use Symfony\Component\Ldap\Entry;
16+
use Symfony\Component\Ldap\Exception\LdapException;
17+
18+
/**
19+
* @author Charles Sarrazin <[email protected]>
20+
*/
21+
class EntryManager implements EntryManagerInterface
22+
{
23+
private $connection;
24+
25+
public function __construct(Connection $connection)
26+
{
27+
$this->connection = $connection;
28+
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public function add(Entry $entry)
34+
{
35+
$con = $this->connection->getResource();
36+
37+
if (!@ldap_add($con, $entry->getDn(), $entry->getAttributes())) {
38+
throw new LdapException(sprintf('Could not add entry "%s": %s', $entry->getDn(), ldap_error($con)));
39+
}
40+
41+
return $this;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function update(Entry $entry)
48+
{
49+
$con = $this->connection->getResource();
50+
51+
if (!@ldap_modify($con, $entry->getDn(), $entry->getAttributes())) {
52+
throw new LdapException(sprintf('Could not update entry "%s": %s', $entry->getDn(), ldap_error($con)));
53+
}
54+
}
55+
56+
/**
57+
* {@inheritdoc}
58+
*/
59+
public function remove(Entry $entry)
60+
{
61+
$con = $this->connection->getResource();
62+
63+
if (!@ldap_delete($con, $entry->getDn())) {
64+
throw new LdapException(sprintf('Could not remove entry "%s": %s', $entry->getDn(), ldap_error($con)));
65+
}
66+
}
67+
}

src/Symfony/Component/Ldap/Entry.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,25 @@ public function getAttributes()
5959
{
6060
return $this->attributes;
6161
}
62+
63+
/**
64+
* Sets a value for the given attribute.
65+
*
66+
* @param $name
67+
* @param array $value
68+
*/
69+
public function setAttribute($name, array $value)
70+
{
71+
$this->attributes[$name] = $value;
72+
}
73+
74+
/**
75+
* Removes a given attribute.
76+
*
77+
* @param $name
78+
*/
79+
public function removeAttribute($name)
80+
{
81+
unset($this->attributes[$name]);
82+
}
6283
}

src/Symfony/Component/Ldap/Ldap.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ public function query($dn, $query, array $options = array())
4646
return $this->adapter->createQuery($dn, $query, $options);
4747
}
4848

49+
/**
50+
* {@inheritdoc}
51+
*/
52+
public function getEntryManager()
53+
{
54+
return $this->adapter->getEntryManager();
55+
}
56+
4957
/**
5058
* {@inheritdoc}
5159
*/

src/Symfony/Component/Ldap/LdapInterface.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Ldap;
1313

14+
use Symfony\Component\Ldap\Adapter\EntryManagerInterface;
1415
use Symfony\Component\Ldap\Adapter\QueryInterface;
1516

1617
/**
@@ -33,4 +34,9 @@ interface LdapInterface extends BaseLdapInterface
3334
* @return QueryInterface
3435
*/
3536
public function query($dn, $query, array $options = array());
37+
38+
/**
39+
* @return EntryManagerInterface
40+
*/
41+
public function getEntryManager();
3642
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Ldap\Tests;
13+
14+
use Symfony\Component\Ldap\Adapter\ExtLdap\Adapter;
15+
use Symfony\Component\Ldap\Adapter\ExtLdap\Collection;
16+
use Symfony\Component\Ldap\Entry;
17+
use Symfony\Component\Ldap\Exception\LdapException;
18+
19+
/**
20+
* @requires extension ldap
21+
*/
22+
class LdapManagerTest extends \PHPUnit_Framework_TestCase
23+
{
24+
/** @var Adapter */
25+
private $adapter;
26+
27+
protected function setUp()
28+
{
29+
$this->adapter = new Adapter(array('host' => 'localhost', 'port' => 3389));
30+
$this->adapter->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony');
31+
}
32+
33+
/**
34+
* @group functional
35+
*/
36+
public function testLdapAddAndRemove()
37+
{
38+
$this->executeSearchQuery(1);
39+
40+
$entry = new Entry('cn=Charles Sarrazin,dc=symfony,dc=com', array(
41+
'sn' => array('csarrazi'),
42+
'objectclass' => array(
43+
'inetOrgPerson',
44+
),
45+
));
46+
47+
$em = $this->adapter->getEntryManager();
48+
$em->add($entry);
49+
50+
$this->executeSearchQuery(2);
51+
52+
$em->remove($entry);
53+
$this->executeSearchQuery(1);
54+
}
55+
56+
/**
57+
* @group functional
58+
*/
59+
public function testLdapAddInvalidEntry()
60+
{
61+
$this->setExpectedException(LdapException::class);
62+
$this->executeSearchQuery(1);
63+
64+
// The entry is missing a subject name
65+
$entry = new Entry('cn=Charles Sarrazin,dc=symfony,dc=com', array(
66+
'objectclass' => array(
67+
'inetOrgPerson',
68+
),
69+
));
70+
71+
$em = $this->adapter->getEntryManager();
72+
$em->add($entry);
73+
}
74+
75+
/**
76+
* @group functional
77+
*/
78+
public function testLdapUpdate()
79+
{
80+
$result = $this->executeSearchQuery(1);
81+
82+
$entry = $result[0];
83+
$this->assertNull($entry->getAttribute('email'));
84+
85+
$em = $this->adapter->getEntryManager();
86+
$em->update($entry);
87+
88+
$result = $this->executeSearchQuery(1);
89+
90+
$entry = $result[0];
91+
$this->assertNull($entry->getAttribute('email'));
92+
93+
$entry->removeAttribute('email');
94+
$em->update($entry);
95+
96+
$result = $this->executeSearchQuery(1);
97+
$entry = $result[0];
98+
$this->assertNull($entry->getAttribute('email'));
99+
}
100+
101+
/**
102+
* @return Collection|Entry[]
103+
*/
104+
private function executeSearchQuery($expectedResults = 1)
105+
{
106+
$results = $this
107+
->adapter
108+
->createQuery('dc=symfony,dc=com', '(objectclass=person)')
109+
->execute()
110+
;
111+
112+
$this->assertCount($expectedResults, $results);
113+
114+
return $results;
115+
}
116+
}

0 commit comments

Comments
 (0)