More work on work on adding/removing objectclasses to an entry, still need to automatically remove attrs from removed objectclasses
Some checks failed
Create Docker Image / Build Docker Image (arm64) (push) Has been cancelled
Create Docker Image / Build Docker Image (x86_64) (push) Has been cancelled
Create Docker Image / Final Docker Image Manifest (push) Has been cancelled
Create Docker Image / Test Application (x86_64) (push) Has been cancelled
Some checks failed
Create Docker Image / Build Docker Image (arm64) (push) Has been cancelled
Create Docker Image / Build Docker Image (x86_64) (push) Has been cancelled
Create Docker Image / Final Docker Image Manifest (push) Has been cancelled
Create Docker Image / Test Application (x86_64) (push) Has been cancelled
This commit is contained in:
parent
bbef155fd2
commit
7513ed6def
@ -35,8 +35,8 @@ The update to v2 is progressing well - here is a list of work to do and done:
|
||||
- [X] Validate password is correct
|
||||
- [ ] JpegPhoto Create/Delete
|
||||
- [X] JpegPhoto Display
|
||||
- [ ] ObjectClass Add/Remove
|
||||
- [ ] Add additional required attributes (for ObjectClass Addition)
|
||||
- [X] ObjectClass Add/Remove
|
||||
- [X] Add additional required attributes (for ObjectClass Addition)
|
||||
- [ ] Remove existing required attributes (for ObjectClass Removal)
|
||||
- [X] Add additional values to Attributes that support multiple values
|
||||
- [X] Delete extra values for Attributes that support multiple values
|
||||
|
@ -33,9 +33,6 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
// Is this attribute the RDN?
|
||||
protected bool $is_rdn = FALSE;
|
||||
|
||||
// Objectclasses that require this attribute
|
||||
protected Collection $required_by;
|
||||
|
||||
// MIN/MAX number of values
|
||||
protected int $min_values_count = 0;
|
||||
protected int $max_values_count = 0;
|
||||
@ -102,7 +99,6 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
$this->name = $name;
|
||||
$this->values = collect($values);
|
||||
$this->lang_tags = collect();
|
||||
$this->required_by = collect();
|
||||
$this->oldValues = collect($values);
|
||||
|
||||
// No need to load our schema for internal attributes
|
||||
@ -149,6 +145,10 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
'old_values' => $this->oldValues,
|
||||
// Attribute values
|
||||
'values' => $this->values,
|
||||
// Required by Object Classes
|
||||
'required_by' => $this->schema->required_by_object_classes,
|
||||
// Used in Object Classes
|
||||
'used_in' => $this->schema->used_in_object_classes,
|
||||
|
||||
default => throw new \Exception('Unknown key:' . $key),
|
||||
};
|
||||
@ -296,19 +296,6 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
return Arr::get($this->values,$key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the objectclasses that require this attribute
|
||||
*
|
||||
* @param Collection $oc
|
||||
* @return Collection
|
||||
*/
|
||||
public function required_by(Collection $oc): Collection
|
||||
{
|
||||
return $this->required_by = ($this->schema
|
||||
? $oc->intersect($this->schema->required_by_object_classes)
|
||||
: collect());
|
||||
}
|
||||
|
||||
/**
|
||||
* If this attribute has RFC3866 Language Tags, this will enable those values to be captured
|
||||
*
|
||||
|
@ -549,17 +549,6 @@ final class AttributeType extends Base {
|
||||
$this->aliases->forget($x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of object classes, determine if this is a required attribute
|
||||
*
|
||||
* @param Collection $oc List of objectclasses to compare.
|
||||
* @return Collection
|
||||
*/
|
||||
public function required_by(Collection $oc): Collection
|
||||
{
|
||||
return $oc->diff($this->required_by_object_classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's list of aliases.
|
||||
*
|
||||
|
@ -82,4 +82,21 @@ class APIController extends Controller
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the required and additional attributes for an object class
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $objectclass
|
||||
* @return array
|
||||
*/
|
||||
public function schema_objectclass_attrs(Request $request,string $objectclass): array
|
||||
{
|
||||
$oc = config('server')->schema('objectclasses',$objectclass);
|
||||
|
||||
return [
|
||||
'must' => $oc->getMustAttrs()->pluck('name'),
|
||||
'may' => $oc->getMayAttrs()->pluck('name'),
|
||||
];
|
||||
}
|
||||
}
|
@ -85,7 +85,7 @@ class HomeController extends Controller
|
||||
->with('o',new Attribute($id,[]))
|
||||
->with('value',$request->value)
|
||||
->with('loop',$xx)
|
||||
: (new AttributeType(new Attribute($id,[]),TRUE))->render();
|
||||
: (new AttributeType(new Attribute($id,[]),TRUE,collect($request->oc ?: [])))->render();
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
@ -186,12 +186,8 @@ class Entry extends Model
|
||||
if (preg_match('/^'.$attribute.'=/i',$this->dn))
|
||||
$o->setRDN();
|
||||
|
||||
// Set required flag
|
||||
$o->required_by(collect($this->getAttribute('objectclass')));
|
||||
|
||||
// Store our original value to know if this attribute has changed
|
||||
if ($x=Arr::get($this->original,$attribute))
|
||||
$o->oldValues($x);
|
||||
$o->oldValues(Arr::get($this->original,$attribute,[]));
|
||||
|
||||
$result->put($attribute,$o);
|
||||
}
|
||||
|
@ -4,21 +4,24 @@ namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
use App\Classes\LDAP\Attribute as LDAPAttribute;
|
||||
|
||||
class AttributeType extends Component
|
||||
{
|
||||
public Collection $oc;
|
||||
public LDAPAttribute $o;
|
||||
public bool $new;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(LDAPAttribute $o,bool $new=FALSE)
|
||||
public function __construct(LDAPAttribute $o,bool $new=FALSE,Collection $oc=NULL)
|
||||
{
|
||||
$this->o = $o;
|
||||
$this->oc = $oc;
|
||||
$this->new = $new;
|
||||
}
|
||||
|
||||
@ -29,6 +32,7 @@ class AttributeType extends Component
|
||||
{
|
||||
return view('components.attribute-type')
|
||||
->with('o',$this->o)
|
||||
->with('oc',$this->oc)
|
||||
->with('new',$this->new);
|
||||
}
|
||||
}
|
8
public/css/fixes.css
vendored
8
public/css/fixes.css
vendored
@ -296,3 +296,11 @@ select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__
|
||||
color: #212529;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
div#objectclass .input-group-delete {
|
||||
position: relative;
|
||||
float: inline-end;
|
||||
bottom: 30px;
|
||||
right: 10px;
|
||||
height: 5px;
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
<div class="col-12 col-sm-10 col-md-8">
|
||||
<div class="row">
|
||||
<div class="col-12 bg-light text-dark p-2">
|
||||
<strong><abbr title="{{ $o->description }}">{{ $o->name }}</abbr></strong>
|
||||
<strong><abbr title="{{ $o->description }}" data-attr-name="{{ $o->name_lc }}" data-attr-required="{{ $o->required_by->intersect($oc)->join('|') }}" data-oc="{{ $oc->count() ? $o->required_by->keys()->intersect($oc)->join('|') : $o->used_in->keys()->join('|') }}">{{ $o->name }}</abbr></strong>
|
||||
<!-- Attribute Hints -->
|
||||
<span class="float-end small">
|
||||
@foreach($o->hints as $name => $description)
|
||||
|
@ -1,19 +1,12 @@
|
||||
<div class="input-group has-validation">
|
||||
<!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way -->
|
||||
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)>
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
<span id="objectclass_{{$value}}">
|
||||
<div class="input-group has-validation">
|
||||
<!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way -->
|
||||
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)>
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e)
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="input-group-delete"><i class="fas fa-fw fa-xmark"></i></span>
|
||||
|
||||
<style>
|
||||
.input-group-delete {
|
||||
float: right;
|
||||
position: relative;
|
||||
top: -32px;
|
||||
right: 10px;
|
||||
}
|
||||
</style>
|
||||
<span class="input-group-delete"><i class="fas fa-fw fa-xmark"></i></span>
|
||||
</span>
|
@ -68,42 +68,97 @@
|
||||
var newadded = $('select#newoc').val();
|
||||
|
||||
// If nothing selected, we dont have anything to do
|
||||
if (! newadded.length)
|
||||
if (added_oc.sort().join('|') == newadded.sort().join('|'))
|
||||
return;
|
||||
|
||||
var attrs = $('[data-attr-name]').map(function() {
|
||||
return $(this).data('attrName');
|
||||
});
|
||||
|
||||
// Find out what was selected, and add them
|
||||
newadded.forEach(function (item) {
|
||||
if (added_oc.indexOf(item) !== -1)
|
||||
return;
|
||||
|
||||
// Add attribute to the page
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
type: 'POST',
|
||||
beforeSend: function() {},
|
||||
success: function(data) {
|
||||
console.log(data);
|
||||
$('#{{ $o->name_lc }}').append(data);
|
||||
console.log('set to:'+item);
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status != 412)
|
||||
alert('That didnt work? Please try again....');
|
||||
},
|
||||
url: '{{ url('entry/attr/add',[$o->name_lc]) }}',
|
||||
data: {noheader: true,value: item,loop: c++}, // @todo can we omit loop and c
|
||||
data: {
|
||||
noheader: true,
|
||||
value: item,
|
||||
objectclasses: oc,
|
||||
loop: c++, // @todo can we omit loop and c
|
||||
},
|
||||
cache: false
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
beforeSend: function() {},
|
||||
success: function(data) {
|
||||
// Render any must attributes
|
||||
if (data.must.length) {
|
||||
data.must.forEach(function(item) {
|
||||
// Add attribute to the page
|
||||
$.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,
|
||||
data: {
|
||||
value: item,
|
||||
objectclasses: oc,
|
||||
loop: c++, // @todo can we omit loop and c
|
||||
},
|
||||
cache: false
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Add attributes to "Add new Attribute" that are now available
|
||||
if (data.may.length) {
|
||||
var newattr = $('select#newattr');
|
||||
|
||||
// @todo It might be nice to resort this options
|
||||
data.may.forEach(function(item) {
|
||||
newattr.append(new Option(item,item,false,false));
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status != 412)
|
||||
alert('That didnt work? Please try again....');
|
||||
},
|
||||
url: '{{ url('api/schema/objectclass/attrs') }}/'+item,
|
||||
cache: false
|
||||
});
|
||||
|
||||
// @todo add any required attributes that are defined required as a result of adding this OC
|
||||
// @todo Add attributes to "Add new Attribute" that are now available
|
||||
});
|
||||
|
||||
// Loop through added_oc, and remove anything not in newadded
|
||||
added_oc.forEach(function(item) {
|
||||
if (newadded.indexOf(item) === -1) {
|
||||
$('input[value="'+item+'"]').parent().empty();
|
||||
$('span#objectclass_'+item).empty();
|
||||
|
||||
// @todo remove any required attributes that are no longer defined as a result of removing this OC
|
||||
console.log('Remove required attributes of:'+item);
|
||||
// @todo Remove attributes from "Add new Attribute" that are no longer available
|
||||
console.log('Remove additional attributes of:'+item);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
<input type="hidden" name="dn" value="">
|
||||
|
||||
@foreach ($o->getVisibleAttributes() as $ao)
|
||||
<x-attribute-type :edit="true" :o="$ao"/>
|
||||
<x-attribute-type :edit="true" :o="$ao" :oc="collect($o->objectclass)"/>
|
||||
@endforeach
|
||||
|
||||
<div id="newattrs"></div>
|
||||
@ -173,6 +173,7 @@
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
var dn = '{{ $o->getDNSecure() }}';
|
||||
var oc = {!! $o->getObject('objectclass')->values !!};
|
||||
|
||||
function download(filename,text) {
|
||||
var element = document.createElement('a');
|
||||
@ -217,7 +218,7 @@
|
||||
$(document).ready(function() {
|
||||
$('#newattr').on('change',function(item) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
type: 'POST',
|
||||
beforeSend: function() {},
|
||||
success: function(data) {
|
||||
$('#newattrs').append(data);
|
||||
@ -227,6 +228,9 @@
|
||||
alert('That didnt work? Please try again....');
|
||||
},
|
||||
url: '{{ url('entry/attr/add') }}/'+item.target.value,
|
||||
data: {
|
||||
objectclasses: oc,
|
||||
},
|
||||
cache: false
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@ Route::group([],function() {
|
||||
Route::get('bases',[APIController::class,'bases']);
|
||||
Route::get('children',[APIController::class,'children']);
|
||||
Route::post('schema/view',[APIController::class,'schema_view']);
|
||||
Route::post('schema/objectclass/attrs/{id}',[APIController::class,'schema_objectclass_attrs']);
|
||||
});
|
||||
|
||||
Route::group(['middleware'=>'auth:api','prefix'=>'user'],function() {
|
||||
|
@ -40,7 +40,7 @@ Route::group(['prefix'=>'user'],function() {
|
||||
|
||||
Route::get('entry/export/{id}',[HomeController::class,'entry_export']);
|
||||
Route::post('entry/password/check/',[HomeController::class,'entry_password_check']);
|
||||
Route::get('entry/attr/add/{id}',[HomeController::class,'entry_attr_add']);
|
||||
Route::post('entry/attr/add/{id}',[HomeController::class,'entry_attr_add']);
|
||||
Route::post('entry/objectclass/add/{id}',[HomeController::class,'entry_objectclass_add']);
|
||||
Route::post('entry/update/commit',[HomeController::class,'entry_update']);
|
||||
Route::post('entry/update/pending',[HomeController::class,'entry_pending_update']);
|
||||
|
Loading…
x
Reference in New Issue
Block a user