Commit 7a1f9ee8 authored by Côme Chilliet's avatar Côme Chilliet
Browse files

🚑 feat(ldap) Cleaned up Ldif parsing by using a dedicated LdifRecord class

issue #1
parent 94bb8e39
Pipeline #9213 failed with stages
in 35 seconds
......@@ -40,13 +40,13 @@ class Ldif
*/
protected $changes;
/**
* @var array<int, array<string,string|array<string>|array<array<string>>>>
* @var array<int, LdifRecord>
*/
protected $entries;
/**
* LDIF constructor
* @param array<int, array<string,string|array<string>|array<array<string>>>> $entries
* @param array<int, LdifRecord> $entries
*/
public function __construct (bool $changes, array $entries = [], ?int $version = NULL)
{
......@@ -61,7 +61,7 @@ class Ldif
}
/**
* @return array<int, array<string,string|array<string>|array<array<string>>>>
* @return array<int, LdifRecord>
*/
public function getEntries (): array
{
......@@ -69,15 +69,15 @@ class Ldif
}
/**
* @param array<int, array<string,string|array<string>|array<array<string>>>> $entries
* @param array<string,string|array<string>|array<array<string>>> $entry
* @param array<int, LdifRecord> $entries
* @param LdifRecord $entry
* @throws \FusionDirectory\Ldap\Exception
*/
static protected function parseLine (
int $lineNumber,
string $fileLine,
?string &$line,
array &$entry,
LdifRecord &$entry,
array &$entries,
int &$entryStart,
?int &$version,
......@@ -96,7 +96,7 @@ class Ldif
/* Ignore comment */
} elseif ($line === '-') {
/* Changeset split */
$entry['changesets'][] = [];
$entry->addChangeset();
} else {
/* Line has ended */
if (strpos($line, ':') === FALSE) {
......@@ -116,49 +116,41 @@ class Ldif
if ($value === '') {
throw new Exception(sprintf(_('Error line %s, attribute "%s" has no value'), $lineNumber, $key));
}
if (($key === 'version') && (count($entry) === 0) && (count($entries) === 0) && ($version === NULL)) {
if (($key === 'version') && ($entry->isEmpty()) && (count($entries) === 0) && ($version === NULL)) {
/* Store version number */
$version = intval($value);
} elseif ($key == 'dn') {
if (count($entry) > 0) {
if (!$entry->isEmpty()) {
throw new Exception(sprintf(_('Error line %s, an entry bloc can only have one dn'), $lineNumber));
}
$entry['dn'] = $value;
$entry->dn = $value;
$entryStart = $lineNumber;
} elseif (count($entry) === 0) {
} elseif ($entry->isEmpty()) {
throw new Exception(sprintf(_('Error line %s, an entry bloc should start with the dn'), $lineNumber));
} elseif ($key === 'changetype') {
$changes = TRUE;
$entry['changetype'] = $value;
$entry['changesets'] = [[]];
} else {
if ($changes && ($key !== 'control')) {
if (!isset($entry['changetype'])) {
throw new Exception(sprintf(_('Error line %s, all entry blocs must set changetype, or none of them should'), $lineNumber));
}
$changeset = array_key_last($entry['changesets']);
if (!isset($entry['changesets'][$changeset][$key])) {
$entry['changesets'][$changeset][$key] = [];
}
$entry['changesets'][$changeset][$key][] = $value;
} else {
if (!isset($entry[$key])) {
$entry[$key] = [];
}
$entry[$key][] = $value;
$entry->changetype = $value;
} elseif ($key === 'control') {
$entry->addControl($value);
} elseif ($changes) {
if (!isset($entry->changetype)) {
throw new Exception(sprintf(_('Error line %s, all entry blocs must set changetype, or none of them should'), $lineNumber));
}
$entry->appendChangesetData($key, $value);
} else {
$entry->addAttributeValue($key, $value);
}
}
}
/* Start new line */
$line = ltrim($fileLine);
if ($line == '') {
if (count($entry) > 0) {
if (!$entry->isEmpty()) {
/* Entry is finished */
$entries[$entryStart] = $entry;
}
/* Start a new entry */
$entry = [];
$entry = new LdifRecord();
$entryStart = -1;
$line = NULL;
}
......@@ -181,7 +173,7 @@ class Ldif
/* Parsing lines */
$line = NULL;
$entry = [];
$entry = new LdifRecord();
$entries = [];
$entryStart = -1;
$version = NULL;
......@@ -200,7 +192,7 @@ class Ldif
static public function parseFromFileHandle ($fh): Ldif
{
$line = NULL;
$entry = [];
$entry = new LdifRecord;
$entries = [];
$entryStart = -1;
$version = NULL;
......@@ -210,7 +202,7 @@ class Ldif
static::parseLine($lineNumber, rtrim($fileLine, "\n\r"), $line, $entry, $entries, $entryStart, $version, $changes);
$lineNumber++;
}
if (count($entry) !== 0) {
if (!$entry->isEmpty()) {
static::parseLine($lineNumber, '', $line, $entry, $entries, $entryStart, $version, $changes);
}
......
<?php
/*
This code is part of FusionDirectory\Ldap (https://www.fusiondirectory.org/)
Copyright (C) 2020 FusionDirectory
SPDX-License-Identifier: GPL-2.0-or-later
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
declare(strict_types = 1);
namespace FusionDirectory\Ldap;
/**
* This class is used by Ldif to store record data
*/
class LdifRecord
{
/**
* @var ?string
*/
public $dn = NULL;
/**
* @var ?string
*/
public $changetype = NULL;
/**
* @var array<string,array<string>>
*/
public $controls = [];
/**
* @var array<string,array<string>>
*/
public $attrs = [];
/**
* @var array<array<array<string,array<string>>>>
*/
public $changesets = [];
public function isEmpty (): bool
{
return (
($this->dn === NULL) &&
($this->changetype === NULL) &&
(count($this->controls) === 0) &&
(count($this->attrs) === 0) &&
(count($this->changesets) === 0)
);
}
public function addChangeset (): void
{
$this->changesets[] = [];
}
public function appendChangesetData (string $key, string $value): void
{
if (count($this->changesets) === 0) {
$this->addChangeset();
}
$changeset = array_key_last($this->changesets);
if (!isset($this->changesets[$changeset][$key])) {
$this->changesets[$changeset][$key] = [];
}
$this->changesets[$changeset][$key][] = $value;
}
public function addAttributeValue (string $key, string $value): void
{
if (!isset($this->attrs[$key])) {
$this->attrs[$key] = [];
}
$this->attrs[$key][] = $value;
}
public function addControl (string $value): void
{
$this->controls[] = $value;
}
}
......@@ -161,19 +161,19 @@ class Schema
throw new Exception($path.' LDIF file contains changes and not records');
}
$ldifEntries = $ldifData->getEntries();
$data = reset($ldifEntries);
if ($data === FALSE) {
$entry = reset($ldifEntries);
if ($entry === FALSE) {
throw new Exception($path.' LDIF file does not contain any entry');
} elseif (count($ldifEntries) > 1) {
throw new Exception($path.' LDIF file contains several entries');
}
return new Schema(
$data['cn'][0] ?? $cn,
$data['olcObjectIdentifier'] ?? [],
$data['olcLdapSyntaxes'] ?? [],
$data['olcAttributeTypes'] ?? [],
$data['olcObjectClasses'] ?? [],
$data['olcDitContentRules'] ?? []
$entry->attrs['cn'][0] ?? $cn,
$entry->attrs['olcObjectIdentifier'] ?? [],
$entry->attrs['olcLdapSyntaxes'] ?? [],
$entry->attrs['olcAttributeTypes'] ?? [],
$entry->attrs['olcObjectClasses'] ?? [],
$entry->attrs['olcDitContentRules'] ?? []
);
} else {
$data = static::parseSchemaContent($fh);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment