Start of work to enable creation of new entries
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 27s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m26s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 4m35s
Create Docker Image / Final Docker Image Manifest (push) Successful in 9s
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 27s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m26s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 4m35s
Create Docker Image / Final Docker Image Manifest (push) Successful in 9s
This commit is contained in:
parent
bfe2aeac78
commit
29fb20ca6d
@ -145,9 +145,9 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
|||||||
// Attribute values
|
// Attribute values
|
||||||
'values' => $this->values,
|
'values' => $this->values,
|
||||||
// Required by Object Classes
|
// Required by Object Classes
|
||||||
'required_by' => $this->schema->required_by_object_classes,
|
'required_by' => $this->schema?->required_by_object_classes ?: collect(),
|
||||||
// Used in Object Classes
|
// Used in Object Classes
|
||||||
'used_in' => $this->schema->used_in_object_classes,
|
'used_in' => $this->schema?->used_in_object_classes ?: collect(),
|
||||||
|
|
||||||
default => throw new \Exception('Unknown key:' . $key),
|
default => throw new \Exception('Unknown key:' . $key),
|
||||||
};
|
};
|
||||||
|
51
app/Classes/LDAP/Attribute/RDN.php
Normal file
51
app/Classes/LDAP/Attribute/RDN.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Classes\LDAP\Attribute;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
use App\Classes\LDAP\Attribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the RDN for an Entry
|
||||||
|
*/
|
||||||
|
final class RDN extends Attribute
|
||||||
|
{
|
||||||
|
private string $base;
|
||||||
|
private Collection $objectclasses;
|
||||||
|
|
||||||
|
public function __get(string $key): mixed
|
||||||
|
{
|
||||||
|
return match ($key) {
|
||||||
|
'base' => $this->base,
|
||||||
|
default => parent::__get($key),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hints(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'required' => __('RDN is required')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||||
|
{
|
||||||
|
return view('components.attribute.rdn')
|
||||||
|
->with('o',$this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBase(string $base): void
|
||||||
|
{
|
||||||
|
$this->base = $base;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setObjectClasses(array $classes): void
|
||||||
|
{
|
||||||
|
$this->objectclasses = collect();
|
||||||
|
|
||||||
|
foreach ($classes as $class)
|
||||||
|
$this->objectclasses->push(cofig('server')->schema('objectclasses',$class));
|
||||||
|
}
|
||||||
|
}
|
@ -22,15 +22,15 @@ class APIController extends Controller
|
|||||||
{
|
{
|
||||||
$base = Server::baseDNs() ?: collect();
|
$base = Server::baseDNs() ?: collect();
|
||||||
|
|
||||||
return $base->transform(function($item) {
|
return $base
|
||||||
return [
|
->transform(fn($item)=>
|
||||||
|
[
|
||||||
'title'=>$item->getRdn(),
|
'title'=>$item->getRdn(),
|
||||||
'item'=>$item->getDNSecure(),
|
'item'=>$item->getDNSecure(),
|
||||||
'lazy'=>TRUE,
|
'lazy'=>TRUE,
|
||||||
'icon'=>'fa-fw fas fa-sitemap',
|
'icon'=>'fa-fw fas fa-sitemap',
|
||||||
'tooltip'=>$item->getDn(),
|
'tooltip'=>$item->getDn(),
|
||||||
];
|
]);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,15 +45,22 @@ class APIController extends Controller
|
|||||||
|
|
||||||
return (config('server'))
|
return (config('server'))
|
||||||
->children($dn)
|
->children($dn)
|
||||||
->transform(function($item) {
|
->transform(fn($item)=>
|
||||||
return [
|
[
|
||||||
'title'=>$item->getRdn(),
|
'title'=>$item->getRdn(),
|
||||||
'item'=>$item->getDNSecure(),
|
'item'=>$item->getDNSecure(),
|
||||||
'icon'=>$item->icon(),
|
'icon'=>$item->icon(),
|
||||||
'lazy'=>Arr::get($item->getAttribute('hassubordinates'),0) == 'TRUE',
|
'lazy'=>Arr::get($item->getAttribute('hassubordinates'),0) == 'TRUE',
|
||||||
'tooltip'=>$item->getDn(),
|
'tooltip'=>$item->getDn(),
|
||||||
];
|
])
|
||||||
});
|
->prepend(
|
||||||
|
[
|
||||||
|
'title'=>sprintf('[%s]',__('Create Entry')),
|
||||||
|
'item'=>Crypt::encryptString(sprintf('*%s|%s','create_new',$dn)),
|
||||||
|
'lazy'=>FALSE,
|
||||||
|
'icon'=>'fas fa-fw fa-square-plus text-warning',
|
||||||
|
'tooltip'=>__('Create new LDAP item here'),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schema_view(Request $request)
|
public function schema_view(Request $request)
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@ -12,16 +15,16 @@ use Illuminate\Support\Facades\Redirect;
|
|||||||
use LdapRecord\Exceptions\InsufficientAccessException;
|
use LdapRecord\Exceptions\InsufficientAccessException;
|
||||||
use LdapRecord\LdapRecordException;
|
use LdapRecord\LdapRecordException;
|
||||||
use LdapRecord\Query\ObjectNotFoundException;
|
use LdapRecord\Query\ObjectNotFoundException;
|
||||||
|
use Nette\NotImplementedException;
|
||||||
|
|
||||||
use App\Classes\LDAP\{Attribute,Server};
|
use App\Classes\LDAP\{Attribute,Server};
|
||||||
use App\Classes\LDAP\Import\LDIF as LDIFImport;
|
use App\Classes\LDAP\Import\LDIF as LDIFImport;
|
||||||
use App\Classes\LDAP\Export\LDIF as LDIFExport;
|
use App\Classes\LDAP\Export\LDIF as LDIFExport;
|
||||||
use App\Exceptions\Import\{GeneralException,VersionException};
|
use App\Exceptions\Import\{GeneralException,VersionException};
|
||||||
use App\Exceptions\InvalidUsage;
|
use App\Exceptions\InvalidUsage;
|
||||||
use App\Http\Requests\{EntryRequest,ImportRequest};
|
use App\Http\Requests\{EntryAdd,EntryRequest,ImportRequest};
|
||||||
use App\Ldap\Entry;
|
use App\Ldap\Entry;
|
||||||
use App\View\Components\AttributeType;
|
use App\View\Components\AttributeType;
|
||||||
use Nette\NotImplementedException;
|
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
@ -59,13 +62,57 @@ class HomeController extends Controller
|
|||||||
public function dn_frame(Request $request)
|
public function dn_frame(Request $request)
|
||||||
{
|
{
|
||||||
$dn = Crypt::decryptString($request->post('key'));
|
$dn = Crypt::decryptString($request->post('key'));
|
||||||
|
$cmd = '';
|
||||||
|
|
||||||
$page_actions = collect(['edit'=>TRUE,'copy'=>TRUE]);
|
if (str_contains($dn,'|')) {
|
||||||
|
$m = [];
|
||||||
|
|
||||||
return view('frames.dn')
|
if (preg_match('/\*([a-z_]+)\|(.+)$/',$dn,$m)) {
|
||||||
|
$cmd = $m[1];
|
||||||
|
$dn = $m[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match ($cmd) {
|
||||||
|
'create_new' => view('frames.create')
|
||||||
|
->with('o',config('server')->fetch($dn))
|
||||||
|
->with('step',0)
|
||||||
|
->with('dn',$dn),
|
||||||
|
|
||||||
|
default => view('frames.dn')
|
||||||
->with('o',config('server')->fetch($dn))
|
->with('o',config('server')->fetch($dn))
|
||||||
->with('dn',$dn)
|
->with('dn',$dn)
|
||||||
->with('page_actions',$page_actions);
|
->with('page_actions',collect(['edit'=>TRUE,'copy'=>TRUE])),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new object in the LDAP server
|
||||||
|
*
|
||||||
|
* @param EntryAdd $request
|
||||||
|
* @return Factory|View|Application|object
|
||||||
|
* @throws InvalidUsage
|
||||||
|
*/
|
||||||
|
public function entry_add(EntryAdd $request)
|
||||||
|
{
|
||||||
|
switch ($request->step) {
|
||||||
|
case 1:
|
||||||
|
$container = Crypt::decryptString($request->dn);
|
||||||
|
|
||||||
|
$o = new Entry;
|
||||||
|
$o->objectclass = $request->objectclass;
|
||||||
|
$o->setRDNBase($container);
|
||||||
|
|
||||||
|
return view('frame')
|
||||||
|
->with('subframe',$request->frame)
|
||||||
|
->with('bases',$this->bases())
|
||||||
|
->with('o',$o)
|
||||||
|
->with('step',$request->step)
|
||||||
|
->with('dn',$container);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new InvalidUsage('Invalid entry step');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,26 +306,30 @@ class HomeController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application home page
|
* This is the main page render function
|
||||||
|
*
|
||||||
|
* If a DN is set, when render a DN info/edit frame
|
||||||
|
* If a frame is set, then we render that (sub)frame
|
||||||
*/
|
*/
|
||||||
public function home()
|
public function home()
|
||||||
{
|
{
|
||||||
if (old('dn'))
|
if (old('frame'))
|
||||||
|
return view('frame')
|
||||||
|
->with('subframe',old('frame'))
|
||||||
|
->with('bases',$this->bases())
|
||||||
|
->with('o',old('dn') ? config('server')->fetch($dn=Crypt::decryptString(old('dn'))) : NULL)
|
||||||
|
->with('dn',$dn ?? NULL);
|
||||||
|
|
||||||
|
elseif (old('dn'))
|
||||||
return view('frame')
|
return view('frame')
|
||||||
->with('subframe','dn')
|
->with('subframe','dn')
|
||||||
->with('bases',$this->bases())
|
->with('bases',$this->bases())
|
||||||
->with('o',config('server')->fetch($dn=Crypt::decryptString(old('dn'))))
|
->with('o',config('server')->fetch($dn=Crypt::decryptString(old('dn'))))
|
||||||
->with('dn',$dn);
|
->with('dn',$dn);
|
||||||
|
|
||||||
elseif (old('frame'))
|
|
||||||
return view('frame')
|
|
||||||
->with('subframe',old('frame'))
|
|
||||||
->with('bases',$this->bases());
|
|
||||||
|
|
||||||
else
|
else
|
||||||
return view('home')
|
return view('home')
|
||||||
->with('bases',$this->bases())
|
->with('bases',$this->bases());
|
||||||
->with('server',config('ldap.connections.default.name'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
33
app/Http/Requests/EntryAdd.php
Normal file
33
app/Http/Requests/EntryAdd.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
use App\Rules\{DNExists,StructuralObjectClass};
|
||||||
|
|
||||||
|
class EntryAdd extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'dn' => new DNExists,
|
||||||
|
'objectclass' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
new StructuralObjectClass,
|
||||||
|
],
|
||||||
|
'step' => 'int|min:1|max:2',
|
||||||
|
'frame' => [
|
||||||
|
'string',
|
||||||
|
Rule::in(['create']),
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -6,22 +6,12 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
|
|
||||||
class EntryRequest extends FormRequest
|
class EntryRequest extends FormRequest
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function authorize()
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return config('server')
|
return config('server')
|
||||||
->schema('attributetypes')
|
->schema('attributetypes')
|
||||||
|
@ -6,12 +6,7 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
|
|
||||||
class ImportRequest extends FormRequest
|
class ImportRequest extends FormRequest
|
||||||
{
|
{
|
||||||
public function authorize()
|
public function rules(): array
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'frame' => 'required|string|in:import',
|
'frame' => 'required|string|in:import',
|
||||||
|
@ -12,11 +12,14 @@ use App\Classes\LDAP\Attribute;
|
|||||||
use App\Classes\LDAP\Attribute\Factory;
|
use App\Classes\LDAP\Attribute\Factory;
|
||||||
use App\Classes\LDAP\Export\LDIF;
|
use App\Classes\LDAP\Export\LDIF;
|
||||||
use App\Exceptions\Import\AttributeException;
|
use App\Exceptions\Import\AttributeException;
|
||||||
|
use App\Exceptions\InvalidUsage;
|
||||||
|
|
||||||
class Entry extends Model
|
class Entry extends Model
|
||||||
{
|
{
|
||||||
private Collection $objects;
|
private Collection $objects;
|
||||||
private bool $noObjectAttributes = FALSE;
|
private bool $noObjectAttributes = FALSE;
|
||||||
|
// For new entries, this is the container that this entry will be stored in
|
||||||
|
private string $rdnbase;
|
||||||
|
|
||||||
/* OVERRIDES */
|
/* OVERRIDES */
|
||||||
|
|
||||||
@ -46,7 +49,7 @@ class Entry extends Model
|
|||||||
public function getAttributes(): array
|
public function getAttributes(): array
|
||||||
{
|
{
|
||||||
return $this->objects
|
return $this->objects
|
||||||
->map(fn($item)=>$item->values->toArray())
|
->map(fn($item)=>$item->values)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,10 +95,7 @@ class Entry extends Model
|
|||||||
$key = $this->normalizeAttributeKey($key);
|
$key = $this->normalizeAttributeKey($key);
|
||||||
|
|
||||||
if ((! $this->objects->get($key)) && $value) {
|
if ((! $this->objects->get($key)) && $value) {
|
||||||
$o = new Attribute($key,[]);
|
$this->objects->put($key,Factory::create($key,[$value]));
|
||||||
$o->value = $value;
|
|
||||||
|
|
||||||
$this->objects->put($key,$o);
|
|
||||||
|
|
||||||
} elseif ($this->objects->get($key)) {
|
} elseif ($this->objects->get($key)) {
|
||||||
$this->objects->get($key)->value = $this->attributes[$key];
|
$this->objects->get($key)->value = $this->attributes[$key];
|
||||||
@ -265,8 +265,12 @@ class Entry extends Model
|
|||||||
*/
|
*/
|
||||||
public function getObject(string $key): Attribute|null
|
public function getObject(string $key): Attribute|null
|
||||||
{
|
{
|
||||||
return $this->objects
|
return match ($key) {
|
||||||
->get($this->normalizeAttributeKey($key));
|
'rdn' => $this->getRDNObject(),
|
||||||
|
|
||||||
|
default => $this->objects
|
||||||
|
->get($this->normalizeAttributeKey($key))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getObjects(): Collection
|
public function getObjects(): Collection
|
||||||
@ -289,6 +293,14 @@ class Entry extends Model
|
|||||||
->filter(fn($a)=>(! $this->getVisibleAttributes()->contains(fn($b)=>($a->name === $b->name))));
|
->filter(fn($a)=>(! $this->getVisibleAttributes()->contains(fn($b)=>($a->name === $b->name))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getRDNObject(): Attribute\RDN
|
||||||
|
{
|
||||||
|
$o = new Attribute\RDN('dn',[' ']);
|
||||||
|
$o->setBase($this->rdnbase); // @todo for an existing object, return the base.
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return this list of user attributes
|
* Return this list of user attributes
|
||||||
*
|
*
|
||||||
@ -413,4 +425,12 @@ class Entry extends Model
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setRDNBase(string $bdn): void
|
||||||
|
{
|
||||||
|
if ($this->exists)
|
||||||
|
throw new InvalidUsage('Cannot set RDN base on existing entries');
|
||||||
|
|
||||||
|
$this->rdnbase = $bdn;
|
||||||
|
}
|
||||||
}
|
}
|
21
app/Rules/DNExists.php
Normal file
21
app/Rules/DNExists.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
|
|
||||||
|
class DNExists implements ValidationRule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the validation rule.
|
||||||
|
*
|
||||||
|
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||||
|
*/
|
||||||
|
public function validate(string $attribute,mixed $value,Closure $fail): void
|
||||||
|
{
|
||||||
|
if (! config('server')->fetch($x=Crypt::decryptString($value)))
|
||||||
|
$fail(sprintf('The DN %s doesnt exist.',$x));
|
||||||
|
}
|
||||||
|
}
|
20
app/Rules/StructuralObjectClass.php
Normal file
20
app/Rules/StructuralObjectClass.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
|
||||||
|
class StructuralObjectClass implements ValidationRule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the validation rule.
|
||||||
|
*
|
||||||
|
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||||
|
*/
|
||||||
|
public function validate(string $attribute,mixed $value,Closure $fail): void
|
||||||
|
{
|
||||||
|
if (! config('server')->schema('objectclasses',$value)->isStructural())
|
||||||
|
$fail(sprintf('The object class %s is not a StructuralObject class.',$value));
|
||||||
|
}
|
||||||
|
}
|
4
public/css/fixes.css
vendored
4
public/css/fixes.css
vendored
@ -304,3 +304,7 @@ div#objectClass .input-group-delete {
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
25
resources/views/components/attribute/rdn.blade.php
Normal file
25
resources/views/components/attribute/rdn.blade.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!-- $o=RDN::class -->
|
||||||
|
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||||
|
@foreach($o->values as $value)
|
||||||
|
@if($edit)
|
||||||
|
<div class="input-group has-validation mb-3">
|
||||||
|
<x-form.select
|
||||||
|
name="rdn"
|
||||||
|
:options="[]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span class="input-group-text">=</span>
|
||||||
|
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'border-focus'=>$o->values->contains($value)]) name="rdn" placeholder="rdn">
|
||||||
|
<label class="input-group-text" for="inputGroupSelect02">,{{ $o->base }}</label>
|
||||||
|
|
||||||
|
<div class="invalid-feedback pb-2">
|
||||||
|
@if($e)
|
||||||
|
{{ join('|',$e) }}
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
{{ $value }}
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</x-attribute.layout>
|
@ -51,7 +51,6 @@
|
|||||||
$('select#newoc').select2({
|
$('select#newoc').select2({
|
||||||
dropdownParent: $('#new_objectclass-modal'),
|
dropdownParent: $('#new_objectclass-modal'),
|
||||||
theme: 'bootstrap-5',
|
theme: 'bootstrap-5',
|
||||||
allowClear: true,
|
|
||||||
multiple: true,
|
multiple: true,
|
||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
|
@ -54,10 +54,14 @@
|
|||||||
width: 'style',
|
width: 'style',
|
||||||
allowClear: {{ $allowclear ?? 'false' }},
|
allowClear: {{ $allowclear ?? 'false' }},
|
||||||
placeholder: '{{ $placeholder ?? '' }}',
|
placeholder: '{{ $placeholder ?? '' }}',
|
||||||
|
multiple: {{ $multiple ?? 'false' }},
|
||||||
@isset($addvalues)
|
@isset($addvalues)
|
||||||
tags: true,
|
tags: true,
|
||||||
@endisset
|
@endisset
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#{{ $id ?? $name }}').val(' ');
|
||||||
|
$('#{{ $id ?? $name }}').trigger('change');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@append
|
@append
|
163
resources/views/frames/create.blade.php
Normal file
163
resources/views/frames/create.blade.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
@extends('layouts.dn')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
@include('fragment.dn.header')
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('main-content')
|
||||||
|
<div class="row">
|
||||||
|
<p class="alert alert-danger text-center">
|
||||||
|
This is a tech preview of what is to come, and it is by no means complete.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="offset-1 col-10">
|
||||||
|
<div class="main-card mb-3 card">
|
||||||
|
<form id="create-form" action="{{ url('entry/add') }}" method="POST" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="frame" value="create">
|
||||||
|
<input type="hidden" name="dn" value="{{ Crypt::encryptString($dn) }}">
|
||||||
|
<input type="hidden" name="step" value="{{ ++$step }}">
|
||||||
|
|
||||||
|
<div class="card-header">
|
||||||
|
@lang('Create New Entry')
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@switch($step)
|
||||||
|
@case(1)
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<x-form.select
|
||||||
|
name="objectclass"
|
||||||
|
:label="__('Select a Structural ObjectClass...')"
|
||||||
|
:options="($oc=config('server')->schema('objectclasses'))
|
||||||
|
->filter(fn($item)=>$item->isStructural())
|
||||||
|
->sortBy(fn($item)=>$item->name_lc)
|
||||||
|
->map(fn($item,$key)=>['id'=>$key,'value'=>$item->name])"
|
||||||
|
multiple="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case(2)
|
||||||
|
<div class="card-body">
|
||||||
|
<x-attribute-type :edit="true" :o="$o->getObject('rdn')"/>
|
||||||
|
|
||||||
|
@foreach ($o->getVisibleAttributes() as $ao)
|
||||||
|
<x-attribute-type :edit="true" :o="$ao"/>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<div id="newattrs"></div>
|
||||||
|
|
||||||
|
<!-- Add new attributes -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-1 col-md-2"></div>
|
||||||
|
<div class="col-12 col-sm-10 col-md-8">
|
||||||
|
<div class="d-none" id="newattr-select">
|
||||||
|
|
||||||
|
@if($o->getMissingAttributes()->count())
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 bg-dark text-light p-2">
|
||||||
|
<i class="fas fa-plus-circle"></i> Add New Attribute
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 pt-2">
|
||||||
|
<x-form.select id="newattr" label="Select from..." :options="$o->getMissingAttributes()->sortBy('name')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name_lc])"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-2"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pt-3">
|
||||||
|
<div class="col-12 offset-sm-2 col-sm-4 col-lg-2">
|
||||||
|
<x-form.reset form="dn-add"/>
|
||||||
|
<x-form.submit action="Create" form="dn-add"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@break;
|
||||||
|
@endswitch
|
||||||
|
|
||||||
|
<div class="card-footer">
|
||||||
|
<span class="ms-auto">
|
||||||
|
<x-form.submit action="Next" form="create-form"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('page-scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
var dn = '{{ $o->getDNSecure() }}';
|
||||||
|
var oc = {!! $o->getObject('objectclass')->values !!};
|
||||||
|
|
||||||
|
function editmode() {
|
||||||
|
$('#dn-edit input[name="dn"]').val(dn);
|
||||||
|
|
||||||
|
$('button[id=entry-edit]').addClass('active').removeClass('btn-outline-dark').addClass('btn-outline-light');
|
||||||
|
|
||||||
|
// Find all input items and turn off readonly
|
||||||
|
$('input.form-control').each(function() {
|
||||||
|
// Except for objectClass - @todo show an "X" instead
|
||||||
|
if ($(this)[0].name.match(/^objectclass/))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$(this).attr('readonly',false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Our password type
|
||||||
|
$('div#userPassword .form-select').each(function() {
|
||||||
|
$(this).prop('disabled',false);
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.row.d-none').removeClass('d-none');
|
||||||
|
$('.addable.d-none').removeClass('d-none');
|
||||||
|
$('.deletable.d-none').removeClass('d-none');
|
||||||
|
|
||||||
|
@if($o->getMissingAttributes()->count())
|
||||||
|
$('#newattr-select.d-none').removeClass('d-none');
|
||||||
|
@endif
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#newattr').on('change',function(item) {
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
beforeSend: function() {},
|
||||||
|
success: function(data) {
|
||||||
|
$('#newattrs').append(data);
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
if (e.status != 412)
|
||||||
|
alert('That didnt work? Please try again....');
|
||||||
|
},
|
||||||
|
url: '{{ url('entry/attr/add') }}/'+item.target.value,
|
||||||
|
data: {
|
||||||
|
objectclasses: oc,
|
||||||
|
},
|
||||||
|
cache: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove the option from the list
|
||||||
|
$(this).find('[value="'+item.target.value+'"]').remove()
|
||||||
|
|
||||||
|
// If there are no more options
|
||||||
|
if ($(this).find("option").length === 1)
|
||||||
|
$('#newattr-select').remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
editmode();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@append
|
@ -38,6 +38,7 @@ Route::group(['prefix'=>'user'],function() {
|
|||||||
Route::get('image',[HomeController::class,'user_image']);
|
Route::get('image',[HomeController::class,'user_image']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::post('entry/add',[HomeController::class,'entry_add']);
|
||||||
Route::get('entry/export/{id}',[HomeController::class,'entry_export']);
|
Route::get('entry/export/{id}',[HomeController::class,'entry_export']);
|
||||||
Route::post('entry/password/check/',[HomeController::class,'entry_password_check']);
|
Route::post('entry/password/check/',[HomeController::class,'entry_password_check']);
|
||||||
Route::post('entry/attr/add/{id}',[HomeController::class,'entry_attr_add']);
|
Route::post('entry/attr/add/{id}',[HomeController::class,'entry_attr_add']);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user