From b35b44b2b8b4c88cbbf838d1db2072a03e06d562 Mon Sep 17 00:00:00 2001 From: Deon George Date: Mon, 17 Mar 2025 20:45:49 +1100 Subject: [PATCH] Import and Export work with attribute tags --- app/Classes/LDAP/Attribute.php | 8 +++++-- app/Classes/LDAP/Import/LDIF.php | 13 +++++------ app/Ldap/Entry.php | 38 +++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/app/Classes/LDAP/Attribute.php b/app/Classes/LDAP/Attribute.php index b02cf744..73d35bf8 100644 --- a/app/Classes/LDAP/Attribute.php +++ b/app/Classes/LDAP/Attribute.php @@ -178,9 +178,13 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator return $this->name; } - public function addValue(string $value): void + public function addValue(string $tag,string $value): void { - $this->values->push($value); + $this->_values->put( + $tag, + $this->_values + ->get($tag,collect()) + ->push($value)); } public function current(): mixed diff --git a/app/Classes/LDAP/Import/LDIF.php b/app/Classes/LDAP/Import/LDIF.php index eb2c3408..03a0be0b 100644 --- a/app/Classes/LDAP/Import/LDIF.php +++ b/app/Classes/LDAP/Import/LDIF.php @@ -59,8 +59,6 @@ class LDIF extends Import $base64encoded = FALSE; $attribute = NULL; $value = ''; - - // Else its a blank line } continue; @@ -69,7 +67,7 @@ class LDIF extends Import $m = []; preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m); - switch ($x=Arr::get($m,1)) { + switch (Arr::get($m,1)) { case 'changetype': if ($m[2] !== ':') throw new GeneralException(sprintf('ChangeType cannot be base64 encoded set at [%d]. (line %d)',$version,$c)); @@ -133,7 +131,6 @@ class LDIF extends Import // Start of a new attribute $base64encoded = ($m[2] === '::'); - // @todo Need to parse attributes with ';' options $attribute = $m[1]; $value = $m[3]; @@ -160,7 +157,7 @@ class LDIF extends Import } public function readEntry() { - static $haveVersion = false; + static $haveVersion = FALSE; if ($lines = $this->nextLines()) { @@ -179,7 +176,7 @@ class LDIF extends Import } else $changetype = 'add'; - $this->template = new Template($this->server_id,null,null,$changetype); + $this->template = new Template($this->server_id,NULL,NULL,$changetype); switch ($changetype) { case 'add': @@ -201,7 +198,7 @@ class LDIF extends Import return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines); $this->template->setDN($dn); - $this->template->accept(false,true); + $this->template->accept(FALSE,TRUE); return $this->getModifyDetails($lines); @@ -228,6 +225,6 @@ class LDIF extends Import return $this->error(_('A valid dn line is required'),$lines); } else - return false; + return FALSE; } } \ No newline at end of file diff --git a/app/Ldap/Entry.php b/app/Ldap/Entry.php index a4e1ac47..adb7103d 100644 --- a/app/Ldap/Entry.php +++ b/app/Ldap/Entry.php @@ -16,6 +16,9 @@ use App\Exceptions\InvalidUsage; class Entry extends Model { + private const TAG_CHARS = 'a-zA-Z0-9-'; + private const TAG_CHARS_LANG = 'lang-['.self::TAG_CHARS.']'; + // Our Attribute objects private Collection $objects; /* @deprecated */ @@ -51,7 +54,11 @@ class Entry extends Model public function getAttributes(): array { return $this->objects - ->map(fn($item)=>$item->values) + ->flatMap(fn($item)=> + ($item->no_attr_tags) + ? [strtolower($item->name)=>$item->values] + : $item->values + ->flatMap(fn($v,$k)=>[strtolower($item->name.($k ? ';'.$k : ''))=>$v])) ->toArray(); } @@ -158,15 +165,26 @@ class Entry extends Model if (! is_string($value)) throw new \Exception('value should be a string'); - $key = $this->normalizeAttributeKey($key); + $key = $this->normalizeAttributeKey(strtolower($key)); - if (! config('server')->schema('attributetypes')->has($key)) - throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$key)); + // If the attribute name has tags + $matches = []; + if (preg_match(sprintf('/^([%s]+);+([%s;]+)/',self::TAG_CHARS,self::TAG_CHARS),$key,$matches)) { + $attribute = $matches[1]; + $tags = $matches[2]; - $o = $this->objects->get($key) ?: Attribute\Factory::create($this->dn ?: '',$key,[]); - $o->addValue($value); + } else { + $attribute = $key; + $tags = ''; + } - $this->objects->put($key,$o); + if (! config('server')->schema('attributetypes')->has($attribute)) + throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$attribute)); + + $o = $this->objects->get($attribute) ?: Attribute\Factory::create($this->dn ?: '',$attribute,[]); + $o->addValue($tags,$value); + + $this->objects->put($attribute,$o); } /** @@ -182,7 +200,7 @@ class Entry extends Model foreach ($this->attributes as $attrtag => $values) { // If the attribute name has tags $matches = []; - if (preg_match('/^([a-zA-Z]+);+([a-zA-Z-;]+)/',$attrtag,$matches)) { + if (preg_match(sprintf('/^([%s]+);+([%s;]+)/',self::TAG_CHARS,self::TAG_CHARS),$attrtag,$matches)) { $attribute = $matches[1]; $tags = $matches[2]; @@ -286,7 +304,7 @@ class Entry extends Model ->map(fn($item)=>$item ->values ->keys() - ->filter(fn($item)=>preg_match('/lang-[A-Za-z0-9-]+;?/',$item))) + ->filter(fn($item)=>preg_match(sprintf('/%s+;?/',self::TAG_CHARS_LANG),$item))) ->filter(fn($item)=>$item->count()); } @@ -344,7 +362,7 @@ class Entry extends Model ->filter(fn($item)=> $item && collect(explode(';',$item))->filter( fn($item)=> - (! preg_match('/^lang-[A-Za-z0-9-]+$/',$item)) + (! preg_match(sprintf('/^%s+$/',self::TAG_CHARS_LANG),$item)) && (! preg_match('/^binary$/',$item)) ) ->count())