Compare commits

..

No commits in common. "6cfde7f08425eb0d825f8a8ecf1b0abf3b762a00" and "24d76d6c9c3461b7781b36b3880f5d1512fb94f9" have entirely different histories.

5 changed files with 161 additions and 262 deletions

View file

@ -47,13 +47,7 @@ class LSattr_html_select_object extends LSattr_html{
*/ */
public function addToForm (&$form,$idForm,$data=NULL) { public function addToForm (&$form,$idForm,$data=NULL) {
$this -> config['attrObject'] = $this; $this -> config['attrObject'] = $this;
$element = $form -> addElement( $element=$form -> addElement($this -> LSformElement_type, $this -> name, $this -> getLabel(), $this -> config, $this);
$this -> LSformElement_type,
$this -> name,
$this -> getLabel(),
$this -> config,
$this
);
if(!$element) { if(!$element) {
LSerror :: addErrorCode('LSform_06',$this -> name); LSerror :: addErrorCode('LSform_06',$this -> name);
return false; return false;
@ -180,8 +174,8 @@ class LSattr_html_select_object extends LSattr_html{
* *
* @param mixed $values array|null Array of the input values () * @param mixed $values array|null Array of the input values ()
* @param boolean $fromDNs boolean If true, considered provided values as DNs (default: false) * @param boolean $fromDNs boolean If true, considered provided values as DNs (default: false)
* @param boolean $retrieveAttrValues boolean If true, final attribute values will be returned * @param boolean $retrieveAttrValues boolean If true, attribute values will be returned instead
* instead of selected objects info (default: false) * of selected objects info (default: false)
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
@ -199,131 +193,62 @@ class LSattr_html_select_object extends LSattr_html{
self :: log_warning('getFormValues(): $values is not array'); self :: log_warning('getFormValues(): $values is not array');
return false; return false;
} }
if (!LSsession :: loadLSclass("LSsearch"))
return false;
// Retrieve/check selectable objects config // Retrieve/check selectable objects config
$objs = []; $objs = array();
$confs = $this -> getSelectableObjectsConfig($objs); $confs = $this -> getSelectableObjectsConfig($objs);
if (!is_array($confs) || empty($confs)) { if (!is_array($confs) || empty($confs)) {
self :: log_warning('getFormValues(): invalid selectable objects config'); self :: log_warning('getFormValues(): invalid selectable objects config');
return false; return false;
} }
$selected_objects = []; $selected_objects = array();
$found_values = []; $unrecognizedValues = array();
$unrecognizedValues = []; $found_values = array();
foreach ($confs as $conf) { foreach ($confs as $conf) {
$common_search_params = [
"filter" => $conf['filter'],
"attributes" => (
$retrieveAttrValues && !in_array($conf['value_attribute'], ["dn", "%{dn}"])?
[$conf['value_attribute']]:
[$objs[$conf['object_type']]->rdn_attr]
),
"displayFormat" => (
$conf['display_name_format']?
$conf['display_name_format']:
$objs[$conf['object_type']] -> getDisplayNameFormat()
),
];
foreach($values as $value) { foreach($values as $value) {
// Ignore empty value and value already marked as unrecognized // If we already mark its value as unrecognized, pass
if (empty($value) || in_array($value, $unrecognizedValues)) if (in_array($value, $unrecognizedValues))
continue; continue;
// Compute search params based on value attribute type (DN or attribute valued) and $fromDNs // Ignore empty value
if($fromDNs || in_array($conf['value_attribute'], ['dn', '%{dn}'])) { if (empty($value))
if ($conf['onlyAccessible'] && !LSsession :: canAccess($conf['object_type'], $value)) { continue;
self :: log_debug(
"getFormValues(): object {$conf['object_type']} '$value' is not accessible, pass" // Determine value attribute: DN/attribute valued (or force form DNs)
); if(($conf['value_attribute']=='dn') || ($conf['value_attribute']=='%{dn}') || $fromDNs) {
// Construct resulting list from DN values
if ($conf['onlyAccessible']) {
if (!LSsession :: canAccess($conf['object_type'], $value)) {
self :: log_debug("getFormValues(): ".$conf['object_type']."($value): not accessible, pass");
continue; continue;
} }
$search_params = array_merge(
$common_search_params,
["basedn" => $value, "scope" => "base"]
);
}
else {
$filter = Net_LDAP2_Filter::create($conf['value_attribute'], 'equals', $value);
$search_params = array_merge(
$common_search_params,
[
"filter" => (
$common_search_params["filter"]?
LSldap::combineFilters('and', [$common_search_params["filter"], $filter]):
$filter
),
]
);
} }
// Search object // Load object data (with custom filter if defined)
$LSsearch = new LSsearch( if(!$objs[$conf['object_type']] -> loadData($value, $conf['filter'])) {
$conf['object_type'], self :: log_debug("getFormValues(): ".$conf['object_type']."($value): not found, pass");
'LSattr_html_select_object::getFormValues',
$search_params,
true
);
if(!$LSsearch -> run(false)) {
self :: log_warning(
"getFormValues(): error during search of object(s) {$conf['object_type']} ".
"for value '$value', pass"
);
continue; continue;
} }
self :: log_debug("getFormValues(): ".$conf['object_type']."($value): found");
$entries = $LSsearch -> listEntries();
if (!is_array($entries) || empty($entries)) {
self :: log_debug(
"getFormValues(): value '$value' not found as {$conf['object_type']}, pass"
);
continue;
}
if (count($entries) > 1) {
self :: log_warning(
"getFormValues(): ".count($entries)." objects {$conf['object_type']} found ".
"for value '$value', pass: ".implode(" / ", array_keys($entries))
);
if (array_key_exists($value, $selected_objects))
unset($selected_objects[$value]);
$unrecognizedValues[] = $value;
$found_values[$value] = (
array_key_exists($value, $found_values)?
array_merge($found_values[$value], array_keys($entries)):
array_keys($entries)
);
break;
}
$entry = $entries[key($entries)];
self :: log_debug(
"getFormValues(): value '$value' found as {$conf['object_type']}: {$entry->dn}"
);
// Check if it's the first this value match with an object // Check if it's the first this value match with an object
if (array_key_exists($value, $found_values)) { if (isset($found_values[$value])) {
// DN match with multiple object type // DN match with multiple object type
LSerror :: addErrorCode( LSerror :: addErrorCode('LSattr_html_select_object_03',array('val' => $value, 'attribute' => $this -> name));
'LSattr_html_select_object_03',
['val' => $value, 'attribute' => $this -> name]
);
unset($selected_objects[$value]);
$unrecognizedValues[] = $value; $unrecognizedValues[] = $value;
$found_values[$value][] = $entry->dn; unset($selected_objects[$found_values[$value]]);
break; break;
} }
$found_values[$value] = [$entry->dn]; $found_values[$value] = $value;
if ($retrieveAttrValues) { if ($retrieveAttrValues) {
// Retrieve attribute value case: $selected_objects[dn] = attribute value // Retrieve attribute value case: $selected_objects[dn] = attribute value
if(($conf['value_attribute']=='dn') || ($conf['value_attribute']=='%{dn}')) { if(($conf['value_attribute']=='dn') || ($conf['value_attribute']=='%{dn}')) {
$selected_objects[$value] = $entry->dn; $selected_objects[$value] = $value;
} }
else { else {
$val = ensureIsArray($entry -> get($conf['value_attribute'])); $val = $objs[$conf['object_type']] -> getValue($conf['value_attribute']);
if (!empty($val)) { if (!empty($val)) {
$selected_objects[$value] = $val[0]; $selected_objects[$value] = $val[0];
} }
@ -331,7 +256,7 @@ class LSattr_html_select_object extends LSattr_html{
LSerror :: addErrorCode( LSerror :: addErrorCode(
'LSattr_html_select_object_06', 'LSattr_html_select_object_06',
array( array(
'name' => $entry -> displayName, 'name' => $objs[$conf['object_type']] -> getDisplayName($conf['display_name_format']),
'attr' => $this -> name 'attr' => $this -> name
) )
); );
@ -341,15 +266,56 @@ class LSattr_html_select_object extends LSattr_html{
else { else {
// General case: $selected_objects[dn] = array(name + object_type) // General case: $selected_objects[dn] = array(name + object_type)
$selected_objects[$value] = array( $selected_objects[$value] = array(
'name' => $entry -> displayName, 'name' => $objs[$conf['object_type']] -> getDisplayName($conf['display_name_format']),
'object_type' => $conf['object_type'], 'object_type' => $conf['object_type'],
); );
self :: log_debug( self :: log_debug("getFormValues(): ".$conf['object_type']."($value): ".varDump($selected_objects[$value]));
"getFormValues(): object {$conf['object_type']} info for value '$value': ".
varDump($selected_objects[$value])
);
} }
} }
else {
// Construct resulting list from attributes values
$filter = Net_LDAP2_Filter::create($conf['value_attribute'], 'equals', $value);
if (isset($conf['filter']))
$filter = LSldap::combineFilters('and', array($filter, $conf['filter']));
$sparams = array();
$sparams['onlyAccessible'] = $conf['onlyAccessible'];
$listobj = $objs[$conf['object_type']] -> listObjectsName(
$filter,
NULL,
$sparams,
$conf['display_name_format']
);
if (count($listobj)==1) {
if (isset($found_values[$value])) {
// Value match with multiple object type
LSerror :: addErrorCode('LSattr_html_select_object_03',array('val' => $value, 'attribute' => $this -> name));
$unrecognizedValues[] = $value;
unset($selected_objects[$found_values[$value]]);
break;
}
$dn = key($listobj);
$selected_objects[$dn] = array(
'name' => $listobj[$dn],
'object_type' => $conf['object_type'],
);
$found_values[$value] = $dn;
}
else if(count($listobj) > 1) {
LSerror :: addErrorCode('LSattr_html_select_object_03',array('val' => $value, 'attribute' => $this -> name));
if (!in_array($value, $unrecognizedValues))
$unrecognizedValues[] = $value;
break;
}
}
}
}
// Check if all values have been found (or already considered as unrecognized)
foreach ($values as $value) {
if (!isset($found_values[$value]) && !in_array($value, $unrecognizedValues)) {
self :: log_debug("getFormValues(): value '$value' not recognized");
$unrecognizedValues[] = $value;
}
} }
// Retrieve attribute values case: return forged array values (list of attribute values) // Retrieve attribute values case: return forged array values (list of attribute values)
@ -357,8 +323,9 @@ class LSattr_html_select_object extends LSattr_html{
return array_values($selected_objects); return array_values($selected_objects);
// General case // General case
$this -> unrecognizedValues = array_diff($values, array_keys($selected_objects)); self :: log_debug("getFormValues(): unrecognizedValues=".varDump($unrecognizedValues));
self :: log_debug("getFormValues(): unrecognizedValues=".varDump($this -> unrecognizedValues)); $this -> unrecognizedValues = $unrecognizedValues;
self :: log_debug("getFormValues(): final values=".varDump($selected_objects)); self :: log_debug("getFormValues(): final values=".varDump($selected_objects));
return $selected_objects; return $selected_objects;
} }
@ -380,7 +347,7 @@ class LSattr_html_select_object extends LSattr_html{
/** /**
* Return array of attribute values form array of form values * Return array of atttribute values form array of form values
* *
* @param mixed $values Array of form values * @param mixed $values Array of form values
* *

View file

@ -140,8 +140,7 @@ class LSformElement_select_object extends LSformElement {
$this -> attr_html -> getLSselectId(), $this -> attr_html -> getLSselectId(),
$select_conf, $select_conf,
boolval($this -> getParam('multiple', 0, 'int')), boolval($this -> getParam('multiple', 0, 'int')),
$this -> values, $this -> values
false
); );
return True; return True;
} }

View file

@ -462,17 +462,8 @@ class LSldap extends LSlog_staticLoggerClass {
* *
* @return boolean True if entry exists, false otherwise * @return boolean True if entry exists, false otherwise
*/ */
public static function exists($dn, $filter=null) { public static function exists($dn) {
$entry = self :: search( return is_a(self :: getLdapEntry($dn), 'Net_LDAP2_Entry');
$filter?$filter:"(objectClass=*)",
$dn,
[
"scope" => "base",
"attronly" => true,
"attributes" => ["objectClass"],
]
);
return boolval($entry);
} }
/** /**

View file

@ -149,23 +149,6 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
} }
/**
* Check if the specified object exists
* @param string $dn Object's DN
* @param string|Net_LDAP2_Filter|null $filter Extra LDAP that object must match (optional, default: null)
* @return bool
*/
public static function exists($dn, $filter=null) {
return LSldap::exists(
$dn,
(
$filter?
LSldap::combineFilters("and", [static :: _getObjectFilter(), $filter]):
static :: _getObjectFilter()
)
);
}
/** /**
* Load object data from LDAP * Load object data from LDAP
* *
@ -918,30 +901,27 @@ class LSldapObject extends LSlog_staticLoggerClass {
} }
/** /**
* Return LDAP filter string of the current object type * Retourne le filtre correpondants aux objetcClass de l'objet courant
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @return Net_LDAP2_Filter LDAP filter as a Net_LDAP2_Filter object, or false in case of error * @return Net_LDAP2_Filter le filtre ldap correspondant au type de l'objet
*/ */
public function getObjectFilter() { public function getObjectFilter() {
return self :: _getObjectFilter($this -> type_name); return self :: _getObjectFilter($this -> type_name);
} }
/** /**
* Return object type LDAP filter string * Retourne le filtre correpondants aux objetcClass de l'objet
*
* @param string|null $type Object type (optional, default: called class)
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @return Net_LDAP2_Filter|false LDAP filter as a Net_LDAP2_Filter object, or false in case of error * @return Net_LDAP2_Filter|false le filtre ldap correspondant au type de l'objet, ou false
*/ */
public static function _getObjectFilter($type=null) { public static function _getObjectFilter($type) {
$type = $type?$type:get_called_class();
$oc=LSconfig::get("LSobjects.$type.objectclass"); $oc=LSconfig::get("LSobjects.$type.objectclass");
if(!is_array($oc) || !$oc) return false; if(!is_array($oc)) return false;
$filters = []; $filters=array();
foreach ($oc as $class) { foreach ($oc as $class) {
$filters[]=Net_LDAP2_Filter::create('objectClass','equals',$class); $filters[]=Net_LDAP2_Filter::create('objectClass','equals',$class);
} }
@ -1024,40 +1004,37 @@ class LSldapObject extends LSlog_staticLoggerClass {
* *
* @param Net_LDAP2_Filter|string|null $filter LDAP search filter * @param Net_LDAP2_Filter|string|null $filter LDAP search filter
* @param string|null $sbasedn Base DN of the search * @param string|null $sbasedn Base DN of the search
* @param array|null $sparams Search parameters (as expected by Net_LDAP2::search()) * @param array $sparams Search parameters (as expected by Net_LDAP2::search())
* @param string|false $displayFormat LSformat of objects's display name * @param string|false $displayFormat LSformat of objects's display name
* @param bool $cache Enable/disable cache (default: true) * @param bool $cache Enable/disable cache (default: true)
* *
* @return array|false Tableau dn => name correspondant au resultat de la recherche, ou false * @return array|false Tableau dn => name correspondant au resultat de la recherche, ou false
*/ */
public function listObjectsName($filter=NULL, $sbasedn=NULL, $sparams=null, $displayFormat=false, $cache=true) { public function listObjectsName($filter=NULL,$sbasedn=NULL,$sparams=array(),$displayFormat=false,$cache=true) {
if (!LSsession :: loadLSclass('LSsearch')) { if (!LSsession :: loadLSclass('LSsearch')) {
LSerror::addErrorCode('LSsession_05','LSsearch'); LSerror::addErrorCode('LSsession_05','LSsearch');
return false; return false;
} }
$params = [ if (!$displayFormat) {
'displayFormat' => $displayFormat?$displayFormat:$this -> getDisplayNameFormat(), $displayFormat = $this -> getDisplayNameFormat();
}
$params = array(
'displayFormat' => $displayFormat,
'basedn' => $sbasedn, 'basedn' => $sbasedn,
'filter' => $filter 'filter' => $filter
];
$LSsearch = new LSsearch(
$this -> type_name,
'LSldapObject::listObjectsName',
(
is_array($sparams)?
$params = array_merge($sparams, $params):
$sparams
),
true
); );
return ( if (is_array($sparams)) {
$LSsearch -> run($cache)? $params=array_merge($sparams,$params);
$LSsearch -> listObjectsName(): }
false
); $LSsearch = new LSsearch($this -> type_name,'LSldapObject::listObjectsName',$params,true);
$LSsearch -> run($cache);
return $LSsearch -> listObjectsName();
} }

View file

@ -51,10 +51,9 @@ class LSselect extends LSlog_staticLoggerClass {
* @param boolean $multiple True if this selection permit to select more than one object, False otherwise (optional, * @param boolean $multiple True if this selection permit to select more than one object, False otherwise (optional,
* default: false) * default: false)
* @param array|null $current_selected_objects Array of current selected objects (optional, see setSelectedObjects for format specification) * @param array|null $current_selected_objects Array of current selected objects (optional, see setSelectedObjects for format specification)
* @param bool $check_objects Check selected objects (optional, default: true)
* @return void * @return void
*/ */
public static function init($id, $LSobjects, $multiple=false, $current_selected_objects=null, $check_objects=true) { public static function init($id, $LSobjects, $multiple=false, $current_selected_objects=null) {
if ( !isset($_SESSION['LSselect']) || !is_array($_SESSION['LSselect'])) if ( !isset($_SESSION['LSselect']) || !is_array($_SESSION['LSselect']))
$_SESSION['LSselect'] = array(); $_SESSION['LSselect'] = array();
$_SESSION['LSselect'][$id] = array ( $_SESSION['LSselect'][$id] = array (
@ -63,11 +62,8 @@ class LSselect extends LSlog_staticLoggerClass {
'selected_objects' => array(), 'selected_objects' => array(),
); );
if (is_array($current_selected_objects)) if (is_array($current_selected_objects))
self :: setSelectedObjects($id, $current_selected_objects, $check_objects); self :: setSelectedObjects($id, $current_selected_objects);
self :: log_debug( self :: log_debug("Initialized with id=$id: multiple=".($multiple?'yes':'no')." ".count($_SESSION['LSselect'][$id]['selected_objects'])." selected object(s).");
"Initialized with id=$id: multiple=".($multiple?'yes':'no')." ".
count($_SESSION['LSselect'][$id]['selected_objects'])." selected object(s)."
);
} }
/** /**
@ -220,7 +216,6 @@ class LSselect extends LSlog_staticLoggerClass {
* @param array $selected_objects Array of selectable object info with objects's DN * @param array $selected_objects Array of selectable object info with objects's DN
* as key and array of object's info as value. Objects's * as key and array of object's info as value. Objects's
* info currently contains only the object type (key=object_type). * info currently contains only the object type (key=object_type).
* @param bool $check_objects Check selected objects (optional, default: true)
* *
* @return array|false Array of selectable object info with objects's DN as key * @return array|false Array of selectable object info with objects's DN as key
* and array of object's info as value. Objects's info returned * and array of object's info as value. Objects's info returned
@ -229,37 +224,24 @@ class LSselect extends LSlog_staticLoggerClass {
* *
* @return void * @return void
*/ */
public static function setSelectedObjects($id, $selected_objects, $check_objects=true) { public static function setSelectedObjects($id, $selected_objects) {
if (!self :: exists($id)) if (!self :: exists($id))
return; return;
if (!is_array($selected_objects)) if (!is_array($selected_objects))
return; return;
$previously_selected = $_SESSION['LSselect'][$id]['selected_objects']; $_SESSION['LSselect'][$id]['selected_objects'] = array();
$_SESSION['LSselect'][$id]['selected_objects'] = [];
foreach($selected_objects as $dn => $info) { foreach($selected_objects as $dn => $info) {
if (!is_array($info) || !isset($info['object_type'])) { if (!is_array($info) || !isset($info['object_type'])) {
self :: log_warning("setSelectedObjects($id): invalid object info for dn='$dn'"); self :: log_warning("setSelectedObjects($id): invalid object info for dn='$dn'");
continue; continue;
} }
if ( if (self :: checkObjectIsSelectable($id, $info['object_type'], $dn))
$check_objects
&& !(
in_array($dn, $previously_selected)
|| self :: checkObjectIsSelectable($id, $info['object_type'], $dn)
)
) {
self :: log_warning(
"setSelectedObjects($id): object type='{$info['object_type']}' and dn='$dn' is not ".
"selectable"
);
continue;
}
$_SESSION['LSselect'][$id]['selected_objects'][$dn] = $info; $_SESSION['LSselect'][$id]['selected_objects'][$dn] = $info;
else {
self :: log_warning("setSelectedObjects($id): object type='".$info['object_type']."' and dn='$dn' is not selectable".varDump($_SESSION['LSselect'][$id]));
} }
self :: log_debug( }
"setSelectedObjects($id): updated with ". self :: log_debug("id=$id: updated with ".count($_SESSION['LSselect'][$id]['selected_objects'])." selected object(s).");
count($_SESSION['LSselect'][$id]['selected_objects'])." selected object(s)."
);
} }
/** /**
@ -268,46 +250,29 @@ class LSselect extends LSlog_staticLoggerClass {
* @param string $id The LSselect ID * @param string $id The LSselect ID
* @param string $object_type The object type * @param string $object_type The object type
* @param string $object_dn The object DN * @param string $object_dn The object DN
* @param bool $check_exists Check if object exists in LDAP (optional, default: true)
* *
* @return boolean True if object is selectable, false otherwise * @return boolean True if object is selectable, false otherwise
*/ */
public static function checkObjectIsSelectable($id, $object_type, $object_dn, $check_exists=true) { public static function checkObjectIsSelectable($id, $object_type, $object_dn) {
if (!self :: exists($id)) { if (!self :: exists($id)) {
self :: log_warning( self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): LSselect $id doesn't exists");
"checkObjectIsSelectable($id, $object_type, $object_dn): LSselect $id doesn't exists"
);
return false; return false;
} }
if (!array_key_exists($object_type, $_SESSION['LSselect'][$id]['LSobjects'])) { if (!array_key_exists($object_type, $_SESSION['LSselect'][$id]['LSobjects'])) {
self :: log_warning( self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): object type $object_type not selectabled");
"checkObjectIsSelectable($id, $object_type, $object_dn): object type $object_type not ".
"selectable"
);
return false; return false;
} }
// Load LSobject type // Load LSobject type
if ( !LSsession :: loadLSobject($object_type) ) { if ( !LSsession :: loadLSobject($object_type) ) {
self :: log_warning( self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): fail to load object type $object_type");
"checkObjectIsSelectable($id, $object_type, $object_dn): fail to load object type ".
$object_type
);
return false; return false;
} }
// Check object exists // Instanciate object and load object data from DN
if ( $object = new $object_type();
$check_exists if (!$object -> loadData($object_dn, self :: getConfig($id, "LSobjects.$object_type.filter", null))) {
&& !$object_type :: exists( self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): object $object_dn not found (or does not match with selection filter)");
$object_dn,
self :: getConfig($id, "LSobjects.$object_type.filter", null, "string")
)
) {
self :: log_warning(
"checkObjectIsSelectable($id, $object_type, $object_dn): object $object_dn not found ".
"(or does not match with selection filter)"
);
return false; return false;
} }