Compare commits
4 Commits
31524418b9
...
dba104105e
Author | SHA1 | Date | |
---|---|---|---|
dba104105e | |||
e667d139b0 | |||
45953b4e41 | |||
6b279d1df1 |
@ -39,57 +39,6 @@ class Attribute implements \Countable, \ArrayAccess
|
|||||||
private const SYNTAX_CERTIFICATE = '1.3.6.1.4.1.1466.115.121.1.8';
|
private const SYNTAX_CERTIFICATE = '1.3.6.1.4.1.1466.115.121.1.8';
|
||||||
private const SYNTAX_CERTIFICATE_LIST = '1.3.6.1.4.1.1466.115.121.1.9';
|
private const SYNTAX_CERTIFICATE_LIST = '1.3.6.1.4.1.1466.115.121.1.9';
|
||||||
|
|
||||||
/*
|
|
||||||
# Has the attribute been modified
|
|
||||||
protected $modified = false;
|
|
||||||
# Is the attribute being deleted because of an object class removal
|
|
||||||
protected $forcedelete = false;
|
|
||||||
# Is the attribute visible
|
|
||||||
protected $visible = false;
|
|
||||||
protected $forcehide = false;
|
|
||||||
# Is the attribute modifiable
|
|
||||||
protected $readonly = false;
|
|
||||||
# LDAP attribute type MUST/MAY
|
|
||||||
protected $ldaptype = null;
|
|
||||||
# Attribute property type (eg password, select, multiselect)
|
|
||||||
protected $type = '';
|
|
||||||
# Attribute value to keep unique
|
|
||||||
protected $unique = false;
|
|
||||||
|
|
||||||
# Display parameters
|
|
||||||
protected $display = '';
|
|
||||||
protected $icon = '';
|
|
||||||
protected $hint = '';
|
|
||||||
# Helper details
|
|
||||||
protected $helper = array();
|
|
||||||
protected $helpervalue = array();
|
|
||||||
# Onchange details
|
|
||||||
protected $onchange = array();
|
|
||||||
# Show spacer after this attribute is rendered
|
|
||||||
protected $spacer = false;
|
|
||||||
protected $verify = false;
|
|
||||||
|
|
||||||
# Component size
|
|
||||||
protected $size = 0;
|
|
||||||
# Value max length
|
|
||||||
protected $maxlength = 0;
|
|
||||||
# Text Area sizings
|
|
||||||
protected $cols = 0;
|
|
||||||
protected $rows = 0;
|
|
||||||
|
|
||||||
# Public for sorting
|
|
||||||
public $page = 1;
|
|
||||||
public $order = 255;
|
|
||||||
public $ordersort = 255;
|
|
||||||
|
|
||||||
# Schema Aliases for this attribute (stored in lowercase)
|
|
||||||
protected $aliases = array();
|
|
||||||
|
|
||||||
# Configuration for automatically generated values
|
|
||||||
protected $autovalue = array();
|
|
||||||
protected $postvalue = array();
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an Attribute
|
* Create an Attribute
|
||||||
*
|
*
|
||||||
@ -119,20 +68,6 @@ class Attribute implements \Countable, \ArrayAccess
|
|||||||
$this->oc = $this->oc->merge($soc->getParents()->pluck('oid'));
|
$this->oc = $this->oc->merge($soc->getParents()->pluck('oid'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
# Should this attribute be hidden
|
|
||||||
if ($server->isAttrHidden($this->name))
|
|
||||||
$this->forcehide = true;
|
|
||||||
|
|
||||||
# Should this attribute value be read only
|
|
||||||
if ($server->isAttrReadOnly($this->name))
|
|
||||||
$this->readonly = true;
|
|
||||||
|
|
||||||
# Should this attribute value be unique
|
|
||||||
if ($server->isAttrUnique($this->name))
|
|
||||||
$this->unique = true;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __call(string $name,array $arguments)
|
public function __call(string $name,array $arguments)
|
||||||
@ -255,6 +190,21 @@ class Attribute implements \Countable, \ArrayAccess
|
|||||||
->get($tag,[]),$values)));
|
->get($tag,[]),$values)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this attribute has changes, re-render the attribute values
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getDirty(): array
|
||||||
|
{
|
||||||
|
$dirty = [];
|
||||||
|
|
||||||
|
if ($this->isDirty())
|
||||||
|
$dirty = [$this->name_lc => $this->_values->toArray()];
|
||||||
|
|
||||||
|
return $dirty;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the hints about this attribute, ie: RDN, Required, etc
|
* Return the hints about this attribute, ie: RDN, Required, etc
|
||||||
*
|
*
|
||||||
|
@ -56,6 +56,7 @@ abstract class Import
|
|||||||
{
|
{
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case static::LDAP_IMPORT_ADD:
|
case static::LDAP_IMPORT_ADD:
|
||||||
|
case static::LDAP_IMPORT_MODIFY:
|
||||||
try {
|
try {
|
||||||
$o->save();
|
$o->save();
|
||||||
|
|
||||||
@ -65,15 +66,17 @@ abstract class Import
|
|||||||
if ($e->getDetailedError())
|
if ($e->getDetailedError())
|
||||||
return collect([
|
return collect([
|
||||||
'dn'=>$o->getDN(),
|
'dn'=>$o->getDN(),
|
||||||
'result'=>sprintf('%d: %s (%s)',
|
'link'=>$o->getDNSecure(),
|
||||||
|
'result'=>sprintf('%d: %s%s',
|
||||||
($x=$e->getDetailedError())->getErrorCode(),
|
($x=$e->getDetailedError())->getErrorCode(),
|
||||||
$x->getErrorMessage(),
|
$x->getErrorMessage(),
|
||||||
$x->getDiagnosticMessage(),
|
$x->getDiagnosticMessage() ? ' ('.$x->getDiagnosticMessage().')' : '',
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
else
|
else
|
||||||
return collect([
|
return collect([
|
||||||
'dn'=>$o->getDN(),
|
'dn'=>$o->getDN(),
|
||||||
|
'link'=>$o->getDNSecure(),
|
||||||
'result'=>sprintf('%d: %s',
|
'result'=>sprintf('%d: %s',
|
||||||
$e->getCode(),
|
$e->getCode(),
|
||||||
$e->getMessage(),
|
$e->getMessage(),
|
||||||
@ -81,9 +84,13 @@ abstract class Import
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::debug(sprintf('%s:Import Commited',self::LOGKEY));
|
Log::debug(sprintf('%s:= Import Commited',self::LOGKEY));
|
||||||
|
|
||||||
return collect(['dn'=>$o->getDN(),'result'=>__('Created')]);
|
return collect([
|
||||||
|
'dn'=>$o->getDN(),
|
||||||
|
'link'=>$o->getDNSecure(),
|
||||||
|
'result'=>$action === self::LDAP_IMPORT_ADD ? __('Created') : __('Modified'),
|
||||||
|
]);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new GeneralException('Unhandled action during commit: '.$action);
|
throw new GeneralException('Unhandled action during commit: '.$action);
|
||||||
|
@ -24,7 +24,9 @@ class LDIF extends Import
|
|||||||
public function process(): Collection
|
public function process(): Collection
|
||||||
{
|
{
|
||||||
$c = 0;
|
$c = 0;
|
||||||
$action = NULL;
|
$action = self::LDAP_IMPORT_ADD; // Assume add mode
|
||||||
|
$subaction = 'add'; // Assume add
|
||||||
|
$dn = NULL;
|
||||||
$attribute = NULL;
|
$attribute = NULL;
|
||||||
$base64encoded = FALSE;
|
$base64encoded = FALSE;
|
||||||
$o = NULL;
|
$o = NULL;
|
||||||
@ -32,21 +34,29 @@ class LDIF extends Import
|
|||||||
$version = NULL;
|
$version = NULL;
|
||||||
$result = collect();
|
$result = collect();
|
||||||
|
|
||||||
// @todo When renaming DNs, the hotlink should point to the new entry on success, or the old entry on failure.
|
|
||||||
foreach (preg_split('/(\r?\n|\r)/',$this->input) as $line) {
|
foreach (preg_split('/(\r?\n|\r)/',$this->input) as $line) {
|
||||||
$c++;
|
$c++;
|
||||||
Log::debug(sprintf('%s:LDIF Line [%s]',self::LOGKEY,$line));
|
Log::debug(sprintf('%s:LDIF Line [%s] (%d)',self::LOGKEY,$line,$c));
|
||||||
$line = trim($line);
|
$line = trim($line);
|
||||||
|
|
||||||
// If the line starts with a comment, ignore it
|
// If the line starts with a comment, ignore it
|
||||||
if (preg_match('/^#/',$line))
|
if (preg_match('/^#/',$line))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// If the line starts with a dash, its more updates to the same entry
|
||||||
|
if (preg_match('/^-/',$line)) {
|
||||||
|
$o = $this->entry($o,$attribute,$subaction,$base64encoded ? base64_decode($value) : $value,$c);
|
||||||
|
|
||||||
|
$base64encoded = FALSE;
|
||||||
|
$value = '';
|
||||||
|
$attribute = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If we have a blank line, then that completes this command
|
// If we have a blank line, then that completes this command
|
||||||
if (! $line) {
|
if (! $line) {
|
||||||
if (! is_null($o)) {
|
if (! is_null($o)) {
|
||||||
// Add the last attribute;
|
$o = $this->entry($o,$attribute,$subaction,$base64encoded ? base64_decode($value) : $value,$c);
|
||||||
$o->addAttributeItem($attribute,$base64encoded ? base64_decode($value) : $value);
|
|
||||||
|
|
||||||
Log::debug(sprintf('%s:- Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
Log::debug(sprintf('%s:- Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
||||||
|
|
||||||
@ -59,27 +69,106 @@ class LDIF extends Import
|
|||||||
$base64encoded = FALSE;
|
$base64encoded = FALSE;
|
||||||
$attribute = NULL;
|
$attribute = NULL;
|
||||||
$value = '';
|
$value = '';
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new GeneralException(sprintf('Processing Error - Line exists [%s] on (%d) but object is NULL',$line,$c));
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$m = [];
|
$m = [];
|
||||||
preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m);
|
preg_match('/^([a-zA-Z0-9;-]+)(:+)\s*(.*)$/',$line,$m);
|
||||||
|
|
||||||
|
// If $m is NULL, then this is the 2nd (or more) line of a base64 encoded value
|
||||||
|
if (! $m) {
|
||||||
|
$value .= $line;
|
||||||
|
Log::debug(sprintf('%s:+ Attribute [%s] adding [%s] (%d)',self::LOGKEY,$attribute,$line,$c));
|
||||||
|
|
||||||
|
// add to last attr value
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$base64encoded = ($m[2] === '::');
|
||||||
|
$value = $m[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// changetype needs to be after the dn, and if it isnt we'll assume add.
|
||||||
|
if ($dn && Arr::get($m,1) !== 'changetype') {
|
||||||
|
if ($action === self::LDAP_IMPORT_ADD) {
|
||||||
|
Log::debug(sprintf('%s:Creating new entry [%s]:',self::LOGKEY,$dn),['o'=>$o]);
|
||||||
|
$o = new Entry;
|
||||||
|
$o->setDn($dn);
|
||||||
|
$dn = NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log::debug(sprintf('%s:Looking for existing entry [%s]:',self::LOGKEY,$dn),['o'=>$o]);
|
||||||
|
$o = Entry::find($dn);
|
||||||
|
$dn = NULL;
|
||||||
|
|
||||||
|
if (! $o) {
|
||||||
|
$result->push(collect(['dn'=>$dn,'result'=>__('Entry doesnt exist')]));
|
||||||
|
$result->last()->put('line',$c);;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (Arr::get($m,1)) {
|
switch (Arr::get($m,1)) {
|
||||||
|
case 'dn':
|
||||||
|
$dn = $base64encoded ? base64_decode($value) : $value;
|
||||||
|
Log::debug(sprintf('%s:Got DN [%s]:',self::LOGKEY,$dn));
|
||||||
|
|
||||||
|
$value = '';
|
||||||
|
$base64encoded = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
|
if (! is_null($o))
|
||||||
|
throw new GeneralException(sprintf('Previous Entry not complete? (line %d)',$c));
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s:- Action [%s]',self::LOGKEY,$m[3]));
|
||||||
|
|
||||||
switch ($m[3]) {
|
switch ($m[3]) {
|
||||||
// if (preg_match('/^changetype:[ ]*(delete|add|modrdn|moddn|modify)/i',$lines[0])) {
|
case 'add':
|
||||||
|
$action = self::LDAP_IMPORT_ADD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'modify':
|
||||||
|
$action = self::LDAP_IMPORT_MODIFY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
case 'delete':
|
||||||
|
$action = self::LDAP_IMPORT_DELETE;
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @todo modrdn|moddn
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException(sprintf('Unknown change type [%s]? (line %d)',$m[3],$c));
|
throw new NotImplementedException(sprintf('Unknown change type [%s]? (line %d)',$m[3],$c));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'add':
|
||||||
|
case 'replace':
|
||||||
|
if ($action !== self::LDAP_IMPORT_MODIFY)
|
||||||
|
throw new GeneralException(sprintf('%s action can only be used with changetype: modify (line %d)',$m[1],$c));
|
||||||
|
|
||||||
|
$subaction = $m[1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete':
|
||||||
|
$subaction = $m[1];
|
||||||
|
$attribute = NULL;
|
||||||
|
$o = $this->entry($o,$m[3],'delete','',$c);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'version':
|
case 'version':
|
||||||
if (! is_null($version))
|
if (! is_null($version))
|
||||||
throw new VersionException(sprintf('Version has already been set at [%d]. (line %d)',$version,$c));
|
throw new VersionException(sprintf('Version has already been set at [%d]. (line %d)',$version,$c));
|
||||||
@ -92,49 +181,12 @@ class LDIF extends Import
|
|||||||
|
|
||||||
// Treat it as an attribute
|
// Treat it as an attribute
|
||||||
default:
|
default:
|
||||||
// If $m is NULL, then this is the 2nd (or more) line of a base64 encoded value
|
// Start of a new attribute
|
||||||
if (! $m) {
|
$attribute = $m[1];
|
||||||
$value .= $line;
|
Log::debug(sprintf('%s:- Working with Attribute [%s] with [%s] (%d)',self::LOGKEY,$attribute,$value,$c));
|
||||||
Log::debug(sprintf('%s:- Attribute [%s] adding [%s] (%d)',self::LOGKEY,$attribute,$line,$c));
|
|
||||||
|
|
||||||
// add to last attr value
|
|
||||||
continue 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are ready to create the entry or add the attribute
|
// We are ready to create the entry or add the attribute
|
||||||
if ($attribute) {
|
$o = $this->entry($o,$attribute,$subaction,$base64encoded ? base64_decode($value) : $value,$c);
|
||||||
if ($attribute === 'dn') {
|
|
||||||
if (! is_null($o))
|
|
||||||
throw new GeneralException(sprintf('Previous Entry not complete? (line %d)',$c));
|
|
||||||
|
|
||||||
$dn = $base64encoded ? base64_decode($value) : $value;
|
|
||||||
Log::debug(sprintf('%s:Creating new entry:',self::LOGKEY,$dn));
|
|
||||||
//$o = Entry::find($dn);
|
|
||||||
|
|
||||||
// If it doesnt exist, we'll create it
|
|
||||||
//if (! $o) {
|
|
||||||
$o = new Entry;
|
|
||||||
$o->setDn($dn);
|
|
||||||
//}
|
|
||||||
|
|
||||||
$action = self::LDAP_IMPORT_ADD;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Log::debug(sprintf('%s:Adding Attribute [%s] value [%s] (%d)',self::LOGKEY,$attribute,$value,$c));
|
|
||||||
|
|
||||||
if ($value)
|
|
||||||
$o->addAttributeItem($attribute,$base64encoded ? base64_decode($value) : $value);
|
|
||||||
else
|
|
||||||
throw new GeneralException(sprintf('Attribute has no value [%s] (line %d)',$attribute,$c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start of a new attribute
|
|
||||||
$base64encoded = ($m[2] === '::');
|
|
||||||
$attribute = $m[1];
|
|
||||||
$value = $m[3];
|
|
||||||
|
|
||||||
Log::debug(sprintf('%s:- New Attribute [%s] with [%s] (%d)',self::LOGKEY,$attribute,$value,$c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($version !== 1)
|
if ($version !== 1)
|
||||||
@ -142,9 +194,9 @@ class LDIF extends Import
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We may still have a pending action
|
// We may still have a pending action
|
||||||
if ($action) {
|
if ($o) {
|
||||||
// Add the last attribute;
|
if ($attribute)
|
||||||
$o->addAttributeItem($attribute,$base64encoded ? base64_decode($value) : $value);
|
$o = $this->entry($o,$attribute,$subaction,$base64encoded ? base64_decode($value) : $value,$c);
|
||||||
|
|
||||||
Log::debug(sprintf('%s:- Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
Log::debug(sprintf('%s:- Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
||||||
|
|
||||||
@ -156,75 +208,40 @@ class LDIF extends Import
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function xreadEntry() {
|
private function entry(Entry $o,string $attribute,string $subaction,string $value,int $c): Entry
|
||||||
static $haveVersion = FALSE;
|
{
|
||||||
|
Log::debug(sprintf('%s:/ %s Attribute [%s] value [%s] (%d)',self::LOGKEY,$subaction,$attribute,$value,$c));
|
||||||
|
|
||||||
if ($lines = $this->nextLines()) {
|
switch ($subaction) {
|
||||||
|
case 'add':
|
||||||
|
if (! $value)
|
||||||
|
throw new GeneralException(sprintf('Attribute has no value [%s] (line %d)',$attribute,$c));
|
||||||
|
|
||||||
$server = $this->getServer();
|
$o->addAttributeItem($attribute,$value);
|
||||||
|
break;
|
||||||
|
|
||||||
# The first line should be the DN
|
case 'replace':
|
||||||
if (preg_match('/^dn:/',$lines[0])) {
|
if (! $value)
|
||||||
list($text,$dn) = $this->getAttrValue(array_shift($lines));
|
throw new GeneralException(sprintf('Attribute has no value [%s] (line %d)',$attribute,$c));
|
||||||
|
|
||||||
# The second line should be our changetype
|
if (! $o->getObject($attribute))
|
||||||
if (preg_match('/^changetype:[ ]*(delete|add|modrdn|moddn|modify)/i',$lines[0])) {
|
throw new \Exception(sprintf('Attribute [%s] doesnt exist in [%s] (line %d)',$attribute,$o->getDn(),$c));
|
||||||
$attrvalue = $this->getAttrValue($lines[0]);
|
|
||||||
$changetype = $attrvalue[1];
|
|
||||||
array_shift($lines);
|
|
||||||
|
|
||||||
} else
|
$o->{$attribute} = [Entry::TAG_NOTAG=>[$value]];
|
||||||
$changetype = 'add';
|
|
||||||
|
|
||||||
$this->template = new Template($this->server_id,NULL,NULL,$changetype);
|
break;
|
||||||
|
|
||||||
switch ($changetype) {
|
case 'delete':
|
||||||
case 'add':
|
if (! $o->getObject($attribute))
|
||||||
$rdn = get_rdn($dn);
|
throw new \Exception(sprintf('Attribute [%s] doesnt exist in [%s] (line %d)',$attribute,$o->getDn(),$c));
|
||||||
$container = $server->getContainer($dn);
|
|
||||||
|
|
||||||
$this->template->setContainer($container);
|
$o->{$attribute} = [];
|
||||||
$this->template->accept();
|
break;
|
||||||
|
|
||||||
$this->getAddDetails($lines);
|
default:
|
||||||
$this->template->setRDNAttributes($rdn);
|
throw new \Exception('Unknown subaction:'.$subaction);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->template;
|
return $o;
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'modify':
|
|
||||||
if (! $server->dnExists($dn))
|
|
||||||
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
|
|
||||||
|
|
||||||
$this->template->setDN($dn);
|
|
||||||
$this->template->accept(FALSE,TRUE);
|
|
||||||
|
|
||||||
return $this->getModifyDetails($lines);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'moddn':
|
|
||||||
case 'modrdn':
|
|
||||||
if (! $server->dnExists($dn))
|
|
||||||
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
|
|
||||||
|
|
||||||
$this->template->setDN($dn);
|
|
||||||
$this->template->accept();
|
|
||||||
|
|
||||||
return $this->getModRDNAttributes($lines);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (! $server->dnExists($dn))
|
|
||||||
return $this->error(_('Unknown change type'),$lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
return $this->error(_('A valid dn line is required'),$lines);
|
|
||||||
|
|
||||||
} else
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -329,6 +329,11 @@ final class Server
|
|||||||
: NULL;
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasMore(): bool
|
||||||
|
{
|
||||||
|
return (new Entry)->hasMore();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this server support RFC3666 language tags
|
* Does this server support RFC3666 language tags
|
||||||
* OID: 1.3.6.1.4.1.4203.1.5.4
|
* OID: 1.3.6.1.4.1.4203.1.5.4
|
||||||
@ -509,4 +514,15 @@ final class Server
|
|||||||
{
|
{
|
||||||
return Arr::get($this->rootDSE->subschemasubentry,0);
|
return Arr::get($this->rootDSE->subschemasubentry,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function subordinates(string $dn,array $attrs=['dn']): ?LDAPCollection
|
||||||
|
{
|
||||||
|
return $this
|
||||||
|
->get(
|
||||||
|
dn: $dn,
|
||||||
|
attrs: array_merge($attrs,[]))
|
||||||
|
->rawFilter('(hassubordinates=TRUE)')
|
||||||
|
->search()
|
||||||
|
->get() ?: NULL;
|
||||||
|
}
|
||||||
}
|
}
|
@ -67,6 +67,17 @@ class AjaxController extends Controller
|
|||||||
]
|
]
|
||||||
: []
|
: []
|
||||||
)
|
)
|
||||||
|
->push(
|
||||||
|
config('server')->hasMore()
|
||||||
|
? [
|
||||||
|
'title'=>sprintf('[%s]',__('Size Limit')),
|
||||||
|
'item'=>'',
|
||||||
|
'lazy'=>FALSE,
|
||||||
|
'icon'=>'fas fa-fw fa-triangle-exclamation text-danger',
|
||||||
|
'tooltip'=>__('There may be more entries'),
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
)
|
||||||
->filter()
|
->filter()
|
||||||
->values();
|
->values();
|
||||||
}
|
}
|
||||||
@ -113,4 +124,27 @@ class AjaxController extends Controller
|
|||||||
'may' => $oc->getMayAttrs()->pluck('name'),
|
'may' => $oc->getMayAttrs()->pluck('name'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function subordinates(?string $dn=NULL): array
|
||||||
|
{
|
||||||
|
$dn = $dn ? Crypt::decryptString($dn) : '';
|
||||||
|
|
||||||
|
// Sometimes our key has a command, so we'll ignore it
|
||||||
|
if (str_starts_with($dn,'*') && ($x=strpos($dn,'|')))
|
||||||
|
$dn = substr($dn,$x+1);
|
||||||
|
|
||||||
|
$result = collect();
|
||||||
|
// If no DN, we'll find all children
|
||||||
|
if (! $dn)
|
||||||
|
foreach (Server::baseDNs() as $base)
|
||||||
|
$result = $result->merge(config('server')
|
||||||
|
->subordinates($base->getDN()));
|
||||||
|
else
|
||||||
|
$result = config('server')
|
||||||
|
->subordinates(collect(explode(',',$dn))->last());
|
||||||
|
|
||||||
|
return
|
||||||
|
$result->map(fn($item)=>['id'=>$item->getDNSecure(),'value'=>$item->getDN()])
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
}
|
}
|
@ -112,6 +112,60 @@ class HomeController extends Controller
|
|||||||
->with('updated',FALSE);
|
->with('updated',FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function entry_copy_move(Request $request): \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||||
|
{
|
||||||
|
$from_dn = Crypt::decryptString($request->post('dn'));
|
||||||
|
Log::info(sprintf('%s:Renaming [%s] to [%s]',self::LOGKEY,$from_dn,$request->post('to_dn')));
|
||||||
|
|
||||||
|
$o = clone config('server')->fetch($from_dn);
|
||||||
|
|
||||||
|
if (! $o)
|
||||||
|
return back()
|
||||||
|
->withInput()
|
||||||
|
->with('note',__('DN doesnt exist'));
|
||||||
|
|
||||||
|
$o->setDN($request->post('to_dn'));
|
||||||
|
$o->exists = FALSE;
|
||||||
|
|
||||||
|
// Add the RDN attribute to match the new RDN
|
||||||
|
$rdn = collect(explode(',',$request->post('to_dn')))->first();
|
||||||
|
|
||||||
|
list($attr,$value) = explode('=',$rdn);
|
||||||
|
$o->{$attr} = [Entry::TAG_NOTAG => $o->getObject($attr)->tagValuesOld(Entry::TAG_NOTAG)->push($value)->unique()];
|
||||||
|
|
||||||
|
Log::info(sprintf('%s:Copying [%s] to [%s]',self::LOGKEY,$from_dn,$o->getDN()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$o->save();
|
||||||
|
|
||||||
|
} catch (LdapRecordException $e) {
|
||||||
|
return Redirect::to('/')
|
||||||
|
->withInput(['_key'=>Crypt::encryptString('*dn|'.$from_dn)])
|
||||||
|
->with('failed',sprintf('%s: %s - %s: %s',
|
||||||
|
__('LDAP Server Error Code'),
|
||||||
|
$e->getDetailedError()?->getErrorCode() ?: $e->getMessage(),
|
||||||
|
$e->getDetailedError()?->getErrorMessage() ?: $e->getFile(),
|
||||||
|
$e->getDetailedError()?->getDiagnosticMessage() ?: $e->getLine(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->post('delete') && $request->post('delete') === '1') {
|
||||||
|
Log::info(sprintf('%s:Deleting [%s] after copy',self::LOGKEY,$from_dn));
|
||||||
|
|
||||||
|
$x = $this->entry_delete($request);
|
||||||
|
|
||||||
|
return ($x->getSession()->has('success'))
|
||||||
|
? Redirect::to('/')
|
||||||
|
->withInput(['_key'=>Crypt::encryptString('*dn|'.$o->getDN())])
|
||||||
|
->with('success',__('Entry copied and deleted'))
|
||||||
|
: $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect::to('/')
|
||||||
|
->withInput(['_key'=>Crypt::encryptString('*dn|'.$o->getDN())])
|
||||||
|
->with('success',__('Entry copied'));
|
||||||
|
}
|
||||||
|
|
||||||
public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse
|
public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
$key = $this->request_key($request,collect(old()));
|
$key = $this->request_key($request,collect(old()));
|
||||||
@ -154,7 +208,7 @@ class HomeController extends Controller
|
|||||||
->with('failed',sprintf('%s: %s - %s: %s',
|
->with('failed',sprintf('%s: %s - %s: %s',
|
||||||
__('LDAP Server Error Code'),
|
__('LDAP Server Error Code'),
|
||||||
$e->getDetailedError()->getErrorCode(),
|
$e->getDetailedError()->getErrorCode(),
|
||||||
__($e->getDetailedError()->getErrorMessage()),
|
$e->getDetailedError()->getErrorMessage(),
|
||||||
$e->getDetailedError()->getDiagnosticMessage(),
|
$e->getDetailedError()->getDiagnosticMessage(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -377,7 +431,7 @@ class HomeController extends Controller
|
|||||||
->with('failed',sprintf('%s: %s - %s: %s',
|
->with('failed',sprintf('%s: %s - %s: %s',
|
||||||
__('LDAP Server Error Code'),
|
__('LDAP Server Error Code'),
|
||||||
$e->getDetailedError()->getErrorCode(),
|
$e->getDetailedError()->getErrorCode(),
|
||||||
__($e->getDetailedError()->getErrorMessage()),
|
$e->getDetailedError()->getErrorMessage(),
|
||||||
$e->getDetailedError()->getDiagnosticMessage(),
|
$e->getDetailedError()->getDiagnosticMessage(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -435,8 +489,8 @@ class HomeController extends Controller
|
|||||||
->with('dn',$key['dn'])
|
->with('dn',$key['dn'])
|
||||||
->with('o',$o)
|
->with('o',$o)
|
||||||
->with('page_actions',collect([
|
->with('page_actions',collect([
|
||||||
'copy'=>FALSE,
|
|
||||||
'create'=>($x=($o->getObjects()->except('entryuuid')->count() > 0)),
|
'create'=>($x=($o->getObjects()->except('entryuuid')->count() > 0)),
|
||||||
|
'copy'=>$x,
|
||||||
'delete'=>(! is_null($xx=$o->getObject('hassubordinates')->value)) && ($xx === 'FALSE'),
|
'delete'=>(! is_null($xx=$o->getObject('hassubordinates')->value)) && ($xx === 'FALSE'),
|
||||||
'edit'=>$x,
|
'edit'=>$x,
|
||||||
'export'=>$x,
|
'export'=>$x,
|
||||||
|
@ -92,14 +92,39 @@ class Entry extends Model
|
|||||||
public function getAttributes(): array
|
public function getAttributes(): array
|
||||||
{
|
{
|
||||||
return $this->objects
|
return $this->objects
|
||||||
|
->filter(fn($item)=>(! $item->is_internal))
|
||||||
->flatMap(fn($item)=>
|
->flatMap(fn($item)=>
|
||||||
($item->no_attr_tags)
|
$item->no_attr_tags
|
||||||
? [strtolower($item->name)=>$item->values]
|
? [strtolower($item->name)=>$item->values]
|
||||||
: $item->values
|
: $item->values
|
||||||
->flatMap(fn($v,$k)=>[strtolower($item->name.($k !== self::TAG_NOTAG ? ';'.$k : ''))=>$v]))
|
->flatMap(fn($v,$k)=>[strtolower($item->name.(($k !== self::TAG_NOTAG) ? ';'.$k : ''))=>$v]))
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This replaces the model's get dirty, given that we store LDAP attributes in $this->objects, replacing
|
||||||
|
* $this->original/$this->attributes
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getDirty(): array
|
||||||
|
{
|
||||||
|
$result = collect();
|
||||||
|
|
||||||
|
foreach ($this->objects as $o)
|
||||||
|
if ($o->isDirty())
|
||||||
|
$result = $result->merge($o->getDirty());
|
||||||
|
|
||||||
|
$result = $result
|
||||||
|
->flatMap(function($item,$attr) {
|
||||||
|
return ($x=collect($item))->count()
|
||||||
|
? $x->flatMap(fn($v,$k)=>[strtolower($attr.(($k !== self::TAG_NOTAG) ? ';'.$k : ''))=>$v])
|
||||||
|
: [strtolower($attr)=>[]];
|
||||||
|
});
|
||||||
|
|
||||||
|
return $result->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the new and old values for a given key are equivalent.
|
* Determine if the new and old values for a given key are equivalent.
|
||||||
*/
|
*/
|
||||||
@ -453,7 +478,7 @@ class Entry extends Model
|
|||||||
$ot = $this->getOtherTags();
|
$ot = $this->getOtherTags();
|
||||||
|
|
||||||
$cache[$tag ?: '_all_'] = $this->objects
|
$cache[$tag ?: '_all_'] = $this->objects
|
||||||
->filter(fn($item)=>(! $item->is_internal) && ((! $item->no_attr_tags) || (! $tag) || ($tag === Entry::TAG_NOTAG)))
|
->filter(fn($item)=>(! $item->is_internal) && ((! $item->no_attr_tags) || (! $tag) || ($tag === self::TAG_NOTAG)))
|
||||||
->filter(fn($item)=>(! $tag) || $ot->has($item->name_lc) || count($item->tagValues($tag)) > 0);
|
->filter(fn($item)=>(! $tag) || $ot->has($item->name_lc) || count($item->tagValues($tag)) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ attribute#objectclass .input-group-end:not(input.form-control) {
|
|||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group:first-child:not(.select-group) .select2-container--bootstrap-5 .select2-selection {
|
.input-group:first-child:not(.select-group):not(:last-child) .select2-container--bootstrap-5 .select2-selection {
|
||||||
border-bottom-right-radius: unset;
|
border-bottom-right-radius: unset;
|
||||||
border-top-right-radius: unset;
|
border-top-right-radius: unset;
|
||||||
}
|
}
|
||||||
@ -97,4 +97,9 @@ input.form-control.input-group-end {
|
|||||||
/* Square UL items */
|
/* Square UL items */
|
||||||
ul.square {
|
ul.square {
|
||||||
list-style-type: square;
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix select2 selections when set up with d-none */
|
||||||
|
select[class*="d-none"] + span.select2 {
|
||||||
|
display: none;
|
||||||
}
|
}
|
@ -89,7 +89,7 @@ $(document).ready(function() {
|
|||||||
types: 'active expanded focus selected' // which status types to store
|
types: 'active expanded focus selected' // which status types to store
|
||||||
},
|
},
|
||||||
click: function(event,data) {
|
click: function(event,data) {
|
||||||
if (data.targetType === 'title')
|
if (data.targetType === 'title' && data.node.data.item)
|
||||||
getNode(data.node.data.item);
|
getNode(data.node.data.item);
|
||||||
},
|
},
|
||||||
source: sources,
|
source: sources,
|
||||||
|
@ -23,7 +23,9 @@
|
|||||||
@endif
|
@endif
|
||||||
@if($page_actions->get('copy'))
|
@if($page_actions->get('copy'))
|
||||||
<li>
|
<li>
|
||||||
<button class="btn btn-outline-dark p-1 m-1" id="entry-copy-move" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Copy/Move')" disabled><i class="fas fa-fw fa-copy fs-5"></i></button>
|
<span id="entry-copy-move" data-bs-toggle="modal" data-bs-target="#page-modal">
|
||||||
|
<button class="btn btn-outline-dark p-1 m-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="@lang('Copy/Move')"><i class="fas fa-fw fa-copy fs-5"></i></button>
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
@if($page_actions->get('edit'))
|
@if($page_actions->get('edit'))
|
||||||
@ -79,7 +81,7 @@
|
|||||||
<span data-bs-toggle="tab" href="#template-{{ $template->name }}" @class(['btn','btn-outline-focus','active'=>$loop->index === 0])><i class="fa fa-fw pe-2 {{ $template->icon }}"></i> {{ $template->title }}</span>
|
<span data-bs-toggle="tab" href="#template-{{ $template->name }}" @class(['btn','btn-outline-focus','active'=>$loop->index === 0])><i class="fa fa-fw pe-2 {{ $template->icon }}"></i> {{ $template->title }}</span>
|
||||||
@endforeach
|
@endforeach
|
||||||
@if($o->templates->count())
|
@if($o->templates->count())
|
||||||
<span data-bs-toggle="tab" href="#template-default" @class(['btn','btn-outline-focus','p-1','active'=>(! $o->templates->count())])>{{ __('LDAP Entry') }}</span>
|
<span data-bs-toggle="tab" href="#template-default" @class(['btn','btn-outline-focus','p-1','active'=>(! $o->templates->count())])><i class="fa fa-fw fa-list pe-2"></i> {{ __('LDAP Entry') }}</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -226,6 +228,25 @@
|
|||||||
var that = $(this).find('.modal-content');
|
var that = $(this).find('.modal-content');
|
||||||
|
|
||||||
switch ($(item.relatedTarget).attr('id')) {
|
switch ($(item.relatedTarget).attr('id')) {
|
||||||
|
case 'entry-copy-move':
|
||||||
|
$.ajax({
|
||||||
|
method: 'GET',
|
||||||
|
url: '{{ url('modal/copy-move') }}/'+dn,
|
||||||
|
dataType: 'html',
|
||||||
|
cache: false,
|
||||||
|
beforeSend: function() {
|
||||||
|
that.empty().append('<span class="p-3"><i class="fas fa-3x fa-spinner fa-pulse"></i></span>');
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
that.empty().html(data);
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
if (e.status !== 412)
|
||||||
|
alert('That didnt work? Please try again....');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
case 'entry-delete':
|
case 'entry-delete':
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
@ -30,7 +30,13 @@
|
|||||||
</thead>
|
</thead>
|
||||||
@foreach($result as $item)
|
@foreach($result as $item)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $item->get('dn') }}</td>
|
<td>
|
||||||
|
@if($x=$item->get('link'))
|
||||||
|
<a href="{{ url('/') }}#{{ $x }}">{{ $item->get('dn') }}</a>
|
||||||
|
@else
|
||||||
|
{{ $item->get('dn') }}
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
<td>{{ $item->get('result') }}</td>
|
<td>{{ $item->get('result') }}</td>
|
||||||
<td class="text-end">{{ $item->get('line') }}</td>
|
<td class="text-end">{{ $item->get('line') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
178
resources/views/modals/entry-copy-move.blade.php
Normal file
178
resources/views/modals/entry-copy-move.blade.php
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
<div class="modal-header bg-dark text-white">
|
||||||
|
<h1 class="modal-title fs-5">
|
||||||
|
<i class="fas fa-fw fa-exclamation-triangle"></i> @lang('Rename') <strong>{{ $x=Crypt::decryptString($dn) }}</strong>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<span>
|
||||||
|
@lang('New') DN: <strong><span id="newdn" class="fs-4 opacity-50"><small class="fs-5">[@lang('Select Base')]</small></span></strong>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<form id="entry-rename-form" method="POST" action="{{ url('entry/copy-move') }}">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="dn" value="{{ $dn }}">
|
||||||
|
<input type="hidden" name="to_dn" value="">
|
||||||
|
|
||||||
|
<div class="row pb-3">
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="delete-checkbox" name="delete" value="1">
|
||||||
|
<label class="form-check-label" for="delete-checkbox">
|
||||||
|
<i class="fas fa-fw fa-trash"></i> @lang('Delete after Copy')
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="label">@lang('Select Base of Entry')</span>
|
||||||
|
<input type="text" id="rdn" class="form-control d-none" style="width:20%;" placeholder="{{ $rdn=collect(explode(',',$x))->first() }}" value="{{ $rdn }}">
|
||||||
|
<span class="input-group-text p-1 d-none">,</span>
|
||||||
|
<select class="form-select w-25 d-none" id="rename-subbase" disabled style="width:30%;"></select>
|
||||||
|
<span class="input-group-text p-1 d-none">,</span>
|
||||||
|
<select class="form-select w-25" id="rename-base" style="width:30%;" disabled></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<x-modal.close/>
|
||||||
|
<button id="entry-rename" type="button" class="btn btn-sm btn-primary">@lang('Copy')</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function refreshdn(value) {
|
||||||
|
$('#newdn')
|
||||||
|
.removeClass('opacity-50')
|
||||||
|
.empty()
|
||||||
|
.append(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
var rdn = '{{ $rdn }}';
|
||||||
|
var base = '';
|
||||||
|
|
||||||
|
var that=$('#newdn');
|
||||||
|
|
||||||
|
// Get our bases
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
url: '{{ url('ajax/subordinates') }}',
|
||||||
|
dataType: 'json',
|
||||||
|
cache: false,
|
||||||
|
beforeSend: function() {
|
||||||
|
that.empty().append('<span class="p-3"><i class="fas fa-xs fa-spinner fa-pulse"></i></span>');
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
that.empty().html('<small class="fs-5">[@lang('Select Base')]</small>');
|
||||||
|
|
||||||
|
$('#rename-base').children().remove();
|
||||||
|
$('#rename-base').append('<option value=""></option>');
|
||||||
|
data.forEach(function(item) {
|
||||||
|
$('#rename-base').append('<option value="'+item.id+'">'+item.value+'</option>');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#rename-base').prop('disabled',false);
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
if (e.status !== 412)
|
||||||
|
alert('That didnt work? Please try again....');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// The base DN container
|
||||||
|
$('#rename-base').select2({
|
||||||
|
dropdownParent: $('#page-modal'),
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
dropdownAutoWidth: true,
|
||||||
|
width: 'style',
|
||||||
|
allowClear: false,
|
||||||
|
placeholder: 'Choose Base',
|
||||||
|
})
|
||||||
|
.on('change',function() {
|
||||||
|
$(this).prev().removeClass('d-none');
|
||||||
|
$('#rename-subbase').removeClass('d-none')
|
||||||
|
.prev().removeClass('d-none')
|
||||||
|
.prev().removeClass('d-none');
|
||||||
|
$('#label').empty().append("@lang('Complete Path')");
|
||||||
|
|
||||||
|
base = '';
|
||||||
|
if (x=$('#rename-subbase option:selected').text())
|
||||||
|
base += x+',';
|
||||||
|
base += $('#rename-base option:selected').text();
|
||||||
|
|
||||||
|
refreshdn(rdn+','+base);
|
||||||
|
var newdn = '';
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
url:'{{ url('ajax/children') }}',
|
||||||
|
data: {_key: $(this).val() },
|
||||||
|
dataType: 'json',
|
||||||
|
cache: false,
|
||||||
|
beforeSend: function() {
|
||||||
|
newdn = that.text();
|
||||||
|
console.log(newdn);
|
||||||
|
that.empty().append('<span class="p-3"><i class="fas fa-xs fa-spinner fa-pulse"></i></span>');
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
that.empty().text(newdn);
|
||||||
|
$('#rename-subbase').children().remove();
|
||||||
|
$('#rename-subbase').append('<option value=""></option>');
|
||||||
|
data.forEach(function(item) {
|
||||||
|
$('#rename-subbase').append('<option value="'+item.item+'">'+item.title+'</option>');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#rename-subbase').prop('disabled',false);
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
if (e.status !== 412)
|
||||||
|
alert('That didnt work? Please try again....');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optional make a child a new branch
|
||||||
|
$('#rename-subbase').select2({
|
||||||
|
dropdownParent: $('#page-modal'),
|
||||||
|
theme: 'bootstrap-5',
|
||||||
|
dropdownAutoWidth: true,
|
||||||
|
width: 'style',
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: 'New Subordinate (optional)',
|
||||||
|
})
|
||||||
|
.on('change',function(item) {
|
||||||
|
base = '';
|
||||||
|
if (x=$('#rename-subbase option:selected').text())
|
||||||
|
base += x+',';
|
||||||
|
base += $('#rename-base option:selected').text();
|
||||||
|
|
||||||
|
refreshdn(rdn+','+base);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Complete the RDN
|
||||||
|
$('#rdn').on('input',function(item) {
|
||||||
|
rdn = $(this).val();
|
||||||
|
refreshdn(rdn+','+base);
|
||||||
|
|
||||||
|
$('button[id=entry-rename]').attr('disabled',! rdn.includes('='));
|
||||||
|
})
|
||||||
|
|
||||||
|
// The submit button text
|
||||||
|
$('input#delete-checkbox').on('change',function() {
|
||||||
|
$('button#entry-rename').html($(this).prop('checked') ? '{{ __('Move') }}' : '{{ __('Copy') }}');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Submit
|
||||||
|
$('button[id=entry-rename]').on('click',function() {
|
||||||
|
$('input[name=to_dn]').val(rdn+','+base);
|
||||||
|
$('form#entry-rename-form').submit();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
@ -43,18 +43,21 @@ Route::controller(HomeController::class)->group(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Route::match(['get','post'],'entry/add','entry_add');
|
Route::match(['get','post'],'entry/add','entry_add');
|
||||||
|
Route::post('entry/attr/add/{id}','entry_attr_add');
|
||||||
Route::post('entry/create','entry_create');
|
Route::post('entry/create','entry_create');
|
||||||
|
Route::post('entry/copy-move','entry_copy_move');
|
||||||
Route::post('entry/delete','entry_delete');
|
Route::post('entry/delete','entry_delete');
|
||||||
Route::get('entry/export/{id}','entry_export');
|
Route::get('entry/export/{id}','entry_export');
|
||||||
Route::post('entry/password/check/','entry_password_check');
|
Route::post('entry/password/check/','entry_password_check');
|
||||||
Route::post('entry/attr/add/{id}','entry_attr_add');
|
|
||||||
Route::post('entry/objectclass/add','entry_objectclass_add');
|
Route::post('entry/objectclass/add','entry_objectclass_add');
|
||||||
Route::post('entry/rename','entry_rename');
|
Route::post('entry/rename','entry_rename');
|
||||||
|
|
||||||
Route::post('entry/update/commit','entry_update');
|
Route::post('entry/update/commit','entry_update');
|
||||||
Route::post('entry/update/pending','entry_pending_update');
|
Route::post('entry/update/pending','entry_pending_update');
|
||||||
|
|
||||||
Route::post('import/process/{type}','import');
|
Route::post('import/process/{type}','import');
|
||||||
|
|
||||||
|
Route::view('modal/copy-move/{dn}','modals.entry-copy-move');
|
||||||
Route::view('modal/delete/{dn}','modals.entry-delete');
|
Route::view('modal/delete/{dn}','modals.entry-delete');
|
||||||
Route::view('modal/export/{dn}','modals.entry-export');
|
Route::view('modal/export/{dn}','modals.entry-export');
|
||||||
Route::view('modal/rename/{dn}','modals.entry-rename');
|
Route::view('modal/rename/{dn}','modals.entry-rename');
|
||||||
@ -69,4 +72,5 @@ Route::controller(AjaxController::class)
|
|||||||
Route::post('children','children');
|
Route::post('children','children');
|
||||||
Route::post('schema/view','schema_view');
|
Route::post('schema/view','schema_view');
|
||||||
Route::post('schema/objectclass/attrs/{id}','schema_objectclass_attrs');
|
Route::post('schema/objectclass/attrs/{id}','schema_objectclass_attrs');
|
||||||
|
Route::post('subordinates','subordinates');
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user