diff --git a/app/Classes/LDAP/Schema/AttributeType.php b/app/Classes/LDAP/Schema/AttributeType.php index 33af446d..b4463ef6 100644 --- a/app/Classes/LDAP/Schema/AttributeType.php +++ b/app/Classes/LDAP/Schema/AttributeType.php @@ -6,6 +6,9 @@ use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; +use App\Classes\LDAP\Attribute; +use App\Ldap\Entry; + /** * Represents an LDAP AttributeType * @@ -341,6 +344,11 @@ final class AttributeType extends Base { $this->used_in_object_classes->put($name,$structural); } + private function factory(): Attribute + { + return Attribute\Factory::create(dn:'',attribute:$this->name,values:[]); + } + /** * Gets the names of attributes that are an alias for this attribute (if any). * @@ -548,6 +556,7 @@ final class AttributeType extends Base { { // For each item in array, we need to get the OC hierarchy $heirachy = collect($array) + ->flatten() ->filter() ->map(fn($item)=>config('server') ->schema('objectclasses',$item) @@ -556,14 +565,17 @@ final class AttributeType extends Base { ->flatten() ->unique(); + // Get any config validation $validation = collect(Arr::get(config('ldap.validation'),$this->name_lc,[])); + $nolangtag = sprintf('%s.%s.0',$this->name_lc,Entry::TAG_NOTAG); + // Add in schema required by conditions if (($heirachy->intersect($this->required_by_object_classes->keys())->count() > 0) && (! collect($validation->get($this->name_lc))->contains('required'))) { $validation - ->prepend(array_merge(['required','min:1'],$validation->get($this->name_lc.'.0',[])),$this->name_lc.'.0') - ->prepend(array_merge(['required','array','min:1'],$validation->get($this->name_lc,[])),$this->name_lc); + ->prepend(array_merge(['required','min:1'],$validation->get($nolangtag,[])),$nolangtag) + ->prepend(array_merge(['required','array','min:1',($this->factory()->no_attr_tags ? 'max:1' : NULL)],$validation->get($this->name_lc,[])),$this->name_lc); } return $validation->toArray(); diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 3adc6045..a5da0265 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -57,9 +57,10 @@ class HomeController extends Controller $o = new Entry; - if (count(array_filter($x=old('objectclass',$request->objectclass)))) { - $o->objectclass = [Entry::TAG_NOTAG=>$x]; + if (count($x=array_filter(old('objectclass',$request->objectclass)))) { + $o->objectclass = $x; + // Also add in our required attributes foreach($o->getAvailableAttributes()->filter(fn($item)=>$item->required) as $ao) $o->{$ao->name} = [Entry::TAG_NOTAG=>'']; @@ -375,8 +376,7 @@ class HomeController extends Controller // If we are rendering a DN, rebuild our object $o = config('server')->fetch($key['dn']); - // @todo We need to dynamically exclude request items, so we dont need to add them here - foreach (collect(old())->except(['dn','_token','userpassword_hash']) as $attr => $value) + foreach (collect(old())->except(['key','step','_token','userpassword_hash']) as $attr => $value) $o->{$attr} = $value; return match ($key['cmd']) { diff --git a/app/Http/Requests/EntryAddRequest.php b/app/Http/Requests/EntryAddRequest.php index dc2b865d..d3231772 100644 --- a/app/Http/Requests/EntryAddRequest.php +++ b/app/Http/Requests/EntryAddRequest.php @@ -34,10 +34,11 @@ class EntryAddRequest extends FormRequest if (request()->method() === 'GET') return []; + $r = request() ?: collect(); return config('server') ->schema('attributetypes') - ->intersectByKeys($this->request) - ->map(fn($item)=>$item->validation(request()->get('objectclass'))) + ->intersectByKeys($r->all()) + ->map(fn($item)=>$item->validation($r->get('objectclass',[]))) ->filter() ->flatMap(fn($item)=>$item) ->merge([ @@ -60,6 +61,12 @@ class EntryAddRequest extends FormRequest 'rdn_value' => 'required_if:step,2|string|min:1', 'step' => 'int|min:1|max:2', 'objectclass'=>[ + 'required', + 'array', + 'min:1', + 'max:1', + ], + 'objectclass._null_'=>[ 'required', 'array', 'min:1', diff --git a/app/Http/Requests/EntryRequest.php b/app/Http/Requests/EntryRequest.php index b7b0dd1c..2facca6e 100644 --- a/app/Http/Requests/EntryRequest.php +++ b/app/Http/Requests/EntryRequest.php @@ -13,10 +13,12 @@ class EntryRequest extends FormRequest */ public function rules(): array { + $r = request() ?: collect(); + return config('server') ->schema('attributetypes') - ->intersectByKeys($this->request) - ->map(fn($item)=>$item->validation(request()?->get('objectclass') ?: [])) + ->intersectByKeys($r->all()) + ->map(fn($item)=>$item->validation($r->get('objectclass',[]))) ->filter() ->flatMap(fn($item)=>$item) ->toArray(); diff --git a/app/Ldap/Entry.php b/app/Ldap/Entry.php index 6491938a..741ee998 100644 --- a/app/Ldap/Entry.php +++ b/app/Ldap/Entry.php @@ -188,6 +188,36 @@ class Entry extends Model $this->objects->put($attribute,$o); } + /** + * Export this record + * + * @param string $method + * @param string $scope + * @return string + * @throws \Exception + */ + public function export(string $method,string $scope): string + { + // @todo To implement + switch ($scope) { + case 'base': + case 'one': + case 'sub': + break; + + default: + throw new \Exception('Export scope unknown:'.$scope); + } + + switch ($method) { + case 'ldif': + return new LDIF(collect($this)); + + default: + throw new \Exception('Export method not implemented:'.$method); + } + } + /** * Convert all our attribute values into an array of Objects * @@ -409,36 +439,6 @@ class Entry extends Model ->has($key); } - /** - * Export this record - * - * @param string $method - * @param string $scope - * @return string - * @throws \Exception - */ - public function export(string $method,string $scope): string - { - // @todo To implement - switch ($scope) { - case 'base': - case 'one': - case 'sub': - break; - - default: - throw new \Exception('Export scope unknown:'.$scope); - } - - switch ($method) { - case 'ldif': - return new LDIF(collect($this)); - - default: - throw new \Exception('Export method not implemented:'.$method); - } - } - /** * Return an icon for a DN based on objectClass * diff --git a/app/Rules/HasStructuralObjectClass.php b/app/Rules/HasStructuralObjectClass.php index a6e57c5a..7af2a313 100644 --- a/app/Rules/HasStructuralObjectClass.php +++ b/app/Rules/HasStructuralObjectClass.php @@ -20,7 +20,7 @@ class HasStructuralObjectClass implements ValidationRule */ public function validate(string $attribute,mixed $value,Closure $fail): void { - foreach ($value as $item) + foreach (collect($value)->dot() as $item) if ($item && config('server')->schema('objectclasses',$item)->isStructural()) return; diff --git a/config/ldap.php b/config/ldap.php index 21c2448b..b9da888a 100644 --- a/config/ldap.php +++ b/config/ldap.php @@ -122,47 +122,47 @@ return [ */ 'validation' => [ 'objectclass' => [ - 'objectclass'=>[ + 'objectclass.*'=>[ new HasStructuralObjectClass, ] ], 'gidnumber' => [ - 'gidnumber'=> [ + 'gidnumber.*'=> [ 'sometimes', 'max:1' ], - 'gidnumber.*' => [ + 'gidnumber.*.*' => [ 'nullable', 'integer', 'max:65535' ] ], 'mail' => [ - 'mail'=>[ + 'mail.*'=>[ 'sometimes', 'min:1' ], - 'mail.*' => [ + 'mail.*.*' => [ 'nullable', 'email' ] ], 'userpassword' => [ - 'userpassword' => [ + 'userpassword.*' => [ 'sometimes', 'min:1' ], - 'userpassword.*' => [ + 'userpassword.*.*' => [ 'nullable', 'min:8' ] ], 'uidnumber' => [ - 'uidnumber' => [ + 'uidnumber.*' => [ 'sometimes', 'max:1' ], - 'uidnumber.*' => [ + 'uidnumber.*.*' => [ 'nullable', 'integer', 'max:65535' diff --git a/resources/views/components/attribute.blade.php b/resources/views/components/attribute.blade.php index 1fd59cd7..68d6867b 100644 --- a/resources/views/components/attribute.blade.php +++ b/resources/views/components/attribute.blade.php @@ -4,7 +4,7 @@ @foreach(Arr::get(old($o->name_lc,[$langtag=>($new ?? FALSE) ? [NULL] : $o->tagValues($langtag)]),$langtag) as $key => $value) @if(($edit ?? FALSE) && ! $o->is_rdn)
- ($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! ($new ?? FALSE))> + ($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! ($new ?? FALSE))>
@if($e) diff --git a/resources/views/components/attribute/binary/jpegphoto.blade.php b/resources/views/components/attribute/binary/jpegphoto.blade.php index 6a22bfe1..ee5a2929 100644 --- a/resources/views/components/attribute/binary/jpegphoto.blade.php +++ b/resources/views/components/attribute/binary/jpegphoto.blade.php @@ -9,7 +9,7 @@ @default - {{ $o->dn }}($e=$errors->get($o->name_lc.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" /> + {{ $o->dn }}($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" /> @if($edit)
diff --git a/resources/views/components/attribute/krbprincipalkey.blade.php b/resources/views/components/attribute/krbprincipalkey.blade.php index eea148e7..f1925b62 100644 --- a/resources/views/components/attribute/krbprincipalkey.blade.php +++ b/resources/views/components/attribute/krbprincipalkey.blade.php @@ -4,7 +4,7 @@ @foreach($o->tagValuesOld($langtag) as $key => $value) @if($edit)
- ($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)> + ($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)>
@if($e) diff --git a/resources/views/components/attribute/krbticketflags.blade.php b/resources/views/components/attribute/krbticketflags.blade.php index 1631a31f..80418109 100644 --- a/resources/views/components/attribute/krbticketflags.blade.php +++ b/resources/views/components/attribute/krbticketflags.blade.php @@ -9,7 +9,7 @@
- @if($e=$errors->get($o->name_lc.'.'.$loop->index)) + @if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)) {{ join('|',$e) }} @endif
diff --git a/resources/views/components/attribute/password.blade.php b/resources/views/components/attribute/password.blade.php index 9b78dce6..412f0229 100644 --- a/resources/views/components/attribute/password.blade.php +++ b/resources/views/components/attribute/password.blade.php @@ -5,7 +5,7 @@ @if($edit)
- ($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)> + ($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)>
@if($e) diff --git a/resources/views/components/attribute/widget/objectclass.blade.php b/resources/views/components/attribute/widget/objectclass.blade.php index 817badec..0218b63e 100644 --- a/resources/views/components/attribute/widget/objectclass.blade.php +++ b/resources/views/components/attribute/widget/objectclass.blade.php @@ -1,7 +1,7 @@
- ($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)> + ($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)> @if ($o->isStructural($value)) @lang('structural') @else diff --git a/resources/views/frames/create.blade.php b/resources/views/frames/create.blade.php index ebc33f59..834ff452 100644 --- a/resources/views/frames/create.blade.php +++ b/resources/views/frames/create.blade.php @@ -1,3 +1,5 @@ +@use(App\Ldap\Entry) + @extends('layouts.dn') @section('page_title') @@ -31,7 +33,7 @@
This entry has multi-language tags used by [{!! $x->keys()->join(', ') !!}] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
- @elseif(($x=$o->getLangTags())->count()) -
- This entry has language tags used by [{!! $x->keys()->join(', ') !!}] that cant be managed by PLA yet. You can though manage those lang tags with an LDIF import. -
@endif