Skip to content

Commit bcea6de

Browse files
committed
Validation of inputs for a DN with language tags - work for #16
1 parent 28f4869 commit bcea6de

File tree

15 files changed

+80
-61
lines changed

15 files changed

+80
-61
lines changed

app/Classes/LDAP/Schema/AttributeType.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
use Illuminate\Support\Collection;
77
use Illuminate\Support\Facades\Log;
88

9+
use App\Classes\LDAP\Attribute;
10+
use App\Ldap\Entry;
11+
912
/**
1013
* Represents an LDAP AttributeType
1114
*
@@ -341,6 +344,11 @@ public function addUsedInObjectClass(string $name,bool $structural): void
341344
$this->used_in_object_classes->put($name,$structural);
342345
}
343346

347+
private function factory(): Attribute
348+
{
349+
return Attribute\Factory::create(dn:'',attribute:$this->name,values:[]);
350+
}
351+
344352
/**
345353
* Gets the names of attributes that are an alias for this attribute (if any).
346354
*
@@ -548,6 +556,7 @@ public function validation(array $array): ?array
548556
{
549557
// For each item in array, we need to get the OC hierarchy
550558
$heirachy = collect($array)
559+
->flatten()
551560
->filter()
552561
->map(fn($item)=>config('server')
553562
->schema('objectclasses',$item)
@@ -556,14 +565,17 @@ public function validation(array $array): ?array
556565
->flatten()
557566
->unique();
558567

568+
// Get any config validation
559569
$validation = collect(Arr::get(config('ldap.validation'),$this->name_lc,[]));
560570

571+
$nolangtag = sprintf('%s.%s.0',$this->name_lc,Entry::TAG_NOTAG);
572+
561573
// Add in schema required by conditions
562574
if (($heirachy->intersect($this->required_by_object_classes->keys())->count() > 0)
563575
&& (! collect($validation->get($this->name_lc))->contains('required'))) {
564576
$validation
565-
->prepend(array_merge(['required','min:1'],$validation->get($this->name_lc.'.0',[])),$this->name_lc.'.0')
566-
->prepend(array_merge(['required','array','min:1'],$validation->get($this->name_lc,[])),$this->name_lc);
577+
->prepend(array_merge(['required','min:1'],$validation->get($nolangtag,[])),$nolangtag)
578+
->prepend(array_merge(['required','array','min:1',($this->factory()->no_attr_tags ? 'max:1' : NULL)],$validation->get($this->name_lc,[])),$this->name_lc);
567579
}
568580

569581
return $validation->toArray();

app/Http/Controllers/HomeController.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ public function entry_add(EntryAddRequest $request): \Illuminate\View\View
5757

5858
$o = new Entry;
5959

60-
if (count(array_filter($x=old('objectclass',$request->objectclass)))) {
61-
$o->objectclass = [Entry::TAG_NOTAG=>$x];
60+
if (count($x=array_filter(old('objectclass',$request->objectclass)))) {
61+
$o->objectclass = $x;
6262

63+
// Also add in our required attributes
6364
foreach($o->getAvailableAttributes()->filter(fn($item)=>$item->required) as $ao)
6465
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
6566

@@ -375,8 +376,7 @@ public function frame(Request $request,?Collection $old=NULL): \Illuminate\View\
375376
// If we are rendering a DN, rebuild our object
376377
$o = config('server')->fetch($key['dn']);
377378

378-
// @todo We need to dynamically exclude request items, so we dont need to add them here
379-
foreach (collect(old())->except(['dn','_token','userpassword_hash']) as $attr => $value)
379+
foreach (collect(old())->except(['key','step','_token','userpassword_hash']) as $attr => $value)
380380
$o->{$attr} = $value;
381381

382382
return match ($key['cmd']) {

app/Http/Requests/EntryAddRequest.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ public function rules(): array
3434
if (request()->method() === 'GET')
3535
return [];
3636

37+
$r = request() ?: collect();
3738
return config('server')
3839
->schema('attributetypes')
39-
->intersectByKeys($this->request)
40-
->map(fn($item)=>$item->validation(request()->get('objectclass')))
40+
->intersectByKeys($r->all())
41+
->map(fn($item)=>$item->validation($r->get('objectclass',[])))
4142
->filter()
4243
->flatMap(fn($item)=>$item)
4344
->merge([
@@ -60,6 +61,12 @@ function (string $attribute,mixed $value,\Closure $fail) {
6061
'rdn_value' => 'required_if:step,2|string|min:1',
6162
'step' => 'int|min:1|max:2',
6263
'objectclass'=>[
64+
'required',
65+
'array',
66+
'min:1',
67+
'max:1',
68+
],
69+
'objectclass._null_'=>[
6370
'required',
6471
'array',
6572
'min:1',

app/Http/Requests/EntryRequest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ class EntryRequest extends FormRequest
1313
*/
1414
public function rules(): array
1515
{
16+
$r = request() ?: collect();
17+
1618
return config('server')
1719
->schema('attributetypes')
18-
->intersectByKeys($this->request)
19-
->map(fn($item)=>$item->validation(request()?->get('objectclass') ?: []))
20+
->intersectByKeys($r->all())
21+
->map(fn($item)=>$item->validation($r->get('objectclass',[])))
2022
->filter()
2123
->flatMap(fn($item)=>$item)
2224
->toArray();

app/Ldap/Entry.php

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,36 @@ public function addAttributeItem(string $key,mixed $value): void
188188
$this->objects->put($attribute,$o);
189189
}
190190

191+
/**
192+
* Export this record
193+
*
194+
* @param string $method
195+
* @param string $scope
196+
* @return string
197+
* @throws \Exception
198+
*/
199+
public function export(string $method,string $scope): string
200+
{
201+
// @todo To implement
202+
switch ($scope) {
203+
case 'base':
204+
case 'one':
205+
case 'sub':
206+
break;
207+
208+
default:
209+
throw new \Exception('Export scope unknown:'.$scope);
210+
}
211+
212+
switch ($method) {
213+
case 'ldif':
214+
return new LDIF(collect($this));
215+
216+
default:
217+
throw new \Exception('Export method not implemented:'.$method);
218+
}
219+
}
220+
191221
/**
192222
* Convert all our attribute values into an array of Objects
193223
*
@@ -409,36 +439,6 @@ public function hasAttribute(int|string $key): bool
409439
->has($key);
410440
}
411441

412-
/**
413-
* Export this record
414-
*
415-
* @param string $method
416-
* @param string $scope
417-
* @return string
418-
* @throws \Exception
419-
*/
420-
public function export(string $method,string $scope): string
421-
{
422-
// @todo To implement
423-
switch ($scope) {
424-
case 'base':
425-
case 'one':
426-
case 'sub':
427-
break;
428-
429-
default:
430-
throw new \Exception('Export scope unknown:'.$scope);
431-
}
432-
433-
switch ($method) {
434-
case 'ldif':
435-
return new LDIF(collect($this));
436-
437-
default:
438-
throw new \Exception('Export method not implemented:'.$method);
439-
}
440-
}
441-
442442
/**
443443
* Return an icon for a DN based on objectClass
444444
*

app/Rules/HasStructuralObjectClass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static function __set_state(array $array): self
2020
*/
2121
public function validate(string $attribute,mixed $value,Closure $fail): void
2222
{
23-
foreach ($value as $item)
23+
foreach (collect($value)->dot() as $item)
2424
if ($item && config('server')->schema('objectclasses',$item)->isStructural())
2525
return;
2626

config/ldap.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,47 +122,47 @@
122122
*/
123123
'validation' => [
124124
'objectclass' => [
125-
'objectclass'=>[
125+
'objectclass.*'=>[
126126
new HasStructuralObjectClass,
127127
]
128128
],
129129
'gidnumber' => [
130-
'gidnumber'=> [
130+
'gidnumber.*'=> [
131131
'sometimes',
132132
'max:1'
133133
],
134-
'gidnumber.*' => [
134+
'gidnumber.*.*' => [
135135
'nullable',
136136
'integer',
137137
'max:65535'
138138
]
139139
],
140140
'mail' => [
141-
'mail'=>[
141+
'mail.*'=>[
142142
'sometimes',
143143
'min:1'
144144
],
145-
'mail.*' => [
145+
'mail.*.*' => [
146146
'nullable',
147147
'email'
148148
]
149149
],
150150
'userpassword' => [
151-
'userpassword' => [
151+
'userpassword.*' => [
152152
'sometimes',
153153
'min:1'
154154
],
155-
'userpassword.*' => [
155+
'userpassword.*.*' => [
156156
'nullable',
157157
'min:8'
158158
]
159159
],
160160
'uidnumber' => [
161-
'uidnumber' => [
161+
'uidnumber.*' => [
162162
'sometimes',
163163
'max:1'
164164
],
165-
'uidnumber.*' => [
165+
'uidnumber.*.*' => [
166166
'nullable',
167167
'integer',
168168
'max:65535'

resources/views/components/attribute.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
@foreach(Arr::get(old($o->name_lc,[$langtag=>($new ?? FALSE) ? [NULL] : $o->tagValues($langtag)]),$langtag) as $key => $value)
55
@if(($edit ?? FALSE) && ! $o->is_rdn)
66
<div class="input-group has-validation">
7-
<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))>
7+
<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))>
88

99
<div class="invalid-feedback pb-2">
1010
@if($e)

resources/views/components/attribute/binary/jpegphoto.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
@default
1010
<td>
1111
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}">
12-
<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) }}" />
12+
<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) }}" />
1313

1414
@if($edit)
1515
<br>

resources/views/components/attribute/krbprincipalkey.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
@foreach($o->tagValuesOld($langtag) as $key => $value)
55
@if($edit)
66
<div class="input-group has-validation mb-3">
7-
<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)>
7+
<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)>
88

99
<div class="invalid-feedback pb-2">
1010
@if($e)

0 commit comments

Comments
 (0)