LSldap: fix/improve update() and getEntry() methods

This commit is contained in:
Benjamin Renard 2020-09-09 19:02:32 +02:00
parent a4183a88fc
commit 63f57cfd77

View file

@ -220,25 +220,26 @@ class LSldap extends LSlog_staticLoggerClass {
* ) * )
*/ */
public static function getEntry($object_type,$dn) { public static function getEntry($object_type,$dn) {
$obj_conf=LSconfig :: get('LSobjects.'.$object_type); $obj_classes = LSconfig :: get("LSobjects.$object_type.objectclass");
if(is_array($obj_conf)){ if(!is_array($obj_classes)){
$entry = self :: getLdapEntry($dn);
if ($entry === false) {
$newentry = self :: getNewEntry($dn,$obj_conf['objectclass'],array());
if (!$newentry) {
return;
}
return array('entry' => $newentry,'new' => true);
}
else {
return $entry;
}
}
else {
LSerror :: addErrorCode('LSldap_03'); LSerror :: addErrorCode('LSldap_03');
return; return;
} }
$entry = self :: getLdapEntry($dn);
if ($entry === false) {
$newentry = self :: getNewEntry($dn, $obj_classes, array());
if (!$newentry) {
return;
}
// Mark entry as new
$newentry -> markAsNew();
return $newentry;
}
// Mark entry as NOT new
$entry -> markAsNew(false);
return $entry;
} }
/** /**
@ -296,88 +297,104 @@ class LSldap extends LSlog_staticLoggerClass {
* *
* @retval boolean true si l'objet a bien été mis à jour, false sinon * @retval boolean true si l'objet a bien été mis à jour, false sinon
*/ */
public static function update($object_type,$dn,$change) { public static function update($object_type, $dn, $change) {
self :: log_debug($change); self :: log_trace("update($object_type, $dn): change=".varDump($change));
$dropAttr=array();
$entry=self :: getEntry($object_type,$dn); // Retreive current LDAP entry
if (is_array($entry)) { $entry = self :: getEntry($object_type, $dn);
$new = $entry['new']; if(!is_a($entry, 'Net_LDAP2_Entry')) {
$entry = $entry['entry']; LSerror :: addErrorCode('LSldap_04');
} return;
else {
$new = false;
} }
if($entry) { // Distinguish drop attributes from change attributes
$changed_attrs = array();
$dropped_attrs = array();
foreach($change as $attrName => $attrVal) { foreach($change as $attrName => $attrVal) {
$drop = true; $drop = true;
if (is_array($attrVal)) { if (is_array($attrVal)) {
foreach($attrVal as $val) { foreach($attrVal as $val) {
if (!empty($val)||(is_string($val)&&($val=="0"))) { if (!empty($val)||(is_string($val)&&($val=="0"))) {
$drop = false; $drop = false;
$changeData[$attrName][]=$val; $changed_attrs[$attrName][]=$val;
} }
} }
} }
else { else {
if (!empty($attrVal)||(is_string($attrVal)&&($attrVal=="0"))) { if (!empty($attrVal)||(is_string($attrVal)&&($attrVal=="0"))) {
$drop = false; $drop = false;
$changeData[$attrName][]=$attrVal; $changed_attrs[$attrName][]=$attrVal;
} }
} }
if($drop) { if($drop) {
$dropAttr[] = $attrName; $dropped_attrs[] = $attrName;
} }
} }
if (isset($changeData)) { self :: log_trace("update($object_type, $dn): changed attrs=".varDump($changed_attrs));
$entry -> replace($changeData); self :: log_trace("update($object_type, $dn): dropped attrs=".varDump($dropped_attrs));
self :: log_debug('change : <pre>'.print_r($changeData,true).'</pre>');
self :: log_debug('drop : <pre>'.print_r($dropAttr,true).'</pre>');
}
else {
self :: log_debug('No change');
}
if ($new) { // Set an error flag to false
self :: log_debug('LSldap :: add()'); $error = false;
// Handle attributes changes (if need)
if ($changed_attrs) {
$entry -> replace($changed_attrs);
if ($entry -> isNew()) {
self :: log_debug("update($object_type, $dn): add new entry");
$ret = self :: $cnx -> add($entry); $ret = self :: $cnx -> add($entry);
} }
else { else {
self :: log_debug('LSldap :: update()'); self :: log_debug("update($object_type, $dn): update entry (for changed attributes)");
$ret = $entry -> update(); $ret = $entry -> update();
} }
if (Net_LDAP2::isError($ret)) { if (Net_LDAP2::isError($ret)) {
LSerror :: addErrorCode('LSldap_05',$dn); LSerror :: addErrorCode('LSldap_05',$dn);
LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage()); LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage());
return false;
}
}
elseif ($entry -> isNew()) {
self :: log_error("update($object_type, $dn): no changed attribute but it's a new entry...");
return false;
} }
else { else {
if (!empty($dropAttr) && !$new) { self :: log_debug("update($object_type, $dn): no changed attribute");
foreach($dropAttr as $attr) { }
$value = $entry -> getValue($attr);
if(Net_LDAP2::isError($value) || empty($value)) { // Handle droped attributes (is need and not a new entry)
// Attribut n'existe pas dans l'annuaire if ($dropped_attrs && !$entry -> isNew()) {
// $entry -> delete() method is buggy (for some attribute like jpegPhoto)
// Prefer replace attribute by an empty array
$replace_attrs = array();
foreach($dropped_attrs as $attr) {
// Check if attribute is present
if(!$entry -> exists($attr)) {
// Attribute not present on LDAP entry
self :: log_debug("update($object_type, $dn): dropped attr $attr is not present in LDAP entry => ignore it");
continue; continue;
} }
// M<>thode bugg<67> : suppression impossible de certain attribut $replace_attrs[$attr] = array();
// exemple : jpegPhoto
// $entry -> delete($attr);
$entry -> replace(array($attr =>array()));
} }
if (!$replace_attrs) {
self :: log_debug("update($object_type, $dn): no attribute to drop");
return true;
}
// Replace values in LDAP
$entry -> replace($replace_attrs);
self :: log_debug("update($object_type, $dn): update entry (for dropped attributes: ".implode(', ', array_keys($replace_attrs)).")");
$ret = $entry -> update(); $ret = $entry -> update();
// Check result
if (Net_LDAP2::isError($ret)) { if (Net_LDAP2::isError($ret)) {
LSerror :: addErrorCode('LSldap_06'); LSerror :: addErrorCode('LSldap_06');
LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage()); LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage());
return false;
} }
} }
return true; return true;
} }
}
else {
LSerror :: addErrorCode('LSldap_04');
return;
}
}
/** /**
* Test de bind * Test de bind