8000 bug #19980 [Ldap] Fixed issue with legacy find() method not working a… · symfony/symfony@d79dedf · GitHub
[go: up one dir, main page]

Skip to content

Commit d79dedf

Browse files
committed
bug #19980 [Ldap] Fixed issue with legacy find() method not working as expected (csarrazi)
This PR was merged into the 3.1 branch. Discussion ---------- [Ldap] Fixed issue with legacy find() method not working as expected | Q | A | ------------- | --- | Branch? | 3.1 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #19804 | License | MIT | Doc PR | This PR fixes two bugs. The first, with the legacy `LdapClient` class' `find()` method not working as expected, sometimes throwing errors, which is an after-effect of missing Ldap attributes normalisation in the ResultIterator, and the second one being that the `find()` method does not return the expected output, which should be the same as PHP's `ldap_get_entries()` method. As a reminder, this method should only be used by legacy software, which need to provide compatibility with Symfony 3.0 and Symfony 2.8. Commits ------- 3bae5ea Fixed issue with legacy find() method not working as expected
2 parents 23eee70 + 3bae5ea commit d79dedf

File tree

5 files changed

+106
-164
lines changed

5 files changed

+106
-164
lines changed

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

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,90 +24,102 @@ class Collection implements CollectionInterface
2424
private $search;
2525
private $entries;
2626

27-
public function __construct(Connection $connection, Query $search, array $entries = array())
27+
public function __construct(Connection $connection, Query $search)
2828
{
2929
$this->connection = $connection;
3030
$this->search = $search;
31-
$this->entries = array();
3231
}
3332

3433
/**
3534
* {@inheritdoc}
3635
*/
3736
public function toArray()
3837
{
39-
$this->initialize();
38+
if (null === $this->entries) {
39+
$this->entries = iterator_to_array($this->getIterator(), false);
40+
}
4041

4142
return $this->entries;
4243
}
4344

4445
public function count()
4546
{
46-
$this->initialize();
47+
if (false !== $count = ldap_count_entries($this->connection->getResource(), $this->search->getResource())) {
48+
return $count;
49+
}
4750

48-
return count($this->entries);
51+
throw new LdapException(sprintf('Error while retrieving entry count: %s', ldap_error($this->connection->getResource())));
4952
}
5053

5154
public function getIterator()
5255
{
53-
return new ResultIterator($this->connection, $this->search);
56+
$con = $this->connection->getResource();
57+
$search = $this->search->getResource();
58+
$current = ldap_first_entry($con, $search);
59+
60+
if (0 === $this->count()) {
61+
return;
62+
}
63+
64+
if (false === $current) {
65+
throw new LdapException(sprintf('Could not rewind entries array: %s', ldap_error($con)));
66+
}
67+
68+
yield $this->getSingleEntry($con, $current);
69+
70+
while (false !== $current = ldap_next_entry($con, $current)) {
71+
yield $this->getSingleEntry($con, $current);
72+
}
5473
}
5574

5675
public function offsetExists($offset)
5776
{
58-
$this->initialize();
77+
$this->toArray();
5978

6079
return isset($this->entries[$offset]);
6180
}
6281

6382
public function offsetGet($offset)
6483
{
84+
$this->toArray();
85+
6586
return isset($this->entries[$offset]) ? $this->entries[$offset] : null;
6687
}
6788

6889
public function offsetSet($offset, $value)
6990
{
70-
$this->initialize();
91+
$this->toArray();
7192

7293
$this->entries[$offset] = $value;
7394
}
7495

7596
public function offsetUnset($offset)
7697
{
77-
$this->initialize();
98+
$this->toArray();
7899

79100
unset($this->entries[$offset]);
80101
}
81102

82-
private function initialize()
103+
private function getSingleEntry($con, $current)
83104
{
84-
if (null === $this->entries) {
85-
return;
86-
}
105+
$attributes = ldap_get_attributes($con, $current);
87106

88-
$con = $this->connection->getResource();
89-
90-
$entries = ldap_get_entries($con, $this->search->getResource());
91-
92-
if (false === $entries) {
93-
throw new LdapException(sprintf('Could not load entries: %s', ldap_error($con)));
107+
if (false === $attributes) {
108+
throw new LdapException(sprintf('Could not fetch attributes: %s', ldap_error($con)));
94109
}
95110

96-
if (0 === $entries['count']) {
97-
return array();
98-
}
111+
$attributes = $this->cleanupAttributes($attributes);
99112

100-
unset($entries['count']);
113+
$dn = ldap_get_dn($con, $current);
101114

102-
$this->entries = array_map(function (array $entry) {
103-
$dn = $entry['dn'];
104-
$attributes = $this->cleanupAttributes($entry);
115+
if (false === $dn) {
116+
throw new LdapException(sprintf('Could not fetch DN: %s', ldap_error($con)));
117+
}
105118

106-
return new Entry($dn, $attributes);
107-
}, $entries);
119+
return new Entry($dn, $attributes);
108120
}
109121

110-
private function cleanupAttributes(array $entry = array())
122+
private function cleanupAttributes(array $entry)
111123
{
112124
$attributes = array_diff_key($entry, array_flip(range(0, $entry['count'] - 1)) + array(
113125
'count' => null,

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

Lines changed: 0 additions & 81 deletions
This file was deleted.

src/Symfony/Component/Ldap/LdapClient.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,34 @@ public function find($dn, $query, $filter = '*')
6464

6565
$query = $this->ldap->query($dn, $query, array('filter' => $filter));
6666
$entries = $query->execute();
67-
$result = array();
67+
$result = array(
68+
'count' => 0,
69+
);
6870

6971
foreach ($entries as $entry) {
7072
$resultEntry = array();
7173

7274
foreach ($entry->getAttributes() as $attribute => $values) {
73-
$resultAttribute = $values;
75+
$resultAttribute = array(
76+
'count' => count($values),
77+
);
78+
79+
foreach ($values as $val) {
80+
$resultAttribute[] = $val;
81+
}
82+
$attributeName = strtolower($attribute);
7483

7584
$resultAttribute['count'] = count($values);
76-
$resultEntry[] = $resultAttribute;
77-
$resultEntry[$attribute] = $resultAttribute;
85+
$resultEntry[$attributeName] = $resultAttribute;
86+
$resultEntry[] = $attributeName;
7887
}
7988

8089
$resultEntry['count'] = count($resultEntry) / 2;
90+
$resultEntry['dn'] = $entry->getDn();
8191
$result[] = $resultEntry;
8292
}
8393

84-
$result['count'] = count($result);
94+
$result['count'] = count($result) - 1;
8595

8696
return $result;
8797
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,22 @@ public function testLdapQuery()
4747
$this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn'));
4848
$this->assertEquals(array('fabpot@symfony.com', 'fabien@potencier.com'), $entry->getAttribute('mail'));
4949
}
50+
51+
/**
52+
* @group functional
53+
*/
54+
public function testLdapQueryIterator()
55+
{
56+
$ldap = new Adapter($this->getLdapConfig());
57+
58+
$ldap->getConnection()->bind('cn=admin,dc=symfony,dc=com', 'symfony');
59+
$query = $ldap->createQuery('dc=symfony,dc=com', '(&(objectclass=person)(ou=Maintainers))', array());
60+
$result = $query->execute();
61+
$iterator = $result->getIterator();
62+
$iterator->rewind();
63+
$entry = $iterator->current();
64+
$this->assertInstanceOf(Entry::class, $entry);
65+
$this->assertEquals(array('Fabien Potencier'), $entry->getAttribute('cn'));
66+
$this->assertEquals(array('fabpot@symfony.com', 'fabien@potencier.com'), $entry->getAttribute('mail'));
67+
}
5068
}

0 commit comments

Comments
 (0)
0