From 4fd51abcb192ce88c0f1f5254c8bd249b11acc28 Mon Sep 17 00:00:00 2001 From: Deon George Date: Sun, 2 Apr 2023 22:07:15 +1000 Subject: [PATCH] More work on displaying and editing an LDAP entry --- app/Classes/LDAP/Attribute.php | 18 +++++------ .../LDAP/Attribute/Binary/JpegPhoto.php | 27 +++++------------ app/Classes/LDAP/Attribute/Factory.php | 11 +++---- app/Classes/LDAP/Attribute/Internal.php | 9 ++++++ .../Internal/{EntryDN.php => CSN.php} | 4 +-- .../Internal/{EntryCSN.php => DN.php} | 4 +-- .../LDAP/Attribute/Internal/Timestamp.php | 8 +++-- .../Internal/{EntryUUID.php => UUID.php} | 4 +-- app/Classes/LDAP/Attribute/ObjectClass.php | 17 +++++++++-- app/Classes/LDAP/Attribute/Password.php | 11 ++++--- app/Classes/LDAP/Attribute/Schema.php | 8 +++++ .../LDAP/Attribute/Schema/Mechanisms.php | 26 +++++++--------- app/Classes/LDAP/Attribute/Schema/OID.php | 30 +++++++------------ composer.json | 1 + resources/lang/README.md | 6 ++++ .../views/components/attribute.blade.php | 1 + .../attribute/binary/jpegphoto.blade.php | 18 +++++++++++ .../components/attribute/internal.blade.php | 5 ++++ .../attribute/internal/timestamp.blade.php | 5 ++++ .../attribute/objectclass.blade.php | 24 +++++++++++++++ .../components/attribute/password.blade.php | 18 +++++++++++ .../attribute/schema/mechanisms.blade.php | 9 ++++++ .../components/attribute/schema/oid.blade.php | 11 +++++++ resources/views/frames/dn.blade.php | 6 ++-- resources/views/frames/info.blade.php | 4 ++- 25 files changed, 194 insertions(+), 91 deletions(-) rename app/Classes/LDAP/Attribute/Internal/{EntryDN.php => CSN.php} (60%) rename app/Classes/LDAP/Attribute/Internal/{EntryCSN.php => DN.php} (59%) rename app/Classes/LDAP/Attribute/Internal/{EntryUUID.php => UUID.php} (58%) create mode 100644 resources/lang/README.md create mode 100644 resources/views/components/attribute/binary/jpegphoto.blade.php create mode 100644 resources/views/components/attribute/internal.blade.php create mode 100644 resources/views/components/attribute/internal/timestamp.blade.php create mode 100644 resources/views/components/attribute/objectclass.blade.php create mode 100644 resources/views/components/attribute/password.blade.php create mode 100644 resources/views/components/attribute/schema/mechanisms.blade.php create mode 100644 resources/views/components/attribute/schema/oid.blade.php diff --git a/app/Classes/LDAP/Attribute.php b/app/Classes/LDAP/Attribute.php index 9b027d1..4cab883 100644 --- a/app/Classes/LDAP/Attribute.php +++ b/app/Classes/LDAP/Attribute.php @@ -144,16 +144,6 @@ class Attribute }; } - /** - * Determine how we render this attribute's value - * - * @return string - */ - public function __toString(): string - { - return $this->values->join('
'); - } - /** * Return the hints about this attribute, ie: RDN, Required, etc * @@ -182,7 +172,13 @@ class Attribute return $result->toArray(); } - public function render(bool $edit): View + /** + * Display the attribute value + * + * @param bool $edit + * @return View + */ + public function render(bool $edit=FALSE): View { return view('components.attribute') ->with('edit',$edit) diff --git a/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php b/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php index f93621d..e86dabc 100644 --- a/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php +++ b/app/Classes/LDAP/Attribute/Binary/JpegPhoto.php @@ -2,6 +2,8 @@ namespace App\Classes\LDAP\Attribute\Binary; +use Illuminate\Contracts\View\View; + use App\Classes\LDAP\Attribute\Binary; /** @@ -16,26 +18,11 @@ final class JpegPhoto extends Binary $this->internal = FALSE; } - public function __toString(): string + public function render(bool $edit=FALSE): View { - // We'll use finfo to try and figure out what type of image is stored - $f = new \finfo; - - $result = ''; - - foreach ($this->values as $value) { - switch ($x=$f->buffer($value,FILEINFO_MIME_TYPE)) { - case 'image/jpeg': - default: - $result .= sprintf('', - $x, - base64_encode($value), - $this->is_deletable ? sprintf('
%s',__('Delete')) : ''); - } - } - - $result .= '
%s
'; - - return $result; + return view('components.attribute.binary.jpegphoto') + ->with('edit',$edit) + ->with('o',$this) + ->with('f',new \finfo); } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Factory.php b/app/Classes/LDAP/Attribute/Factory.php index d7bff91..a45b8ea 100644 --- a/app/Classes/LDAP/Attribute/Factory.php +++ b/app/Classes/LDAP/Attribute/Factory.php @@ -21,15 +21,16 @@ class Factory */ public const map = [ 'createtimestamp' => Internal\Timestamp::class, - 'creatorsname' => Internal\EntryDN::class, - 'entrycsn' => Internal\EntryCSN::class, - 'entrydn' => Internal\EntryDN::class, - 'entryuuid' => Internal\EntryUUID::class, + 'creatorsname' => Internal\DN::class, + 'contextcsn' => Internal\CSN::class, + 'entrycsn' => Internal\CSN::class, + 'entrydn' => Internal\DN::class, + 'entryuuid' => Internal\UUID::class, 'gidnumber' => GidNumber::class, 'hassubordinates' => Internal\HasSubordinates::class, 'jpegphoto' => Binary\JpegPhoto::class, 'modifytimestamp' => Internal\Timestamp::class, - 'modifiersname' => Internal\EntryDN::class, + 'modifiersname' => Internal\DN::class, 'objectclass' => ObjectClass::class, 'structuralobjectclass' => Internal\StructuralObjectClass::class, 'subschemasubentry' => Internal\SubschemaSubentry::class, diff --git a/app/Classes/LDAP/Attribute/Internal.php b/app/Classes/LDAP/Attribute/Internal.php index 46279d1..38ab392 100644 --- a/app/Classes/LDAP/Attribute/Internal.php +++ b/app/Classes/LDAP/Attribute/Internal.php @@ -2,6 +2,8 @@ namespace App\Classes\LDAP\Attribute; +use Illuminate\Contracts\View\View; + use App\Classes\LDAP\Attribute; /** @@ -10,4 +12,11 @@ use App\Classes\LDAP\Attribute; abstract class Internal extends Attribute { protected bool $is_internal = TRUE; + + public function render(bool $edit=FALSE): View + { + // @note Internal attributes cannot be edited + return view('components.attribute.internal') + ->with('o',$this); + } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Internal/EntryDN.php b/app/Classes/LDAP/Attribute/Internal/CSN.php similarity index 60% rename from app/Classes/LDAP/Attribute/Internal/EntryDN.php rename to app/Classes/LDAP/Attribute/Internal/CSN.php index a565b59..eb08eb5 100644 --- a/app/Classes/LDAP/Attribute/Internal/EntryDN.php +++ b/app/Classes/LDAP/Attribute/Internal/CSN.php @@ -5,8 +5,8 @@ namespace App\Classes\LDAP\Attribute\Internal; use App\Classes\LDAP\Attribute\Internal; /** - * Represents an EntryDN Attribute + * Represents an CSN Attribute */ -final class EntryDN extends Internal +final class CSN extends Internal { } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Internal/EntryCSN.php b/app/Classes/LDAP/Attribute/Internal/DN.php similarity index 59% rename from app/Classes/LDAP/Attribute/Internal/EntryCSN.php rename to app/Classes/LDAP/Attribute/Internal/DN.php index f2b9330..84b2278 100644 --- a/app/Classes/LDAP/Attribute/Internal/EntryCSN.php +++ b/app/Classes/LDAP/Attribute/Internal/DN.php @@ -5,8 +5,8 @@ namespace App\Classes\LDAP\Attribute\Internal; use App\Classes\LDAP\Attribute\Internal; /** - * Represents an EntryCSN Attribute + * Represents an DN Attribute */ -final class EntryCSN extends Internal +final class DN extends Internal { } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Internal/Timestamp.php b/app/Classes/LDAP/Attribute/Internal/Timestamp.php index 8b68558..587e423 100644 --- a/app/Classes/LDAP/Attribute/Internal/Timestamp.php +++ b/app/Classes/LDAP/Attribute/Internal/Timestamp.php @@ -2,7 +2,7 @@ namespace App\Classes\LDAP\Attribute\Internal; -use Carbon\Carbon; +use Illuminate\Contracts\View\View; use App\Classes\LDAP\Attribute\Internal; @@ -11,8 +11,10 @@ use App\Classes\LDAP\Attribute\Internal; */ final class Timestamp extends Internal { - public function __toString(): string + public function render(bool $edit=FALSE): View { - return Carbon::createFromTimestamp(strtotime($this->values[0]))->format(config('ldap.datetime_format','Y-m-d H:i:s')); + // @note Internal attributes cannot be edited + return view('components.attribute.internal.timestamp') + ->with('o',$this); } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Internal/EntryUUID.php b/app/Classes/LDAP/Attribute/Internal/UUID.php similarity index 58% rename from app/Classes/LDAP/Attribute/Internal/EntryUUID.php rename to app/Classes/LDAP/Attribute/Internal/UUID.php index 33f3e01..e10fcd8 100644 --- a/app/Classes/LDAP/Attribute/Internal/EntryUUID.php +++ b/app/Classes/LDAP/Attribute/Internal/UUID.php @@ -5,8 +5,8 @@ namespace App\Classes\LDAP\Attribute\Internal; use App\Classes\LDAP\Attribute\Internal; /** - * Represents an EntryUUID Attribute + * Represents an UUID Attribute */ -final class EntryUUID extends Internal +final class UUID extends Internal { } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/ObjectClass.php b/app/Classes/LDAP/Attribute/ObjectClass.php index 01e6782..1fb0cbc 100644 --- a/app/Classes/LDAP/Attribute/ObjectClass.php +++ b/app/Classes/LDAP/Attribute/ObjectClass.php @@ -2,6 +2,8 @@ namespace App\Classes\LDAP\Attribute; +use Illuminate\Contracts\View\View; + use App\Classes\LDAP\Attribute; /** @@ -9,8 +11,19 @@ use App\Classes\LDAP\Attribute; */ final class ObjectClass extends Attribute { - public function __toString(): string + public function __get(string $key): mixed { - return $this->values->sort()->join('
'); + switch ($key) { + case 'is_structural': return FALSE; // @todo - need to determine which of the values is the structural objectclass value(s) + default: + return parent::__get($key); + } + } + + public function render(bool $edit=FALSE): View + { + return view('components.attribute.objectclass') + ->with('edit',$edit) + ->with('o',$this); } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Password.php b/app/Classes/LDAP/Attribute/Password.php index 7e50623..18232e5 100644 --- a/app/Classes/LDAP/Attribute/Password.php +++ b/app/Classes/LDAP/Attribute/Password.php @@ -2,16 +2,19 @@ namespace App\Classes\LDAP\Attribute; +use Illuminate\Contracts\View\View; + use App\Classes\LDAP\Attribute; /** * Represents an attribute whose values are passwords */ -class Password extends Attribute +final class Password extends Attribute { - public function __toString(): string + public function render(bool $edit=FALSE): View { - return str_repeat('*',10) - .sprintf('
%s',__('Check Password')); + return view('components.attribute.password') + ->with('edit',$edit) + ->with('o',$this); } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Schema.php b/app/Classes/LDAP/Attribute/Schema.php index 533c4f5..0acf31e 100644 --- a/app/Classes/LDAP/Attribute/Schema.php +++ b/app/Classes/LDAP/Attribute/Schema.php @@ -2,6 +2,7 @@ namespace App\Classes\LDAP\Attribute; +use Illuminate\Contracts\View\View; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Cache; @@ -47,4 +48,11 @@ abstract class Schema extends Attribute return Arr::get(($array ? $array->get($string) : []),$key); } + + public function render(bool $edit=FALSE): View + { + // @note Schema attributes cannot be edited + return view('components.attribute.internal') + ->with('o',$this); + } } \ 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 cffaa8f..a76da71 100644 --- a/app/Classes/LDAP/Attribute/Schema/Mechanisms.php +++ b/app/Classes/LDAP/Attribute/Schema/Mechanisms.php @@ -2,6 +2,8 @@ namespace App\Classes\LDAP\Attribute\Schema; +use Illuminate\Contracts\View\View; + use App\Classes\LDAP\Attribute\Schema; /** @@ -9,21 +11,6 @@ use App\Classes\LDAP\Attribute\Schema; */ final class Mechanisms extends Schema { - public function __toString(): string - { - return $this->values - ->transform(function($item) { - $format = sprintf('%s%s

%s

', - $item, - static::get($item,'title'), - ($x=static::get($item,'ref')) ? sprintf('',$x) : '', - static::get($item,'desc'), - ); - - return $format; - })->join('
'); - } - /** * Given an SASL Mechanism name, returns a verbose description of the Mechanism. * This function parses ldap_supported_saslmechanisms.txt and looks up the specified @@ -41,8 +28,15 @@ final class Mechanisms extends Schema * @param string $key The title|ref|desc to return * @return string|NULL */ - protected static function get(string $string,string $key): ?string + public static function get(string $string,string $key): ?string { return parent::_get(config_path('ldap_supported_saslmechanisms.txt'),$string,$key); } + + public function render(bool $edit=FALSE): View + { + // @note Schema attributes cannot be edited + return view('components.attribute.schema.mechanisms') + ->with('o',$this); + } } \ No newline at end of file diff --git a/app/Classes/LDAP/Attribute/Schema/OID.php b/app/Classes/LDAP/Attribute/Schema/OID.php index 60f5a1a..4c03011 100644 --- a/app/Classes/LDAP/Attribute/Schema/OID.php +++ b/app/Classes/LDAP/Attribute/Schema/OID.php @@ -2,6 +2,8 @@ namespace App\Classes\LDAP\Attribute\Schema; +use Illuminate\Contracts\View\View; + use App\Classes\LDAP\Attribute\Schema; /** @@ -9,25 +11,6 @@ use App\Classes\LDAP\Attribute\Schema; */ final class OID extends Schema { - public function __toString(): string - { - return $this->values - ->transform(function($item) { - if (preg_match('/[0-9]+\.[0-9]+\.[0-9]+/',$item)) { - $format = sprintf('%s%s

%s

', - $item, - static::get($item,'title'), - ($x=static::get($item,'ref')) ? sprintf('',$x) : '', - static::get($item,'desc'), - ); - - return $format; - - } else - return $item; - })->join('
'); - } - /** * Given an LDAP OID number, returns a verbose description of the OID. * This function parses ldap_supported_oids.txt and looks up the specified @@ -46,8 +29,15 @@ final class OID extends Schema * @return string|null * @testedby TranslateOidTest::testRootDSE() */ - protected static function get(string $string,string $key): ?string + public static function get(string $string,string $key): ?string { return parent::_get(config_path('ldap_supported_oids.txt'),$string,$key); } + + public function render(bool $edit=FALSE): View + { + // @note Schema attributes cannot be edited + return view('components.attribute.schema.oid') + ->with('o',$this); + } } \ No newline at end of file diff --git a/composer.json b/composer.json index df7eea8..62d84aa 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,7 @@ "keywords": ["framework","laravel"], "license": "MIT", "require": { + "ext-fileinfo": "*", "php": "^8.0.2", "directorytree/ldaprecord-laravel": "^2", "fideloper/proxy": "^4.4", diff --git a/resources/lang/README.md b/resources/lang/README.md new file mode 100644 index 0000000..60501ef --- /dev/null +++ b/resources/lang/README.md @@ -0,0 +1,6 @@ +This directory contains language translation files for PLA. + +Language files named by 2 letter iso language name (suffixed with .json) +represent the translations for that language. + +eg: en.json diff --git a/resources/views/components/attribute.blade.php b/resources/views/components/attribute.blade.php index 02d06fa..c7f57c6 100644 --- a/resources/views/components/attribute.blade.php +++ b/resources/views/components/attribute.blade.php @@ -1,3 +1,4 @@ +
diff --git a/resources/views/components/attribute/binary/jpegphoto.blade.php b/resources/views/components/attribute/binary/jpegphoto.blade.php new file mode 100644 index 0000000..a7f1b9a --- /dev/null +++ b/resources/views/components/attribute/binary/jpegphoto.blade.php @@ -0,0 +1,18 @@ + + + + @foreach ($o->values as $value) + @switch ($x=$f->buffer($value,FILEINFO_MIME_TYPE)) + @case('image/jpeg') + @default + + @endswitch + @endforeach + +
+ + + @if($edit) +
@lang('Delete') + @endif +
\ No newline at end of file diff --git a/resources/views/components/attribute/internal.blade.php b/resources/views/components/attribute/internal.blade.php new file mode 100644 index 0000000..e13fae0 --- /dev/null +++ b/resources/views/components/attribute/internal.blade.php @@ -0,0 +1,5 @@ + +@foreach (old($o->name_lc,$o->values) as $value) + @if($loop->index)
@endif + {{ $value }} +@endforeach \ No newline at end of file diff --git a/resources/views/components/attribute/internal/timestamp.blade.php b/resources/views/components/attribute/internal/timestamp.blade.php new file mode 100644 index 0000000..487ac36 --- /dev/null +++ b/resources/views/components/attribute/internal/timestamp.blade.php @@ -0,0 +1,5 @@ + +@foreach (old($o->name_lc,$o->values) as $value) + @if($loop->index)
@endif + {{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('ldap.datetime_format','Y-m-d H:i:s')) }} +@endforeach \ No newline at end of file diff --git a/resources/views/components/attribute/objectclass.blade.php b/resources/views/components/attribute/objectclass.blade.php new file mode 100644 index 0000000..9ce92e9 --- /dev/null +++ b/resources/views/components/attribute/objectclass.blade.php @@ -0,0 +1,24 @@ + +
+
+
+ @foreach (old($o->name_lc,$o->values) as $value) + @if ($edit && ! $o->is_structural) + + @else + {{ $value }}@if ($o->is_structural)@lang('structural')@endif
+ @endif + @endforeach +
+
+ +
+ @if($o->is_rdn) + {{ __('Rename') }} + @elseif($edit && $o->can_addvalues) +
+ {{ __('Add Value') }} +
+ @endif +
+
\ No newline at end of file diff --git a/resources/views/components/attribute/password.blade.php b/resources/views/components/attribute/password.blade.php new file mode 100644 index 0000000..fc90b50 --- /dev/null +++ b/resources/views/components/attribute/password.blade.php @@ -0,0 +1,18 @@ + +
+
+
+ @foreach (old($o->name_lc,$o->values) as $value) + @if ($edit) + + @else + {{ $value }}
+ @endif + @endforeach +
+
+ +
+ @lang('Check Password') +
+
\ No newline at end of file diff --git a/resources/views/components/attribute/schema/mechanisms.blade.php b/resources/views/components/attribute/schema/mechanisms.blade.php new file mode 100644 index 0000000..f20e529 --- /dev/null +++ b/resources/views/components/attribute/schema/mechanisms.blade.php @@ -0,0 +1,9 @@ +{!! $o->values + ->transform(function($item) use ($o) { + return sprintf('%s%s

%s

', + $item, + $o->get($item,'title'), + ($x=$o->get($item,'ref')) ? sprintf('',$x) : '', + $o->get($item,'desc'), + ); + })->join('
') !!} \ No newline at end of file diff --git a/resources/views/components/attribute/schema/oid.blade.php b/resources/views/components/attribute/schema/oid.blade.php new file mode 100644 index 0000000..8ec3e3e --- /dev/null +++ b/resources/views/components/attribute/schema/oid.blade.php @@ -0,0 +1,11 @@ +{!! $o->values + ->transform(function($item) use ($o) { + return preg_match('/[0-9]+\.[0-9]+\.[0-9]+/',$item) + ? sprintf('%s%s

%s

', + $item, + $o->get($item,'title'), + ($x=$o->get($item,'ref')) ? sprintf('',$x) : '', + $o->get($item,'desc'), + ) + : $item; + })->join('
') !!} \ No newline at end of file diff --git a/resources/views/frames/dn.blade.php b/resources/views/frames/dn.blade.php index 5216db2..8788577 100644 --- a/resources/views/frames/dn.blade.php +++ b/resources/views/frames/dn.blade.php @@ -3,7 +3,7 @@ @section('page_title') - + @@ -11,11 +11,11 @@
{!! $x ?: sprintf('
',$o->icon() ?? "fas fa-info") !!}
{!! $x ? $x->render() : sprintf('
',$o->icon() ?? "fas fa-info") !!}
{{ $dn }}
- + - + diff --git a/resources/views/frames/info.blade.php b/resources/views/frames/info.blade.php index ce89771..353601f 100644 --- a/resources/views/frames/info.blade.php +++ b/resources/views/frames/info.blade.php @@ -19,7 +19,9 @@ ? sprintf('%s',$x->name_lc,url('schema/attributetypes',$x->name_lc),$x->name) : $attribute !!} - + @endforeach
Created{{ ($x=Arr::get($o->getAttributes(),'createtimestamp')) ? $x : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'creatorsname')) ? $x : __('Unknown') }}]{{ ($x=Arr::get($o->getAttributes(),'createtimestamp')) ? $x->render() : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'creatorsname')) ? $x->render() : __('Unknown') }}]
Modified{{ ($x=Arr::get($o->getAttributes(),'modifytimestamp')) ? $x : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'modifiersname')) ? $x : __('Unknown') }}]{{ ($x=Arr::get($o->getAttributes(),'modifytimestamp')) ? $x->render() : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'modifiersname')) ? $x->render() : __('Unknown') }}]
UUID{!! $ao !!} + +