Implemented more attribute classes

This commit is contained in:
Deon George 2023-03-02 18:21:53 +11:00
parent 7d19b89637
commit a99770951d
26 changed files with 245 additions and 181 deletions

View File

@ -14,7 +14,7 @@ class Attribute
// Attribute Name // Attribute Name
protected string $name; protected string $name;
protected ?AttributeType $schema; protected ?AttributeType $schema = NULL;
/* /*
# Source of this attribute definition # Source of this attribute definition
@ -28,7 +28,7 @@ class Attribute
protected bool $is_deletable = FALSE; protected bool $is_deletable = FALSE;
// Is this attribute an internal attribute // Is this attribute an internal attribute
protected bool $is_internal; protected bool $is_internal = FALSE;
// Is this attribute the RDN? // Is this attribute the RDN?
protected bool $is_rdn = FALSE; protected bool $is_rdn = FALSE;
@ -95,6 +95,8 @@ class Attribute
$this->name = $name; $this->name = $name;
$this->values = collect($values); $this->values = collect($values);
// No need to load our schema for internal attributes
if (! $this->is_internal)
$this->schema = config('server')->schema('attributetypes',$name); $this->schema = config('server')->schema('attributetypes',$name);
/* /*

View File

@ -7,6 +7,6 @@ use App\Classes\LDAP\Attribute;
/** /**
* Represents an attribute whose values are binary * Represents an attribute whose values are binary
*/ */
abstract class Binary extends Attribute class Binary extends Attribute
{ {
} }

View File

@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Binary;
use App\Classes\LDAP\Attribute\Binary; use App\Classes\LDAP\Attribute\Binary;
/** /**
* Represents an attribute whose values are jpeg pictures * Represents an JpegPhoto Attribute
*/ */
final class JpegPhoto extends Binary final class JpegPhoto extends Binary
{ {

View File

@ -20,13 +20,24 @@ class Factory
* Map of attributes to appropriate class * Map of attributes to appropriate class
*/ */
public const map = [ public const map = [
'createtimestamp' => Internal\Timestamp::class,
'creatorsname' => Internal\EntryDN::class,
'entrycsn' => Internal\EntryCSN::class,
'entrydn' => Internal\EntryDN::class,
'entryuuid' => Internal\EntryUUID::class, 'entryuuid' => Internal\EntryUUID::class,
'gidnumber' => GidNumber::class,
'hassubordinates' => Internal\HasSubordinates::class,
'jpegphoto' => Binary\JpegPhoto::class, 'jpegphoto' => Binary\JpegPhoto::class,
'modifytimestamp' => Internal\Timestamp::class,
'modifiersname' => Internal\EntryDN::class,
'objectclass' => ObjectClass::class, 'objectclass' => ObjectClass::class,
'structuralobjectclass' => Internal\StructuralObjectClass::class,
'subschemasubentry' => Internal\SubschemaSubentry::class,
'supportedcontrol' => Schema\OID::class, 'supportedcontrol' => Schema\OID::class,
'supportedextension' => Schema\OID::class, 'supportedextension' => Schema\OID::class,
'supportedfeatures' => Schema\OID::class, 'supportedfeatures' => Schema\OID::class,
'supportedsaslmechanisms' => Schema\Mechanisms::class, 'supportedsaslmechanisms' => Schema\Mechanisms::class,
'userpassword' => Password::class,
]; ];
/** /**

View File

@ -0,0 +1,12 @@
<?php
namespace App\Classes\LDAP\Attribute;
use App\Classes\LDAP\Attribute;
/**
* Represents an GidNumber Attribute
*/
final class GidNumber extends Attribute
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Classes\LDAP\Attribute\Internal;
use App\Classes\LDAP\Attribute\Internal;
/**
* Represents an EntryCSN Attribute
*/
final class EntryCSN extends Internal
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Classes\LDAP\Attribute\Internal;
use App\Classes\LDAP\Attribute\Internal;
/**
* Represents an EntryDN Attribute
*/
final class EntryDN extends Internal
{
}

View File

@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Internal;
use App\Classes\LDAP\Attribute\Internal; use App\Classes\LDAP\Attribute\Internal;
/** /**
* Represents an attribute whose values are binary * Represents an EntryUUID Attribute
*/ */
final class EntryUUID extends Internal final class EntryUUID extends Internal
{ {

View File

@ -0,0 +1,12 @@
<?php
namespace App\Classes\LDAP\Attribute\Internal;
use App\Classes\LDAP\Attribute\Internal;
/**
* Represents an HasSubordinates Attribute
*/
final class HasSubordinates extends Internal
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Classes\LDAP\Attribute\Internal;
use App\Classes\LDAP\Attribute\Internal;
/**
* Represents an StructuralObjectClass Attribute
*/
final class StructuralObjectClass extends Internal
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Classes\LDAP\Attribute\Internal;
use App\Classes\LDAP\Attribute\Internal;
/**
* Represents an SubschemaSubentry Attribute
*/
final class SubschemaSubentry extends Internal
{
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Classes\LDAP\Attribute\Internal;
use Carbon\Carbon;
use App\Classes\LDAP\Attribute\Internal;
/**
* Represents an attribute whose values are timestamps
*/
final class Timestamp extends Internal
{
public function __toString(): string
{
return Carbon::createFromTimestamp(strtotime($this->values[0]))->format(config('ldap.datetime_format','Y-m-d H:i:s'));
}
}

View File

@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
/** /**
* Represents an attribute whose values are jpeg pictures * Represents an ObjectClass Attribute
*/ */
final class ObjectClass extends Attribute final class ObjectClass extends Attribute
{ {

View File

@ -0,0 +1,17 @@
<?php
namespace App\Classes\LDAP\Attribute;
use App\Classes\LDAP\Attribute;
/**
* Represents an attribute whose values are passwords
*/
class Password extends Attribute
{
public function __toString(): string
{
return str_repeat('*',10)
.sprintf('<br><span class="btn btn-sm btn-outline-dark"><i class="fas fa-user-check"></i> %s</span>',__('Check Password'));
}
}

View File

@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Schema;
use App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema;
/** /**
* Represents an attribute whose values are binary * Represents a Mechanisms Attribute
*/ */
final class Mechanisms extends Schema final class Mechanisms extends Schema
{ {

View File

@ -5,7 +5,7 @@ namespace App\Classes\LDAP\Attribute\Schema;
use App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema;
/** /**
* Represents an attribute whose values are binary * Represents an OID Attribute
*/ */
final class OID extends Schema final class OID extends Schema
{ {

View File

@ -6,6 +6,7 @@ use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use LdapRecord\Models\Model; use LdapRecord\Models\Model;
use App\Classes\LDAP\Attribute;
use App\Classes\LDAP\Attribute\Factory; use App\Classes\LDAP\Attribute\Factory;
class Entry extends Model class Entry extends Model
@ -14,6 +15,9 @@ class Entry extends Model
public function getAttributes(): array public function getAttributes(): array
{ {
static $result = NULL;
if (is_null($result)) {
$result = collect(); $result = collect();
foreach (parent::getAttributes() as $attribute => $value) { foreach (parent::getAttributes() as $attribute => $value) {
@ -32,8 +36,8 @@ class Entry extends Model
$sort = collect(config('ldap.attr_display_order',[]))->transform(function($item) { return strtolower($item); }); $sort = collect(config('ldap.attr_display_order',[]))->transform(function($item) { return strtolower($item); });
// Order the attributes // Order the attributes
return $result->sortBy([function($a,$b) use ($sort) { $result = $result->sortBy([function(Attribute $a,Attribute $b) use ($sort): int {
if (! $sort->count() || $a === $b) if ($a === $b)
return 0; return 0;
// Check if $a/$b are in the configuration to be sorted first, if so get it's key // Check if $a/$b are in the configuration to be sorted first, if so get it's key
@ -58,6 +62,9 @@ class Entry extends Model
} ])->toArray(); } ])->toArray();
} }
return $result;
}
/* ATTRIBUTES */ /* ATTRIBUTES */
/** /**
@ -73,6 +80,23 @@ class Entry extends Model
/* METHODS */ /* METHODS */
/**
* Return a list of LDAP internal attributes
*
* @return Collection
*/
public function getInternalAttributes(): Collection
{
return collect($this->getAttributes())->filter(function($item) {
return $item->is_internal;
});
}
/**
* Return this list of user attributes
*
* @return Collection
*/
public function getVisibleAttributes(): Collection public function getVisibleAttributes(): Collection
{ {
return collect($this->getAttributes())->filter(function($item) { return collect($this->getAttributes())->filter(function($item) {

View File

@ -102,4 +102,13 @@ return [
], ],
*/ */
/*
|--------------------------------------------------------------------------
| Custom Date Format
|--------------------------------------------------------------------------
|
| Configuration to determine how date fields will be displayed.
|
*/
'datetime_format' => 'Y-m-d H:i:s',
]; ];

View File

@ -96,18 +96,9 @@ class AttributeFactory {
return $this->newMultiLineAttribute($name,$values,$server_id,$source); return $this->newMultiLineAttribute($name,$values,$server_id,$source);
} }
if (! strcasecmp($name,'objectClass')) { if ($app['server']->isAttrBinary($name)) {
return $this->newObjectClassAttribute($name,$values,$server_id,$source);
} elseif ($app['server']->isJpegPhoto($name) || in_array($name,$app['server']->getValue('server','jpeg_attributes'))) {
return $this->newJpegAttribute($name,$values,$server_id,$source);
} elseif ($app['server']->isAttrBinary($name)) {
return $this->newBinaryAttribute($name,$values,$server_id,$source); return $this->newBinaryAttribute($name,$values,$server_id,$source);
} elseif (! strcasecmp($name,'userPassword')) {
return $this->newPasswordAttribute($name,$values,$server_id,$source);
} elseif (! strcasecmp($name,'sambaLMPassword') || ! strcasecmp($name,'sambaNTPassword')) { } elseif (! strcasecmp($name,'sambaLMPassword') || ! strcasecmp($name,'sambaNTPassword')) {
return $this->newSambaPasswordAttribute($name,$values,$server_id,$source); return $this->newSambaPasswordAttribute($name,$values,$server_id,$source);
@ -129,26 +120,11 @@ class AttributeFactory {
} elseif ($app['server']->isMultiLineAttr($name)) { } elseif ($app['server']->isMultiLineAttr($name)) {
return $this->newMultiLineAttribute($name,$values,$server_id,$source); return $this->newMultiLineAttribute($name,$values,$server_id,$source);
} elseif (! strcasecmp($name,'gidNumber')) {
return $this->newGidAttribute($name,$values,$server_id,$source);
} else { } else {
return new Attribute($name,$values,$server_id,$source); return new Attribute($name,$values,$server_id,$source);
} }
} }
private function newJpegAttribute($name,$values,$server_id,$source) {
return new JpegAttribute($name,$values,$server_id,$source);
}
private function newBinaryAttribute($name,$values,$server_id,$source) {
return new BinaryAttribute($name,$values,$server_id,$source);
}
private function newPasswordAttribute($name,$values,$server_id,$source) {
return new PasswordAttribute($name,$values,$server_id,$source);
}
private function newSambaPasswordAttribute($name,$values,$server_id,$source) { private function newSambaPasswordAttribute($name,$values,$server_id,$source) {
return new SambaPasswordAttribute($name,$values,$server_id,$source); return new SambaPasswordAttribute($name,$values,$server_id,$source);
} }
@ -168,21 +144,5 @@ class AttributeFactory {
private function newMultiLineAttribute($name,$values,$server_id,$source) { private function newMultiLineAttribute($name,$values,$server_id,$source) {
return new MultiLineAttribute($name,$values,$server_id,$source); return new MultiLineAttribute($name,$values,$server_id,$source);
} }
private function newDateAttribute($name,$values,$server_id,$source) {
return new DateAttribute($name,$values,$server_id,$source);
}
private function newObjectClassAttribute($name,$values,$server_id,$source) {
return new ObjectClassAttribute($name,$values,$server_id,$source);
}
private function newDnAttribute($name,$values,$server_id,$source) {
return new DnAttribute($name,$values,$server_id,$source);
}
private function newGidAttribute($name,$values,$server_id,$source) {
return new GidAttribute($name,$values,$server_id,$source);
}
} }
?> ?>

View File

@ -1,17 +0,0 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are dates
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class DateAttribute extends Attribute {
}
?>

View File

@ -1,17 +0,0 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are DNs
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class DnAttribute extends Attribute {
}
?>

View File

@ -1,17 +0,0 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents a 'gidNumber' attribute
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class GidAttribute extends Attribute {
}
?>

View File

@ -1,17 +0,0 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an 'objectClass' attribute
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class ObjectClassAttribute extends Attribute {
}
?>

View File

@ -1,17 +0,0 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are passwords
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class PasswordAttribute extends Attribute {
}
?>

View File

@ -52,10 +52,6 @@ class ldap_pla extends ldap {
'desc'=>'Custom operational attributes to be treated as internal attributes', 'desc'=>'Custom operational attributes to be treated as internal attributes',
'default'=>array('+')); 'default'=>array('+'));
$this->default->server['jpeg_attributes'] = array(
'desc'=>'Additional attributes to treat as Jpeg Attributes',
'default'=>array());
# This was added in case the LDAP server doesnt provide them with a base +,* query. # This was added in case the LDAP server doesnt provide them with a base +,* query.
$this->default->server['root_dse_attributes'] = array( $this->default->server['root_dse_attributes'] = array(
'desc'=>'RootDSE attributes for use when displaying server info', 'desc'=>'RootDSE attributes for use when displaying server info',

View File

@ -3,8 +3,26 @@
@section('page_title') @section('page_title')
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td class="{{ ($x=Arr::get($o->getAttributes(),'jpegphoto')) ? 'border' : '' }}" style="border-radius: 5px;">{!! $x ?: sprintf('<div class="page-title-icon f32"><i class="%s"></i></div>',$o->icon() ?? "fas fa-info") !!}</td> <td class="{{ ($x=Arr::get($o->getAttributes(),'jpegphoto')) ? 'border' : '' }}" rowspan="2">{!! $x ?: sprintf('<div class="page-title-icon f32"><i class="%s"></i></div>',$o->icon() ?? "fas fa-info") !!}</td>
<td class="top text-right align-text-top p-0 {{ $x ? 'pl-5' : 'pt-2' }}"><strong>{{ $dn }}</strong><br><small>{{ $o->entryuuid[0] ?? '' }}</small></td> <td class="text-right align-text-top p-0 {{ $x ? 'pl-5' : 'pt-2' }}"><strong>{{ $dn }}</strong></td>
</tr>
<tr>
<td class="line-height-1" style="font-size: 55%;vertical-align: bottom;" colspan="2">
<table>
<tr>
<td class="p-1 m-1">Created</td>
<th class="p-1 m-1">{{ ($x=Arr::get($o->getAttributes(),'createtimestamp')) ? $x : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'creatorsname')) ? $x : __('Unknown') }}]</th>
</tr>
<tr>
<td class="p-1 m-1">Modified</td>
<th class="p-1 m-1">{{ ($x=Arr::get($o->getAttributes(),'modifytimestamp')) ? $x : __('Unknown') }} [{{ ($x=Arr::get($o->getAttributes(),'modifiersname')) ? $x : __('Unknown') }}]</th>
</tr>
<tr>
<td class="p-1 m-1">UUID</td>
<th class="p-1 m-1">{{ $o->entryuuid[0] ?? '' }}</th>
</tr>
</table>
</td>
</tr> </tr>
</table> </table>
@endsection @endsection
@ -15,9 +33,13 @@
<div class="card-header-tabs"> <div class="card-header-tabs">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="nav-item"><a data-toggle="tab" href="#attributes" class="nav-link active">{{ __('Attributes') }}</a></li> <li class="nav-item"><a data-toggle="tab" href="#attributes" class="nav-link active">{{ __('Attributes') }}</a></li>
{{--
<li class="nav-item"><a data-toggle="tab" href="#placeholder" class="nav-link">placeholder</a></li> <li class="nav-item"><a data-toggle="tab" href="#placeholder" class="nav-link">placeholder</a></li>
--}}
<li class="nav-item"><a data-toggle="tab" href="#internal" class="nav-link">{{ __('Internal') }}</a></li> <li class="nav-item"><a data-toggle="tab" href="#internal" class="nav-link">{{ __('Internal') }}</a></li>
{{--
<li class="nav-item"><a data-toggle="tab" href="#addtemplate" class="nav-link">{{ __('Add Template') }}</a></li> <li class="nav-item"><a data-toggle="tab" href="#addtemplate" class="nav-link">{{ __('Add Template') }}</a></li>
--}}
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
@ -47,9 +69,6 @@
<span class="btn btn-sm btn-outline-primary mt-3 mb-3"><i class="fas fa-plus"></i> {{ __('Add Value') }}</span> <span class="btn btn-sm btn-outline-primary mt-3 mb-3"><i class="fas fa-plus"></i> {{ __('Add Value') }}</span>
@endif @endif
</td> </td>
{{--
<td>@dump($ao)</td>
--}}
</tr> </tr>
@endforeach @endforeach
</table> </table>
@ -57,20 +76,41 @@
</div> </div>
</div> </div>
{{--
<!-- Templates --> <!-- Templates -->
<div class="tab-pane" id="placeholder" role="tabpanel"> <div class="tab-pane" id="placeholder" role="tabpanel">
<div><i class="fas fa-fw fa-spinner fa-pulse"></i></div> <div><i class="fas fa-fw fa-spinner fa-pulse"></i></div>
</div> </div>
--}}
<!-- Internal Attributes --> <!-- Internal Attributes -->
<div class="tab-pane" id="internal" role="tabpanel"> <div class="tab-pane" id="internal" role="tabpanel">
<div><i class="fas fa-fw fa-spinner fa-pulse"></i></div> <div class="row">
<div class="offset-2 col-8">
<table class="table">
@foreach ($o->getInternalAttributes() as $ao)
<tr class="bg-light text-dark small">
<th class="w-25">
<abbr title="{{ $ao->description }}">{{ $ao->name }}</abbr>
</th>
</tr>
<tr>
<td class="pl-5">
{!! $ao !!}
</td>
</tr>
@endforeach
</table>
</div>
</div>
</div> </div>
{{--
<!-- Add Template --> <!-- Add Template -->
<div class="tab-pane" id="addtemplate" role="tabpanel"> <div class="tab-pane" id="addtemplate" role="tabpanel">
<div><i class="fas fa-fw fa-spinner fa-pulse"></i></div> <div><i class="fas fa-fw fa-spinner fa-pulse"></i></div>
</div> </div>
--}}
</div> </div>
</div> </div>
</div> </div>