From a99770951dcd5b99ac1507c9b7b124bce5ada102 Mon Sep 17 00:00:00 2001 From: Deon George Date: Thu, 2 Mar 2023 18:21:53 +1100 Subject: [PATCH] Implemented more attribute classes --- app/Classes/LDAP/Attribute.php | 8 +- app/Classes/LDAP/Attribute/Binary.php | 2 +- .../LDAP/Attribute/Binary/JpegPhoto.php | 2 +- app/Classes/LDAP/Attribute/Factory.php | 11 +++ app/Classes/LDAP/Attribute/GidNumber.php | 12 +++ .../LDAP/Attribute/Internal/EntryCSN.php | 12 +++ .../LDAP/Attribute/Internal/EntryDN.php | 12 +++ .../LDAP/Attribute/Internal/EntryUUID.php | 2 +- .../Attribute/Internal/HasSubordinates.php | 12 +++ .../Internal/StructuralObjectClass.php | 12 +++ .../Attribute/Internal/SubschemaSubentry.php | 12 +++ .../LDAP/Attribute/Internal/Timestamp.php | 18 ++++ app/Classes/LDAP/Attribute/ObjectClass.php | 2 +- app/Classes/LDAP/Attribute/Password.php | 17 ++++ .../LDAP/Attribute/Schema/Mechanisms.php | 2 +- app/Classes/LDAP/Attribute/Schema/OID.php | 2 +- app/Ldap/Entry.php | 96 ++++++++++++------- config/ldap.php | 9 ++ lib/AttributeFactory.php | 42 +------- lib/DateAttribute.php | 17 ---- lib/DnAttribute.php | 17 ---- lib/GidAttribute.php | 17 ---- lib/ObjectClassAttribute.php | 17 ---- lib/PasswordAttribute.php | 17 ---- lib/ds_ldap_pla.php | 4 - resources/views/frames/dn.blade.php | 52 ++++++++-- 26 files changed, 245 insertions(+), 181 deletions(-) create mode 100644 app/Classes/LDAP/Attribute/GidNumber.php create mode 100644 app/Classes/LDAP/Attribute/Internal/EntryCSN.php create mode 100644 app/Classes/LDAP/Attribute/Internal/EntryDN.php create mode 100644 app/Classes/LDAP/Attribute/Internal/HasSubordinates.php create mode 100644 app/Classes/LDAP/Attribute/Internal/StructuralObjectClass.php create mode 100644 app/Classes/LDAP/Attribute/Internal/SubschemaSubentry.php create mode 100644 app/Classes/LDAP/Attribute/Internal/Timestamp.php create mode 100644 app/Classes/LDAP/Attribute/Password.php delete mode 100644 lib/DateAttribute.php delete mode 100644 lib/DnAttribute.php delete mode 100644 lib/GidAttribute.php delete mode 100644 lib/ObjectClassAttribute.php delete mode 100644 lib/PasswordAttribute.php diff --git a/app/Classes/LDAP/Attribute.php b/app/Classes/LDAP/Attribute.php index f39d3b7..3816c6b 100644 --- a/app/Classes/LDAP/Attribute.php +++ b/app/Classes/LDAP/Attribute.php @@ -14,7 +14,7 @@ class Attribute // Attribute Name protected string $name; - protected ?AttributeType $schema; + protected ?AttributeType $schema = NULL; /* # Source of this attribute definition @@ -28,7 +28,7 @@ class Attribute protected bool $is_deletable = FALSE; // Is this attribute an internal attribute - protected bool $is_internal; + protected bool $is_internal = FALSE; // Is this attribute the RDN? protected bool $is_rdn = FALSE; @@ -95,7 +95,9 @@ class Attribute $this->name = $name; $this->values = collect($values); - $this->schema = config('server')->schema('attributetypes',$name); + // No need to load our schema for internal attributes + if (! $this->is_internal) + $this->schema = config('server')->schema('attributetypes',$name); /* # Should this attribute be hidden diff --git a/app/Classes/LDAP/Attribute/Binary.php b/app/Classes/LDAP/Attribute/Binary.php index 56be884..4f84e14 100644 --- a/app/Classes/LDAP/Attribute/Binary.php +++ b/app/Classes/LDAP/Attribute/Binary.php @@ -7,6 +7,6 @@ use App\Classes\LDAP\Attribute; /** * Represents an attribute whose values are binary */ -abstract class Binary extends Attribute +class Binary extends Attribute { } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php b/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php index ac44259..f93621d 100644 --- a/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php +++ b/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php @@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Binary; use App\Classes\LDAP\Attribute\Binary; /** - * Represents an attribute whose values are jpeg pictures + * Represents an JpegPhoto Attribute */ final class JpegPhoto extends Binary { diff --git a/app/Classes/LDAP/Attribute/Factory.php b/app/Classes/LDAP/Attribute/Factory.php index 0f9419d..d7bff91 100644 --- a/app/Classes/LDAP/Attribute/Factory.php +++ b/app/Classes/LDAP/Attribute/Factory.php @@ -20,13 +20,24 @@ class Factory * Map of attributes to appropriate class */ public const map = [ + 'createtimestamp' => Internal\Timestamp::class, + 'creatorsname' => Internal\EntryDN::class, + 'entrycsn' => Internal\EntryCSN::class, + 'entrydn' => Internal\EntryDN::class, 'entryuuid' => Internal\EntryUUID::class, + 'gidnumber' => GidNumber::class, + 'hassubordinates' => Internal\HasSubordinates::class, 'jpegphoto' => Binary\JpegPhoto::class, + 'modifytimestamp' => Internal\Timestamp::class, + 'modifiersname' => Internal\EntryDN::class, 'objectclass' => ObjectClass::class, + 'structuralobjectclass' => Internal\StructuralObjectClass::class, + 'subschemasubentry' => Internal\SubschemaSubentry::class, 'supportedcontrol' => Schema\OID::class, 'supportedextension' => Schema\OID::class, 'supportedfeatures' => Schema\OID::class, 'supportedsaslmechanisms' => Schema\Mechanisms::class, + 'userpassword' => Password::class, ]; /** diff --git a/app/Classes/LDAP/Attribute/GidNumber.php b/app/Classes/LDAP/Attribute/GidNumber.php new file mode 100644 index 0000000..b2a05a3 --- /dev/null +++ b/app/Classes/LDAP/Attribute/GidNumber.php @@ -0,0 +1,12 @@ +values[0]))->format(config('ldap.datetime_format','Y-m-d H:i:s')); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/ObjectClass.php b/app/Classes/LDAP/Attribute/ObjectClass.php index 7851a22..01e6782 100644 --- a/app/Classes/LDAP/Attribute/ObjectClass.php +++ b/app/Classes/LDAP/Attribute/ObjectClass.php @@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute; /** - * Represents an attribute whose values are jpeg pictures + * Represents an ObjectClass Attribute */ final class ObjectClass extends Attribute { diff --git a/app/Classes/LDAP/Attribute/Password.php b/app/Classes/LDAP/Attribute/Password.php new file mode 100644 index 0000000..7e50623 --- /dev/null +++ b/app/Classes/LDAP/Attribute/Password.php @@ -0,0 +1,17 @@ + %s',__('Check Password')); + } +} \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Schema/Mechanisms.php b/app/Classes/LDAP/Attribute/Schema/Mechanisms.php index 51474ae..af154e5 100644 --- a/app/Classes/LDAP/Attribute/Schema/Mechanisms.php +++ b/app/Classes/LDAP/Attribute/Schema/Mechanisms.php @@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema; /** - * Represents an attribute whose values are binary + * Represents a Mechanisms Attribute */ final class Mechanisms extends Schema { diff --git a/app/Classes/LDAP/Attribute/Schema/OID.php b/app/Classes/LDAP/Attribute/Schema/OID.php index 1b202d7..e0254e3 100644 --- a/app/Classes/LDAP/Attribute/Schema/OID.php +++ b/app/Classes/LDAP/Attribute/Schema/OID.php @@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema; /** - * Represents an attribute whose values are binary + * Represents an OID Attribute */ final class OID extends Schema { diff --git a/app/Ldap/Entry.php b/app/Ldap/Entry.php index b6fe4bc..ef3118d 100644 --- a/app/Ldap/Entry.php +++ b/app/Ldap/Entry.php @@ -6,6 +6,7 @@ use Illuminate\Support\Arr; use Illuminate\Support\Collection; use LdapRecord\Models\Model; +use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute\Factory; class Entry extends Model @@ -14,48 +15,54 @@ class Entry extends Model public function getAttributes(): array { - $result = collect(); + static $result = NULL; - foreach (parent::getAttributes() as $attribute => $value) { - $o = Factory::create($attribute,$value); + if (is_null($result)) { + $result = collect(); - // Set the rdn flag - if (preg_match('/^'.$attribute.'=/i',$this->dn)) - $o->setRDN(); + foreach (parent::getAttributes() as $attribute => $value) { + $o = Factory::create($attribute,$value); - // Set required flag - $o->required_by(collect($this->getAttribute('objectclass'))); + // Set the rdn flag + if (preg_match('/^'.$attribute.'=/i',$this->dn)) + $o->setRDN(); - $result->put($attribute,$o); + // Set required flag + $o->required_by(collect($this->getAttribute('objectclass'))); + + $result->put($attribute,$o); + } + + $sort = collect(config('ldap.attr_display_order',[]))->transform(function($item) { return strtolower($item); }); + + // Order the attributes + $result = $result->sortBy([function(Attribute $a,Attribute $b) use ($sort): int { + if ($a === $b) + return 0; + + // Check if $a/$b are in the configuration to be sorted first, if so get it's key + $a_key = $sort->search($a->name_lc); + $b_key = $sort->search($b->name_lc); + + // If the keys were not in the sort list, set the key to be the count of elements (ie: so it is last to be sorted) + if ($a_key === FALSE) + $a_key = $sort->count()+1; + + if ($b_key === FALSE) + $b_key = $sort->count()+1; + + // Case where neither $a, nor $b are in ldap.attr_display_order, $a_key = $b_key = one greater than num elements. + // So we sort them alphabetically + if ($a_key === $b_key) + return strcasecmp($a->name,$b->name); + + // Case where at least one attribute or its friendly name is in $attrs_display_order + // return -1 if $a before $b in $attrs_display_order + return ($a_key < $b_key) ? -1 : 1; + } ])->toArray(); } - $sort = collect(config('ldap.attr_display_order',[]))->transform(function($item) { return strtolower($item); }); - - // Order the attributes - return $result->sortBy([function($a,$b) use ($sort) { - if (! $sort->count() || $a === $b) - return 0; - - // Check if $a/$b are in the configuration to be sorted first, if so get it's key - $a_key = $sort->search($a->name_lc); - $b_key = $sort->search($b->name_lc); - - // If the keys were not in the sort list, set the key to be the count of elements (ie: so it is last to be sorted) - if ($a_key === FALSE) - $a_key = $sort->count()+1; - - if ($b_key === FALSE) - $b_key = $sort->count()+1; - - // Case where neither $a, nor $b are in ldap.attr_display_order, $a_key = $b_key = one greater than num elements. - // So we sort them alphabetically - if ($a_key === $b_key) - return strcasecmp($a->name,$b->name); - - // Case where at least one attribute or its friendly name is in $attrs_display_order - // return -1 if $a before $b in $attrs_display_order - return ($a_key < $b_key) ? -1 : 1; - } ])->toArray(); + return $result; } /* ATTRIBUTES */ @@ -73,6 +80,23 @@ class Entry extends Model /* METHODS */ + /** + * Return a list of LDAP internal attributes + * + * @return Collection + */ + public function getInternalAttributes(): Collection + { + return collect($this->getAttributes())->filter(function($item) { + return $item->is_internal; + }); + } + + /** + * Return this list of user attributes + * + * @return Collection + */ public function getVisibleAttributes(): Collection { return collect($this->getAttributes())->filter(function($item) { diff --git a/config/ldap.php b/config/ldap.php index a0aa2f5..d4b141f 100644 --- a/config/ldap.php +++ b/config/ldap.php @@ -102,4 +102,13 @@ return [ ], */ + /* + |-------------------------------------------------------------------------- + | Custom Date Format + |-------------------------------------------------------------------------- + | + | Configuration to determine how date fields will be displayed. + | + */ + 'datetime_format' => 'Y-m-d H:i:s', ]; diff --git a/lib/AttributeFactory.php b/lib/AttributeFactory.php index 82cf562..f52e939 100644 --- a/lib/AttributeFactory.php +++ b/lib/AttributeFactory.php @@ -96,18 +96,9 @@ class AttributeFactory { return $this->newMultiLineAttribute($name,$values,$server_id,$source); } - if (! strcasecmp($name,'objectClass')) { - return $this->newObjectClassAttribute($name,$values,$server_id,$source); - - } elseif ($app['server']->isJpegPhoto($name) || in_array($name,$app['server']->getValue('server','jpeg_attributes'))) { - return $this->newJpegAttribute($name,$values,$server_id,$source); - - } elseif ($app['server']->isAttrBinary($name)) { + if ($app['server']->isAttrBinary($name)) { return $this->newBinaryAttribute($name,$values,$server_id,$source); - } elseif (! strcasecmp($name,'userPassword')) { - return $this->newPasswordAttribute($name,$values,$server_id,$source); - } elseif (! strcasecmp($name,'sambaLMPassword') || ! strcasecmp($name,'sambaNTPassword')) { return $this->newSambaPasswordAttribute($name,$values,$server_id,$source); @@ -129,26 +120,11 @@ class AttributeFactory { } elseif ($app['server']->isMultiLineAttr($name)) { return $this->newMultiLineAttribute($name,$values,$server_id,$source); - } elseif (! strcasecmp($name,'gidNumber')) { - return $this->newGidAttribute($name,$values,$server_id,$source); - } else { return new Attribute($name,$values,$server_id,$source); } } - private function newJpegAttribute($name,$values,$server_id,$source) { - return new JpegAttribute($name,$values,$server_id,$source); - } - - private function newBinaryAttribute($name,$values,$server_id,$source) { - return new BinaryAttribute($name,$values,$server_id,$source); - } - - private function newPasswordAttribute($name,$values,$server_id,$source) { - return new PasswordAttribute($name,$values,$server_id,$source); - } - private function newSambaPasswordAttribute($name,$values,$server_id,$source) { return new SambaPasswordAttribute($name,$values,$server_id,$source); } @@ -168,21 +144,5 @@ class AttributeFactory { private function newMultiLineAttribute($name,$values,$server_id,$source) { return new MultiLineAttribute($name,$values,$server_id,$source); } - - private function newDateAttribute($name,$values,$server_id,$source) { - return new DateAttribute($name,$values,$server_id,$source); - } - - private function newObjectClassAttribute($name,$values,$server_id,$source) { - return new ObjectClassAttribute($name,$values,$server_id,$source); - } - - private function newDnAttribute($name,$values,$server_id,$source) { - return new DnAttribute($name,$values,$server_id,$source); - } - - private function newGidAttribute($name,$values,$server_id,$source) { - return new GidAttribute($name,$values,$server_id,$source); - } } ?> diff --git a/lib/DateAttribute.php b/lib/DateAttribute.php deleted file mode 100644 index e1a687f..0000000 --- a/lib/DateAttribute.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/lib/DnAttribute.php b/lib/DnAttribute.php deleted file mode 100644 index 1f5c02f..0000000 --- a/lib/DnAttribute.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/lib/GidAttribute.php b/lib/GidAttribute.php deleted file mode 100644 index 7442a07..0000000 --- a/lib/GidAttribute.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/lib/ObjectClassAttribute.php b/lib/ObjectClassAttribute.php deleted file mode 100644 index 939094d..0000000 --- a/lib/ObjectClassAttribute.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/lib/PasswordAttribute.php b/lib/PasswordAttribute.php deleted file mode 100644 index 2667197..0000000 --- a/lib/PasswordAttribute.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/lib/ds_ldap_pla.php b/lib/ds_ldap_pla.php index 4065109..7efa768 100644 --- a/lib/ds_ldap_pla.php +++ b/lib/ds_ldap_pla.php @@ -52,10 +52,6 @@ class ldap_pla extends ldap { 'desc'=>'Custom operational attributes to be treated as internal attributes', 'default'=>array('+')); - $this->default->server['jpeg_attributes'] = array( - 'desc'=>'Additional attributes to treat as Jpeg Attributes', - 'default'=>array()); - # This was added in case the LDAP server doesnt provide them with a base +,* query. $this->default->server['root_dse_attributes'] = array( 'desc'=>'RootDSE attributes for use when displaying server info', diff --git a/resources/views/frames/dn.blade.php b/resources/views/frames/dn.blade.php index e67267d..449a069 100644 --- a/resources/views/frames/dn.blade.php +++ b/resources/views/frames/dn.blade.php @@ -3,8 +3,26 @@ @section('page_title') - - + + + + +
{!! $x ?: sprintf('
',$o->icon() ?? "fas fa-info") !!}
{{ $dn }}
{{ $o->entryuuid[0] ?? '' }}
{!! $x ?: sprintf('
',$o->icon() ?? "fas fa-info") !!}
{{ $dn }}
+ + + + + + + + + + + + + +
Created{{ ($x=Arr::get($o->getAttributes(),'createtimestamp')) ? $x : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'creatorsname')) ? $x : __('Unknown') }}]
Modified{{ ($x=Arr::get($o->getAttributes(),'modifytimestamp')) ? $x : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'modifiersname')) ? $x : __('Unknown') }}]
UUID{{ $o->entryuuid[0] ?? '' }}
+
@endsection @@ -15,9 +33,13 @@
@@ -47,9 +69,6 @@ {{ __('Add Value') }} @endif - {{-- - @dump($ao) - --}} @endforeach @@ -57,20 +76,41 @@
+ {{--
+ --}}
-
+
+
+ + @foreach ($o->getInternalAttributes() as $ao) + + + + + + + @endforeach +
+ {{ $ao->name }} +
+ {!! $ao !!} +
+
+
+ {{--
+ --}}