Compare commits
3 Commits
8e8a902c80
...
b87b1dcfd0
Author | SHA1 | Date | |
---|---|---|---|
b87b1dcfd0 | |||
d61ecc96db | |||
820f398c2c |
@ -30,15 +30,20 @@ class Template
|
|||||||
public function __get(string $key): mixed
|
public function __get(string $key): mixed
|
||||||
{
|
{
|
||||||
return match ($key) {
|
return match ($key) {
|
||||||
'attributes' => array_map('strtolower',array_keys(Arr::get($this->template,$key))),
|
'attributes' => collect(array_map('strtolower',array_keys(Arr::get($this->template,$key)))),
|
||||||
'objectclasses' => array_map('strtolower',Arr::get($this->template,$key)),
|
'objectclasses' => collect(array_map('strtolower',Arr::get($this->template,$key))),
|
||||||
'enabled' => Arr::get($this->template,$key,FALSE),
|
'enabled' => Arr::get($this->template,$key,FALSE) && (! $this->invalid),
|
||||||
'icon','regexp' => Arr::get($this->template,$key),
|
'icon','regexp','title' => Arr::get($this->template,$key),
|
||||||
|
|
||||||
default => throw new \Exception('Unknown key: '.$key),
|
default => throw new \Exception('Unknown key: '.$key),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __isset(string $key): bool
|
||||||
|
{
|
||||||
|
return array_key_exists($key,$this->template);
|
||||||
|
}
|
||||||
|
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return $this->invalid ? '' : Arr::get($this->template,'title','No Template Name');
|
return $this->invalid ? '' : Arr::get($this->template,'title','No Template Name');
|
||||||
|
@ -55,16 +55,24 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
$key = $this->request_key($request,collect(old()));
|
$key = $this->request_key($request,collect(old()));
|
||||||
|
|
||||||
|
$template = NULL;
|
||||||
$o = new Entry;
|
$o = new Entry;
|
||||||
|
$o->setRDNBase($key['dn']);
|
||||||
|
|
||||||
if (count($x=array_filter(old('objectclass',$request->objectclass)))) {
|
if (count($x=collect(old('objectclass',$request->validated('objectclass')))->dot()->filter())) {
|
||||||
$o->objectclass = $x;
|
$o->objectclass = Arr::undot($x);
|
||||||
|
|
||||||
// Also add in our required attributes
|
// 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=>''];
|
||||||
|
|
||||||
$o->setRDNBase($key['dn']);
|
} elseif ($request->validated('template')) {
|
||||||
|
$template = $o->template($request->validated('template'));
|
||||||
|
$o->objectclass = [Entry::TAG_NOTAG=>$template->objectclasses->toArray()];
|
||||||
|
|
||||||
|
// @todo We need to add aliases
|
||||||
|
foreach($o->getAvailableAttributes()->filter(fn($item)=>$template->attributes->contains($item)) as $ao)
|
||||||
|
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
|
||||||
}
|
}
|
||||||
|
|
||||||
$step = $request->step ? $request->step+1 : old('step');
|
$step = $request->step ? $request->step+1 : old('step');
|
||||||
@ -74,6 +82,7 @@ class HomeController extends Controller
|
|||||||
->with('bases',$this->bases())
|
->with('bases',$this->bases())
|
||||||
->with('o',$o)
|
->with('o',$o)
|
||||||
->with('step',$step)
|
->with('step',$step)
|
||||||
|
->with('template',$template)
|
||||||
->with('container',old('container',$key['dn']));
|
->with('container',old('container',$key['dn']));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +392,12 @@ class HomeController extends Controller
|
|||||||
->with('bases',$this->bases());
|
->with('bases',$this->bases());
|
||||||
|
|
||||||
// If we are rendering a DN, rebuild our object
|
// If we are rendering a DN, rebuild our object
|
||||||
if ($key['dn']) {
|
if ($key['cmd'] === 'create') {
|
||||||
|
$o = new Entry;
|
||||||
|
$o->setRDNBase($key['dn']);
|
||||||
|
|
||||||
|
} elseif ($key['dn']) {
|
||||||
|
// @todo Need to handle if DN is null, for example if the user's session expired and the ACLs dont let them retrieve $key['dn']
|
||||||
$o = config('server')->fetch($key['dn']);
|
$o = config('server')->fetch($key['dn']);
|
||||||
|
|
||||||
foreach (collect(old())->except(['key','dn','step','_token','userpassword_hash','rdn','rdn_value']) as $attr => $value)
|
foreach (collect(old())->except(['key','dn','step','_token','userpassword_hash','rdn','rdn_value']) as $attr => $value)
|
||||||
@ -393,6 +407,7 @@ class HomeController extends Controller
|
|||||||
return match ($key['cmd']) {
|
return match ($key['cmd']) {
|
||||||
'create' => $view
|
'create' => $view
|
||||||
->with('container',old('container',$key['dn']))
|
->with('container',old('container',$key['dn']))
|
||||||
|
->with('o',$o)
|
||||||
->with('step',1),
|
->with('step',1),
|
||||||
|
|
||||||
'dn' => $view
|
'dn' => $view
|
||||||
|
@ -67,11 +67,42 @@ class EntryAddRequest extends FormRequest
|
|||||||
'max:1',
|
'max:1',
|
||||||
],
|
],
|
||||||
'objectclass._null_' => [
|
'objectclass._null_' => [
|
||||||
'required',
|
function (string $attribute,mixed $value,\Closure $fail) {
|
||||||
|
$oc = collect($value)->dot()->filter();
|
||||||
|
|
||||||
|
// If this is step 1 and there is no objectclass, and no template, then fail
|
||||||
|
if ((! $oc->count())
|
||||||
|
&& (request()->post('step') == 1)
|
||||||
|
&& (! request()->post('template')))
|
||||||
|
{
|
||||||
|
$fail(__('Select an objectclass or a template'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cant have both an objectclass and a template
|
||||||
|
if (request()->post('template') && $oc->count())
|
||||||
|
$fail(__('You cannot select a template and an objectclass'));
|
||||||
|
},
|
||||||
'array',
|
'array',
|
||||||
'min:1',
|
'min:1',
|
||||||
new HasStructuralObjectClass,
|
new HasStructuralObjectClass,
|
||||||
]
|
],
|
||||||
|
'template' => [
|
||||||
|
function (string $attribute,mixed $value,\Closure $fail) {
|
||||||
|
$oc = collect(request()->post('objectclass'))->dot()->filter();
|
||||||
|
|
||||||
|
// If this is step 1 and there is no objectclass, and no template, then fail
|
||||||
|
if ((! collect($value)->filter()->count())
|
||||||
|
&& (request()->post('step') == 1)
|
||||||
|
&& (! $oc->count()))
|
||||||
|
{
|
||||||
|
$fail(__('Select an objectclass or a template'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cant have both an objectclass and a template
|
||||||
|
if ($oc->count() && strlen($value))
|
||||||
|
$fail(__('You cannot select a template and an objectclass'));
|
||||||
|
},
|
||||||
|
],
|
||||||
])
|
])
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
@ -147,8 +147,7 @@ class Entry extends Model
|
|||||||
// Filter out our templates specific for this entry
|
// Filter out our templates specific for this entry
|
||||||
if ($this->dn && (! in_array(strtolower($this->dn),['cn=subschema']))) {
|
if ($this->dn && (! in_array(strtolower($this->dn),['cn=subschema']))) {
|
||||||
$this->templates = $this->templates
|
$this->templates = $this->templates
|
||||||
->filter(fn($item)=>(! $item->regexp) || preg_match($item->regexp,$this->dn))
|
->filter(fn($item)=>! count($item->objectclasses->diff(array_map('strtolower',Arr::get($this->attributes,'objectclass')))));
|
||||||
->filter(fn($item)=>! count(array_diff($item->objectclasses,array_map('strtolower',Arr::get($this->attributes,'objectclass')))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -550,6 +549,9 @@ class Entry extends Model
|
|||||||
throw new InvalidUsage('Cannot set RDN base on existing entries');
|
throw new InvalidUsage('Cannot set RDN base on existing entries');
|
||||||
|
|
||||||
$this->rdnbase = $bdn;
|
$this->rdnbase = $bdn;
|
||||||
|
|
||||||
|
$this->templates = $this->templates
|
||||||
|
->filter(fn($item)=>(! $item->regexp) || preg_match($item->regexp,$bdn));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function template(string $item): Template|Null
|
public function template(string $item): Template|Null
|
||||||
|
@ -24,6 +24,7 @@ class HasStructuralObjectClass implements ValidationRule
|
|||||||
if ($item && config('server')->schema('objectclasses',$item)->isStructural())
|
if ($item && config('server')->schema('objectclasses',$item)->isStructural())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
$fail('There isnt a Structural Objectclass.');
|
if (collect($value)->dot()->filter()->count())
|
||||||
|
$fail(__('There isnt a Structural Objectclass.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<x-form.select id="newoc" label="Select from..."/>
|
<x-form.select id="newoc" name="newoc" :label="__('Select from').'...'"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<button id="form-reset" class="btn btn-outline-danger">@lang('Reset')</button>
|
<button id="form-reset" class="btn btn-sm btn-outline-danger">@lang('Reset')</button>
|
||||||
|
|
||||||
@section('page-scripts')
|
@section('page-scripts')
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
<x-form.base {{ $attributes }}>
|
<x-form.base {{ $attributes }}>
|
||||||
@isset($name)
|
@isset($name)
|
||||||
<input type="hidden" id="{{ $id ?? $name }}_disabled" name="{{ $name }}" value="" disabled>
|
<input type="hidden" id="{{ $id ?? $name }}_disabled" name="{{ $name }}" value="" disabled>
|
||||||
|
@else
|
||||||
|
@php(throw new \Exception('here'))
|
||||||
|
@dd('no name',$id)
|
||||||
@endisset
|
@endisset
|
||||||
<select class="form-select @isset($name)@error((! empty($old)) ? $old : ($id ?? $name)) is-invalid @enderror @endisset" id="{{ $id ?? $name }}" @isset($name)name="{{ $name }}"@endisset @required(isset($required) && $required) @disabled(isset($disabled) && $disabled)>
|
|
||||||
@if((empty($value) && ! empty($options)) || isset($addnew) || isset($choose))
|
<select class="form-select @error($old ?? ($id ?? $name)) is-invalid @enderror" id="{{ $id ?? $name }}" name="{{ $name }}" @required($required ?? FALSE) @disabled($disabled ?? FALSE)>
|
||||||
|
@if((empty($value) && ! empty($options)) || isset($addnew))
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
|
|
||||||
@isset($addnew)
|
@isset($addnew)
|
||||||
<option value="new">{{ $addnew ?: 'Add New' }}</option>
|
<option value="new">{{ $addnew ?: 'Add New' }}</option>
|
||||||
@endisset
|
@endisset
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@isset($options)
|
@isset($options)
|
||||||
@empty($groupby)
|
@empty($groupby)
|
||||||
@foreach($options as $option)
|
@foreach($options as $option)
|
||||||
@continue(! Arr::get($option,'value'))
|
@continue(! Arr::get($option,'value'))
|
||||||
<option value="{{ Arr::get($option,'id') }}" @selected(isset($name) && (Arr::get($option,'id') == old($old ?? $name,$value ?? '')))>{{ Arr::get($option,'value') }}</option>
|
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == collect(old())->dot()->get(isset($old) ? $old.'.0' : ($id ?? $name)))>{{ Arr::get($option,'value') }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
@else
|
@else
|
||||||
@foreach($options->groupBy($groupby) as $group)
|
@foreach($options->groupBy($groupby) as $group)
|
||||||
<optgroup label="{{ $groupby == 'active' ? (Arr::get($group->first(),$groupby) ? 'Active' : 'Not Active') : Arr::get($group->first(),$groupby) }}">
|
<optgroup label="{{ Arr::get($group->first(),$groupby) }}">
|
||||||
@foreach($group as $option)
|
@foreach($group as $option)
|
||||||
@continue(! Arr::get($option,'value'))
|
@continue(! Arr::get($option,'value'))
|
||||||
<option value="{{ Arr::get($option,'id') }}" @selected(isset($name) && (Arr::get($option,'id') == old($old ?? $name,$value ?? '')))>{{ Arr::get($option,'value') }}</option>
|
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == collect(old())->dot()->get(isset($old) ? $old.'.0' : ($id ?? $name)))>{{ Arr::get($option,'value') }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</optgroup>
|
</optgroup>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 pt-2">
|
<div class="col-12 pt-2">
|
||||||
<x-form.select id="newattr" :label="__('Select from').'...'" :options="$o->getMissingAttributes()->sortBy('name')->unique('name')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name])"/>
|
<x-form.select name="newattr" :label="__('Select from').'...'" :options="$o->getMissingAttributes()->sortBy('name')->unique('name')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name])"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
@php($up=(session()->pull('updated') ?: collect()))
|
@php($up=(session()->pull('updated') ?: collect()))
|
||||||
@php($attributes=$o->template($template)?->attributes)
|
@php($attributes=$o->template($template)?->attributes)
|
||||||
|
|
||||||
@foreach($o->getVisibleAttributes()->filter(fn($item)=>in_array($item,$attributes)) as $ao)
|
@foreach($o->getVisibleAttributes()->filter(fn($item)=>$attributes->contains($item)) as $ao)
|
||||||
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :updated="$up->contains($ao->name_lc)"/>
|
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :updated="$up->contains($ao->name_lc)"/>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<div class="main-card mb-3 card">
|
<div class="main-card mb-3 card">
|
||||||
|
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@lang('Create New Entry') - @lang('Step') {{ $step }}
|
@lang('Create New Entry') - @lang('Step') {{ $step }} @isset($template) <span class="ms-auto"><i class="fa fa-fw {{ $template->icon }}"></i> {{ $template->title }}</span>@endisset
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -30,19 +30,35 @@
|
|||||||
@switch($step)
|
@switch($step)
|
||||||
@case(1)
|
@case(1)
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-5">
|
||||||
<x-form.select
|
<x-form.select
|
||||||
id="objectclass"
|
id="objectclass"
|
||||||
name="objectclass[{{ Entry::TAG_NOTAG }}][]"
|
name="objectclass[{{ Entry::TAG_NOTAG }}][]"
|
||||||
old="objectclass.{{ Entry::TAG_NOTAG }}"
|
old="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())
|
||||||
->sortBy(fn($item)=>$item->name_lc)
|
->sortBy(fn($item)=>$item->name_lc)
|
||||||
->map(fn($item)=>['id'=>$item->name,'value'=>$item->name])"
|
->map(fn($item)=>['id'=>$item->name,'value'=>$item->name])"
|
||||||
multiple="false"
|
:allowclear="TRUE"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if($o->templates->count())
|
||||||
|
<div class="col-md-1">
|
||||||
|
<strong>@lang('OR')</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-md-5">
|
||||||
|
<x-form.select
|
||||||
|
name="template"
|
||||||
|
:label="__('Select a Template').'...'"
|
||||||
|
:options="$o->templates
|
||||||
|
->map(fn($item,$key)=>['id'=>$key,'value'=>$item->title])"
|
||||||
|
:allowclear="TRUE"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@break
|
@break
|
||||||
|
|
||||||
@ -53,14 +69,12 @@
|
|||||||
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :updated="FALSE"/>
|
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :updated="FALSE"/>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
@include('fragment.dn.add_attr')
|
|
||||||
|
|
||||||
@break;
|
@break;
|
||||||
@endswitch
|
@endswitch
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="row d-none pt-3">
|
<div class="row d-none pt-3">
|
||||||
<div class="col-12 {{ $step > 1 ? 'offset-sm-2' : '' }} col-lg-10">
|
<div class="col-11 {{ $step > 1 ? 'text-end' : '' }} pe-0">
|
||||||
<x-form.reset form="dn-create"/>
|
<x-form.reset form="dn-create"/>
|
||||||
<x-form.submit :action="__('Next')" form="dn-create"/>
|
<x-form.submit :action="__('Next')" form="dn-create"/>
|
||||||
</div>
|
</div>
|
||||||
@ -102,7 +116,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
@if($step === 2)
|
@if($step === 1)
|
||||||
|
$('#objectclass').on('select2:open',function(){
|
||||||
|
$('#template').val(null).trigger('change');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#template').on('select2:open',function(){
|
||||||
|
$('#objectclass').val(null).trigger('change');
|
||||||
|
})
|
||||||
|
@elseif($step === 2)
|
||||||
$('#newattr').on('change',function(item) {
|
$('#newattr').on('change',function(item) {
|
||||||
var oc = $('attribute#objectclass input[type=text]')
|
var oc = $('attribute#objectclass input[type=text]')
|
||||||
.map((key,item)=>{return $(item).val()}).toArray();
|
.map((key,item)=>{return $(item).val()}).toArray();
|
||||||
|
@ -13,10 +13,6 @@
|
|||||||
"dc": {
|
"dc": {
|
||||||
"display": "Domain Component",
|
"display": "Domain Component",
|
||||||
"order": 1
|
"order": 1
|
||||||
},
|
|
||||||
"associatedDomain": {
|
|
||||||
"display": "Associated Domain",
|
|
||||||
"order": 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"icon": "fa-building",
|
"icon": "fa-building",
|
||||||
"rdn": "ou",
|
"rdn": "ou",
|
||||||
"regexp": "/^o=/",
|
"regexp": "/^c=.+,?/",
|
||||||
|
|
||||||
"objectclasses": [
|
"objectclasses": [
|
||||||
"organization"
|
"organization"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"icon": "fa-layer-group",
|
"icon": "fa-layer-group",
|
||||||
"rdn": "ou",
|
"rdn": "ou",
|
||||||
"regexp": "/^ou=.+,o=/",
|
"regexp": "/^o=.+,?/",
|
||||||
|
|
||||||
"objectclasses": [
|
"objectclasses": [
|
||||||
"organizationalUnit"
|
"organizationalUnit"
|
||||||
@ -15,11 +15,6 @@
|
|||||||
"display": "Organisational Unit",
|
"display": "Organisational Unit",
|
||||||
"hint": "This is an example",
|
"hint": "This is an example",
|
||||||
"order": 1
|
"order": 1
|
||||||
},
|
|
||||||
"attribute2": {
|
|
||||||
"display": "Attribute 2",
|
|
||||||
"hint": "This is an example",
|
|
||||||
"order": 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"icon": "fa-user",
|
"icon": "fa-user",
|
||||||
"rdn": "cn",
|
"rdn": "cn",
|
||||||
"regexp": "/,ou=People,o=/",
|
"regexp": "/^ou=.+,o=.+,?/",
|
||||||
|
|
||||||
"objectclasses": [
|
"objectclasses": [
|
||||||
"inetOrgPerson",
|
"inetOrgPerson",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user