LSldapObject: clean updata/validate form data code to fix handling just check mode

This commit is contained in:
Benjamin Renard 2021-02-04 11:49:35 +01:00
parent e05f0df20d
commit a25b1e8c10

View file

@ -292,7 +292,7 @@ class LSldapObject extends LSlog_staticLoggerClass {
* _updateData() protected method. * _updateData() protected method.
* *
* @param[in] $idForm Form ID * @param[in] $idForm Form ID
* @param[in] $justValidate Boolean to enable just validation mode * @param[in] $justCheck Boolean to enable just check mode
* *
* @see _updateData() * @see _updateData()
* *
@ -300,7 +300,7 @@ class LSldapObject extends LSlog_staticLoggerClass {
* *
* @retval boolean true if object data was updated, false otherwise * @retval boolean true if object data was updated, false otherwise
*/ */
public function updateData($idForm=NULL,$justValidate=False) { public function updateData($idForm=NULL, $justCheck=False) {
if($idForm!=NULL) { if($idForm!=NULL) {
if(isset($this -> forms[$idForm])) if(isset($this -> forms[$idForm]))
$LSform = $this -> forms[$idForm][0]; $LSform = $this -> forms[$idForm][0];
@ -323,8 +323,8 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
} }
$new_data = $LSform -> exportValues(); $new_data = $LSform -> exportValues();
self :: log_debug($this. "->updateData($idForm, $justValidate): new data=".varDump($new_data)); self :: log_debug($this. "->updateData($idForm, $justCheck): new data=".varDump($new_data));
return $this -> _updateData($new_data,$idForm,$justValidate); return $this -> _updateData($new_data, $idForm, $justCheck);
} }
/** /**
@ -335,7 +335,7 @@ class LSldapObject extends LSlog_staticLoggerClass {
* *
* @param[in] $new_data Array of object data * @param[in] $new_data Array of object data
* @param[in] $idForm Form ID * @param[in] $idForm Form ID
* @param[in] $justValidate Boolean to enable just validation mode * @param[in] $justCheck Boolean to enable just check mode
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
@ -345,7 +345,7 @@ class LSldapObject extends LSlog_staticLoggerClass {
* @see validateAttrsData() * @see validateAttrsData()
* @see submitChange() * @see submitChange()
*/ */
protected function _updateData($new_data,$idForm=null,$justValidate=False) { protected function _updateData($new_data, $idForm=null, $justCheck=False) {
if(!is_array($new_data)) { if(!is_array($new_data)) {
return; return;
} }
@ -354,9 +354,9 @@ class LSldapObject extends LSlog_staticLoggerClass {
$this -> attrs[$attr_name] -> setUpdateData($attr_val); $this -> attrs[$attr_name] -> setUpdateData($attr_val);
} }
} }
if($this -> validateAttrsData($idForm)) { if($this -> validateAttrsData($idForm, $justCheck)) {
self :: log_debug($this."->_updateData(): Update data are validated"); self :: log_debug($this."->_updateData(): Update data are validated");
if ($justValidate) { if ($justCheck) {
self :: log_debug($this."->_updateData(): Just validate mode"); self :: log_debug($this."->_updateData(): Just validate mode");
return True; return True;
} }
@ -398,15 +398,16 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
/** /**
* Valide les données retournées par un formulaire * Validate data returned by form
* *
* @param[in] $idForm Identifiant du formulaire d'origine * @param[in] $idForm string The source LSform ID
* @param[in] $justCheck Boolean to enable just check mode (do not validate data using LDAP search)
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @retval boolean true si les données sont valides, false sinon * @retval boolean True if form data are valid, False otherwise
*/ */
public function validateAttrsData($idForm=null) { public function validateAttrsData($idForm=null, $justCheck=False) {
$retval = true; $retval = true;
if ($idForm) { if ($idForm) {
$LSform=$this -> forms[$idForm][0]; $LSform=$this -> forms[$idForm][0];
@ -418,14 +419,14 @@ class LSldapObject extends LSlog_staticLoggerClass {
$attr_values = $attr -> getValue(); $attr_values = $attr -> getValue();
if (!$attr -> isValidate()) { if (!$attr -> isValidate()) {
if($attr -> isUpdate()) { if($attr -> isUpdate()) {
if (!$this -> validateAttrData($LSform, $attr)) { if (!$this -> validateAttrData($LSform, $attr, $justCheck)) {
$retval = false; $retval = false;
} }
} }
else if( (empty($attr_values)) && ($attr -> isRequired()) ) { else if( (empty($attr_values)) && ($attr -> isRequired()) ) {
if ( $attr -> canBeGenerated()) { if ( $attr -> canBeGenerated()) {
if ($attr -> generateValue()) { if ($attr -> generateValue()) {
if (!$this -> validateAttrData($LSform, $attr)) { if (!$this -> validateAttrData($LSform, $attr, $justCheck)) {
LSerror :: addErrorCode('LSattribute_08',$attr -> getLabel()); LSerror :: addErrorCode('LSattribute_08',$attr -> getLabel());
$retval = false; $retval = false;
} }
@ -450,161 +451,186 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
/** /**
* Valide les données d'un attribut * Validate one attribute's data returned by form
* *
* @param[in] $LSForm Formulaire d'origine * @param[in] $idForm string The source LSform ID
* @param[in] &$attr Attribut à valider * @param[in] &$attr LSattribute The attribute to validate
* @param[in] $justCheck Boolean to enable just check mode (do not validate data using LDAP search)
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @retval boolean true si les données sont valides, false sinon * @retval boolean True if form data for this attribute are valid, False otherwise
*/ */
public function validateAttrData(&$LSform,&$attr) { public function validateAttrData(&$LSform, &$attr, $justCheck=false) {
$retval = true; $retval = true;
$vconfig = $attr -> getValidateConfig(); $vconfig = $attr -> getValidateConfig();
// Validate attribute values // Validate attribute values
foreach($attr -> getConfig('validation', array(), 'array') as $test) { if ($justCheck) {
self :: log_trace("validateAttrData(".$LSform->idForm.", ".$attr->name."): run validation with following config:\n".varDump($test)); self :: log_trace(
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
"just check mode: do not validate attribute data using LDAP search"
);
}
else {
foreach($attr -> getConfig('validation', array(), 'array') as $test) {
self :: log_trace(
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
"run validation with following config:\n".varDump($test)
);
// Generate error message // Generate error message
$msg_error = LSconfig :: get('msg', null, 'string', $test); $msg_error = LSconfig :: get('msg', null, 'string', $test);
if ($msg_error) { if ($msg_error) {
$msg_error = $this -> getFData(__($msg_error)); $msg_error = $this -> getFData(__($msg_error));
} }
else { else {
$msg_error = getFData(_("The attribute %{attr} is not valid."), $attr -> getLabel()); $msg_error = getFData(_("The attribute %{attr} is not valid."), $attr -> getLabel());
} }
// Iter on attribute values to check all of it // Iter on attribute values to check all of it
foreach(ensureIsArray($attr -> getUpdateData()) as $val) { foreach(ensureIsArray($attr -> getUpdateData()) as $val) {
// Validation using LDAP search // Validation using LDAP search
if((isset($test['filter'])||isset($test['basedn']))&&(isset($test['result']))) { if((isset($test['filter']) || isset($test['basedn'])) && isset($test['result'])) {
$this -> other_values['val'] = $val; $this -> other_values['val'] = $val;
$sparams = array( $sparams = array(
'scope' => LSconfig :: get('scope', 'sub', 'string', $test), 'scope' => LSconfig :: get('scope', 'sub', 'string', $test),
'onlyAccessible' => False, 'onlyAccessible' => False,
); );
// Handle filter parameter // Handle filter parameter
$sfilter_user = LSconfig :: get('filter', null, 'string', $test); $sfilter_user = LSconfig :: get('filter', null, 'string', $test);
if ($sfilter_user) { if ($sfilter_user) {
$sfilter_user = $this -> getFData($test['filter']); $sfilter_user = $this -> getFData($test['filter']);
// Check if filter format is surronded by '()' // Check if filter format is surronded by '()'
if ($sfilter_user[0]!='(') if ($sfilter_user[0] != '(')
$sfilter_user = "($sfilter_user)"; $sfilter_user = "($sfilter_user)";
$sfilter_user = Net_LDAP2_Filter::parse($sfilter_user); $sfilter_user = Net_LDAP2_Filter::parse($sfilter_user);
} }
// Handle object_type parameter & compose final LDAP filter string // Handle object_type parameter & compose final LDAP filter string
$object_type = LSconfig :: get('object_type', null, 'string', $test); $object_type = LSconfig :: get('object_type', null, 'string', $test);
if($object_type && LSsession :: loadLSobject($object_type) ) { if($object_type && LSsession :: loadLSobject($object_type) ) {
$sfilter = self :: _getObjectFilter($object_type); $sfilter = self :: _getObjectFilter($object_type);
if ($sfilter_user) if ($sfilter_user)
$sfilter = LSldap::combineFilters('and', array($sfilter_user, $sfilter)); $sfilter = LSldap::combineFilters('and', array($sfilter_user, $sfilter));
} }
else { else {
$sfilter = $sfilter_user; $sfilter = $sfilter_user;
} }
// Handle base_dn parameter // Handle base_dn parameter
$sbasedn = LSconfig :: get('basedn', null, 'string', $test); $sbasedn = LSconfig :: get('basedn', null, 'string', $test);
if ($sbasedn) if ($sbasedn)
$sbasedn = $this -> getFData($sbasedn); $sbasedn = $this -> getFData($sbasedn);
// If except_current_object (and not create form), list matching objets to exclude current one // If except_current_object (and not create form), list matching objets to exclude current one
if (LSconfig :: get('except_current_object', false, 'bool', $test) && $LSform -> idForm != 'create') { if (LSconfig :: get('except_current_object', false, 'bool', $test) &&
$sret = LSldap :: search($sfilter, $sbasedn, $sparams); $LSform -> idForm != 'create') {
$dn = $this->getDn(); $sret = LSldap :: search($sfilter, $sbasedn, $sparams);
$ret = 0; $dn = $this->getDn();
foreach($sret as $obj) $ret = 0;
if ($obj['dn'] != $dn) foreach($sret as $obj)
$ret++; if ($obj['dn'] != $dn)
} $ret++;
else { }
// Otherwise, just retreive number of matching objets else {
$ret = LSldap :: getNumberResult($sfilter, $sbasedn, $sparams); // Otherwise, just retreive number of matching objets
if (!is_int($ret)) { $ret = LSldap :: getNumberResult($sfilter, $sbasedn, $sparams);
// An error occured if (!is_int($ret)) {
// An error occured
$retval = false;
continue;
}
}
// Check result
$configured_result = LSconfig :: get('result', null, 'int', $test);
if(
($configured_result == 0 && $ret != 0) ||
($configured_result > 0 && $ret <= 0)
) {
$retval = false; $retval = false;
continue; self :: log_warning(
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
"validation with LDAP search on base DN='$sbasedn' and ".
"filter='".($sfilter?$sfilter->as_string():null)."' error ($ret object(s) found)"
);
if ($LSform)
$LSform -> setElementError($attr, $msg_error);
}
else {
self :: log_trace(
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
"validation with LDAP search on base DN='$sbasedn' and ".
"filter='".($sfilter?$sfilter->as_string():null)."' success ($ret object(s) found)"
);
} }
} }
// Validation using external function
// Check result else if(isset($test['function'])) {
$configured_result = LSconfig :: get('result', null, 'int', $test); if (function_exists($test['function'])) {
if( if(!call_user_func_array($test['function'], array(&$this))) {
($configured_result == 0 && $ret != 0) || if ($LSform)
($configured_result > 0 && $ret <= 0) $LSform -> setElementError($attr,$msg_error);
) { $retval = false;
$retval = false; }
self :: log_warning( }
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ". else {
"validation with LDAP search on base DN='$sbasedn' and ". LSerror :: addErrorCode(
"filter='".($sfilter?$sfilter->as_string():null)."' error ($ret object(s) found)" 'LSldapObject_04',
); array(
if ($LSform) 'attr' => $attr->name,
$LSform -> setElementError($attr, $msg_error); 'obj' => $this->getType(),
} 'func' => $test['function']
else { )
self :: log_trace( );
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
"validation with LDAP search on base DN='$sbasedn' and ".
"filter='".($sfilter?$sfilter->as_string():null)."' success ($ret object(s) found)"
);
}
}
// Validation using external function
else if(isset($test['function'])) {
if (function_exists($test['function'])) {
if(!call_user_func_array($test['function'], array(&$this))) {
if ($LSform)
$LSform -> setElementError($attr,$msg_error);
$retval = false; $retval = false;
} }
} }
else { else {
LSerror :: addErrorCode( LSerror :: addErrorCode(
'LSldapObject_04', 'LSldapObject_05',
array( array(
'attr' => $attr->name, 'attr' => $attr->name,
'obj' => $this->getType(), 'obj' => $this->getType()
'func' => $test['function']
) )
); );
$retval = false; $retval = false;
} }
} }
else {
LSerror :: addErrorCode(
'LSldapObject_05',
array(
'attr' => $attr->name,
'obj' => $this->getType()
)
);
$retval = false;
}
} }
} }
// Generate values of dependent attributes // Generate values of dependent attributes
$dependsAttrs = $attr->getDependsAttrs(); $dependsAttrs = $attr->getDependsAttrs();
if (!empty($dependsAttrs)) { if (empty($dependsAttrs)) {
self :: log_trace(
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
"no dependent attribute"
);
}
else {
foreach($dependsAttrs as $dependAttr) { foreach($dependsAttrs as $dependAttr) {
if(!isset($this -> attrs[$dependAttr])){ if(!isset($this -> attrs[$dependAttr])){
LSerror :: addErrorCode('LSldapObject_14',array('attr_depend' => $dependAttr, 'attr' => $attr -> getLabel())); LSerror :: addErrorCode(
'LSldapObject_14',
array('attr_depend' => $dependAttr, 'attr' => $attr -> getLabel())
);
continue; continue;
} }
self :: log_debug('Attribute '.$attr->name.' updated: generate new value for attribute '.$dependAttr); self :: log_debug(
"validateAttrData(".$LSform->idForm.", ".$attr->name."): ".
'Attribute '.$attr->name.' updated: generate new value for attribute '.$dependAttr
);
if($this -> attrs[$dependAttr] -> canBeGenerated()) { if($this -> attrs[$dependAttr] -> canBeGenerated()) {
if (!$this -> attrs[$dependAttr] -> generateValue()) { if (!$this -> attrs[$dependAttr] -> generateValue()) {
LSerror :: addErrorCode('LSattribute_07',$this -> attrs[$dependAttr] -> getLabel()); LSerror :: addErrorCode('LSattribute_07', $this -> attrs[$dependAttr] -> getLabel());
$retval = false; $retval = false;
} }
elseif (!$this -> validateAttrData($LSform,$this -> attrs[$dependAttr])) { elseif (!$this -> validateAttrData($LSform, $this -> attrs[$dependAttr], $justCheck)) {
LSerror :: addErrorCode('LSattribute_08',$this -> attrs[$dependAttr] -> getLabel()); LSerror :: addErrorCode('LSattribute_08', $this -> attrs[$dependAttr] -> getLabel());
$retval = false; $retval = false;
} }
} }
@ -614,9 +640,6 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
} }
} }
else {
self :: log_trace("validateAttrData(".$LSform->idForm.", ".$attr->name."): no dependent attribute");
}
$attr -> validate(); $attr -> validate();
unset($this -> other_values['val']); unset($this -> other_values['val']);
@ -624,13 +647,13 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
/** /**
* Met à jour les données modifiés dans l'annuaire * Submit changes made to LDAP directory
* *
* @param[in] $idForm Identifiant du formulaire d'origine * @param[in] $idForm string The source LSform ID
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @retval boolean true si la mise à jour a réussi, false sinon * @retval boolean True if changes are successfully push to LDAP directory, False otherwise
*/ */
public function submitChange($idForm) { public function submitChange($idForm) {
$submitData=array(); $submitData=array();