Change our internal template keys to be prefixed with an underscore for easier identification

This commit is contained in:
Deon George 2025-06-21 08:35:33 +10:00
parent d6ec080ecf
commit b3b3fc6ac1
9 changed files with 38 additions and 36 deletions

View File

@ -38,7 +38,7 @@ class AjaxController extends Controller
*/ */
public function children(Request $request): Collection public function children(Request $request): Collection
{ {
$dn = Crypt::decryptString($request->query('key')); $dn = Crypt::decryptString($request->query('_key'));
// Sometimes our key has a command, so we'll ignore it // Sometimes our key has a command, so we'll ignore it
if (str_starts_with($dn,'*') && ($x=strpos($dn,'|'))) if (str_starts_with($dn,'*') && ($x=strpos($dn,'|')))

View File

@ -28,6 +28,8 @@ class HomeController extends Controller
{ {
private const LOGKEY = 'CHc'; private const LOGKEY = 'CHc';
private const INTERNAL_POST = ['_key','_rdn','_rdn_value','_step','_template','_token','_userpassword_hash'];
/** /**
* Create a new object in the LDAP server * Create a new object in the LDAP server
* *
@ -37,7 +39,7 @@ class HomeController extends Controller
*/ */
public function entry_add(EntryAddRequest $request): \Illuminate\View\View public function entry_add(EntryAddRequest $request): \Illuminate\View\View
{ {
if (! old('step',$request->validated('step'))) if (! old('_step',$request->validated('_step')))
abort(404); abort(404);
$key = $this->request_key($request,collect(old())); $key = $this->request_key($request,collect(old()));
@ -46,7 +48,7 @@ class HomeController extends Controller
$o = new Entry; $o = new Entry;
$o->setRDNBase($key['dn']); $o->setRDNBase($key['dn']);
foreach (collect(old())->except(['_token','key','step','rdn','rdn_value','_template','userpassword_hash']) as $old => $value) foreach (collect(old())->except(self::INTERNAL_POST) as $old => $value)
$o->{$old} = array_filter($value); $o->{$old} = array_filter($value);
if (old('_template',$request->validated('template'))) { if (old('_template',$request->validated('template'))) {
@ -69,7 +71,7 @@ class HomeController extends Controller
$o->{$ao->name} = [Entry::TAG_NOTAG=>'']; $o->{$ao->name} = [Entry::TAG_NOTAG=>''];
} }
$step = $request->step ? $request->step+1 : old('step'); $step = $request->get('_step') ? $request->get('_step')+1 : old('_step');
return view('frame') return view('frame')
->with('subframe','create') ->with('subframe','create')
@ -113,12 +115,12 @@ class HomeController extends Controller
{ {
$key = $this->request_key($request,collect(old())); $key = $this->request_key($request,collect(old()));
$dn = sprintf('%s=%s,%s',$request->rdn,$request->rdn_value,$key['dn']); $dn = sprintf('%s=%s,%s',$request->get('_rdn'),$request->get('_rdn_value'),$key['dn']);
$o = new Entry; $o = new Entry;
$o->setDn($dn); $o->setDn($dn);
foreach ($request->except(['_token','key','step','rdn','rdn_value','_template','userpassword_hash']) as $key => $value) foreach ($request->except(self::INTERNAL_POST) as $key => $value)
$o->{$key} = array_filter($value); $o->{$key} = array_filter($value);
try { try {
@ -214,7 +216,7 @@ class HomeController extends Controller
*/ */
public function entry_objectclass_add(Request $request): Collection public function entry_objectclass_add(Request $request): Collection
{ {
$dn = $request->key ? Crypt::decryptString($request->dn) : ''; $dn = $request->get('_key') ? Crypt::decryptString($request->dn) : '';
$oc = Factory::create($dn,'objectclass',$request->oc); $oc = Factory::create($dn,'objectclass',$request->oc);
$ocs = $oc $ocs = $oc
@ -269,7 +271,7 @@ class HomeController extends Controller
$o = config('server')->fetch($dn); $o = config('server')->fetch($dn);
foreach ($request->except(['_token','dn','userpassword_hash','userpassword']) as $key => $value) foreach ($request->except(['_token','dn','_userpassword_hash','userpassword']) as $key => $value)
$o->{$key} = array_filter($value,fn($item)=>! is_null($item)); $o->{$key} = array_filter($value,fn($item)=>! is_null($item));
// @todo Need to handle incoming attributes that were modified by MD5Updates Trait (eg: jpegphoto) // @todo Need to handle incoming attributes that were modified by MD5Updates Trait (eg: jpegphoto)
@ -286,7 +288,7 @@ class HomeController extends Controller
} }
if ($value) { if ($value) {
$type = Arr::get($request->userpassword_hash,$dotkey); $type = Arr::get($request->get('_userpassword_hash'),$dotkey);
$passwords[$dotkey] = Password::hash_id($type) $passwords[$dotkey] = Password::hash_id($type)
->encode($value); ->encode($value);
} }
@ -393,7 +395,7 @@ class HomeController extends Controller
// @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'] // @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(array_merge(self::INTERNAL_POST,['dn'])) as $attr => $value)
$o->{$attr} = $value; $o->{$attr} = $value;
} }
@ -481,8 +483,8 @@ class HomeController extends Controller
// Setup // Setup
$cmd = NULL; $cmd = NULL;
$dn = NULL; $dn = NULL;
$key = $request->get('key',old('key')) $key = $request->get('_key',old('_key'))
? Crypt::decryptString($request->get('key',old('key'))) ? Crypt::decryptString($request->get('_key',old('_key')))
: NULL; : NULL;
// Determine if our key has a command // Determine if our key has a command
@ -494,9 +496,9 @@ class HomeController extends Controller
$dn = ($m[2] !== '_NOP') ? $m[2] : NULL; $dn = ($m[2] !== '_NOP') ? $m[2] : NULL;
} }
} elseif (old('dn',$request->get('key'))) { } elseif (old('dn',$request->get('_key'))) {
$cmd = 'dn'; $cmd = 'dn';
$dn = Crypt::decryptString(old('dn',$request->get('key'))); $dn = Crypt::decryptString(old('dn',$request->get('_key')));
} }
return ['cmd'=>$cmd,'dn'=>$dn]; return ['cmd'=>$cmd,'dn'=>$dn];
@ -513,12 +515,12 @@ class HomeController extends Controller
public function schema_frame(Request $request): \Illuminate\View\View public function schema_frame(Request $request): \Illuminate\View\View
{ {
// If an invalid key, we'll 404 // If an invalid key, we'll 404
if ($request->type && $request->key && (! config('server')->schema($request->type)->has($request->key))) if ($request->type && $request->get('_key') && (! config('server')->schema($request->type)->has($request->get('_key'))))
abort(404); abort(404);
return view('frames.schema') return view('frames.schema')
->with('type',$request->type) ->with('type',$request->type)
->with('key',$request->key); ->with('key',$request->get('_key'));
} }
/** /**

View File

@ -17,8 +17,8 @@ class EntryAddRequest extends FormRequest
public function messages(): array public function messages(): array
{ {
return [ return [
'rdn' => __('RDN is required.'), '_rdn' => __('RDN is required.'),
'rdn_value' => __('RDN value is required.'), '_rdn_value' => __('RDN value is required.'),
]; ];
} }
@ -51,7 +51,7 @@ class EntryAddRequest extends FormRequest
->filter() ->filter()
->flatMap(fn($item)=>$item) ->flatMap(fn($item)=>$item)
->merge([ ->merge([
'key' => [ '_key' => [
'required', 'required',
new DNExists, new DNExists,
function (string $attribute,mixed $value,\Closure $fail) { function (string $attribute,mixed $value,\Closure $fail) {
@ -66,9 +66,9 @@ class EntryAddRequest extends FormRequest
} }
}, },
], ],
'rdn' => 'required_if:step,2|string|min:1', '_rdn' => 'required_if:_step,2|string|min:1',
'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', 'required',
'array', 'array',
@ -81,7 +81,7 @@ class EntryAddRequest extends FormRequest
// If this is step 1 and there is no objectclass, and no template, then fail // If this is step 1 and there is no objectclass, and no template, then fail
if ((! $oc->count()) if ((! $oc->count())
&& (request()->post('step') == 1) && (request()->post('_step') == 1)
&& (! request()->post('template'))) && (! request()->post('template')))
{ {
$fail(__('Select an objectclass or a template')); $fail(__('Select an objectclass or a template'));
@ -101,7 +101,7 @@ class EntryAddRequest extends FormRequest
// If this is step 1 and there is no objectclass, and no template, then fail // If this is step 1 and there is no objectclass, and no template, then fail
if ((! collect($value)->filter()->count()) if ((! collect($value)->filter()->count())
&& (request()->post('step') == 1) && (request()->post('_step') == 1)
&& (! $oc->count())) && (! $oc->count()))
{ {
$fail(__('Select an objectclass or a template')); $fail(__('Select an objectclass or a template'));

4
public/js/custom.js vendored
View File

@ -15,7 +15,7 @@ function getNode(item) {
$.ajax({ $.ajax({
url: '/frame', url: '/frame',
method: 'POST', method: 'POST',
data: { key: item }, data: { _key: item },
dataType: 'html', dataType: 'html',
beforeSend: function() { beforeSend: function() {
content = $('.main-content') content = $('.main-content')
@ -96,7 +96,7 @@ $(document).ready(function() {
lazyLoad: function(event,data) { lazyLoad: function(event,data) {
data.result = { data.result = {
url: '/ajax/children', url: '/ajax/children',
data: {key: data.node.data.item,depth: 1} data: {_key: data.node.data.item,depth: 1}
}; };
expandChildren(data.tree.rootNode); expandChildren(data.tree.rootNode);

View File

@ -4,7 +4,7 @@
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<div class="input-group has-validation"> <div class="input-group has-validation">
<x-form.select id="userpassword_hash_{{$loop->index}}{{$template?->name ?? ''}}" name="userpassword_hash[{{ $langtag }}][]" :value="$o->hash($new ? '' : ($value ?? ''))->id()" :options="$helpers" allowclear="false" :disabled="! $new"/> <x-form.select id="userpassword_hash_{{$loop->index}}{{$template?->name ?? ''}}" name="_userpassword_hash[{{ $langtag }}][]" :value="$o->hash($new ? '' : ($value ?? ''))->id()" :options="$helpers" allowclear="false" :disabled="! $new"/>
<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),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ Arr::get(old($o->name_lc),$langtag.'.'.$loop->index,$value ? md5($value) : '') }}" @readonly(! $new)> <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),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ Arr::get(old($o->name_lc),$langtag.'.'.$loop->index,$value ? md5($value) : '') }}" @readonly(! $new)>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">

View File

@ -3,24 +3,24 @@
@foreach(($o->values->count() ? $o->values : [NULL]) as $value) @foreach(($o->values->count() ? $o->values : [NULL]) as $value)
@if($edit) @if($edit)
<div class="input-group has-validation mb-3"> <div class="input-group has-validation mb-3">
<select class="form-select @error('rdn')is-invalid @enderror" id="rdn" name="rdn"> <select @class(['form-select','is-invalid'=>$errors->get('_rdn')]) id="rdn" name="_rdn">
<option value=""></option> <option value=""></option>
@foreach($o->attrs->map(fn($item)=>['id'=>$item,'value'=>$item]) as $option) @foreach($o->attrs->map(fn($item)=>['id'=>$item,'value'=>$item]) as $option)
@continue(! Arr::get($option,'value')) @continue(! Arr::get($option,'value'))
<option value="{{ strtolower(Arr::get($option,'id')) }}" @selected(Arr::get($option,'id') == old('rdn',$value ?? ''))>{{ Arr::get($option,'value') }}</option> <option value="{{ strtolower(Arr::get($option,'id')) }}" @selected(Arr::get($option,'id') == old('_rdn',$value ?? ''))>{{ Arr::get($option,'value') }}</option>
@endforeach @endforeach
</select> </select>
<span class="input-group-text">=</span> <span class="input-group-text">=</span>
<input type="text" @class(['form-control','is-invalid'=>$errors->get('rdn_value')]) id="rdn_value" name="rdn_value" value="{{ old('rdn_value') }}" placeholder="rdn"> <input type="text" @class(['form-control','is-invalid'=>$errors->get('_rdn_value')]) id="rdn_value" name="_rdn_value" value="{{ old('_rdn_value') }}" placeholder="rdn">
<label class="input-group-text" for="inputGroupSelect02">,{{ $o->base }}</label> <label class="input-group-text" for="inputGroupSelect02">,{{ $o->base }}</label>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@error('rdn') @error('_rdn')
{{ $message }} {{ $message }}
@enderror @enderror
@error('rdn_value') @error('_rdn_value')
{{ $message }} {{ $message }}
@enderror @enderror
</div> </div>

View File

@ -24,8 +24,8 @@
<form id="dn-create" method="POST" class="needs-validation" action="{{ url((int)$step === 2 ? 'entry/create' : 'entry/add') }}" enctype="multipart/form-data" novalidate> <form id="dn-create" method="POST" class="needs-validation" action="{{ url((int)$step === 2 ? 'entry/create' : 'entry/add') }}" enctype="multipart/form-data" novalidate>
@csrf @csrf
<input type="hidden" name="key" value="{{ Crypt::encryptString('*create|'.$container) }}"> <input type="hidden" name="_key" value="{{ Crypt::encryptString('*create|'.$container) }}">
<input type="hidden" name="step" value="{{ $step }}"> <input type="hidden" name="_step" value="{{ $step }}">
@switch($step) @switch($step)
@case(1) @case(1)

View File

@ -15,7 +15,7 @@
<div class="main-card mb-3 card"> <div class="main-card mb-3 card">
<form id="import-form" action="{{ url('import/process/ldif') }}" method="POST" enctype="multipart/form-data"> <form id="import-form" action="{{ url('import/process/ldif') }}" method="POST" enctype="multipart/form-data">
@csrf @csrf
<input type="hidden" name="key" value="{{ Crypt::encryptString('*import|_NOP') }}"> <input type="hidden" name="_key" value="{{ Crypt::encryptString('*import|_NOP') }}">
<div class="card-header"> <div class="card-header">
@lang('LDIF Import') @lang('LDIF Import')

View File

@ -34,7 +34,7 @@ class ImportTest extends TestCase
->from('/import') ->from('/import')
->post('/import/process/ldif',[ ->post('/import/process/ldif',[
'_token' => csrf_token(), '_token' => csrf_token(),
'key'=>Crypt::encryptString('*import|_NOP'), '_key'=>Crypt::encryptString('*import|_NOP'),
'file' => $file, 'file' => $file,
]); ]);