Validation of inputs for a DN with language tags - work for #16
Some checks failed
Create Docker Image / Build Docker Image (arm64) (push) Has been cancelled
Create Docker Image / Build Docker Image (x86_64) (push) Has been cancelled
Create Docker Image / Final Docker Image Manifest (push) Has been cancelled
Create Docker Image / Test Application (x86_64) (push) Has been cancelled
Some checks failed
Create Docker Image / Build Docker Image (arm64) (push) Has been cancelled
Create Docker Image / Build Docker Image (x86_64) (push) Has been cancelled
Create Docker Image / Final Docker Image Manifest (push) Has been cancelled
Create Docker Image / Test Application (x86_64) (push) Has been cancelled
This commit is contained in:
parent
28f4869628
commit
bcea6de791
@ -6,6 +6,9 @@ use Illuminate\Support\Arr;
|
|||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
use App\Classes\LDAP\Attribute;
|
||||||
|
use App\Ldap\Entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an LDAP AttributeType
|
* Represents an LDAP AttributeType
|
||||||
*
|
*
|
||||||
@ -341,6 +344,11 @@ final class AttributeType extends Base {
|
|||||||
$this->used_in_object_classes->put($name,$structural);
|
$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).
|
* 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
|
// For each item in array, we need to get the OC hierarchy
|
||||||
$heirachy = collect($array)
|
$heirachy = collect($array)
|
||||||
|
->flatten()
|
||||||
->filter()
|
->filter()
|
||||||
->map(fn($item)=>config('server')
|
->map(fn($item)=>config('server')
|
||||||
->schema('objectclasses',$item)
|
->schema('objectclasses',$item)
|
||||||
@ -556,14 +565,17 @@ final class AttributeType extends Base {
|
|||||||
->flatten()
|
->flatten()
|
||||||
->unique();
|
->unique();
|
||||||
|
|
||||||
|
// Get any config validation
|
||||||
$validation = collect(Arr::get(config('ldap.validation'),$this->name_lc,[]));
|
$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
|
// Add in schema required by conditions
|
||||||
if (($heirachy->intersect($this->required_by_object_classes->keys())->count() > 0)
|
if (($heirachy->intersect($this->required_by_object_classes->keys())->count() > 0)
|
||||||
&& (! collect($validation->get($this->name_lc))->contains('required'))) {
|
&& (! collect($validation->get($this->name_lc))->contains('required'))) {
|
||||||
$validation
|
$validation
|
||||||
->prepend(array_merge(['required','min:1'],$validation->get($this->name_lc.'.0',[])),$this->name_lc.'.0')
|
->prepend(array_merge(['required','min:1'],$validation->get($nolangtag,[])),$nolangtag)
|
||||||
->prepend(array_merge(['required','array','min:1'],$validation->get($this->name_lc,[])),$this->name_lc);
|
->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();
|
return $validation->toArray();
|
||||||
|
@ -57,9 +57,10 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
$o = new Entry;
|
$o = new Entry;
|
||||||
|
|
||||||
if (count(array_filter($x=old('objectclass',$request->objectclass)))) {
|
if (count($x=array_filter(old('objectclass',$request->objectclass)))) {
|
||||||
$o->objectclass = [Entry::TAG_NOTAG=>$x];
|
$o->objectclass = $x;
|
||||||
|
|
||||||
|
// Also add in our required attributes
|
||||||
foreach($o->getAvailableAttributes()->filter(fn($item)=>$item->required) as $ao)
|
foreach($o->getAvailableAttributes()->filter(fn($item)=>$item->required) as $ao)
|
||||||
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
|
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
|
||||||
|
|
||||||
@ -375,8 +376,7 @@ class HomeController extends Controller
|
|||||||
// If we are rendering a DN, rebuild our object
|
// If we are rendering a DN, rebuild our object
|
||||||
$o = config('server')->fetch($key['dn']);
|
$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(['key','step','_token','userpassword_hash']) as $attr => $value)
|
||||||
foreach (collect(old())->except(['dn','_token','userpassword_hash']) as $attr => $value)
|
|
||||||
$o->{$attr} = $value;
|
$o->{$attr} = $value;
|
||||||
|
|
||||||
return match ($key['cmd']) {
|
return match ($key['cmd']) {
|
||||||
|
@ -34,10 +34,11 @@ class EntryAddRequest extends FormRequest
|
|||||||
if (request()->method() === 'GET')
|
if (request()->method() === 'GET')
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
|
$r = request() ?: collect();
|
||||||
return config('server')
|
return config('server')
|
||||||
->schema('attributetypes')
|
->schema('attributetypes')
|
||||||
->intersectByKeys($this->request)
|
->intersectByKeys($r->all())
|
||||||
->map(fn($item)=>$item->validation(request()->get('objectclass')))
|
->map(fn($item)=>$item->validation($r->get('objectclass',[])))
|
||||||
->filter()
|
->filter()
|
||||||
->flatMap(fn($item)=>$item)
|
->flatMap(fn($item)=>$item)
|
||||||
->merge([
|
->merge([
|
||||||
@ -60,6 +61,12 @@ class EntryAddRequest extends FormRequest
|
|||||||
'rdn_value' => 'required_if:step,2|string|min:1',
|
'rdn_value' => 'required_if:step,2|string|min:1',
|
||||||
'step' => 'int|min:1|max:2',
|
'step' => 'int|min:1|max:2',
|
||||||
'objectclass'=>[
|
'objectclass'=>[
|
||||||
|
'required',
|
||||||
|
'array',
|
||||||
|
'min:1',
|
||||||
|
'max:1',
|
||||||
|
],
|
||||||
|
'objectclass._null_'=>[
|
||||||
'required',
|
'required',
|
||||||
'array',
|
'array',
|
||||||
'min:1',
|
'min:1',
|
||||||
|
@ -13,10 +13,12 @@ class EntryRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
|
$r = request() ?: collect();
|
||||||
|
|
||||||
return config('server')
|
return config('server')
|
||||||
->schema('attributetypes')
|
->schema('attributetypes')
|
||||||
->intersectByKeys($this->request)
|
->intersectByKeys($r->all())
|
||||||
->map(fn($item)=>$item->validation(request()?->get('objectclass') ?: []))
|
->map(fn($item)=>$item->validation($r->get('objectclass',[])))
|
||||||
->filter()
|
->filter()
|
||||||
->flatMap(fn($item)=>$item)
|
->flatMap(fn($item)=>$item)
|
||||||
->toArray();
|
->toArray();
|
||||||
|
@ -188,6 +188,36 @@ class Entry extends Model
|
|||||||
$this->objects->put($attribute,$o);
|
$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
|
* Convert all our attribute values into an array of Objects
|
||||||
*
|
*
|
||||||
@ -409,36 +439,6 @@ class Entry extends Model
|
|||||||
->has($key);
|
->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
|
* Return an icon for a DN based on objectClass
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,7 @@ class HasStructuralObjectClass implements ValidationRule
|
|||||||
*/
|
*/
|
||||||
public function validate(string $attribute,mixed $value,Closure $fail): void
|
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())
|
if ($item && config('server')->schema('objectclasses',$item)->isStructural())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -122,47 +122,47 @@ return [
|
|||||||
*/
|
*/
|
||||||
'validation' => [
|
'validation' => [
|
||||||
'objectclass' => [
|
'objectclass' => [
|
||||||
'objectclass'=>[
|
'objectclass.*'=>[
|
||||||
new HasStructuralObjectClass,
|
new HasStructuralObjectClass,
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'gidnumber' => [
|
'gidnumber' => [
|
||||||
'gidnumber'=> [
|
'gidnumber.*'=> [
|
||||||
'sometimes',
|
'sometimes',
|
||||||
'max:1'
|
'max:1'
|
||||||
],
|
],
|
||||||
'gidnumber.*' => [
|
'gidnumber.*.*' => [
|
||||||
'nullable',
|
'nullable',
|
||||||
'integer',
|
'integer',
|
||||||
'max:65535'
|
'max:65535'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'mail' => [
|
'mail' => [
|
||||||
'mail'=>[
|
'mail.*'=>[
|
||||||
'sometimes',
|
'sometimes',
|
||||||
'min:1'
|
'min:1'
|
||||||
],
|
],
|
||||||
'mail.*' => [
|
'mail.*.*' => [
|
||||||
'nullable',
|
'nullable',
|
||||||
'email'
|
'email'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'userpassword' => [
|
'userpassword' => [
|
||||||
'userpassword' => [
|
'userpassword.*' => [
|
||||||
'sometimes',
|
'sometimes',
|
||||||
'min:1'
|
'min:1'
|
||||||
],
|
],
|
||||||
'userpassword.*' => [
|
'userpassword.*.*' => [
|
||||||
'nullable',
|
'nullable',
|
||||||
'min:8'
|
'min:8'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'uidnumber' => [
|
'uidnumber' => [
|
||||||
'uidnumber' => [
|
'uidnumber.*' => [
|
||||||
'sometimes',
|
'sometimes',
|
||||||
'max:1'
|
'max:1'
|
||||||
],
|
],
|
||||||
'uidnumber.*' => [
|
'uidnumber.*.*' => [
|
||||||
'nullable',
|
'nullable',
|
||||||
'integer',
|
'integer',
|
||||||
'max:65535'
|
'max:65535'
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
@foreach(Arr::get(old($o->name_lc,[$langtag=>($new ?? FALSE) ? [NULL] : $o->tagValues($langtag)]),$langtag) as $key => $value)
|
@foreach(Arr::get(old($o->name_lc,[$langtag=>($new ?? FALSE) ? [NULL] : $o->tagValues($langtag)]),$langtag) as $key => $value)
|
||||||
@if(($edit ?? FALSE) && ! $o->is_rdn)
|
@if(($edit ?? FALSE) && ! $o->is_rdn)
|
||||||
<div class="input-group has-validation">
|
<div class="input-group has-validation">
|
||||||
<input type="text" @class(['form-control','is-invalid'=>($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))>
|
<input type="text" @class(['form-control','is-invalid'=>($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))>
|
||||||
|
|
||||||
<div class="invalid-feedback pb-2">
|
<div class="invalid-feedback pb-2">
|
||||||
@if($e)
|
@if($e)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
@default
|
@default
|
||||||
<td>
|
<td>
|
||||||
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}">
|
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}">
|
||||||
<img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
|
<img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
|
||||||
|
|
||||||
@if($edit)
|
@if($edit)
|
||||||
<br>
|
<br>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
@foreach($o->tagValuesOld($langtag) as $key => $value)
|
@foreach($o->tagValuesOld($langtag) as $key => $value)
|
||||||
@if($edit)
|
@if($edit)
|
||||||
<div class="input-group has-validation mb-3">
|
<div class="input-group has-validation mb-3">
|
||||||
<input type="password" @class(['form-control','is-invalid'=>($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)>
|
<input type="password" @class(['form-control','is-invalid'=>($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)>
|
||||||
|
|
||||||
<div class="invalid-feedback pb-2">
|
<div class="invalid-feedback pb-2">
|
||||||
@if($e)
|
@if($e)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" @readonly(true)>
|
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" @readonly(true)>
|
||||||
|
|
||||||
<div class="invalid-feedback pb-2">
|
<div class="invalid-feedback pb-2">
|
||||||
@if($e=$errors->get($o->name_lc.'.'.$loop->index))
|
@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))
|
||||||
{{ join('|',$e) }}
|
{{ join('|',$e) }}
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
@if($edit)
|
@if($edit)
|
||||||
<div class="input-group has-validation mb-3">
|
<div class="input-group has-validation mb-3">
|
||||||
<x-form.select id="userpassword_hash_{{$loop->index}}" name="userpassword_hash[{{ $langtag }}][]" :value="$o->hash($value)->id()" :options="$helpers" allowclear="false" :disabled="true"/>
|
<x-form.select id="userpassword_hash_{{$loop->index}}" name="userpassword_hash[{{ $langtag }}][]" :value="$o->hash($value)->id()" :options="$helpers" allowclear="false" :disabled="true"/>
|
||||||
<input type="password" @class(['form-control','is-invalid'=>($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)>
|
<input type="password" @class(['form-control','is-invalid'=>($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)>
|
||||||
|
|
||||||
<div class="invalid-feedback pb-2">
|
<div class="invalid-feedback pb-2">
|
||||||
@if($e)
|
@if($e)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<span id="objectclass_{{$value}}">
|
<span id="objectclass_{{$value}}">
|
||||||
<div class="input-group has-validation">
|
<div class="input-group has-validation">
|
||||||
<!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way -->
|
<!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way -->
|
||||||
<input type="text" @class(['form-control','input-group-end','is-invalid'=>($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)>
|
<input type="text" @class(['form-control','input-group-end','is-invalid'=>($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))
|
@if ($o->isStructural($value))
|
||||||
<span class="input-group-end text-black-50">@lang('structural')</span>
|
<span class="input-group-end text-black-50">@lang('structural')</span>
|
||||||
@else
|
@else
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@use(App\Ldap\Entry)
|
||||||
|
|
||||||
@extends('layouts.dn')
|
@extends('layouts.dn')
|
||||||
|
|
||||||
@section('page_title')
|
@section('page_title')
|
||||||
@ -31,7 +33,7 @@
|
|||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<x-form.select
|
<x-form.select
|
||||||
id="objectclass"
|
id="objectclass"
|
||||||
name="objectclass[]"
|
name="objectclass[{{ Entry::TAG_NOTAG }}][]"
|
||||||
:label="__('Select a Structural ObjectClass...')"
|
:label="__('Select a Structural ObjectClass...')"
|
||||||
:options="($oc=$server->schema('objectclasses'))
|
:options="($oc=$server->schema('objectclasses'))
|
||||||
->filter(fn($item)=>$item->isStructural())
|
->filter(fn($item)=>$item->isStructural())
|
||||||
|
@ -62,10 +62,6 @@
|
|||||||
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
|
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
|
||||||
This entry has multi-language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
|
This entry has multi-language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
|
||||||
</div>
|
</div>
|
||||||
@elseif(($x=$o->getLangTags())->count())
|
|
||||||
<div class="ms-4 mt-4 alert alert-warning p-2" style="max-width: 30em; font-size: 0.80em;">
|
|
||||||
This entry has language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA yet. You can though manage those lang tags with an LDIF import.
|
|
||||||
</div>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user