Compare commits
11 Commits
baf5acc01a
...
af7ca851d5
Author | SHA1 | Date | |
---|---|---|---|
af7ca851d5 | |||
b34dad8836 | |||
ef2ea5e266 | |||
91b5b53137 | |||
d4c916923d | |||
e94a7d58e1 | |||
15d5bf605a | |||
33c59e5e65 | |||
c86d3c97a1 | |||
be87a12f21 | |||
e99e349c0b |
@ -46,6 +46,7 @@ The update to v2 is progressing well - here is a list of work to do and done:
|
|||||||
- [X] Delete extra values for Attributes that support multiple values
|
- [X] Delete extra values for Attributes that support multiple values
|
||||||
- [ ] Delete Attributes
|
- [ ] Delete Attributes
|
||||||
- [ ] Templates to enable entries to conform to a custom standard
|
- [ ] Templates to enable entries to conform to a custom standard
|
||||||
|
- [ ] Autopopulate attribute values
|
||||||
- [X] Login to LDAP server
|
- [X] Login to LDAP server
|
||||||
- [X] Configure login by a specific attribute
|
- [X] Configure login by a specific attribute
|
||||||
- [X] Logout LDAP server
|
- [X] Logout LDAP server
|
||||||
@ -53,6 +54,7 @@ The update to v2 is progressing well - here is a list of work to do and done:
|
|||||||
- [X] Import LDIF
|
- [X] Import LDIF
|
||||||
- [X] Schema Browser
|
- [X] Schema Browser
|
||||||
- [ ] Searching
|
- [ ] Searching
|
||||||
|
- [ ] Enforcing attribute uniqueness
|
||||||
- [ ] Is there something missing?
|
- [ ] Is there something missing?
|
||||||
|
|
||||||
Support is known for these LDAP servers:
|
Support is known for these LDAP servers:
|
||||||
|
@ -383,6 +383,11 @@ class HomeController extends Controller
|
|||||||
: view('frames.'.$key['cmd']))
|
: view('frames.'.$key['cmd']))
|
||||||
->with('bases',$this->bases());
|
->with('bases',$this->bases());
|
||||||
|
|
||||||
|
// If we are rendering a DN, rebuild our object
|
||||||
|
$o = config('server')->fetch($key['dn']);
|
||||||
|
foreach (collect(old())->except(['dn','_token']) as $attr => $value)
|
||||||
|
$o->{$attr} = $value;
|
||||||
|
|
||||||
return match ($key['cmd']) {
|
return match ($key['cmd']) {
|
||||||
'create' => $view
|
'create' => $view
|
||||||
->with('container',old('container',$key['dn']))
|
->with('container',old('container',$key['dn']))
|
||||||
@ -390,7 +395,8 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
'dn' => $view
|
'dn' => $view
|
||||||
->with('dn',$key['dn'])
|
->with('dn',$key['dn'])
|
||||||
->with('page_actions',collect(['edit'=>TRUE,'copy'=>TRUE])),
|
->with('o',$o)
|
||||||
|
->with('page_actions',collect(['edit'=>TRUE])),
|
||||||
|
|
||||||
'import' => $view,
|
'import' => $view,
|
||||||
|
|
||||||
|
@ -94,12 +94,10 @@ class Entry extends Model
|
|||||||
|
|
||||||
$key = $this->normalizeAttributeKey($key);
|
$key = $this->normalizeAttributeKey($key);
|
||||||
|
|
||||||
if ((! $this->objects->get($key)) && $value) {
|
if ((! $this->objects->get($key)) && $value)
|
||||||
$this->objects->put($key,Factory::create($key,$value));
|
$this->objects->put($key,Factory::create($key,[]));
|
||||||
|
|
||||||
} elseif ($this->objects->get($key)) {
|
$this->objects->get($key)->value = $this->attributes[$key];
|
||||||
$this->objects->get($key)->value = $this->attributes[$key];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -164,7 +162,6 @@ class Entry extends Model
|
|||||||
/**
|
/**
|
||||||
* Convert all our attribute values into an array of Objects
|
* Convert all our attribute values into an array of Objects
|
||||||
*
|
*
|
||||||
* @param array $attributes
|
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function getAttributesAsObjects(): Collection
|
public function getAttributesAsObjects(): Collection
|
||||||
|
@ -16,20 +16,21 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||||||
)
|
)
|
||||||
->withMiddleware(function (Middleware $middleware) {
|
->withMiddleware(function (Middleware $middleware) {
|
||||||
$middleware->appendToGroup('web', [
|
$middleware->appendToGroup('web', [
|
||||||
ApplicationSession::class,
|
|
||||||
SwapinAuthUser::class,
|
SwapinAuthUser::class,
|
||||||
|
ApplicationSession::class,
|
||||||
CheckUpdate::class,
|
CheckUpdate::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$middleware->prependToGroup('api', [
|
$middleware->prependToGroup('api', [
|
||||||
EncryptCookies::class,
|
EncryptCookies::class,
|
||||||
ApplicationSession::class,
|
|
||||||
SwapinAuthUser::class,
|
SwapinAuthUser::class,
|
||||||
|
ApplicationSession::class,
|
||||||
AllowAnonymous::class,
|
AllowAnonymous::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$middleware->trustProxies(at: [
|
$middleware->trustProxies(at: [
|
||||||
'10.0.0.0/8',
|
'10.0.0.0/8',
|
||||||
|
'127.0.0.0/8',
|
||||||
'172.16.0.0/12',
|
'172.16.0.0/12',
|
||||||
'192.168.0.0/12',
|
'192.168.0.0/12',
|
||||||
]);
|
]);
|
||||||
|
@ -1 +1 @@
|
|||||||
v2.0.1-dev
|
v2.0.2-rel
|
||||||
|
4
public/css/custom.css
vendored
4
public/css/custom.css
vendored
@ -1,5 +1,5 @@
|
|||||||
/** ensure our userpassword has select is next to the password input */
|
/** ensure our userpassword has select is next to the password input */
|
||||||
div#userPassword .select2-container--bootstrap-5 .select2-selection {
|
attribute#userPassword .select2-container--bootstrap-5 .select2-selection {
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
width: 9em;
|
width: 9em;
|
||||||
border: #444054 1px solid;
|
border: #444054 1px solid;
|
||||||
@ -11,7 +11,7 @@ div#userPassword .select2-container--bootstrap-5 .select2-selection {
|
|||||||
border-top-right-radius: unset;
|
border-top-right-radius: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#objectClass .input-group-end:not(input.form-control) {
|
attribute#objectClass .input-group-end:not(input.form-control) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 1em;
|
right: 1em;
|
||||||
top: 0.5em;
|
top: 0.5em;
|
||||||
|
5
public/css/fixes.css
vendored
5
public/css/fixes.css
vendored
@ -248,3 +248,8 @@ select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__
|
|||||||
.input-group-text {
|
.input-group-text {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop showing a border on our user's drop down menu when open */
|
||||||
|
.btn-check:checked+.btn, .btn.active, .btn.show, .btn:first-child:active, :not(.btn-check)+.btn:active {
|
||||||
|
border-color: var(--bs-btn-bg);
|
||||||
|
}
|
@ -27,7 +27,7 @@
|
|||||||
@endif
|
@endif
|
||||||
@if(isset($page_actions) && $page_actions->contains('copy'))
|
@if(isset($page_actions) && $page_actions->contains('copy'))
|
||||||
<li>
|
<li>
|
||||||
<button class="btn btn-outline-dark p-1 m-1" id="entry-copy-move" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Copy/Move')"><i class="fas fa-fw fa-copy fs-5"></i></button>
|
<button class="btn btn-outline-dark p-1 m-1" id="entry-copy-move" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Copy/Move')" disabled><i class="fas fa-fw fa-copy fs-5"></i></button>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
@if((isset($page_actions) && $page_actions->contains('edit')) || old())
|
@if((isset($page_actions) && $page_actions->contains('edit')) || old())
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
--}}
|
--}}
|
||||||
<div class="widget-content-left header-user-info ms-3">
|
<div class="widget-content-left header-user-info ms-3">
|
||||||
<div class="widget-heading">
|
<div class="widget-heading">
|
||||||
{{ $user->exists ? Arr::get($user->getAttribute('cn'),0,'Anonymous') : 'Anonymous' }}
|
{{ $user->exists ? Arr::get($user->getAttribute('cn'),0,Arr::get($user->getAttribute('entryuuid'),0,'Secret Person')) : 'Anonymous' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="widget-subheading">
|
<div class="widget-subheading">
|
||||||
{{ $user->exists ? Arr::get($user->getAttribute('mail'),0,'') : '' }}
|
{{ $user->exists ? Arr::get($user->getAttribute('mail'),0,'') : '' }}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
@if ($edit)
|
@if ($edit)
|
||||||
<br>
|
<br>
|
||||||
<!-- @todo TO IMPLEMENT -->
|
<!-- @todo TO IMPLEMENT -->
|
||||||
<span class="btn btn-sm btn-danger deletable d-none mt-3"><i class="fas fa-trash-alt"></i> @lang('Delete')</span>
|
<button class="btn btn-sm btn-danger deletable d-none mt-3" disabled><i class="fas fa-trash-alt"></i> @lang('Delete')</button>
|
||||||
|
|
||||||
<div class="invalid-feedback pb-2">
|
<div class="invalid-feedback pb-2">
|
||||||
@if($e)
|
@if($e)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<div class="row pt-2">
|
<div class="row pt-2">
|
||||||
<div @class(['col-1','d-none'=>(! $edit)])></div>
|
<div @class(['col-1','d-none'=>(! $edit)])></div>
|
||||||
<div class="col-10 p-2">
|
<div class="col-10 p-2">
|
||||||
<div id="{{ $o->name }}">
|
<attribute id="{{ $o->name }}">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</div>
|
</attribute>
|
||||||
|
|
||||||
<x-attribute.widget.options :o="$o" :edit="$edit" :new="$new"/>
|
<x-attribute.widget.options :o="$o" :edit="$edit" :new="$new"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
|
@use(App\Classes\LDAP\Attribute\Binary\JpegPhoto)
|
||||||
|
@use(App\Classes\LDAP\Attribute\ObjectClass)
|
||||||
@php($clone=FALSE)
|
@php($clone=FALSE)
|
||||||
@if($o->is_rdn)
|
<span class="p-0 m-0">
|
||||||
<span class="btn btn-sm btn-outline-focus mt-3"><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</span>
|
@if($o->is_rdn)
|
||||||
@elseif($edit && $o->can_addvalues)
|
<br/>
|
||||||
<span class="p-0 m-0">
|
<button class="btn btn-sm btn-outline-focus mt-3" disabled><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</button>
|
||||||
|
@elseif($edit && $o->can_addvalues)
|
||||||
@switch(get_class($o))
|
@switch(get_class($o))
|
||||||
@case('App\Classes\LDAP\Attribute\Binary\JpegPhoto')
|
@case(JpegPhoto::class)
|
||||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}"><i class="fas fa-fw fa-plus"></i> @lang('Upload JpegPhoto')</span>
|
<button @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}" disabled><i class="fas fa-fw fa-plus"></i> @lang('Upload JpegPhoto')</button>
|
||||||
|
|
||||||
@break
|
@break
|
||||||
|
|
||||||
@case('App\Classes\LDAP\Attribute\ObjectClass')
|
@case(ObjectClass::class)
|
||||||
<button type="button" @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) data-bs-toggle="modal" data-bs-target="#new_objectclass-modal"><i class="fas fa-fw fa-plus"></i> @lang('Add Objectclass')</button>
|
<button type="button" @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) data-bs-toggle="modal" data-bs-target="#new_objectclass-modal"><i class="fas fa-fw fa-plus"></i> @lang('Add Objectclass')</button>
|
||||||
|
|
||||||
<!-- NEW OBJECT CLASS -->
|
<!-- NEW OBJECT CLASS -->
|
||||||
@ -37,42 +40,12 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var added_oc = []; // Object classes being added to this entry
|
var added_oc = []; // Object classes being added to this entry
|
||||||
var rendered = false;
|
var rendered = false;
|
||||||
|
var newadded = [];
|
||||||
|
|
||||||
// Show our ObjectClass modal so that we can add more objectclasses
|
if (newadded.length)
|
||||||
$('#new_objectclass-modal').on('shown.bs.modal',function() {
|
process_oc();
|
||||||
if (! rendered)
|
|
||||||
$.ajax({
|
|
||||||
method: 'POST',
|
|
||||||
url: '{{ url('entry/objectclass/add') }}',
|
|
||||||
data: {
|
|
||||||
oc: oc,
|
|
||||||
},
|
|
||||||
cache: false,
|
|
||||||
success: function(data) {
|
|
||||||
$('select#newoc').select2({
|
|
||||||
dropdownParent: $('#new_objectclass-modal'),
|
|
||||||
theme: 'bootstrap-5',
|
|
||||||
multiple: true,
|
|
||||||
data: data,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error: function(e) {
|
|
||||||
if (e.status !== 412)
|
|
||||||
alert('That didnt work? Please try again....');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
rendered = true;
|
|
||||||
})
|
|
||||||
|
|
||||||
// When the ObjectClass modal is closed, process what was selected
|
|
||||||
$('#new_objectclass-modal').on('hide.bs.modal',function() {
|
|
||||||
var newadded = $('select#newoc').val();
|
|
||||||
|
|
||||||
// If nothing selected, we dont have anything to do
|
|
||||||
if (added_oc.sort().join('|') === newadded.sort().join('|'))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
function process_oc() {
|
||||||
// Find out what was selected, and add them
|
// Find out what was selected, and add them
|
||||||
newadded.forEach(function (item) {
|
newadded.forEach(function (item) {
|
||||||
if (added_oc.indexOf(item) !== -1)
|
if (added_oc.indexOf(item) !== -1)
|
||||||
@ -97,6 +70,7 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get a list of attributes already on the page, so we dont double up
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '{{ url('api/schema/objectclass/attrs') }}/'+item,
|
url: '{{ url('api/schema/objectclass/attrs') }}/'+item,
|
||||||
@ -105,6 +79,9 @@
|
|||||||
// Render any must attributes
|
// Render any must attributes
|
||||||
if (data.must.length) {
|
if (data.must.length) {
|
||||||
data.must.forEach(function(item) {
|
data.must.forEach(function(item) {
|
||||||
|
if ($('attribute#'+item).length)
|
||||||
|
return;
|
||||||
|
|
||||||
// Add attribute to the page
|
// Add attribute to the page
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -174,7 +151,7 @@
|
|||||||
if (x.length) {
|
if (x.length) {
|
||||||
x.remove();
|
x.remove();
|
||||||
|
|
||||||
// Add this to the must attrs list, because its been rendered
|
// Add this to the must attrs list, because its been rendered
|
||||||
} else {
|
} else {
|
||||||
attrs.push(mayitem);
|
attrs.push(mayitem);
|
||||||
}
|
}
|
||||||
@ -196,13 +173,51 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
added_oc = newadded;
|
added_oc = newadded;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show our ObjectClass modal so that we can add more objectclasses
|
||||||
|
$('#new_objectclass-modal').on('shown.bs.modal',function() {
|
||||||
|
if (! rendered)
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
url: '{{ url('entry/objectclass/add') }}',
|
||||||
|
data: {
|
||||||
|
oc: oc,
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
success: function(data) {
|
||||||
|
$('select#newoc').select2({
|
||||||
|
dropdownParent: $('#new_objectclass-modal'),
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
multiple: true,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
if (e.status !== 412)
|
||||||
|
alert('That didnt work? Please try again....');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendered = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
// When the ObjectClass modal is closed, process what was selected
|
||||||
|
$('#new_objectclass-modal').on('hide.bs.modal',function() {
|
||||||
|
newadded = $('select#newoc').val();
|
||||||
|
|
||||||
|
// If nothing selected, we dont have anything to do
|
||||||
|
if (added_oc.sort().join('|') === newadded.sort().join('|'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
process_oc();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@append
|
@append
|
||||||
@break
|
@break
|
||||||
|
|
||||||
@case('App\Classes\LDAP\Attribute')
|
<!-- All other attributes -->
|
||||||
@default
|
@default
|
||||||
@php($clone=TRUE)
|
@php($clone=TRUE)
|
||||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-addnew"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span>
|
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-addnew"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span>
|
||||||
@ -222,5 +237,5 @@
|
|||||||
@endif
|
@endif
|
||||||
@append
|
@append
|
||||||
@endswitch
|
@endswitch
|
||||||
</span>
|
@endif
|
||||||
@endif
|
</span>
|
@ -1,7 +1,7 @@
|
|||||||
@if(file_exists($file))
|
@if(file_exists($file))
|
||||||
<div class="row pb-3">
|
<div class="row pb-3">
|
||||||
<div class="col-12">
|
<div class="col-12 offset-md-2 col-md-8">
|
||||||
<div class="mx-auto card text-white card-body bg-primary w-50">
|
<div class="mx-auto card text-white card-body bg-primary">
|
||||||
<h5 class="text-white card-title"><i class="icon fa-2x fas fa-info pe-3"></i><span class="font-size-xlg">NOTE</span></h5>
|
<h5 class="text-white card-title"><i class="icon fa-2x fas fa-info pe-3"></i><span class="font-size-xlg">NOTE</span></h5>
|
||||||
<span class="w-100 pb-0">
|
<span class="w-100 pb-0">
|
||||||
{!! file_get_contents($file) !!}
|
{!! file_get_contents($file) !!}
|
||||||
|
@ -13,10 +13,9 @@
|
|||||||
|
|
||||||
<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')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name_lc])"/>
|
<x-form.select id="newattr" label="Select from..." :options="$o->getMissingAttributes()->sortBy('name')->unique('name')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name_lc])"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2"></div>
|
|
||||||
</div>
|
</div>
|
@ -1,7 +1,7 @@
|
|||||||
@extends('layouts.dn')
|
@extends('layouts.dn')
|
||||||
|
|
||||||
@section('page_title')
|
@section('page_title')
|
||||||
@include('fragment.dn.header',['o'=>($o=config('server')->fetch($dn))])
|
@include('fragment.dn.header',['o'=>($o ?? $o=config('server')->fetch($dn))])
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('main-content')
|
@section('main-content')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user