mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-12-22 16:33:48 +01:00
Allow a sequence of filters in LSobjects profile configurations
It's now possible for example to define a profile on an LSobject whose attribute would contain the DN of a group the user is member of instead of directly the dn of the user. A possible configuation using this new feature: 'LSprofile' => array( 'admin' => array( 'LSobjects' => array( 'LSsupannGroupAdminByGroup' => array( 'filters' => array( array( 'basedn' => $basedn, 'attr' => 'member', 'attr_value' => '%{dn}', 'LSobject' => 'LSsupannGroup', ), array( 'basedn' => $basedn, 'attr' => 'supannGroupeAdminDN', 'attr_value' => '%{dn}', 'LSobject' => 'LSsupannGroup', ) ), ), ), ), ) Signed-off-by: Benjamin Renard <brenard@easter-eggs.com>
This commit is contained in:
parent
10019fc9fe
commit
9add9c3321
2 changed files with 166 additions and 38 deletions
|
@ -35,6 +35,20 @@
|
|||
'basedn' => [basedn de recherche],
|
||||
'params' => [configuration de la recherche]
|
||||
),
|
||||
[nom quelconque] => array (
|
||||
'filters' => array(
|
||||
array(
|
||||
'LSobject' => [nom du LSobject],
|
||||
'attr' => [nom de l'attribut clé],
|
||||
'attr_value' => [format de la valeur de l'attribut clé],
|
||||
// ou
|
||||
'filter' => [format du filtre de recherche],
|
||||
|
||||
'basedn' => [basedn de recherche],
|
||||
'params' => [configuration de la recherche]
|
||||
),
|
||||
),
|
||||
),
|
||||
...
|
||||
)
|
||||
),
|
||||
|
@ -151,6 +165,20 @@ objets pour lesquels l'utilisateur appartiendra au
|
|||
'basedn' => [basedn de recherche],
|
||||
'params' => [configuration de la recherche]
|
||||
),
|
||||
array (
|
||||
'filters' => array(
|
||||
array(
|
||||
'LSobject' => [nom du LSobject],
|
||||
'attr' => [nom de l'attribut clé],
|
||||
'attr_value' => [format de la valeur de l'attribut clé],
|
||||
// ou
|
||||
'filter' => [format du filtre de recherche],
|
||||
|
||||
'basedn' => [basedn de recherche],
|
||||
'params' => [configuration de la recherche]
|
||||
),
|
||||
),
|
||||
),
|
||||
...
|
||||
)
|
||||
),
|
||||
|
@ -159,18 +187,43 @@ objets pour lesquels l'utilisateur appartiendra au
|
|||
...
|
||||
</programlisting>
|
||||
<para>Explications : Dans la configuration d'un <emphasis>LSprofile</emphasis>,
|
||||
la valeur clé <emphasis>LSprofile</emphasis> signifie qu'on est dans un cas de la
|
||||
délégation de droits sur des types d'LSobject. Dans ce tableau associatif, il
|
||||
la valeur clé <emphasis>LSobjects</emphasis> signifie qu'on est dans un cas de la
|
||||
délégation de droits sur des types d'LSobject. Dans ce tableau associatif, il
|
||||
est possible de définir un ou plusieurs types de LSobject pour lesquels on délègue
|
||||
des droits. Dans ce tableau la valeur clé est le nom du LSobject et la valeur
|
||||
associée est un tableau contenant la configuration permettant de dire quels sont
|
||||
les LSobjets de ce type concernés par la délégation.</para>
|
||||
<para>Cette configuration contient les paramètres d'une recherche dans l'annuaire
|
||||
des droits via des recherches simples ou enchaînées. Le fonctionnement simple
|
||||
consiste à partir de l'objet de l'utilisateur et à générer un filtre de
|
||||
recherche sur un type de LSobject. Le fonctionnement enchainée consiste à faire
|
||||
un première recherche à partir de l'objet de l'utilisateur puis à recommencer à
|
||||
partir des objets trouvés en construisant une liste de filtres de recherche
|
||||
pour chaque objet qui seront combinés via l'opérateur booléen
|
||||
<emphasis>ou</emphasis>.</para>
|
||||
|
||||
<para>Pour configurer une délégation de type simple on mettra le nom du
|
||||
LSobject dans la clé du tableau et dans la valeur un tableau définissant la
|
||||
recherche. Il est possible de ne pas utiliser la clé du tableau comme nom du
|
||||
LSobject grâce à la clé de configuration
|
||||
<emphasis>LSobject</emphasis>.</para>
|
||||
|
||||
<para>Pour configurer une délégation de type enchaîné on pourra utiliser
|
||||
n'importe quelle valeur unique pour la clé du tableau et pour la valeur un
|
||||
tableau contenant une unique clé <emphasis>filters</emphasis>. La valeur
|
||||
associée à cette clé est celle d'une délégation de type simple où la clé
|
||||
<emphasis>LSobject</emphasis> est devenue obligatoire.</para>
|
||||
|
||||
<para>Cette configuration contient les paramètres d'une ou plusieurs recherches dans l'annuaire
|
||||
en considérant que l'utilisateur connecté aura les droits du LSprofile sur les
|
||||
objets retournés. Les paramètres de la recherche sont :
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>LSobject</term>
|
||||
<listitem>
|
||||
<simpara>C'est le nom du LSobject recherché.
|
||||
<emphasis>(Paramètre facultatif pour une délégation de type simple)</emphasis></simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>attr</term>
|
||||
<listitem>
|
||||
|
|
|
@ -1484,6 +1484,111 @@ class LSsession {
|
|||
return LStemplate :: fetch($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prend un tableau de LSobject et le réduit en utilisant un filtre de
|
||||
* recherche sur un autre type de LSobject.
|
||||
*
|
||||
* Si une erreur est présente dans le tableau de définition du filtre, un
|
||||
* tableau vide est renvoyé.
|
||||
*
|
||||
* @param[in] string $LSobject le type LSobject par défaut
|
||||
* @param[in] array $set tableau de LSobject
|
||||
* @param[in] array $filter_def définition du filtre de recherche pour la réduction
|
||||
* @param[in] string $basend basedn pour la recherche, null par défaut
|
||||
*
|
||||
* @retval array le nouveau tableau de LSobject
|
||||
*/
|
||||
private static function reduceLdapSet($LSobject, $set, $filter_def, $basedn=null) {
|
||||
if (empty($set)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (! isset($filter_def['filter']) &&
|
||||
(! isset($filter_def['attr']) ||
|
||||
! isset($filter_def['attr_value']))) {
|
||||
LSdebug("Filtre de profil LSobject invalide " . var_export($filter_def, true));
|
||||
return array();
|
||||
}
|
||||
|
||||
LSdebug('LSsession :: reducing set of');
|
||||
foreach ($set as $object) {
|
||||
LSdebug('LSsession :: -> ' . $object -> getDn());
|
||||
}
|
||||
|
||||
$LSobject = isset($filter_def['LSObject']) ? $filter_def['LSobject'] : $LSobject;
|
||||
LSdebug('LSobject :: ' . $LSobject);
|
||||
$filters = array();
|
||||
foreach ($set as $object) {
|
||||
if (isset($filter_def['filter'])) {
|
||||
$filters[] = $object -> getFData($filter_def['filter']);
|
||||
}
|
||||
else {
|
||||
$value = $object -> getFData($filter_def['attr_value']);
|
||||
$filters[] = Net_LDAP2_Filter::create($filter_def['attr'], 'equals', $value);
|
||||
}
|
||||
}
|
||||
$filter = LSldap::combineFilters('or', $filters);
|
||||
$params = array(
|
||||
'basedn' => isset($filter_def['basedn']) ? $filter_def['basedn'] : $basedn,
|
||||
'filter' => $filter,
|
||||
);
|
||||
if (isset($filter_def['params']) && is_array($filter_def['params'])) {
|
||||
$params = array_merge($filter_def['params'],$params);
|
||||
}
|
||||
$LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
|
||||
$LSsearch -> run(false);
|
||||
|
||||
$set = $LSsearch -> listObjects();
|
||||
LSdebug('LSsession :: reduced set to');
|
||||
foreach ($set as $object) {
|
||||
LSdebug('LSsession :: -> ' . $object -> getDn());
|
||||
}
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge les droits LS de l'utilisateur : uniquement du type LSobjects
|
||||
*
|
||||
* @param[in] string $
|
||||
*
|
||||
* @retval void
|
||||
*/
|
||||
private static function loadLSprofilesLSobjects($profile, $LSobject, $listInfos) {
|
||||
if (! self :: loadLSclass('LSsearch')) {
|
||||
LSdebug('Impossible de charger la classe LSsearch');
|
||||
return;
|
||||
}
|
||||
# we are gonna grow a set of objects progressively, we start from the user
|
||||
$set = array(self :: getLSuserObject());
|
||||
$basedn = isset($listInfos['basedn']) ? $listInfos['basedn'] : null;
|
||||
$LSobject = isset($listInfos['LSobject']) ? $listInfos['LSobject'] : $LSobject;
|
||||
|
||||
if (isset($listInfos['filters']) && is_array($listInfos['filters'])) {
|
||||
foreach ($listInfos['filters'] as $filter_def) {
|
||||
$set = self :: reduceLdapSet($LSobject, $set, $filter_def, $basedn);
|
||||
}
|
||||
}
|
||||
if (isset($listInfos['filter']) || (isset($listInfos['attr']) && isset($listInfos['attr_value']))) {
|
||||
# support legacy profile definition
|
||||
$set = self :: reduceLdapSet($LSobject, $set, $listInfos, $basedn);
|
||||
}
|
||||
|
||||
$DNs = [];
|
||||
foreach ($set as $object) {
|
||||
$DNs[] = $object -> getDn();
|
||||
}
|
||||
if (!is_array(self :: $LSprofiles[$profile])) {
|
||||
self :: $LSprofiles[$profile]=$DNs;
|
||||
}
|
||||
else {
|
||||
foreach($DNs as $dn) {
|
||||
if (!in_array($dn,self :: $LSprofiles[$profile])) {
|
||||
self :: $LSprofiles[$profile][] = $dn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge les droits LS de l'utilisateur
|
||||
*
|
||||
|
@ -1501,38 +1606,8 @@ class LSsession {
|
|||
if ($topDn == 'LSobjects') {
|
||||
if (is_array($rightsInfos)) {
|
||||
foreach ($rightsInfos as $LSobject => $listInfos) {
|
||||
if (self :: loadLSclass('LSsearch')) {
|
||||
if (isset($listInfos['filter'])) {
|
||||
$filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
|
||||
}
|
||||
else {
|
||||
$filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')';
|
||||
}
|
||||
|
||||
$params = array (
|
||||
'basedn' => (isset($listInfos['basedn'])?$listInfos['basedn']:null),
|
||||
'filter' => $filter
|
||||
);
|
||||
|
||||
if (isset($listInfos['params']) && is_array($listInfos['params'])) {
|
||||
$params = array_merge($listInfos['params'],$params);
|
||||
}
|
||||
|
||||
$LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
|
||||
$LSsearch -> run(false);
|
||||
|
||||
$DNs = $LSsearch -> listObjectsDn();
|
||||
if (!is_array(self :: $LSprofiles[$profile])) {
|
||||
self :: $LSprofiles[$profile]=$DNs;
|
||||
}
|
||||
else {
|
||||
foreach($DNs as $dn) {
|
||||
if (!in_array($dn,self :: $LSprofiles[$profile])) {
|
||||
self :: $LSprofiles[$profile][] = $dn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LSdebug('loading LSprofile ' . $profile . ' for LSobject ' . $LSobject . ' with params ' . var_export($listInfos, true));
|
||||
self :: loadLSprofilesLSobjects($profile, $LSobject, $listInfos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in a new issue