Store our DN and objectclasses in Attribute::class entries, so that we can dynamically calculate is_rdn and required objects (to be implemented)
This commit is contained in:
parent
d3fc9c135f
commit
d326d3c308
@ -34,10 +34,14 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
// The schema's representation of this attribute
|
||||
protected(set) ?AttributeType $schema;
|
||||
|
||||
// The DN this object is in
|
||||
protected(set) string $dn;
|
||||
// The old values for this attribute - helps with isDirty() to determine if there is an update pending
|
||||
protected(set) Collection $values_old;
|
||||
// Current Values
|
||||
public Collection $values;
|
||||
// The other object classes of the entry that include this attribute
|
||||
protected(set) Collection $oc;
|
||||
|
||||
/*
|
||||
# Has the attribute been modified
|
||||
@ -90,12 +94,22 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
|
||||
protected $postvalue = array();
|
||||
*/
|
||||
|
||||
public function __construct(string $name,array $values)
|
||||
/**
|
||||
* Create an Attribute
|
||||
*
|
||||
* @param string $dn DN this attribute is used in
|
||||
* @param string $name Name of the attribute
|
||||
* @param array $values Current Values
|
||||
* @param array $oc ObjectClasses that the DN has, that includes this attribute
|
||||
*/
|
||||
public function __construct(string $dn,string $name,array $values,array $oc=[])
|
||||
{
|
||||
$this->dn = $dn;
|
||||
$this->name = $name;
|
||||
$this->values_old = collect($values);
|
||||
|
||||
$this->values = collect();
|
||||
$this->oc = collect($oc);
|
||||
$this->lang_tags = collect();
|
||||
|
||||
$this->schema = (new Server)
|
||||
|
@ -49,15 +49,17 @@ class Factory
|
||||
/**
|
||||
* Create the new Object for an attribute
|
||||
*
|
||||
* @param string $dn
|
||||
* @param string $attribute
|
||||
* @param array $values
|
||||
* @param array $oc
|
||||
* @return Attribute
|
||||
*/
|
||||
public static function create(string $attribute,array $values): Attribute
|
||||
public static function create(string $dn,string $attribute,array $values,array $oc=[]): Attribute
|
||||
{
|
||||
$class = Arr::get(self::map,strtolower($attribute),Attribute::class);
|
||||
Log::debug(sprintf('%s:Creating LDAP Attribute [%s] as [%s]',static::LOGKEY,$attribute,$class));
|
||||
|
||||
return new $class($attribute,$values);
|
||||
return new $class($dn,$attribute,$values,$oc);
|
||||
}
|
||||
}
|
@ -15,9 +15,17 @@ final class ObjectClass extends Attribute
|
||||
// The schema ObjectClasses for this objectclass of a DN
|
||||
protected Collection $oc_schema;
|
||||
|
||||
public function __construct(string $name,array $values)
|
||||
/**
|
||||
* Create an ObjectClass Attribute
|
||||
*
|
||||
* @param string $dn DN this attribute is used in
|
||||
* @param string $name Name of the attribute
|
||||
* @param array $values Current Values
|
||||
* @param array $oc ObjectClasses that the DN has, that includes this attribute
|
||||
*/
|
||||
public function __construct(string $dn,string $name,array $values,array $oc=[])
|
||||
{
|
||||
parent::__construct($name,$values);
|
||||
parent::__construct($dn,$name,$values,$oc);
|
||||
|
||||
$this->oc_schema = config('server')
|
||||
->schema('objectclasses')
|
||||
|
@ -3,9 +3,9 @@
|
||||
namespace App\Classes\LDAP;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use LdapRecord\LdapRecordException;
|
||||
|
||||
use App\Exceptions\Import\GeneralException;
|
||||
use App\Exceptions\Import\ObjectExistsException;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
@ -48,7 +48,6 @@ abstract class Import
|
||||
* @param int $action
|
||||
* @return Collection
|
||||
* @throws GeneralException
|
||||
* @throws ObjectExistsException
|
||||
*/
|
||||
final protected function commit(Entry $o,int $action): Collection
|
||||
{
|
||||
@ -57,15 +56,24 @@ abstract class Import
|
||||
try {
|
||||
$o->save();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return collect([
|
||||
'dn'=>$o->getDN(),
|
||||
'result'=>sprintf('%d: %s (%s)',
|
||||
($x=$e->getDetailedError())->getErrorCode(),
|
||||
$x->getErrorMessage(),
|
||||
$x->getDiagnosticMessage(),
|
||||
)
|
||||
]);
|
||||
} catch (LdapRecordException $e) {
|
||||
if ($e->getDetailedError())
|
||||
return collect([
|
||||
'dn'=>$o->getDN(),
|
||||
'result'=>sprintf('%d: %s (%s)',
|
||||
($x=$e->getDetailedError())->getErrorCode(),
|
||||
$x->getErrorMessage(),
|
||||
$x->getDiagnosticMessage(),
|
||||
)
|
||||
]);
|
||||
else
|
||||
return collect([
|
||||
'dn'=>$o->getDN(),
|
||||
'result'=>sprintf('%d: %s',
|
||||
$e->getCode(),
|
||||
$e->getMessage(),
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
return collect(['dn'=>$o->getDN(),'result'=>__('Created')]);
|
||||
|
@ -46,7 +46,7 @@ class LDIF extends Import
|
||||
if (! $line) {
|
||||
if (! is_null($o)) {
|
||||
// Add the last attribute;
|
||||
$o->addAttribute($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
$o->addAttributeItem($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
|
||||
Log::debug(sprintf('%s: Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
||||
|
||||
@ -125,7 +125,7 @@ class LDIF extends Import
|
||||
Log::debug(sprintf('%s: Adding Attribute [%s] value [%s] (%d)',self::LOGKEY,$attribute,$value,$c));
|
||||
|
||||
if ($value)
|
||||
$o->addAttribute($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
$o->addAttributeItem($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
else
|
||||
throw new GeneralException(sprintf('Attribute has no value [%s] (line %d)',$attribute,$c));
|
||||
}
|
||||
@ -147,7 +147,7 @@ class LDIF extends Import
|
||||
// We may still have a pending action
|
||||
if ($action) {
|
||||
// Add the last attribute;
|
||||
$o->addAttribute($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
$o->addAttributeItem($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
|
||||
Log::debug(sprintf('%s: Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
||||
|
||||
|
@ -69,7 +69,7 @@ class HomeController extends Controller
|
||||
$o->objectclass = $x;
|
||||
|
||||
foreach($o->getAvailableAttributes()->filter(fn($item)=>$item->required) as $ao)
|
||||
$o->addAttribute($ao,'');
|
||||
$o->{$ao->name} = '';
|
||||
|
||||
$o->setRDNBase($key['dn']);
|
||||
}
|
||||
@ -96,14 +96,14 @@ class HomeController extends Controller
|
||||
$xx = new \stdClass;
|
||||
$xx->index = 0;
|
||||
|
||||
$x = $request->noheader
|
||||
$dn = $request->dn ? Crypt::decrypt($request->dn) : '';
|
||||
|
||||
return $request->noheader
|
||||
? view(sprintf('components.attribute.widget.%s',$id))
|
||||
->with('o',Factory::create($id,[]))
|
||||
->with('o',Factory::create($dn,$id,[],$request->oc ?: []))
|
||||
->with('value',$request->value)
|
||||
->with('loop',$xx)
|
||||
: (new AttributeType(Factory::create($id,[]),TRUE,collect($request->oc ?: [])))->render();
|
||||
|
||||
return $x;
|
||||
: (new AttributeType(Factory::create($dn,$id,[],$request->oc ?: []),TRUE,collect($request->oc ?: [])))->render();
|
||||
}
|
||||
|
||||
public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse
|
||||
@ -214,7 +214,8 @@ class HomeController extends Controller
|
||||
*/
|
||||
public function entry_objectclass_add(Request $request): Collection
|
||||
{
|
||||
$oc = Factory::create('objectclass',$request->oc);
|
||||
$dn = $request->key ? Crypt::decryptString($request->dn) : '';
|
||||
$oc = Factory::create($dn,'objectclass',$request->oc);
|
||||
|
||||
$ocs = $oc
|
||||
->structural
|
||||
|
@ -82,22 +82,22 @@ class Entry extends Model
|
||||
|
||||
/**
|
||||
* As attribute values are updated, or new ones created, we need to mirror that
|
||||
* into our $objects
|
||||
* into our $objects. This is called when we $o->key = $value
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute(string $key, mixed $value): static
|
||||
public function setAttribute(string $key,mixed $value): static
|
||||
{
|
||||
parent::setAttribute($key,$value);
|
||||
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
|
||||
if ((! $this->objects->get($key)) && $value)
|
||||
$this->objects->put($key,Factory::create($key,[]));
|
||||
$o = $this->objects->get($key) ?: Factory::create($this->dn ?: '',$key,[],Arr::get($this->attributes,'objectclass',[]));
|
||||
$o->values = collect($this->attributes[$key]);
|
||||
|
||||
$this->objects->get($key)->values = collect($this->attributes[$key]);
|
||||
$this->objects->put($key,$o);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -140,7 +140,18 @@ class Entry extends Model
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function addAttribute(string $key,mixed $value): void
|
||||
/**
|
||||
* Add an attribute to this entry, if the attribute already exists, then we'll add the value to the existing item.
|
||||
*
|
||||
* This is primarily used by LDIF imports, where attributes have multiple entries over multiple lines
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws AttributeException
|
||||
* @note Attributes added this way dont have objectclass information, and the Model::attributes are not populated
|
||||
*/
|
||||
public function addAttributeItem(string $key,mixed $value): void
|
||||
{
|
||||
// While $value is mixed, it can only be a string
|
||||
if (! is_string($value))
|
||||
@ -151,15 +162,10 @@ class Entry extends Model
|
||||
if (! config('server')->schema('attributetypes')->has($key))
|
||||
throw new AttributeException(sprintf('Schema doesnt have attribute [%s]',$key));
|
||||
|
||||
if ($x=$this->objects->get($key)) {
|
||||
$x->addValue($value);
|
||||
$o = $this->objects->get($key) ?: Attribute\Factory::create($this->dn ?: '',$key,[]);
|
||||
$o->addValue($value);
|
||||
|
||||
} else {
|
||||
$o = Attribute\Factory::create($key,[]);
|
||||
$o->values = collect(Arr::wrap($value));
|
||||
|
||||
$this->objects->put($key,$o);
|
||||
}
|
||||
$this->objects->put($key,$o);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,11 +184,11 @@ class Entry extends Model
|
||||
$attribute = $matches[1];
|
||||
|
||||
// If the attribute doesnt exist we'll create it
|
||||
$o = Arr::get($result,$attribute,Factory::create($attribute,Arr::get($this->original,$attribute,[])));
|
||||
$o = Arr::get($result,$attribute,Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),Arr::get($this->original,'objectclass',[])));
|
||||
$o->setLangTag($matches[3],$values);
|
||||
|
||||
} else {
|
||||
$o = Factory::create($attribute,Arr::get($this->original,$attribute,[]));
|
||||
$o = Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),Arr::get($this->original,'objectclass',[]));
|
||||
}
|
||||
|
||||
if (! $result->has($attribute)) {
|
||||
@ -299,7 +305,7 @@ class Entry extends Model
|
||||
|
||||
private function getRDNObject(): Attribute\RDN
|
||||
{
|
||||
$o = new Attribute\RDN('dn',['']);
|
||||
$o = new Attribute\RDN('','dn',['']);
|
||||
// @todo for an existing object, return the base.
|
||||
$o->setBase($this->rdnbase);
|
||||
$o->setAttributes($this->getAvailableAttributes()->filter(fn($item)=>$item->required));
|
||||
|
Loading…
x
Reference in New Issue
Block a user