8000 [LDAP] Add "applyOperations" method to EntryManager by mablae · Pull Request #27069 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[LDAP] Add "applyOperations" method to EntryManager #27069

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\Ldap\Adapter\EntryManagerInterface;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\UpdateOperationException;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

Expand Down Expand Up @@ -121,4 +122,21 @@ private function getConnectionResource()

return $this->connection->getResource();
}

/**
* @param iterable|UpdateOperation[] $operations An array or iterable of UpdateOperation instances
*
* @throws UpdateOperationException in case of an error
*/
public function applyOperations(string $dn, iterable $operations): void
{
$operationsMapped = array();
foreach ($operations as $modification) {
$operationsMapped[] = $modification->toArray();
}

if (!@ldap_modify_batch($this->getConnectionResource(), $dn, $operationsMapped)) {
throw new UpdateOperationException(sprintf('Error executing UpdateOperation on "%s": "%s".', $dn, ldap_error($this->getConnectionResource())));
}
}
}
76 changes: 76 additions & 0 deletions src/Symfony/Component/Ldap/Adapter/ExtLdap/UpdateOperation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?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\Exception\UpdateOperationException;

class UpdateOperation
{
private $operationType;
private $values;
private $attribute;

private $validOperationTypes = array(
LDAP_MODIFY_BATCH_ADD,
LDAP_MODIFY_BATCH_REMOVE,
LDAP_MODIFY_BATCH_REMOVE_ALL,
LDAP_MODIFY_BATCH_REPLACE,
);

/**
* @param int $operationType An LDAP_MODIFY_BATCH_* constant
* @param string $attribute The attribute to batch modify on
*
* @throws UpdateOperationException on consistency errors during construction
*/
public function __construct(int $operationType, string $attribute, ?array $values)
{
$this->assertValidOperationType($operationType);
$this->assertNullValuesOnRemoveAll($operationType, $values);

$this->operationType = $operationType;
$this->attribute = $attribute;
$this->values = $values;
}

public function toArray(): array
{
return array(
'attrib' => $this->attribute,
'modtype' => $this->operationType,
'values' => $this->values,
);
}

/**
* @param int $operationType
*/
private function assertValidOperationType(int $operationType): void
{
if (!in_array($operationType, $this->validOperationTypes, true)) {
throw new UpdateOperationException(sprintf('"%s" is not a valid modification type.', $operationType));
}
}

/**
* @param int $operationType
* @param array|null $values
*
* @throws \Symfony\Component\Ldap\Exception\UpdateOperationException
*/
private function assertNullValuesOnRemoveAll(int $operationType, ?array $values): void
{
if (LDAP_MODIFY_BATCH_REMOVE_ALL === $operationType && null !== $values) {
throw new UpdateOperationException(sprintf('$values must be null for LDAP_MODIFY_BATCH_REMOVE_ALL operation, "%s" given.', gettype($values)));
}
}
}
16 changes: 16 additions & 0 deletions src/Symfony/Component/Ldap/Exception/UpdateOperationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?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;

class UpdateOperationException extends LdapException
{
}
103 changes: 103 additions & 0 deletions src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/LdapManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

use Symfony\Component\Ldap\Adapter\ExtLdap\Adapter;
use Symfony\Component\Ldap\Adapter\ExtLdap\Collection;
use Symfony\Component\Ldap\Adapter\ExtLdap\UpdateOperation;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\UpdateOperationException;
use Symfony\Component\Ldap\Exception\LdapException;
use Symfony\Component\Ldap\Exception\NotBoundException;

Expand Down Expand Up @@ -238,4 +240,105 @@ public function testLdapAddAttributeValuesError()

$entryManager->addAttributeValues($entry, 'mail', $entry->getAttribute('mail'));
}

public function testLdapApplyOperationsRemoveAllWithArrayError()
{
$entryManager = $this->adapter->getEntryManager();

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(UpdateOperationException::class);

$entryManager->applyOperations($entry->getDn(), array(new UpdateOperation(LDAP_MODIFY_BATCH_REMOVE_ALL, 'mail', array())));
}

public function testLdapApplyOperationsWithWrongConstantError()
{
$entryManager = $this->adapter->getEntryManager();

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(UpdateOperationException::class);

$entryManager->applyOperations($entry->getDn(), array(new UpdateOperation(512, 'mail', array())));
}

public function testApplyOperationsAddRemoveAttributeValues()
{
$entryManager = $this->adapter->getEntryManager();

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$entryManager->applyOperations($entry->getDn(), array(
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'mail', array('fabpot@example.org', 'fabpot2@example.org')),
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'mail', array('fabpot3@example.org', 'fabpot4@example.org')),
));

$result = $this->executeSearchQuery(1);
$newEntry = $result[0];

$this->assertCount(6, $newEntry->getAttribute('mail'));

$entryManager->applyOperations($entry->getDn(), array(
new UpdateOperation(LDAP_MODIFY_BATCH_REMOVE, 'mail', array('fabpot@example.org', 'fabpot2@example.org')),
new UpdateOperation(LDAP_MODIFY_BATCH_REMOVE, 'mail', array('fabpot3@example.org', 'fabpot4@example.org')),
));

$result = $this->executeSearchQuery(1);
$newNewEntry = $result[0];

$this->assertCount(2, $newNewEntry->getAttribute('mail'));
}

public function testUpdateOperationsWithIterator()
{
$iteratorAdd = new \ArrayIterator(array(
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'mail', array('fabpot@example.org', 'fabpot2@example.org')),
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'mail', array('fabpot3@example.org', 'fabpot4@example.org')),
));

$iteratorRemove = new \ArrayIterator(array(
new UpdateOperation(LDAP_MODIFY_BATCH_REMOVE, 'mail', array('fabpot@example.org', 'fabpot2@example.org')),
new UpdateOperation(LDAP_MODIFY_BATCH_REMOVE, 'mail', array('fabpot3@example.org', 'fabpot4@example.org')),
));

$entryManager = $this->adapter->getEntryManager();

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$entryManager->applyOperations($entry->getDn(), $iteratorAdd);

$result = $this->executeSearchQuery(1);
$newEntry = $result[0];

$this->assertCount(6, $newEntry->getAttribute('mail'));

$entryManager->applyOperations($entry->getDn(), $iteratorRemove);

$result = $this->executeSearchQuery(1);
$newNewEntry = $result[0];

$this->assertCount(2, $newNewEntry->getAttribute('mail'));
}

public function testUpdateOperationsThrowsExceptionWhenAddedDuplicatedValue()
{
$duplicateIterator = new \ArrayIterator(array(
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'mail', array('fabpot@example.org')),
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'mail', array('fabpot@example.org')),
));

$entryManager = $this->adapter->getEntryManager();

$result = $this->executeSearchQuery(1);
$entry = $result[0];

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(UpdateOperationException::class);

$entryManager->applyOperations($entry->getDn(), $duplicateIterator);
}
}
0