From 1e19213566f94f761c321770b9d1f7c6c589937a Mon Sep 17 00:00:00 2001 From: Deon George Date: Sun, 23 Feb 2025 18:14:41 +1100 Subject: [PATCH] Start of work to enable creation of new entries --- app/Http/Controllers/APIController.php | 33 ++++---- app/Http/Controllers/HomeController.php | 76 +++++++++++++++---- app/Http/Requests/EntryAdd.php | 33 ++++++++ app/Http/Requests/EntryRequest.php | 12 +-- app/Http/Requests/ImportRequest.php | 7 +- app/Rules/DNExists.php | 21 +++++ app/Rules/StructuralObjectClass.php | 20 +++++ .../attribute/widget/options.blade.php | 1 - .../views/components/form/select.blade.php | 4 + resources/views/frames/create.blade.php | 64 ++++++++++++++++ routes/web.php | 1 + 11 files changed, 225 insertions(+), 47 deletions(-) create mode 100644 app/Http/Requests/EntryAdd.php create mode 100644 app/Rules/DNExists.php create mode 100644 app/Rules/StructuralObjectClass.php create mode 100644 resources/views/frames/create.blade.php diff --git a/app/Http/Controllers/APIController.php b/app/Http/Controllers/APIController.php index f2283029..88aa3505 100644 --- a/app/Http/Controllers/APIController.php +++ b/app/Http/Controllers/APIController.php @@ -22,15 +22,15 @@ class APIController extends Controller { $base = Server::baseDNs() ?: collect(); - return $base->transform(function($item) { - return [ - 'title'=>$item->getRdn(), - 'item'=>$item->getDNSecure(), - 'lazy'=>TRUE, - 'icon'=>'fa-fw fas fa-sitemap', - 'tooltip'=>$item->getDn(), - ]; - }); + return $base + ->transform(fn($item)=> + [ + 'title'=>$item->getRdn(), + 'item'=>$item->getDNSecure(), + 'lazy'=>TRUE, + 'icon'=>'fa-fw fas fa-sitemap', + 'tooltip'=>$item->getDn(), + ]); } /** @@ -45,15 +45,22 @@ class APIController extends Controller return (config('server')) ->children($dn) - ->transform(function($item) { - return [ + ->transform(fn($item)=> + [ 'title'=>$item->getRdn(), 'item'=>$item->getDNSecure(), 'icon'=>$item->icon(), 'lazy'=>Arr::get($item->getAttribute('hassubordinates'),0) == 'TRUE', '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) diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 74cb4a34..ae1216b4 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -2,6 +2,9 @@ namespace App\Http\Controllers; +use Illuminate\Contracts\View\Factory; +use Illuminate\Contracts\View\View; +use Illuminate\Foundation\Application; use Illuminate\Http\Request; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -12,16 +15,16 @@ use Illuminate\Support\Facades\Redirect; use LdapRecord\Exceptions\InsufficientAccessException; use LdapRecord\LdapRecordException; use LdapRecord\Query\ObjectNotFoundException; +use Nette\NotImplementedException; use App\Classes\LDAP\{Attribute,Server}; use App\Classes\LDAP\Import\LDIF as LDIFImport; use App\Classes\LDAP\Export\LDIF as LDIFExport; use App\Exceptions\Import\{GeneralException,VersionException}; use App\Exceptions\InvalidUsage; -use App\Http\Requests\{EntryRequest,ImportRequest}; +use App\Http\Requests\{EntryAdd,EntryRequest,ImportRequest}; use App\Ldap\Entry; use App\View\Components\AttributeType; -use Nette\NotImplementedException; class HomeController extends Controller { @@ -59,13 +62,50 @@ class HomeController extends Controller public function dn_frame(Request $request) { $dn = Crypt::decryptString($request->post('key')); + $cmd = ''; - $page_actions = collect(['edit'=>TRUE,'copy'=>TRUE]); + if (str_contains($dn,'|')) { + $m = []; - return view('frames.dn') - ->with('o',config('server')->fetch($dn)) - ->with('dn',$dn) - ->with('page_actions',$page_actions); + 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('dn',$dn) + ->with('page_actions',collect(['edit'=>TRUE,'copy'=>TRUE])), + }; + } + + /** + * Create a new object in the LDAP server + * + * @param EntryAdd $request + * @return Factory|View|Application|object + */ + public function entry_add(EntryAdd $request) + { + switch ($request->step) { + case 1: + return view('frame') + ->with('subframe',$request->frame) + ->with('bases',$this->bases()) + ->with('o',config('server')->fetch($x=Crypt::decryptString($request->dn))) + ->with('step',$request->step) + ->with('dn',$x); + + default: + dd($request); + } } /** @@ -259,26 +299,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() { - 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') ->with('subframe','dn') ->with('bases',$this->bases()) ->with('o',config('server')->fetch($dn=Crypt::decryptString(old('dn')))) ->with('dn',$dn); - elseif (old('frame')) - return view('frame') - ->with('subframe',old('frame')) - ->with('bases',$this->bases()); - else return view('home') - ->with('bases',$this->bases()) - ->with('server',config('ldap.connections.default.name')); + ->with('bases',$this->bases()); } /** diff --git a/app/Http/Requests/EntryAdd.php b/app/Http/Requests/EntryAdd.php new file mode 100644 index 00000000..b5fc92c8 --- /dev/null +++ b/app/Http/Requests/EntryAdd.php @@ -0,0 +1,33 @@ + + */ + public function rules(): array + { + return [ + 'dn' => new DNExists, + 'objectclass' => [ + 'required', + 'string', + new StructuralObjectClass, + ], + 'step' => 'int|min:1|max:2', + 'frame' => [ + 'string', + Rule::in(['create']), + ] + ]; + } +} \ No newline at end of file diff --git a/app/Http/Requests/EntryRequest.php b/app/Http/Requests/EntryRequest.php index 5aba0c77..c8927bd6 100644 --- a/app/Http/Requests/EntryRequest.php +++ b/app/Http/Requests/EntryRequest.php @@ -6,22 +6,12 @@ use Illuminate\Foundation\Http\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. * * @return array */ - public function rules() + public function rules(): array { return config('server') ->schema('attributetypes') diff --git a/app/Http/Requests/ImportRequest.php b/app/Http/Requests/ImportRequest.php index abdf8c16..5f5ffac9 100644 --- a/app/Http/Requests/ImportRequest.php +++ b/app/Http/Requests/ImportRequest.php @@ -6,12 +6,7 @@ use Illuminate\Foundation\Http\FormRequest; class ImportRequest extends FormRequest { - public function authorize() - { - return TRUE; - } - - public function rules() + public function rules(): array { return [ 'frame' => 'required|string|in:import', diff --git a/app/Rules/DNExists.php b/app/Rules/DNExists.php new file mode 100644 index 00000000..a3692748 --- /dev/null +++ b/app/Rules/DNExists.php @@ -0,0 +1,21 @@ +fetch($x=Crypt::decryptString($value))) + $fail(sprintf('The DN %s doesnt exist.',$x)); + } +} diff --git a/app/Rules/StructuralObjectClass.php b/app/Rules/StructuralObjectClass.php new file mode 100644 index 00000000..c346503a --- /dev/null +++ b/app/Rules/StructuralObjectClass.php @@ -0,0 +1,20 @@ +schema('objectclasses',$value)->isStructural()) + $fail(sprintf('The object class %s is not a StructuralObject class.',$value)); + } +} diff --git a/resources/views/components/attribute/widget/options.blade.php b/resources/views/components/attribute/widget/options.blade.php index c62c0127..f097ef2d 100644 --- a/resources/views/components/attribute/widget/options.blade.php +++ b/resources/views/components/attribute/widget/options.blade.php @@ -51,7 +51,6 @@ $('select#newoc').select2({ dropdownParent: $('#new_objectclass-modal'), theme: 'bootstrap-5', - allowClear: true, multiple: true, data: data, }); diff --git a/resources/views/components/form/select.blade.php b/resources/views/components/form/select.blade.php index 6a11feb7..78aa0c71 100644 --- a/resources/views/components/form/select.blade.php +++ b/resources/views/components/form/select.blade.php @@ -54,10 +54,14 @@ width: 'style', allowClear: {{ $allowclear ?? 'true' }}, placeholder: '{{ $placeholder ?? '' }}', + multiple: {{ $multiple ?? 'false' }}, @isset($addvalues) tags: true, @endisset }); + + $('#{{ $id ?? $name }}').val(' '); + $('#{{ $id ?? $name }}').trigger('change'); }); @append \ No newline at end of file diff --git a/resources/views/frames/create.blade.php b/resources/views/frames/create.blade.php new file mode 100644 index 00000000..37055dd4 --- /dev/null +++ b/resources/views/frames/create.blade.php @@ -0,0 +1,64 @@ +@extends('layouts.dn') + +@section('page_title') + @include('fragment.dn.header') +@endsection + +@section('main-content') +
+
+
+
+ @csrf + + + + +
+ @lang('Create New Entry') +
+ + @switch($step) + @case(1) +
+
+
+ +
+
+
+ @break + + @case(2) +
+
+
+

+ Not ready yet :) +

+
+
+
+ @break; + + @endswitch + + +
+
+
+
+@endsection \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 36e32ea6..59aa8417 100644 --- a/routes/web.php +++ b/routes/web.php @@ -38,6 +38,7 @@ Route::group(['prefix'=>'user'],function() { 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::post('entry/password/check/',[HomeController::class,'entry_password_check']); Route::post('entry/attr/add/{id}',[HomeController::class,'entry_attr_add']);