modify - add, delete, replace

This commit is contained in:
Roland Gruber 2018-09-15 15:03:47 +02:00
parent fe3c054825
commit 5b81c8e03c
2 changed files with 363 additions and 15 deletions

View File

@ -82,6 +82,9 @@ class Importer {
$currentEntry[sizeof($currentEntry) - 1] .= substr($line, 1); $currentEntry[sizeof($currentEntry) - 1] .= substr($line, 1);
} }
} }
elseif ($line === '-') {
$currentEntry[] = $line;
}
else { else {
$parts = explode(':', $line, 2); $parts = explode(':', $line, 2);
if (sizeof($parts) < 2) { if (sizeof($parts) < 2) {
@ -284,6 +287,9 @@ class Importer {
} }
return new DeleteEntryTask($dn); return new DeleteEntryTask($dn);
} }
elseif ($type !== 'modify') {
throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . ' - changeType: ' . htmlspecialchars($type));
}
$changes = array(); $changes = array();
$subtasks = array(); $subtasks = array();
$currentLines = array(); $currentLines = array();
@ -291,18 +297,14 @@ class Importer {
for ($i = 0; $i < $linesCount; $i++) { for ($i = 0; $i < $linesCount; $i++) {
$line = $entry[$i]; $line = $entry[$i];
if ($line === '-') { if ($line === '-') {
$subtasks[] = $this->getChangeTypeTask($dn, $currentLines, $type); $subtasks[] = $this->getChangeTypeTask($dn, $currentLines);
$currentLines = array(); $currentLines = array();
$i++;
$line = $entry[$i];
$lineTypeData = $this->getLineKeyValue($line);
if ($lineTypeData[Importer::KEY] != Importer::CHANGETYPE) {
throw new LAMException(_('Invalid data'), htmlspecialchars($line));
}
} }
$currentLines[] = $line; else {
$currentLines[] = $line;
}
} }
$subtasks[] = $this->getChangeTypeTask($dn, $currentLines, $type); $subtasks[] = $this->getChangeTypeTask($dn, $currentLines);
return new MultiTask($subtasks, $dn); return new MultiTask($subtasks, $dn);
} }
} }
@ -326,7 +328,7 @@ class Importer {
$newRdn = $newRdnData[Importer::VALUE]; $newRdn = $newRdnData[Importer::VALUE];
$delOldRdnData = $this->getLineKeyValue($entry[1]); $delOldRdnData = $this->getLineKeyValue($entry[1]);
if (($delOldRdnData[Importer::KEY] !== 'deleteoldrdn') || !in_array($delOldRdnData[Importer::VALUE], array('0', '1'), true)) { if (($delOldRdnData[Importer::KEY] !== 'deleteoldrdn') || !in_array($delOldRdnData[Importer::VALUE], array('0', '1'), true)) {
throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . '<br>' . $delOldRdnData); throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . '<br>' . $entry[1]);
} }
$delOldRdn = ($delOldRdnData[Importer::VALUE] === '0') ? false : true; $delOldRdn = ($delOldRdnData[Importer::VALUE] === '0') ? false : true;
return new RenameEntryTask($dn, $newRdn, $delOldRdn); return new RenameEntryTask($dn, $newRdn, $delOldRdn);
@ -337,19 +339,31 @@ class Importer {
* *
* @param string $dn DN * @param string $dn DN
* @param string $lines lines * @param string $lines lines
* @param string $type change type
* @return ImporterTask task * @return ImporterTask task
*/ */
private function getChangeTypeTask($dn, $lines, $type) { private function getChangeTypeTask($dn, $lines) {
$firstLine = array_shift($lines);
$firstLineData = $this->getLineKeyValue($firstLine);
$type = $firstLineData[Importer::KEY];
$attributeName = $firstLineData[Importer::VALUE];
$attributes = array(); $attributes = array();
foreach ($lines as $line) { foreach ($lines as $line) {
$lineData = $this->getLineKeyValue($line); $lineData = $this->getLineKeyValue($line);
$attributes[$lineData[Importer::KEY]][] = $lineData[Importer::VALUE]; if ($lineData[Importer::KEY] !== $attributeName) {
throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . ' - ' . htmlspecialchars($type));
}
$attributes[$attributeName][] = $lineData[Importer::VALUE];
} }
if ($type === 'add') { if ($type === 'add') {
return new AddEntryTask($dn, $attributes); return new AddAttributesTask($dn, $attributes);
} }
throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . ' - ' . Importer::CHANGETYPE . ': ' . htmlspecialchars($type)); elseif ($type === 'delete') {
return new DeleteAttributesTask($dn, $attributeName, $attributes);
}
elseif ($type === 'replace') {
return new ReplaceAttributesTask($dn, $attributes);
}
throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . ' - ' . htmlspecialchars($type));
} }
/** /**
@ -599,6 +613,158 @@ class AddAttributesTask implements ImporterTask {
throw new LAMException(sprintf(_('Was unable to create DN: %s.'), $this->dn), getExtendedLDAPErrorMessage($ldap)); throw new LAMException(sprintf(_('Was unable to create DN: %s.'), $this->dn), getExtendedLDAPErrorMessage($ldap));
} }
/**
* Returns the DN.
*
* @return string DN
*/
public function getDn() {
return $this->dn;
}
/**
* Returns the attributes to add.
*
* @return string[] attributes (array('attr' => array('val1', 'val2')))
*/
public function getAttributes() {
return $this->attributes;
}
}
/**
* Deletes attributes from an existing LDAP entry.
*
* @author Roland Gruber
*/
class DeleteAttributesTask implements ImporterTask {
private $dn = '';
private $attributes = array();
private $attributeName = null;
/**
* Constructor
*
* @param string $dn DN
* @param string $attributeName attribute name
* @param array[string[]] $attributes list of attributes
*/
public function __construct($dn, $attributeName, $attributes) {
$this->dn = $dn;
$this->attributeName = $attributeName;
$this->attributes = $attributes;
}
/**
* {@inheritDoc}
* @see \LAM\TOOLS\IMPORT_EXPORT\ImporterTask::run()
*/
public function run() {
$ldap = $_SESSION['ldap']->server();
if (!empty($this->attributes)) {
$success = @ldap_mod_del($ldap, $this->dn, $this->attributes);
}
else {
$success = @ldap_modify($ldap, $this->dn, array($this->attributeName => array()));
}
if ($success) {
return '';
}
throw new LAMException(sprintf(_('Was unable to create DN: %s.'), $this->dn), getExtendedLDAPErrorMessage($ldap));
}
/**
* Returns the DN.
*
* @return string DN
*/
public function getDn() {
return $this->dn;
}
/**
* Returns the attributes to add.
*
* @return string[] attributes (array('attr' => array('val1', 'val2')))
*/
public function getAttributes() {
return $this->attributes;
}
/**
* Returns the attributes name.
*
* @return string name
*/
public function getAttributeName() {
return $this->attributeName;
}
}
/**
* Replaces attributes in an existing LDAP entry.
*
* @author Roland Gruber
*/
class ReplaceAttributesTask implements ImporterTask {
private $dn = '';
private $attributes = array();
/**
* Constructor
*
* @param string $dn DN
* @param array[string[]] $attributes list of attributes
*/
public function __construct($dn, $attributes) {
$this->dn = $dn;
$this->attributes = $attributes;
}
/**
* {@inheritDoc}
* @see \LAM\TOOLS\IMPORT_EXPORT\ImporterTask::run()
*/
public function run() {
$ldap = $_SESSION['ldap']->server();
$success = @ldap_modify($ldap, $this->dn, $this->attributes);
if ($success) {
return '';
}
throw new LAMException(sprintf(_('Was unable to create DN: %s.'), $this->dn), getExtendedLDAPErrorMessage($ldap));
}
/**
* Returns the DN.
*
* @return string DN
*/
public function getDn() {
return $this->dn;
}
/**
* Returns the attributes to add.
*
* @return string[] attributes (array('attr' => array('val1', 'val2')))
*/
public function getAttributes() {
return $this->attributes;
}
/**
* Returns the attributes name.
*
* @return string name
*/
public function getAttributeName() {
return $this->attributeName;
}
} }
?> ?>

View File

@ -5,6 +5,8 @@ use LAM\TOOLS\IMPORT_EXPORT\AddAttributesTask;
use LAM\TOOLS\IMPORT_EXPORT\AddEntryTask; use LAM\TOOLS\IMPORT_EXPORT\AddEntryTask;
use LAM\TOOLS\IMPORT_EXPORT\RenameEntryTask; use LAM\TOOLS\IMPORT_EXPORT\RenameEntryTask;
use LAM\TOOLS\IMPORT_EXPORT\DeleteEntryTask; use LAM\TOOLS\IMPORT_EXPORT\DeleteEntryTask;
use LAM\TOOLS\IMPORT_EXPORT\DeleteAttributesTask;
use LAM\TOOLS\IMPORT_EXPORT\ReplaceAttributesTask;
/* /*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
@ -257,4 +259,184 @@ class ImporterTest extends PHPUnit_Framework_TestCase {
$this->assertEquals(DeleteEntryTask::class, get_class($task)); $this->assertEquals(DeleteEntryTask::class, get_class($task));
} }
/**
* Change entry with modify changetype with invalid operation.
*/
public function testChangeModifyInvalid() {
$lines = array(
"version: 1",
"",
"dn: uid=test,dc=example,dc=com",
"changeType: modify",
"invalid: test",
);
$this->setExpectedException(LAMException::class, 'uid=test,dc=example,dc=com');
$importer = new Importer();
$tasks = $importer->getTasks($lines);
}
/**
* Change entry with modify changetype and add operation.
*/
public function testChangeModifyAdd() {
$lines = array(
"version: 1",
"",
"dn: uid=test,dc=example,dc=com",
"changeType: modify",
"add: uid",
"uid: uid1",
"uid: uid2"
);
$importer = new Importer();
$tasks = $importer->getTasks($lines);
$this->assertEquals(1, sizeof($tasks));
$task = $tasks[0];
$this->assertEquals(MultiTask::class, get_class($task));
$subtasks = $task->getTasks();
$this->assertEquals(1, sizeof($subtasks));
$subTask = $subtasks[0];
$this->assertEquals(AddAttributesTask::class, get_class($subTask));
$this->assertEquals($subTask->getDn(), 'uid=test,dc=example,dc=com');
$attributes = $subTask->getAttributes();
$this->assertEquals(1, sizeof($attributes));
$this->assertEquals(2, sizeof($attributes['uid']));
$this->assertTrue(in_array('uid1', $attributes['uid']));
$this->assertTrue(in_array('uid2', $attributes['uid']));
}
/**
* Change entry with modify changetype and two add operations.
*/
public function testChangeModifyAddTwice() {
$lines = array(
"version: 1",
"",
"dn: uid=test,dc=example,dc=com",
"changeType: modify",
"add: uid",
"uid: uid1",
"uid: uid2",
"-",
"add: gn",
"gn: name1",
"gn: name2"
);
$importer = new Importer();
$tasks = $importer->getTasks($lines);
$this->assertEquals(1, sizeof($tasks));
$task = $tasks[0];
$this->assertEquals(MultiTask::class, get_class($task));
$subtasks = $task->getTasks();
$this->assertEquals(2, sizeof($subtasks));
$subTask = $subtasks[0];
$this->assertEquals(AddAttributesTask::class, get_class($subTask));
$this->assertEquals($subTask->getDn(), 'uid=test,dc=example,dc=com');
$attributes = $subTask->getAttributes();
$this->assertEquals(1, sizeof($attributes));
$this->assertEquals(2, sizeof($attributes['uid']));
$this->assertTrue(in_array('uid1', $attributes['uid']));
$this->assertTrue(in_array('uid2', $attributes['uid']));
$subTask = $subtasks[1];
$this->assertEquals(AddAttributesTask::class, get_class($subTask));
$this->assertEquals($subTask->getDn(), 'uid=test,dc=example,dc=com');
$attributes = $subTask->getAttributes();
$this->assertEquals(1, sizeof($attributes));
$this->assertEquals(2, sizeof($attributes['gn']));
$this->assertTrue(in_array('name1', $attributes['gn']));
$this->assertTrue(in_array('name2', $attributes['gn']));
}
/**
* Change entry with modify changetype and delete operation.
*/
public function testChangeModifyDelete() {
$lines = array(
"version: 1",
"",
"dn: uid=test,dc=example,dc=com",
"changeType: modify",
"delete: uid",
"uid: uid1",
"uid: uid2"
);
$importer = new Importer();
$tasks = $importer->getTasks($lines);
$this->assertEquals(1, sizeof($tasks));
$task = $tasks[0];
$this->assertEquals(MultiTask::class, get_class($task));
$subtasks = $task->getTasks();
$this->assertEquals(1, sizeof($subtasks));
$subTask = $subtasks[0];
$this->assertEquals(DeleteAttributesTask::class, get_class($subTask));
$this->assertEquals($subTask->getDn(), 'uid=test,dc=example,dc=com');
$attributes = $subTask->getAttributes();
$this->assertEquals(1, sizeof($attributes));
$this->assertEquals(2, sizeof($attributes['uid']));
$this->assertTrue(in_array('uid1', $attributes['uid']));
$this->assertTrue(in_array('uid2', $attributes['uid']));
}
/**
* Change entry with modify changetype and delete operation.
*/
public function testChangeModifyDeleteAll() {
$lines = array(
"version: 1",
"",
"dn: uid=test,dc=example,dc=com",
"changeType: modify",
"delete: uid",
);
$importer = new Importer();
$tasks = $importer->getTasks($lines);
$this->assertEquals(1, sizeof($tasks));
$task = $tasks[0];
$this->assertEquals(MultiTask::class, get_class($task));
$subtasks = $task->getTasks();
$this->assertEquals(1, sizeof($subtasks));
$subTask = $subtasks[0];
$this->assertEquals(DeleteAttributesTask::class, get_class($subTask));
$this->assertEquals($subTask->getDn(), 'uid=test,dc=example,dc=com');
$attributes = $subTask->getAttributes();
$this->assertTrue(empty($attributes));
}
/**
* Change entry with modify changetype and replace operation.
*/
public function testChangeModifyReplace() {
$lines = array(
"version: 1",
"",
"dn: uid=test,dc=example,dc=com",
"changeType: modify",
"replace: uid",
"uid: uid1",
"uid: uid2",
);
$importer = new Importer();
$tasks = $importer->getTasks($lines);
$this->assertEquals(1, sizeof($tasks));
$task = $tasks[0];
$this->assertEquals(MultiTask::class, get_class($task));
$subtasks = $task->getTasks();
$this->assertEquals(1, sizeof($subtasks));
$subTask = $subtasks[0];
$this->assertEquals(ReplaceAttributesTask::class, get_class($subTask));
$this->assertEquals($subTask->getDn(), 'uid=test,dc=example,dc=com');
$attributes = $subTask->getAttributes();
$this->assertEquals(1, sizeof($attributes));
$this->assertEquals(2, sizeof($attributes['uid']));
$this->assertTrue(in_array('uid1', $attributes['uid']));
$this->assertTrue(in_array('uid2', $attributes['uid']));
}
} }