Compare commits

..

No commits in common. "817b72cdac94110596c857837bc3a40351161195" and "16880cd0e250dd9369e7cf01ab0762567727275b" have entirely different histories.

31 changed files with 108 additions and 301 deletions

View File

@ -19,21 +19,24 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
// Is this attribute an internal attribute // Is this attribute an internal attribute
protected(set) bool $is_internal = FALSE; protected(set) bool $is_internal = FALSE;
protected(set) bool $no_attr_tags = FALSE;
// MIN/MAX number of values // MIN/MAX number of values
protected(set) int $min_values_count = 0; protected(set) int $min_values_count = 0;
protected(set) int $max_values_count = 0; protected(set) int $max_values_count = 0;
// RFC3866 Language Tags
/* @deprecated use $values/$values_old when playing with language tags */
protected Collection $lang_tags;
// The schema's representation of this attribute // The schema's representation of this attribute
protected(set) ?AttributeType $schema; protected(set) ?AttributeType $schema;
// The DN this object is in // The DN this object is in
protected(set) string $dn; protected(set) string $dn;
// The old values for this attribute - helps with isDirty() to determine if there is an update pending // The old values for this attribute - helps with isDirty() to determine if there is an update pending
private Collection $_values_old; protected(set) Collection $values_old;
// Current Values // Current Values
private Collection $_values; public Collection $values;
// The objectclasses of the entry that has this attribute // The objectclasses of the entry that has this attribute
protected(set) Collection $oc; protected(set) Collection $oc;
@ -104,6 +107,7 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
$this->values = collect(); $this->values = collect();
$this->oc = collect($oc); $this->oc = collect($oc);
$this->lang_tags = collect();
$this->schema = (new Server) $this->schema = (new Server)
->schema('attributetypes',$name); ->schema('attributetypes',$name);
@ -148,43 +152,19 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
'required_by' => $this->schema?->required_by_object_classes ?: collect(), 'required_by' => $this->schema?->required_by_object_classes ?: collect(),
// Used in Object Classes // Used in Object Classes
'used_in' => $this->schema?->used_in_object_classes ?: collect(), 'used_in' => $this->schema?->used_in_object_classes ?: collect(),
// The current attribute values
'values' => $this->no_attr_tags ? collect($this->_values->first()) : $this->_values,
// The original attribute values
'values_old' => $this->no_attr_tags ? collect($this->_values_old->first()) : $this->_values_old,
default => throw new \Exception('Unknown key:' . $key), default => throw new \Exception('Unknown key:' . $key),
}; };
} }
public function __set(string $key,mixed $values)
{
switch ($key) {
case 'values':
$this->_values = $values;
break;
case 'values_old':
$this->_values_old = $values;
break;
default:
throw new \Exception('Unknown key:'.$key);
}
}
public function __toString(): string public function __toString(): string
{ {
return $this->name; return $this->name;
} }
public function addValue(string $tag,string $value): void public function addValue(string $value): void
{ {
$this->_values->put( $this->values->push($value);
$tag,
$this->_values
->get($tag,collect())
->push($value));
} }
public function current(): mixed public function current(): mixed
@ -256,6 +236,10 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
if ($this->required()->count()) if ($this->required()->count())
$result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required()->join(', '))); $result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required()->join(', ')));
// This attribute has language tags
if ($this->lang_tags->count())
$result->put(__('language tags'),sprintf('%s: %d',__('This Attribute has Language Tags'),$this->lang_tags->count()));
return $result->toArray(); return $result->toArray();
} }
@ -329,4 +313,17 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
? $this->oc->intersect($this->schema->required_by_object_classes->keys())->sort() ? $this->oc->intersect($this->schema->required_by_object_classes->keys())->sort()
: collect(); : collect();
} }
/**
* If this attribute has RFC3866 Language Tags, this will enable those values to be captured
*
* @param string $tag
* @param array $value
* @return void
* @deprecated
*/
public function setLangTag(string $tag,array $value): void
{
$this->lang_tags->put($tag,$value);
}
} }

View File

@ -22,17 +22,11 @@ class Factory
public const map = [ public const map = [
'createtimestamp' => Internal\Timestamp::class, 'createtimestamp' => Internal\Timestamp::class,
'creatorsname' => Internal\DN::class, 'creatorsname' => Internal\DN::class,
'configcontext' => Schema\Generic::class,
'contextcsn' => Internal\CSN::class, 'contextcsn' => Internal\CSN::class,
'entrycsn' => Internal\CSN::class, 'entrycsn' => Internal\CSN::class,
'entrydn' => Internal\DN::class, 'entrydn' => Internal\DN::class,
'entryuuid' => Internal\UUID::class, 'entryuuid' => Internal\UUID::class,
'etag' => Internal\Etag::class, 'etag' => Internal\Etag::class,
'krblastfailedauth' => Attribute\NoAttrTags\Generic::class,
'krblastpwdchange' => Attribute\NoAttrTags\Generic::class,
'krblastsuccessfulauth' => Attribute\NoAttrTags\Generic::class,
'krbpasswordexpiration' => Attribute\NoAttrTags\Generic::class,
'krbloginfailedcount' => Attribute\NoAttrTags\Generic::class,
'krbprincipalkey' => KrbPrincipalKey::class, 'krbprincipalkey' => KrbPrincipalKey::class,
'krbticketflags' => KrbTicketFlags::class, 'krbticketflags' => KrbTicketFlags::class,
'gidnumber' => GidNumber::class, 'gidnumber' => GidNumber::class,
@ -40,8 +34,6 @@ class Factory
'jpegphoto' => Binary\JpegPhoto::class, 'jpegphoto' => Binary\JpegPhoto::class,
'modifytimestamp' => Internal\Timestamp::class, 'modifytimestamp' => Internal\Timestamp::class,
'modifiersname' => Internal\DN::class, 'modifiersname' => Internal\DN::class,
'monitorcontext' => Schema\Generic::class,
'namingcontexts' => Schema\Generic::class,
'numsubordinates' => Internal\NumSubordinates::class, 'numsubordinates' => Internal\NumSubordinates::class,
'objectclass' => ObjectClass::class, 'objectclass' => ObjectClass::class,
'pwdpolicysubentry' => Internal\PwdPolicySubentry::class, 'pwdpolicysubentry' => Internal\PwdPolicySubentry::class,
@ -50,7 +42,6 @@ class Factory
'supportedcontrol' => Schema\OID::class, 'supportedcontrol' => Schema\OID::class,
'supportedextension' => Schema\OID::class, 'supportedextension' => Schema\OID::class,
'supportedfeatures' => Schema\OID::class, 'supportedfeatures' => Schema\OID::class,
'supportedldapversion' => Schema\Generic::class,
'supportedsaslmechanisms' => Schema\Mechanisms::class, 'supportedsaslmechanisms' => Schema\Mechanisms::class,
'userpassword' => Password::class, 'userpassword' => Password::class,
]; ];

View File

@ -9,5 +9,4 @@ use App\Classes\LDAP\Attribute;
*/ */
final class GidNumber extends Attribute final class GidNumber extends Attribute
{ {
protected(set) bool $no_attr_tags = FALSE;
} }

View File

@ -12,7 +12,6 @@ use App\Classes\LDAP\Attribute;
abstract class Internal extends Attribute abstract class Internal extends Attribute
{ {
protected(set) bool $is_internal = TRUE; protected(set) bool $is_internal = TRUE;
protected(set) bool $no_attr_tags = TRUE;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
{ {

View File

@ -15,8 +15,6 @@ final class KrbPrincipalKey extends Attribute
{ {
use MD5Updates; use MD5Updates;
protected(set) bool $no_attr_tags = TRUE;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
{ {
return view('components.attribute.krbprincipalkey') return view('components.attribute.krbprincipalkey')

View File

@ -13,8 +13,6 @@ use Illuminate\Support\Collection;
*/ */
final class KrbTicketFlags extends Attribute final class KrbTicketFlags extends Attribute
{ {
protected(set) bool $no_attr_tags = TRUE;
private const DISALLOW_POSTDATED = 0x00000001; private const DISALLOW_POSTDATED = 0x00000001;
private const DISALLOW_FORWARDABLE = 0x00000002; private const DISALLOW_FORWARDABLE = 0x00000002;
private const DISALLOW_TGT_BASED = 0x00000004; private const DISALLOW_TGT_BASED = 0x00000004;

View File

@ -1,13 +0,0 @@
<?php
namespace App\Classes\LDAP\Attribute\NoAttrTags;
use App\Classes\LDAP\Attribute;
/**
* Represents an Attribute that doesnt have Lang Tags
*/
class Generic extends Attribute
{
protected(set) bool $no_attr_tags = TRUE;
}

View File

@ -12,8 +12,6 @@ use App\Classes\LDAP\Attribute;
*/ */
final class ObjectClass extends Attribute final class ObjectClass extends Attribute
{ {
protected(set) bool $no_attr_tags = TRUE;
// The schema ObjectClasses for this objectclass of a DN // The schema ObjectClasses for this objectclass of a DN
protected Collection $oc_schema; protected Collection $oc_schema;
@ -23,7 +21,7 @@ final class ObjectClass extends Attribute
* @param string $dn DN this attribute is used in * @param string $dn DN this attribute is used in
* @param string $name Name of the attribute * @param string $name Name of the attribute
* @param array $values Current Values * @param array $values Current Values
* @param array $oc The objectclasses that the DN of this attribute has (ignored for objectclasses) * @param array $oc The objectclasses that the DN of this attribute has
*/ */
public function __construct(string $dn,string $name,array $values,array $oc=[]) public function __construct(string $dn,string $name,array $values,array $oc=[])
{ {
@ -31,7 +29,7 @@ final class ObjectClass extends Attribute
$this->oc_schema = config('server') $this->oc_schema = config('server')
->schema('objectclasses') ->schema('objectclasses')
->filter(fn($item)=>$this->values_old->contains($item->name)); ->filter(fn($item)=>$this->values->merge($this->values_old)->unique()->contains($item->name));
} }
public function __get(string $key): mixed public function __get(string $key): mixed

View File

@ -15,9 +15,6 @@ use App\Traits\MD5Updates;
final class Password extends Attribute final class Password extends Attribute
{ {
use MD5Updates; use MD5Updates;
protected(set) bool $no_attr_tags = TRUE;
private const password_helpers = 'Classes/LDAP/Attribute/Password'; private const password_helpers = 'Classes/LDAP/Attribute/Password';
public const commands = 'App\\Classes\\LDAP\\Attribute\\Password\\'; public const commands = 'App\\Classes\\LDAP\\Attribute\\Password\\';

View File

@ -14,7 +14,6 @@ use App\Classes\LDAP\Attribute;
abstract class Schema extends Attribute abstract class Schema extends Attribute
{ {
protected bool $internal = TRUE; protected bool $internal = TRUE;
protected(set) bool $no_attr_tags = TRUE;
protected static function _get(string $filename,string $string,string $key): ?string protected static function _get(string $filename,string $string,string $key): ?string
{ {
@ -31,7 +30,7 @@ abstract class Schema extends Attribute
while (! feof($f)) { while (! feof($f)) {
$line = trim(fgets($f)); $line = trim(fgets($f));
if ((! $line) || preg_match('/^#/',$line)) if (! $line OR preg_match('/^#/',$line))
continue; continue;
$fields = explode(':',$line); $fields = explode(':',$line);
@ -42,15 +41,12 @@ abstract class Schema extends Attribute
'desc'=>Arr::get($fields,3,__('No description available, can you help with one?')), 'desc'=>Arr::get($fields,3,__('No description available, can you help with one?')),
]); ]);
} }
fclose($f); fclose($f);
return $result; return $result;
}); });
return Arr::get(($array ? $array->get($string) : []), return Arr::get(($array ? $array->get($string) : []),$key);
$key,
__('No description available, can you help with one?'));
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View

View File

@ -1,20 +0,0 @@
<?php
namespace App\Classes\LDAP\Attribute\Schema;
use Illuminate\Contracts\View\View;
use App\Classes\LDAP\Attribute\Schema;
/**
* Represents a Generic Schema Attribute
*/
class Generic extends Schema
{
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
{
// @note Schema attributes cannot be edited
return view('components.attribute.schema.generic')
->with('o',$this);
}
}

View File

@ -41,7 +41,6 @@ class LDIF extends Export
// Display Attributes // Display Attributes
foreach ($o->getObjects() as $ao) { foreach ($o->getObjects() as $ao) {
if ($ao->no_attr_tags)
foreach ($ao->values as $value) { foreach ($ao->values as $value) {
$result .= $this->multiLineDisplay( $result .= $this->multiLineDisplay(
Str::isAscii($value) Str::isAscii($value)
@ -49,17 +48,6 @@ class LDIF extends Export
: sprintf('%s:: %s',$ao->name,base64_encode($value)) : sprintf('%s:: %s',$ao->name,base64_encode($value))
,$this->br); ,$this->br);
} }
else
foreach ($ao->values as $tag => $tagvalues) {
foreach ($tagvalues as $value) {
$result .= $this->multiLineDisplay(
Str::isAscii($value)
? sprintf('%s: %s',$ao->name.($tag ? ';'.$tag : ''),$value)
: sprintf('%s:: %s',$ao->name.($tag ? ';'.$tag : ''),base64_encode($value))
,$this->br);
}
}
} }
} }

View File

@ -59,6 +59,8 @@ class LDIF extends Import
$base64encoded = FALSE; $base64encoded = FALSE;
$attribute = NULL; $attribute = NULL;
$value = ''; $value = '';
// Else its a blank line
} }
continue; continue;
@ -67,7 +69,7 @@ class LDIF extends Import
$m = []; $m = [];
preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m); preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m);
switch (Arr::get($m,1)) { switch ($x=Arr::get($m,1)) {
case 'changetype': case 'changetype':
if ($m[2] !== ':') if ($m[2] !== ':')
throw new GeneralException(sprintf('ChangeType cannot be base64 encoded set at [%d]. (line %d)',$version,$c)); throw new GeneralException(sprintf('ChangeType cannot be base64 encoded set at [%d]. (line %d)',$version,$c));
@ -131,6 +133,7 @@ class LDIF extends Import
// Start of a new attribute // Start of a new attribute
$base64encoded = ($m[2] === '::'); $base64encoded = ($m[2] === '::');
// @todo Need to parse attributes with ';' options
$attribute = $m[1]; $attribute = $m[1];
$value = $m[3]; $value = $m[3];
@ -157,7 +160,7 @@ class LDIF extends Import
} }
public function readEntry() { public function readEntry() {
static $haveVersion = FALSE; static $haveVersion = false;
if ($lines = $this->nextLines()) { if ($lines = $this->nextLines()) {
@ -176,7 +179,7 @@ class LDIF extends Import
} else } else
$changetype = 'add'; $changetype = 'add';
$this->template = new Template($this->server_id,NULL,NULL,$changetype); $this->template = new Template($this->server_id,null,null,$changetype);
switch ($changetype) { switch ($changetype) {
case 'add': case 'add':
@ -198,7 +201,7 @@ class LDIF extends Import
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines); return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
$this->template->setDN($dn); $this->template->setDN($dn);
$this->template->accept(FALSE,TRUE); $this->template->accept(false,true);
return $this->getModifyDetails($lines); return $this->getModifyDetails($lines);
@ -225,6 +228,6 @@ class LDIF extends Import
return $this->error(_('A valid dn line is required'),$lines); return $this->error(_('A valid dn line is required'),$lines);
} else } else
return FALSE; return false;
} }
} }

View File

@ -16,9 +16,6 @@ use App\Exceptions\InvalidUsage;
class Entry extends Model class Entry extends Model
{ {
private const TAG_CHARS = 'a-zA-Z0-9-';
private const TAG_CHARS_LANG = 'lang-['.self::TAG_CHARS.']';
// Our Attribute objects // Our Attribute objects
private Collection $objects; private Collection $objects;
/* @deprecated */ /* @deprecated */
@ -54,11 +51,7 @@ class Entry extends Model
public function getAttributes(): array public function getAttributes(): array
{ {
return $this->objects return $this->objects
->flatMap(fn($item)=> ->map(fn($item)=>$item->values)
($item->no_attr_tags)
? [strtolower($item->name)=>$item->values]
: $item->values
->flatMap(fn($v,$k)=>[strtolower($item->name.($k ? ';'.$k : ''))=>$v]))
->toArray(); ->toArray();
} }
@ -165,26 +158,15 @@ class Entry extends Model
if (! is_string($value)) if (! is_string($value))
throw new \Exception('value should be a string'); throw new \Exception('value should be a string');
$key = $this->normalizeAttributeKey(strtolower($key)); $key = $this->normalizeAttributeKey($key);
// If the attribute name has tags if (! config('server')->schema('attributetypes')->has($key))
$matches = []; throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$key));
if (preg_match(sprintf('/^([%s]+);+([%s;]+)/',self::TAG_CHARS,self::TAG_CHARS),$key,$matches)) {
$attribute = $matches[1];
$tags = $matches[2];
} else { $o = $this->objects->get($key) ?: Attribute\Factory::create($this->dn ?: '',$key,[]);
$attribute = $key; $o->addValue($value);
$tags = '';
}
if (! config('server')->schema('attributetypes')->has($attribute)) $this->objects->put($key,$o);
throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$attribute));
$o = $this->objects->get($attribute) ?: Attribute\Factory::create($this->dn ?: '',$attribute,[]);
$o->addValue($tags,$value);
$this->objects->put($attribute,$o);
} }
/** /**
@ -197,19 +179,11 @@ class Entry extends Model
$result = collect(); $result = collect();
$entry_oc = Arr::get($this->attributes,'objectclass',[]); $entry_oc = Arr::get($this->attributes,'objectclass',[]);
foreach ($this->attributes as $attrtag => $values) { foreach ($this->attributes as $attribute => $values) {
// If the attribute name has tags // If the attribute name has tags
$matches = []; $matches = [];
if (preg_match(sprintf('/^([%s]+);+([%s;]+)/',self::TAG_CHARS,self::TAG_CHARS),$attrtag,$matches)) { if (preg_match('/^([a-zA-Z]+)(;([a-zA-Z-;]+))+/',$attribute,$matches)) {
$attribute = $matches[1]; $attribute = $matches[1];
$tags = $matches[2];
} else {
$attribute = $attrtag;
$tags = NULL;
}
$orig = Arr::get($this->original,$attrtag,[]);
// If the attribute doesnt exist we'll create it // If the attribute doesnt exist we'll create it
$o = Arr::get( $o = Arr::get(
@ -218,14 +192,22 @@ class Entry extends Model
Factory::create( Factory::create(
$this->dn, $this->dn,
$attribute, $attribute,
[$tags=>$orig], Arr::get($this->original,$attribute,[]),
$entry_oc, $entry_oc,
)); ));
$o->setLangTag($matches[3],$values);
$o->values = $o->values->merge([$tags=>$values]); } else {
$o = Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),$entry_oc);
}
if (! $result->has($attribute)) {
// Store our new values to know if this attribute has changed
$o->values = collect($values);
$result->put($attribute,$o); $result->put($attribute,$o);
} }
}
$sort = collect(config('pla.attr_display_order',[]))->map(fn($item)=>strtolower($item)); $sort = collect(config('pla.attr_display_order',[]))->map(fn($item)=>strtolower($item));
@ -292,36 +274,6 @@ class Entry extends Model
->filter(fn($item)=>$item->is_internal); ->filter(fn($item)=>$item->is_internal);
} }
/**
* Identify the language tags (RFC 3866) used by this entry
*
* @return Collection
*/
public function getLangTags(): Collection
{
return $this->getObjects()
->filter(fn($item)=>! $item->no_attr_tags)
->map(fn($item)=>$item
->values
->keys()
->filter(fn($item)=>preg_match(sprintf('/%s+;?/',self::TAG_CHARS_LANG),$item)))
->filter(fn($item)=>$item->count());
}
/**
* Of all the items with lang tags, which ones have more than 1 lang tag
*
* @return Collection
*/
public function getLangMultiTags(): Collection
{
return $this->getLangTags()
->map(fn($item)=>$item->values()
->map(fn($item)=>explode(';',$item))
->filter(fn($item)=>count($item) > 1))
->filter(fn($item)=>$item->count());
}
/** /**
* Get an attribute as an object * Get an attribute as an object
* *
@ -347,29 +299,6 @@ class Entry extends Model
return $this->objects; return $this->objects;
} }
/**
* Find other attribute tags used by this entry
*
* @return Collection
*/
public function getOtherTags(): Collection
{
return $this->getObjects()
->filter(fn($item)=>! $item->no_attr_tags)
->map(fn($item)=>$item
->values
->keys()
->filter(fn($item)=>
$item && collect(explode(';',$item))->filter(
fn($item)=>
(! preg_match(sprintf('/^%s+$/',self::TAG_CHARS_LANG),$item))
&& (! preg_match('/^binary$/',$item))
)
->count())
)
->filter(fn($item)=>$item->count());
}
/** /**
* Return a list of attributes without any values * Return a list of attributes without any values
* *

View File

@ -1 +1 @@
v2.1.0-dev v2.0.2-rel

View File

@ -1,9 +0,0 @@
<div class="alert alert-danger p-0" style="font-size: .80em;">
<table class="table table-borderless table-danger p-0 m-0">
<tr>
<td class="align-top" style="width: 5%;"><i class="fas fa-fw fa-2x fa-exclamation-triangle"></i></td>
<td>Unable to display this attribute as it has attribute tags [<strong>{!! $tags->join('</strong>, <strong>') !!}</strong>].<br>
You can manage it with an LDIF import.</td>
</tr>
</table>
</div>

View File

@ -1,15 +1,7 @@
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o"> <x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $tag=>$tagvalues) @foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
<div class="row p-2 border rounded"> @if (($edit ?? FALSE) && ! $o->is_rdn)
<div class="col-2">
{{ $tag }}
</div>
<div class="col-10">
<div class="row">
<div class="col-12">
@foreach($tagvalues as $value)
@if(($edit ?? FALSE) && ! $o->is_rdn)
<div class="input-group has-validation"> <div class="input-group has-validation">
<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="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! ($new ?? FALSE))> <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="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! ($new ?? FALSE))>
@ -19,13 +11,9 @@
@endif @endif
</div> </div>
</div> </div>
@else @else
{{ $value }} {{ $value }}
@endif @endif
@endforeach @endforeach
</div>
</div>
</div>
</div>
@endforeach
</x-attribute.layout> </x-attribute.layout>

View File

@ -1,5 +1,5 @@
<!-- $o=Internal::class --> <!-- $o=Internal::class -->
@foreach(old($o->name_lc,$o->values) as $value) @foreach (old($o->name_lc,$o->values) as $value)
@if($loop->index)<br>@endif @if($loop->index)<br>@endif
{{ $value }} {{ $value }}
@endforeach @endforeach

View File

@ -1,5 +1,5 @@
<!-- $o=Internal\Timestamp::class --> <!-- $o=Internal\Timestamp::class -->
@foreach(old($o->name_lc,$o->values) as $value) @foreach (old($o->name_lc,$o->values) as $value)
@if($loop->index)<br>@endif @if($loop->index)<br>@endif
{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }} {{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}
@endforeach @endforeach

View File

@ -1,2 +1,8 @@
<!-- $o=NoAttrTags/Generic::class --> <!-- $o=Attribute::class -->
@include('components.form.disabled.datetime') <x-attribute.layout :edit="false" :new="false" :detail="true" :o="$o">
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
<div class="input-group">
<input type="text" @class(['form-control','mb-1']) name="{{ $o->name_lc }}[]" value="{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}" @disabled(true)>
</div>
@endforeach
</x-attribute.layout>

View File

@ -1,2 +1 @@
<!-- $o=NoAttrTags/Generic::class --> @include('components.attribute.krblastfailedauth')
@include('components.form.disabled.datetime')

View File

@ -1,2 +1 @@
<!-- $o=NoAttrTags/Generic::class --> @include('components.attribute.krblastfailedauth')
@include('components.form.disabled.datetime')

View File

@ -1,2 +1,8 @@
<!-- $o=NoAttrTags/Generic::class --> <!-- $o=Attribute::class -->
@include('components.form.disabled.input') <x-attribute.layout :edit="false" :new="false" :detail="true" :o="$o">
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
<div class="input-group">
<input type="text" @class(['form-control','mb-1']) name="{{ $o->name_lc }}[]" value="{{ $value }}" @disabled(true)>
</div>
@endforeach
</x-attribute.layout>

View File

@ -1,2 +1 @@
<!-- $o=NoAttrTags/Generic::class --> @include('components.attribute.krblastfailedauth')
@include('components.form.disabled.datetime')

View File

@ -1,5 +1,5 @@
<!-- @todo We are not handling redirect backs yet with updated passwords --> <!-- @todo We are not handling redirect backs yet with updated passwords -->
<!-- $o=KrbPrincipleKey::class --> <!-- $o=Password::class -->
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o"> <x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
@foreach($o->values_old as $value) @foreach($o->values_old as $value)
@if($edit) @if($edit)

View File

@ -1,7 +1,7 @@
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@foreach(old($o->name_lc,$o->values) as $value) @foreach(old($o->name_lc,$o->values) as $value)
@if($edit) @if ($edit)
<x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :loop="$loop" :value="$value"/> <x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :loop="$loop" :value="$value"/>
@else @else
{{ $value }} {{ $value }}

View File

@ -1 +0,0 @@
{!! $o->values->join('<br>') !!}

View File

@ -1,8 +0,0 @@
<!-- $o=Attribute::class -->
<x-attribute.layout :edit="false" :new="false" :detail="true" :o="$o">
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
<div class="input-group">
<input type="text" @class(['form-control','mb-1']) name="{{ $o->name_lc }}[]" value="{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}" @disabled(true)>
</div>
@endforeach
</x-attribute.layout>

View File

@ -1,8 +0,0 @@
<!-- $o=Attribute::class -->
<x-attribute.layout :edit="false" :new="false" :detail="true" :o="$o">
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
<div class="input-group">
<input type="text" @class(['form-control','mb-1']) name="{{ $o->name_lc }}[]" value="{{ $value }}" @disabled(true)>
</div>
@endforeach
</x-attribute.layout>

View File

@ -26,12 +26,6 @@
<x-attribute :o="$o->getObject('entryuuid')" :na="__('Unknown')"/> <x-attribute :o="$o->getObject('entryuuid')" :na="__('Unknown')"/>
</th> </th>
</tr> </tr>
@if(($x=$o->getLangTags())->count())
<tr class="mt-1">
<td class="p-0 pe-2">Tags</td>
<th class="p-0">{{ $x->flatMap(fn($item)=>$item->values())->unique()->join(', ') }}</th>
</tr>
@endif
</table> </table>
</td> </td>
</tr> </tr>

View File

@ -38,24 +38,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row">
<div class="col">
@if(($x=$o->getOtherTags())->count())
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
This entry has [<strong>{!! $x->flatten()->join('</strong>, <strong>') !!}</strong>] tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those tags with an LDIF import.
</div>
@elseif(($x=$o->getLangMultiTags())->count())
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
This entry has multi-language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
</div>
@elseif(($x=$o->getLangTags())->count())
<div class="ms-4 mt-4 alert alert-warning p-2" style="max-width: 30em; font-size: 0.80em;">
This entry has language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA yet. You can though manage those lang tags with an LDIF import.
</div>
@endif
</div>
</div>
@endsection @endsection
@section('main-content') @section('main-content')