Update AttributeTypes/LDAPSyntaxes/MatchingRules for performance and process improvements
This commit is contained in:
@@ -7,304 +7,74 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Exceptions\InvalidUsage;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Represents an LDAP AttributeType
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class AttributeType extends Base {
|
||||
// The attribute from which this attribute inherits (if any)
|
||||
private ?string $sup_attribute = NULL;
|
||||
final class AttributeType extends Base
|
||||
{
|
||||
private const LOGKEY = 'SAT';
|
||||
|
||||
// Array of AttributeTypes which inherit from this one
|
||||
private Collection $children;
|
||||
// An array of AttributeTypes which inherit from this one
|
||||
private(set) Collection $children;
|
||||
|
||||
// The equality rule used
|
||||
private ?string $equality = NULL;
|
||||
|
||||
// The ordering of the attributeType
|
||||
private ?string $ordering = NULL;
|
||||
|
||||
// Supports substring matching?
|
||||
private ?string $sub_str_rule = NULL;
|
||||
|
||||
// The full syntax string, ie 1.2.3.4{16}
|
||||
private ?string $syntax = NULL;
|
||||
private ?string $syntax_oid = NULL;
|
||||
|
||||
// boolean: is single valued only?
|
||||
private bool $is_single_value = FALSE;
|
||||
|
||||
// boolean: is collective?
|
||||
private bool $is_collective = FALSE;
|
||||
|
||||
// boolean: can use modify?
|
||||
private bool $is_no_user_modification = FALSE;
|
||||
|
||||
// The usage string set by the LDAP schema
|
||||
private ?string $usage = NULL;
|
||||
|
||||
// An array of alias attribute names, strings
|
||||
private Collection $aliases;
|
||||
|
||||
// The max number of characters this attribute can be
|
||||
private ?int $max_length = NULL;
|
||||
|
||||
// A string description of the syntax type (taken from the LDAPSyntaxes)
|
||||
/**
|
||||
* @deprecated - reference syntaxes directly if possible
|
||||
* @var string
|
||||
*/
|
||||
private ?string $type = NULL;
|
||||
|
||||
// An array of objectClasses which use this attributeType (must be set by caller)
|
||||
private Collection $used_in_object_classes;
|
||||
|
||||
// A list of object class names that require this attribute type.
|
||||
private Collection $required_by_object_classes;
|
||||
private(set) ?string $equality = NULL;
|
||||
|
||||
// This attribute has been forced a MAY attribute by the configuration.
|
||||
private bool $forced_as_may = FALSE;
|
||||
private(set) bool $forced_as_may = FALSE;
|
||||
|
||||
/**
|
||||
* Creates a new AttributeType object from a raw LDAP AttributeType string.
|
||||
*
|
||||
* eg: ( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
|
||||
*/
|
||||
public function __construct(string $line) {
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('Parsing AttributeType [%s]',$line));
|
||||
// boolean: is collective?
|
||||
private(set) bool $is_collective = FALSE;
|
||||
|
||||
parent::__construct($line);
|
||||
// Is this a must attribute
|
||||
private(set) bool $is_must = FALSE;
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
// boolean: can use modify?
|
||||
private(set) bool $is_no_user_modification = FALSE;
|
||||
|
||||
// Init
|
||||
$this->children = collect();
|
||||
$this->aliases = collect();
|
||||
$this->used_in_object_classes = collect();
|
||||
$this->required_by_object_classes = collect();
|
||||
// boolean: is single valued only?
|
||||
private(set) bool $is_single_value = FALSE;
|
||||
|
||||
for ($i=0; $i < count($strings); $i++) {
|
||||
switch ($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
// The max number of characters this attribute can be
|
||||
private(set) ?int $max_length = NULL;
|
||||
|
||||
case 'NAME':
|
||||
// @note Some schema's return a (' instead of a ( '
|
||||
if ($strings[$i+1] != '(' && ! preg_match('/^\(/',$strings[$i+1])) {
|
||||
do {
|
||||
$this->name .= ($this->name ? ' ' : '').$strings[++$i];
|
||||
// An array of names (including aliases) that this attribute is known by
|
||||
private(set) Collection $names;
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
// The ordering of the attributeType
|
||||
private(set) ?string $ordering = NULL;
|
||||
|
||||
// This attribute has no aliases
|
||||
//$this->aliases = collect();
|
||||
// A list of object class names that require this attribute type.
|
||||
private(set) Collection $required_by_object_classes;
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
// Which objectclass is defining this attribute for an Entry
|
||||
public ?string $source = NULL;
|
||||
|
||||
do {
|
||||
// In case we came here becaues of a ('
|
||||
if (preg_match('/^\(/',$strings[$i]))
|
||||
$strings[$i] = preg_replace('/^\(/','',$strings[$i]);
|
||||
else
|
||||
$i++;
|
||||
// Supports substring matching?
|
||||
private(set) ?string $sub_str_rule = NULL;
|
||||
|
||||
$this->name .= ($this->name ? ' ' : '').$strings[++$i];
|
||||
// The attribute from which this attribute inherits (if any)
|
||||
private(set) ?string $sup_attribute = NULL;
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
// The full syntax string, ie 1.2.3.4{16}
|
||||
private(set) ?string $syntax = NULL;
|
||||
private(set) ?string $syntax_oid = NULL;
|
||||
|
||||
// Add alias names for this attribute
|
||||
while ($strings[++$i] != ')') {
|
||||
$alias = $strings[$i];
|
||||
$alias = preg_replace("/^\'(.*)\'$/",'$1',$alias);
|
||||
$this->addAlias($alias);
|
||||
}
|
||||
}
|
||||
// The usage string set by the LDAP schema
|
||||
private(set) ?string $usage = NULL;
|
||||
|
||||
$this->name = preg_replace("/^\'(.*)\'$/",'$1',$this->name);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case NAME returned (%s)',$this->name),['aliases'=>$this->aliases]);
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= ($this->description ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'OBSOLETE':
|
||||
$this->is_obsolete = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case OBSOLETE returned (%s)',$this->is_obsolete));
|
||||
break;
|
||||
|
||||
case 'SUP':
|
||||
$i++;
|
||||
$this->sup_attribute = preg_replace("/^\'(.*)\'$/",'$1',$strings[$i]);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case SUP returned (%s)',$this->sup_attribute));
|
||||
break;
|
||||
|
||||
case 'EQUALITY':
|
||||
$this->equality = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case EQUALITY returned (%s)',$this->equality));
|
||||
break;
|
||||
|
||||
case 'ORDERING':
|
||||
$this->ordering = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case ORDERING returned (%s)',$this->ordering));
|
||||
break;
|
||||
|
||||
case 'SUBSTR':
|
||||
$this->sub_str_rule = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case SUBSTR returned (%s)',$this->sub_str_rule));
|
||||
break;
|
||||
|
||||
case 'SYNTAX':
|
||||
$this->syntax = $strings[++$i];
|
||||
$this->syntax_oid = preg_replace('/{\d+}$/','',$this->syntax);
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('/ Evaluating SYNTAX returned (%s) [%s]',$this->syntax,$this->syntax_oid));
|
||||
|
||||
// Does this SYNTAX string specify a max length (ie, 1.2.3.4{16})
|
||||
$m = [];
|
||||
if (preg_match('/{(\d+)}$/',$this->syntax,$m))
|
||||
$this->max_length = $m[1];
|
||||
else
|
||||
$this->max_length = NULL;
|
||||
|
||||
if ($i < count($strings) - 1 && $strings[$i+1] == '{')
|
||||
do {
|
||||
$this->name .= ' '.$strings[++$i];
|
||||
} while ($strings[$i] != '}');
|
||||
|
||||
$this->syntax = preg_replace("/^\'(.*)\'$/",'$1',$this->syntax);
|
||||
$this->syntax_oid = preg_replace("/^\'(.*)\'$/",'$1',$this->syntax_oid);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case SYNTAX returned (%s) [%s] {%d}',$this->syntax,$this->syntax_oid,$this->max_length));
|
||||
break;
|
||||
|
||||
case 'SINGLE-VALUE':
|
||||
$this->is_single_value = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case SINGLE-VALUE returned (%s)',$this->is_single_value));
|
||||
break;
|
||||
|
||||
case 'COLLECTIVE':
|
||||
$this->is_collective = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case COLLECTIVE returned (%s)',$this->is_collective));
|
||||
break;
|
||||
|
||||
case 'NO-USER-MODIFICATION':
|
||||
$this->is_no_user_modification = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case NO-USER-MODIFICATION returned (%s)',$this->is_no_user_modification));
|
||||
break;
|
||||
|
||||
case 'USAGE':
|
||||
$this->usage = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case USAGE returned (%s)',$this->usage));
|
||||
break;
|
||||
|
||||
// @note currently not captured
|
||||
case 'X-ORDERED':
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::error(sprintf('- Case X-ORDERED returned (%s)',$strings[++$i]));
|
||||
break;
|
||||
|
||||
// @note currently not captured
|
||||
case 'X-ORIGIN':
|
||||
$value = '';
|
||||
|
||||
do {
|
||||
$value .= ($value ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::error(sprintf('- Case X-ORIGIN returned (%s)',$value));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
// When we clone, we need to break the reference too
|
||||
$this->aliases = clone $this->aliases;
|
||||
}
|
||||
// An array of objectClasses which use this attributeType (must be set by caller)
|
||||
private(set) Collection $used_in_object_classes;
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'aliases': return $this->aliases;
|
||||
case 'children': return $this->children;
|
||||
case 'forced_as_may': return $this->forced_as_may;
|
||||
case 'is_collective': return $this->is_collective;
|
||||
case 'is_editable': return ! $this->is_no_user_modification;
|
||||
case 'is_no_user_modification': return $this->is_no_user_modification;
|
||||
case 'is_single_value': return $this->is_single_value;
|
||||
case 'equality': return $this->equality;
|
||||
case 'max_length': return $this->max_length;
|
||||
case 'ordering': return $this->ordering;
|
||||
case 'required_by_object_classes': return $this->required_by_object_classes;
|
||||
case 'sub_str_rule': return $this->sub_str_rule;
|
||||
case 'sup_attribute': return $this->sup_attribute;
|
||||
case 'syntax': return $this->syntax;
|
||||
case 'syntax_oid': return $this->syntax_oid;
|
||||
case 'type': return $this->type;
|
||||
case 'usage': return $this->usage;
|
||||
case 'used_in_object_classes': return $this->used_in_object_classes;
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute name to the alias array.
|
||||
*
|
||||
* @param string $alias The name of a new attribute to add to this attribute's list of aliases.
|
||||
*/
|
||||
public function addAlias(string $alias): void
|
||||
{
|
||||
$this->aliases->push($alias);
|
||||
return match ($key) {
|
||||
'names_lc' => $this->names->map('strtolower'),
|
||||
default => parent::__get($key)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,7 +85,8 @@ final class AttributeType extends Base {
|
||||
*/
|
||||
public function addChild(string $child): void
|
||||
{
|
||||
$this->children->push($child);
|
||||
$this->children
|
||||
->push($child);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,144 +117,10 @@ final class AttributeType extends Base {
|
||||
|
||||
private function factory(): Attribute
|
||||
{
|
||||
return Attribute\Factory::create(dn:'',attribute:$this->name,values:[]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of attributes that are an alias for this attribute (if any).
|
||||
*
|
||||
* @return Collection An array of names of attributes which alias this attribute or
|
||||
* an empty array if no attribute aliases this object.
|
||||
* @deprecated use class->aliases
|
||||
*/
|
||||
public function getAliases(): Collection
|
||||
{
|
||||
return $this->aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's equality string
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->equality
|
||||
*/
|
||||
public function getEquality()
|
||||
{
|
||||
return $this->equality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this attribute is collective.
|
||||
*
|
||||
* @return boolean Returns TRUE if this attribute is collective and FALSE otherwise.
|
||||
* @deprecated use $this->is_collective
|
||||
*/
|
||||
public function getIsCollective(): bool
|
||||
{
|
||||
return $this->is_collective;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this attribute is not modifiable by users.
|
||||
*
|
||||
* @return boolean Returns TRUE if this attribute is not modifiable by users.
|
||||
* @deprecated use $this->is_no_user_modification
|
||||
*/
|
||||
public function getIsNoUserModification(): bool
|
||||
{
|
||||
return $this->is_no_user_modification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this attribute is single-valued. If this attribute only supports single values, TRUE
|
||||
* is returned. If this attribute supports multiple values, FALSE is returned.
|
||||
*
|
||||
* @return boolean Returns TRUE if this attribute is single-valued or FALSE otherwise.
|
||||
* @deprecated use class->is_single_value
|
||||
*/
|
||||
public function getIsSingleValue(): bool
|
||||
{
|
||||
return $this->is_single_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's the maximum length. If no maximum is defined by the LDAP server, NULL is returned.
|
||||
*
|
||||
* @return int The maximum length (in characters) of this attribute or NULL if no maximum is specified.
|
||||
* @deprecated use $this->max_length;
|
||||
*/
|
||||
public function getMaxLength()
|
||||
{
|
||||
return $this->max_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's ordering specification.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->ordering
|
||||
*/
|
||||
public function getOrdering(): string
|
||||
{
|
||||
return $this->ordering;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's substring matching specification
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->sub_str_rule;
|
||||
*/
|
||||
public function getSubstr() {
|
||||
return $this->sub_str_rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's parent attribute (if any). If this attribute does not
|
||||
* inherit from another attribute, NULL is returned.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $class->sup_attribute directly
|
||||
*/
|
||||
public function getSupAttribute() {
|
||||
return $this->sup_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's syntax OID. Differs from getSyntaxString() in that this
|
||||
* function only returns the actual OID with any length specification removed.
|
||||
* Ie, if the syntax string is "1.2.3.4{16}", this function only retruns
|
||||
* "1.2.3.4".
|
||||
*
|
||||
* @return string The syntax OID string.
|
||||
* @deprecated use $this->syntax_oid;
|
||||
*/
|
||||
public function getSyntaxOID()
|
||||
{
|
||||
return $this->syntax_oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's usage string as defined by the LDAP server
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->usage
|
||||
*/
|
||||
public function getUsage()
|
||||
{
|
||||
return $this->usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of "used in" objectClasses, that is the list of objectClasses
|
||||
* which provide this attribute.
|
||||
*
|
||||
* @return Collection An array of names of objectclasses (strings) which provide this attribute
|
||||
* @deprecated use $this->used_in_object_classes
|
||||
*/
|
||||
public function getUsedInObjectClasses(): Collection
|
||||
{
|
||||
return $this->used_in_object_classes;
|
||||
return Attribute\Factory::create(
|
||||
dn:'',
|
||||
attribute:$this->name,
|
||||
values:[]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -492,58 +129,162 @@ final class AttributeType extends Base {
|
||||
* @param Collection $ocs
|
||||
* @return Collection
|
||||
*/
|
||||
public function heirachy(Collection $ocs): Collection
|
||||
private function heirachy(Collection $ocs): Collection
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
foreach ($ocs as $oc) {
|
||||
$schema = config('server')
|
||||
->schema('objectclasses',$oc)
|
||||
->getParents(TRUE)
|
||||
->pluck('name');
|
||||
$item = config('server')
|
||||
->schema('objectclasses',$oc);
|
||||
|
||||
$result = $result->merge($schema)->push($oc);
|
||||
$result = $result
|
||||
->merge($item
|
||||
->getParents(TRUE)
|
||||
->pluck('oid'))
|
||||
->push($item->oid);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @deprecated use $this->forced_as_may
|
||||
*/
|
||||
public function isForceMay(): bool
|
||||
{
|
||||
return $this->forced_as_may;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an attribute name from this attribute's alias array.
|
||||
* Creates a new AttributeType object from a raw LDAP AttributeType string.
|
||||
*
|
||||
* @param string $alias The name of the attribute to remove.
|
||||
* eg: ( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
|
||||
*/
|
||||
public function removeAlias(string $alias): void
|
||||
protected function parse(string $line): void
|
||||
{
|
||||
if (($x=$this->aliases->search($alias)) !== FALSE)
|
||||
$this->aliases->forget($x);
|
||||
Log::debug(sprintf('%s:Parsing AttributeType [%s]',self::LOGKEY,$line));
|
||||
|
||||
// Init
|
||||
$this->names = collect();
|
||||
$this->children = collect();
|
||||
$this->used_in_object_classes = collect();
|
||||
$this->required_by_object_classes = collect();
|
||||
|
||||
parent::parse($line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's list of aliases.
|
||||
*
|
||||
* @param Collection $aliases The array of alias names (strings)
|
||||
* @deprecated use $this->aliases =
|
||||
*/
|
||||
public function setAliases(Collection $aliases): void
|
||||
protected function parse_chunk(array $strings,int &$i): void
|
||||
{
|
||||
$this->aliases = $aliases;
|
||||
}
|
||||
switch ($strings[$i]) {
|
||||
case 'NAME':
|
||||
$name = '';
|
||||
|
||||
/**
|
||||
* This function will mark this attribute as a forced MAY attribute
|
||||
*/
|
||||
public function setForceMay() {
|
||||
$this->forced_as_may = TRUE;
|
||||
// @note Some schema's return a (' instead of a ( '
|
||||
// @note This attribute format has no aliases
|
||||
if ($strings[$i+1] !== '(' && ! preg_match('/^\(/',$strings[$i+1])) {
|
||||
do {
|
||||
$name .= ($name ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
// In case we came here because of a ('
|
||||
if (preg_match('/^\(/',$strings[$i]))
|
||||
$strings[$i] = preg_replace('/^\(/','',$strings[$i]);
|
||||
else
|
||||
$i++;
|
||||
|
||||
$name .= ($name ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
// Add alias names for this attribute
|
||||
while ($strings[++$i] !== ')') {
|
||||
$alias = preg_replace("/^\'(.*)\'$/",'$1',$strings[$i]);
|
||||
$this->names->push($alias);
|
||||
}
|
||||
}
|
||||
|
||||
$this->names = $this->names->push(preg_replace("/^\'(.*)\'$/",'$1',$name))->sort();
|
||||
$this->forced_as_may = $this->names_lc
|
||||
->intersect(array_map('strtolower',config('pla.force_may',[])))
|
||||
->count() > 0;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case NAME returned (%s)',self::LOGKEY,$this->name),['names'=>$this->names]);
|
||||
break;
|
||||
|
||||
case 'SUP':
|
||||
$this->sup_attribute = preg_replace("/^\'(.*)\'$/",'$1',$strings[++$i]);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case SUP returned (%s)',self::LOGKEY,$this->sup_attribute));
|
||||
break;
|
||||
|
||||
case 'EQUALITY':
|
||||
$this->equality = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case EQUALITY returned (%s)',self::LOGKEY,$this->equality));
|
||||
break;
|
||||
|
||||
case 'ORDERING':
|
||||
$this->ordering = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case ORDERING returned (%s)',self::LOGKEY,$this->ordering));
|
||||
break;
|
||||
|
||||
case 'SUBSTR':
|
||||
$this->sub_str_rule = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case SUBSTR returned (%s)',self::LOGKEY,$this->sub_str_rule));
|
||||
break;
|
||||
|
||||
case 'SYNTAX':
|
||||
$this->syntax = preg_replace("/^\'(.*)\'$/",'$1',$strings[++$i]);
|
||||
$this->syntax_oid = preg_replace("/^\'?(.*){\d+}\'?$/",'$1',$this->syntax);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:/ Evaluating SYNTAX returned (%s) [%s]',self::LOGKEY,$this->syntax,$this->syntax_oid));
|
||||
|
||||
// Does this SYNTAX string specify a max length (ie, 1.2.3.4{16})
|
||||
$m = [];
|
||||
$this->max_length = preg_match('/{(\d+)}$/',$this->syntax,$m)
|
||||
? $m[1]
|
||||
: NULL;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case SYNTAX returned (%s) [%s] {%d}',self::LOGKEY,$this->syntax,$this->syntax_oid,$this->max_length));
|
||||
break;
|
||||
|
||||
case 'SINGLE-VALUE':
|
||||
$this->is_single_value = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case SINGLE-VALUE returned (%s)',self::LOGKEY,$this->is_single_value));
|
||||
break;
|
||||
|
||||
case 'COLLECTIVE':
|
||||
$this->is_collective = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case COLLECTIVE returned (%s)',self::LOGKEY,$this->is_collective));
|
||||
break;
|
||||
|
||||
case 'NO-USER-MODIFICATION':
|
||||
$this->is_no_user_modification = TRUE;
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case NO-USER-MODIFICATION returned (%s)',self::LOGKEY,$this->is_no_user_modification));
|
||||
break;
|
||||
|
||||
case 'USAGE':
|
||||
$this->usage = $strings[++$i];
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case USAGE returned (%s)',self::LOGKEY,$this->usage));
|
||||
break;
|
||||
|
||||
default:
|
||||
parent::parse_chunk($strings,$i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,13 +298,28 @@ final class AttributeType extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's SUP attribute (ie, the attribute from which this attribute inherits).
|
||||
* If this is a MUST attribute to the objectclass that defines it
|
||||
*
|
||||
* @param string $attr The name of the new parent (SUP) attribute
|
||||
* @return void
|
||||
*/
|
||||
public function setSupAttribute(string $attr): void
|
||||
public function setMust(): void
|
||||
{
|
||||
$this->sup_attribute = trim($attr);
|
||||
$this->is_must = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's name.
|
||||
*
|
||||
* @param string $name The new name to give this attribute.
|
||||
* @throws InvalidUsage
|
||||
*/
|
||||
public function setName(string $name): void
|
||||
{
|
||||
// Quick validation
|
||||
if ($this->names_lc->count() && (! $this->names_lc->contains(strtolower($name))))
|
||||
throw new InvalidUsage(sprintf('Cannot set attribute name to [%s], its not an alias for [%s]',$name,$this->names->join(',')));
|
||||
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -57,7 +57,7 @@ abstract class Base
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
return $this->oid;
|
||||
}
|
||||
|
||||
protected function parse(string $line): void
|
||||
|
@@ -6,74 +6,49 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Represents an LDAP Syntax
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class LDAPSyntax extends Base {
|
||||
final class LDAPSyntax extends Base
|
||||
{
|
||||
private const LOGKEY = 'SLS';
|
||||
|
||||
// Is human readable?
|
||||
private ?bool $is_not_human_readable = NULL;
|
||||
private(set) ?bool $is_not_human_readable = NULL;
|
||||
|
||||
// Binary transfer required?
|
||||
private ?bool $binary_transfer_required = NULL;
|
||||
private(set) ?bool $binary_transfer_required = NULL;
|
||||
|
||||
/**
|
||||
* Creates a new Syntax object from a raw LDAP syntax string.
|
||||
*/
|
||||
public function __construct(string $line) {
|
||||
Log::debug(sprintf('Parsing LDAPSyntax [%s]',$line));
|
||||
protected function parse(string $line): void
|
||||
{
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:Parsing LDAPSyntax [%s]',self::LOGKEY,$line));
|
||||
|
||||
parent::__construct($line);
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
parent::parse($line);
|
||||
}
|
||||
|
||||
protected function parse_chunk(array $strings,int &$i): void
|
||||
{
|
||||
for ($i=0; $i<count($strings); $i++) {
|
||||
switch($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= (strlen($this->description) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'X-BINARY-TRANSFER-REQUIRED':
|
||||
$this->binary_transfer_required = (str_replace("'",'',$strings[++$i]) === 'TRUE');
|
||||
|
||||
Log::debug(sprintf('- Case X-BINARY-TRANSFER-REQUIRED returned (%s)',$this->binary_transfer_required));
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case X-BINARY-TRANSFER-REQUIRED returned (%s)',self::LOGKEY,$this->binary_transfer_required));
|
||||
break;
|
||||
|
||||
case 'X-NOT-HUMAN-READABLE':
|
||||
$this->is_not_human_readable = (str_replace("'",'',$strings[++$i]) === 'TRUE');
|
||||
|
||||
Log::debug(sprintf('- Case X-NOT-HUMAN-READABLE returned (%s)',$this->is_not_human_readable));
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case X-NOT-HUMAN-READABLE returned (%s)',self::LOGKEY,$this->is_not_human_readable));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
parent::parse_chunk($strings,$i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'binary_transfer_required': return $this->binary_transfer_required;
|
||||
case 'is_not_human_readable': return $this->is_not_human_readable;
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,106 +7,16 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Represents an LDAP MatchingRule
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class MatchingRule extends Base {
|
||||
final class MatchingRule extends Base
|
||||
{
|
||||
private const LOGKEY = 'SMR';
|
||||
|
||||
// This rule's syntax OID
|
||||
private ?string $syntax = NULL;
|
||||
private(set) ?string $syntax = NULL;
|
||||
|
||||
// An array of attribute names who use this MatchingRule
|
||||
private Collection $used_by_attrs;
|
||||
|
||||
/**
|
||||
* Creates a new MatchingRule object from a raw LDAP MatchingRule string.
|
||||
*/
|
||||
function __construct(string $line) {
|
||||
Log::debug(sprintf('Parsing MatchingRule [%s]',$line));
|
||||
|
||||
parent::__construct($line);
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Init
|
||||
$this->used_by_attrs = collect();
|
||||
|
||||
for ($i=0; $i<count($strings); $i++) {
|
||||
switch ($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'NAME':
|
||||
if ($strings[$i+1] != '(') {
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
do {
|
||||
$i++;
|
||||
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i]));
|
||||
}
|
||||
|
||||
$this->name = preg_replace("/^\'/",'',$this->name);
|
||||
$this->name = preg_replace("/\'$/",'',$this->name);
|
||||
|
||||
Log::debug(sprintf(sprintf('- Case NAME returned (%s)',$this->name)));
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= (strlen($this->description) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'OBSOLETE':
|
||||
$this->is_obsolete = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case OBSOLETE returned (%s)',$this->is_obsolete));
|
||||
break;
|
||||
|
||||
case 'SYNTAX':
|
||||
$this->syntax = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case SYNTAX returned (%s)',$this->syntax));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'syntax': return $this->syntax;
|
||||
case 'used_by_attrs': return $this->used_by_attrs;
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
private(set) Collection $used_by_attrs;
|
||||
|
||||
/**
|
||||
* Adds an attribute name to the list of attributes who use this MatchingRule
|
||||
@@ -120,23 +30,33 @@ final class MatchingRule extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of attribute names (strings) which use this MatchingRule
|
||||
* Creates a new MatchingRule object from a raw LDAP MatchingRule string.
|
||||
*
|
||||
* @return array The array of attribute names (strings).
|
||||
* @deprecated use $this->used_by_attrs
|
||||
* @param string $line
|
||||
* @return void
|
||||
*/
|
||||
public function getUsedByAttrs()
|
||||
protected function parse(string $line): void
|
||||
{
|
||||
return $this->used_by_attrs;
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:Parsing MatchingRule [%s]',self::LOGKEY,$line));
|
||||
|
||||
// Init
|
||||
$this->used_by_attrs = collect();
|
||||
|
||||
parent::parse($line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of used_by_attrs to the array specified by $attrs;
|
||||
*
|
||||
* @param Collection $attrs The array of attribute names (strings) which use this MatchingRule
|
||||
*/
|
||||
public function setUsedByAttrs(Collection $attrs): void
|
||||
protected function parse_chunk(array $strings,int &$i): void
|
||||
{
|
||||
$this->used_by_attrs = $attrs;
|
||||
switch ($strings[$i]) {
|
||||
case 'SYNTAX':
|
||||
$this->syntax = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case SYNTAX returned (%s)',$this->syntax));
|
||||
break;
|
||||
|
||||
default:
|
||||
parent::parse_chunk($strings,$i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,9 +10,6 @@ use App\Exceptions\InvalidUsage;
|
||||
|
||||
/**
|
||||
* Represents an LDAP Schema objectClass
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class ObjectClass extends Base
|
||||
{
|
||||
@@ -27,21 +24,14 @@ final class ObjectClass extends Base
|
||||
// One of STRUCTURAL, ABSTRACT, or AUXILIARY
|
||||
private int $type;
|
||||
|
||||
// Arrays of attribute names that this objectClass requires
|
||||
private Collection $must_attrs;
|
||||
|
||||
// Arrays of attribute names that this objectClass allows, but does not require
|
||||
private Collection $may_attrs;
|
||||
|
||||
// Arrays of attribute names that this objectClass has been forced to MAY attrs, due to configuration
|
||||
private(set) Collection $may_force;
|
||||
|
||||
private bool $is_obsolete;
|
||||
// Attributes that this objectclass defines
|
||||
private(set) Collection $attributes;
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
'attributes' => $this->getAllAttrs(TRUE),
|
||||
'all_attributes' => $this->getMustAttrs(TRUE)
|
||||
->merge($this->getMayAttrs(TRUE)),
|
||||
'type_name' => match ($this->type) {
|
||||
Server::OC_STRUCTURAL => 'Structural',
|
||||
Server::OC_ABSTRACT => 'Abstract',
|
||||
@@ -52,20 +42,6 @@ final class ObjectClass extends Base
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of attributes that this objectClass provides
|
||||
*
|
||||
* @param bool $parents
|
||||
* @return Collection
|
||||
* @throws InvalidUsage
|
||||
*/
|
||||
public function getAllAttrs(bool $parents=FALSE): Collection
|
||||
{
|
||||
return $this
|
||||
->getMustAttrs($parents)
|
||||
->merge($this->getMayAttrs($parents));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an objectClass to the list of objectClasses that inherit
|
||||
* from this objectClass.
|
||||
@@ -93,16 +69,26 @@ final class ObjectClass extends Base
|
||||
*/
|
||||
public function getMayAttrs(bool $parents=FALSE): Collection
|
||||
{
|
||||
$attrs = $this->may_attrs;
|
||||
$attrs = $this->attributes
|
||||
->filter(fn($item)=>! $item->is_must)
|
||||
->transform(function($item) {
|
||||
$item->source = $this->name;
|
||||
return $item;
|
||||
});
|
||||
|
||||
if ($parents)
|
||||
foreach ($this->getParents() as $object_class)
|
||||
$attrs = $attrs->merge($object_class->getMayAttrs($parents));
|
||||
$attrs = $attrs->merge($object_class
|
||||
->getMayAttrs($parents)
|
||||
->transform(function($item) use ($object_class) {
|
||||
$item->source = $item->source ?: $object_class->name;
|
||||
return $item;
|
||||
}));
|
||||
|
||||
// Return a sorted list
|
||||
return $attrs
|
||||
->unique(fn($item)=>$item->name)
|
||||
->sortBy(fn($item)=>strtolower($item->name.$item->source));
|
||||
->sortBy(fn($item)=>$item->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,16 +105,26 @@ final class ObjectClass extends Base
|
||||
*/
|
||||
public function getMustAttrs(bool $parents=FALSE): Collection
|
||||
{
|
||||
$attrs = $this->must_attrs;
|
||||
$attrs = $this->attributes
|
||||
->filter(fn($item)=>$item->is_must)
|
||||
->transform(function($item) {
|
||||
$item->source = $this->name;
|
||||
return $item;
|
||||
});
|
||||
|
||||
if ($parents)
|
||||
foreach ($this->getParents() as $object_class)
|
||||
$attrs = $attrs->merge($object_class->getMustAttrs($parents));
|
||||
$attrs = $attrs->merge($object_class
|
||||
->getMustAttrs($parents)
|
||||
->transform(function($item) use ($object_class) {
|
||||
$item->source = $item->source ?: $object_class->name;
|
||||
return $item;
|
||||
}));
|
||||
|
||||
// Return a sorted list
|
||||
return $attrs
|
||||
->unique(fn($item)=>$item->name)
|
||||
->sortBy(fn($item)=>strtolower($item->name.$item->source));
|
||||
->sortBy(fn($item)=>$item->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,16 +161,6 @@ final class ObjectClass extends Base
|
||||
return $this->type === Server::OC_AUXILIARY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an array is listed in the may_force attrs
|
||||
*/
|
||||
public function isForceMay(string $attr): bool
|
||||
{
|
||||
return $this->may_force
|
||||
->pluck('name')
|
||||
->contains($attr);
|
||||
}
|
||||
|
||||
public function isStructural(): bool
|
||||
{
|
||||
return $this->type === Server::OC_STRUCTURAL;
|
||||
@@ -192,9 +178,7 @@ final class ObjectClass extends Base
|
||||
Log::debug(sprintf('%s:Parsing ObjectClass [%s]',self::LOGKEY,$line));
|
||||
|
||||
// Init
|
||||
$this->may_attrs = collect();
|
||||
$this->may_force = collect();
|
||||
$this->must_attrs = collect();
|
||||
$this->attributes = collect();
|
||||
$this->sup_classes = collect();
|
||||
$this->child_classes = collect();
|
||||
|
||||
@@ -204,34 +188,8 @@ final class ObjectClass extends Base
|
||||
protected function parse_chunk(array $strings,int &$i): void
|
||||
{
|
||||
switch ($strings[$i]) {
|
||||
case 'NAME':
|
||||
if ($strings[$i+1] != '(') {
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match('/\'$/s',$strings[$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match('/\'$/s',$strings[$i]));
|
||||
|
||||
do {
|
||||
$i++;
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i]));
|
||||
}
|
||||
|
||||
$this->name = preg_replace("/^\'(.*)\'$/",'$1',$this->name);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case NAME returned (%s)',self::LOGKEY,$this->name));
|
||||
break;
|
||||
|
||||
case 'SUP':
|
||||
if ($strings[$i+1] != '(') {
|
||||
if ($strings[$i+1] !== '(') {
|
||||
$this->sup_classes->push(preg_replace("/'/",'',$strings[++$i]));
|
||||
|
||||
} else {
|
||||
@@ -240,7 +198,7 @@ final class ObjectClass extends Base
|
||||
do {
|
||||
$i++;
|
||||
|
||||
if ($strings[$i] != '$')
|
||||
if ($strings[$i] !== '$')
|
||||
$this->sup_classes->push(preg_replace("/'/",'',$strings[$i]));
|
||||
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i+1]));
|
||||
@@ -276,23 +234,17 @@ final class ObjectClass extends Base
|
||||
|
||||
$i = $this->parseList(++$i,$strings,$attrs);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:= parseList returned %d (%s)',self::LOGKEY,$i,$attrs->join(',')));
|
||||
|
||||
foreach ($attrs as $string) {
|
||||
$attr = new ObjectClassAttribute($string,$this->name);
|
||||
$attr = clone config('server')->schema('attributetypes',$string);
|
||||
|
||||
if (config('server')->isForceMay($attr->getName())) {
|
||||
$this->may_force->push($attr);
|
||||
$this->may_attrs->push($attr);
|
||||
if (! $attr->forced_as_may)
|
||||
$attr->setMust();
|
||||
|
||||
} else
|
||||
$attr->required = TRUE;
|
||||
$this->must_attrs->push($attr);
|
||||
$this->attributes->push($attr);
|
||||
}
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case MUST returned (%s) (%s)',self::LOGKEY,$this->must_attrs->join(','),$this->may_force->join(',')));
|
||||
Log::debug(sprintf('%s:- Case MUST returned (%s) (%s)',self::LOGKEY,$attrs->join(','),$this->forced_as_may ? 'FORCED MAY' : 'MUST'));
|
||||
break;
|
||||
|
||||
case 'MAY':
|
||||
@@ -300,16 +252,11 @@ final class ObjectClass extends Base
|
||||
|
||||
$i = $this->parseList(++$i,$strings,$attrs);
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- parseList returned %d (%s)',self::LOGKEY,$i,$attrs->join(',')));
|
||||
|
||||
foreach ($attrs as $string) {
|
||||
$attr = new ObjectClassAttribute($string,$this->name);
|
||||
$this->may_attrs->push($attr);
|
||||
}
|
||||
foreach ($attrs as $string)
|
||||
$this->attributes->push(config('server')->schema('attributetypes',$string));
|
||||
|
||||
if (static::DEBUG_VERBOSE)
|
||||
Log::debug(sprintf('%s:- Case MAY returned (%s)',self::LOGKEY,$this->may_attrs->join(',')));
|
||||
Log::debug(sprintf('%s:- Case MAY returned (%s)',self::LOGKEY,$attrs->join(',')));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
/**
|
||||
* A simple class for representing AttributeTypes used only by the ObjectClass class.
|
||||
*
|
||||
* Users should never instantiate this class. It represents an attribute internal to
|
||||
* an ObjectClass. If PHP supported inner-classes and variable permissions, this would
|
||||
* be interior to class ObjectClass and flagged private. The reason this class is used
|
||||
* and not the "real" class AttributeType is because this class supports the notion of
|
||||
* a "source" objectClass, meaning that it keeps track of which objectClass originally
|
||||
* specified it. This class is therefore used by the class ObjectClass to determine
|
||||
* inheritance.
|
||||
*/
|
||||
final class ObjectClassAttribute extends Base {
|
||||
// This Attribute's root.
|
||||
private string $source;
|
||||
public bool $required = FALSE;
|
||||
|
||||
/**
|
||||
* Creates a new ObjectClassAttribute with specified name and source objectClass.
|
||||
*
|
||||
* @param string $name the name of the new attribute.
|
||||
* @param string $source the name of the ObjectClass which specifies this attribute.
|
||||
*/
|
||||
public function __construct($name,$source)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
'source' => $this->source,
|
||||
default => parent::__get($key),
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user