mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-11-18 00:09:06 +01:00
LSauth: Add possibility to configure more than one LSobject type as user
This commit is contained in:
parent
5660804ef7
commit
a6f07faca0
7 changed files with 398 additions and 228 deletions
|
@ -18,7 +18,14 @@ serveur LDAP.</para>
|
||||||
),
|
),
|
||||||
'useUserCredentials' => [boolean],
|
'useUserCredentials' => [boolean],
|
||||||
'LSauth' => array (
|
'LSauth' => array (
|
||||||
'method' => [LSauth method]
|
'method' => [LSauth method],
|
||||||
|
'LSobjects' => array(
|
||||||
|
'[object type 1]',
|
||||||
|
'[object type 2]' => array(
|
||||||
|
'filter' => '[LDAP filter]',
|
||||||
|
'password_attribute' => '[attribute name]',
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
'LSprofiles' => array (
|
'LSprofiles' => array (
|
||||||
// Définition des LSprofiles
|
// Définition des LSprofiles
|
||||||
|
@ -26,9 +33,6 @@ serveur LDAP.</para>
|
||||||
'cacheLSprofiles' => [boolean],
|
'cacheLSprofiles' => [boolean],
|
||||||
'cacheSearch' => [boolean],
|
'cacheSearch' => [boolean],
|
||||||
'globalSearch' => [boolean],
|
'globalSearch' => [boolean],
|
||||||
'authObjectType' => [LSobject],
|
|
||||||
'authObjectFilter' => [LSformat],
|
|
||||||
'authObjectTypeAttrPwd' => [attribut],
|
|
||||||
'LSaccess' => array (
|
'LSaccess' => array (
|
||||||
[Type LSobject 1],
|
[Type LSobject 1],
|
||||||
[Type LSobject 2],
|
[Type LSobject 2],
|
||||||
|
@ -102,15 +106,74 @@ serveur LDAP.</para>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>LSauth</term>
|
<term>LSauth</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<simpara>Définition de la méthode d'authentification &LSauthMethod;. Pour le
|
<simpara>Ce tableau défini les paramètres d'authentification à l'application.</simpara>
|
||||||
moment ce tableau associatif ne contient qu'un paramètre <parameter>
|
<variablelist>
|
||||||
method</parameter> qui correpond au nom de la librairie d'authentification.
|
<title>Paramètres de configuration de l'authentification</title>
|
||||||
Exemple : pour utiliser la classe <literal>LSauthMethod_HTTP</literal>, la
|
|
||||||
valeur du paramètre <parameter>method</parameter> sera <literal>HTTP</literal>.
|
<varlistentry>
|
||||||
|
<term>method</term>
|
||||||
|
<listitem>
|
||||||
|
<simpara>Nom de la méthode d'authentification &LSauthMethod;. Exemple : pour utiliser la classe
|
||||||
|
<literal>LSauthMethod_HTTP</literal>, la valeur de ce paramètre sera <literal>HTTP</literal>.
|
||||||
|
<emphasis>Paramètre facultatif, méthode par défaut : <literal>basic</literal>.</emphasis>
|
||||||
</simpara>
|
</simpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>LSobjects</term>
|
||||||
|
<listitem>
|
||||||
|
<simpara>Tableau listant les types &LSobjects; pouvant se connecter à l'application. Les valeurs
|
||||||
|
de ce tableau peuvent être un nom de type d'objet ou bien tableau détaillant les paramètres de
|
||||||
|
connexion de ce type d'objet.</simpara>
|
||||||
|
<variablelist>
|
||||||
|
<title>Paramètres de configuration d'un type d'object</title>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>filter</term>
|
||||||
|
<listitem>
|
||||||
|
<simpara>&LSformat; du filtre de recherche de l'utilisateur à sa connexion.
|
||||||
|
Ce format sera composé avec l'identifiant fourni par l'utilisateur. Cela peut
|
||||||
|
par exemple permettre à l'utilisateur de se connecter en fournissant son login
|
||||||
|
ou son email comme identifiant. Exemple de valeur :
|
||||||
|
<literal>(|(uid=%{user})(mail=%{user}))</literal>. <emphasis>Paramètre facultatif,
|
||||||
|
filtre par défaut composé à l'aide de l'attribut RDN.</emphasis></simpara>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>password_attribute</term>
|
||||||
|
<listitem>
|
||||||
|
<simpara>Nom de l'attribut stockant le mot de passe de ce type d'&LSobject;. <emphasis>
|
||||||
|
Paramètre facultatif, valeur par défaut : <literal>userPassword</literal>.</emphasis></simpara>
|
||||||
|
<note><simpara>C'est cet attribut de l'utilisateur qui sera modifié par la fonctionnalité
|
||||||
|
de récupération de mot de passe.</simpara></note>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>allow_multi_match</term>
|
||||||
|
<listitem>
|
||||||
|
<simpara>Booléen permettant de définir si un doublon d'identifiant utilisateur est autorisé.
|
||||||
|
Si c'est le cas et lorsqu'un identifiant fourni par l'utilisateur a sa connexion a permi
|
||||||
|
de trouver plus d'un utilisateur possible correspondant, l'application tentera de déterminer
|
||||||
|
lequel de ces utilisateurs correspond à la tentative d'authentification. La méthodologie
|
||||||
|
employée dépendra de la &LSauthMethod; configurée. Par exemple, la &LSauthMethod; <literal>
|
||||||
|
basic</literal> tentera de s'identifier avec le mot de passe. Dans tous les cas, si cette
|
||||||
|
méthode n'a pas permi d'identifier un seul utilisateur, l'authentification échoura. <emphasis>
|
||||||
|
Paramètre facultatif, valeur par défaut : <literal>Faux</literal>.</emphasis>
|
||||||
|
</simpara>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>cacheLSprofiles</term>
|
<term>cacheLSprofiles</term>
|
||||||
|
@ -140,36 +203,6 @@ serveur LDAP.</para>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>authObjectType</term>
|
|
||||||
<listitem>
|
|
||||||
<simpara>Nom du type d'&LSobject; pouvant être utilisé pour authentifier un
|
|
||||||
utilisateur se connectant à l'interface.</simpara>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>authObjectFilter</term>
|
|
||||||
<listitem>
|
|
||||||
<simpara>&LSformat; du filtre de recherche de l'utilisateur à sa connexion.
|
|
||||||
Le LSformat sera composé avec la valeur de l'information fourni par l'utilisateur.
|
|
||||||
Cela peut pemettre par exemple de permettre à l'utilisateur de se connecter en
|
|
||||||
fournissant soit son login, soit son email. Exemple de valeur :
|
|
||||||
<literal>(|(uid=%{user})(mail=%{user}))</literal></simpara>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>authObjectTypeAttrPwd</term>
|
|
||||||
<listitem>
|
|
||||||
<simpara>Nom de l'attribut "mot de passe" du type d'&LSobject; utilisé pour
|
|
||||||
l'authentification des utilisateurs se connectant à l'interface.</simpara>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
|
|
||||||
<varlistentry id="config-LSaccess">
|
<varlistentry id="config-LSaccess">
|
||||||
<term>LSaccess</term>
|
<term>LSaccess</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -48,11 +48,16 @@ $GLOBALS['LSconfig'] = array(
|
||||||
'filter' => '(objectClass=*)',
|
'filter' => '(objectClass=*)',
|
||||||
'scope' => 'sub'
|
'scope' => 'sub'
|
||||||
),
|
),
|
||||||
/*
|
|
||||||
'LSauth' => array (
|
'LSauth' => array (
|
||||||
'method' => 'HTTP'
|
//'method' => 'basic', // Auth method : basic(default), HTTP, CAS or anonymous
|
||||||
|
'LSobjects' => array(
|
||||||
|
'LSpeople' => array(
|
||||||
|
'filter' => '(|(uid=%{user})(mail=%{user}))',
|
||||||
|
'password_attribute' => 'userPassword',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//'allow_multi_match' => false, // Allow username multiple match (default: false)
|
||||||
),
|
),
|
||||||
*/
|
|
||||||
'LSprofiles' => array (
|
'LSprofiles' => array (
|
||||||
'admin' => array (
|
'admin' => array (
|
||||||
'label' => 'Administrator',
|
'label' => 'Administrator',
|
||||||
|
@ -82,9 +87,6 @@ $GLOBALS['LSconfig'] = array(
|
||||||
),
|
),
|
||||||
'cacheLSprofiles' => true,
|
'cacheLSprofiles' => true,
|
||||||
'cacheSearch' => true,
|
'cacheSearch' => true,
|
||||||
'authObjectType' => 'LSpeople',
|
|
||||||
'authObjectFilter' => '(|(uid=%{user})(mail=%{user}))',
|
|
||||||
'authObjectTypeAttrPwd' => 'userPassword',
|
|
||||||
'LSaccess' => array(
|
'LSaccess' => array(
|
||||||
'LSpeople',
|
'LSpeople',
|
||||||
'LSgroup'
|
'LSgroup'
|
||||||
|
@ -118,6 +120,9 @@ $GLOBALS['LSconfig'] = array(
|
||||||
'filter' => '(objectClass=*)',
|
'filter' => '(objectClass=*)',
|
||||||
'scope' => 'sub'
|
'scope' => 'sub'
|
||||||
),
|
),
|
||||||
|
'LSauth' => array (
|
||||||
|
'LSobjects' => array('LSpeople'),
|
||||||
|
),
|
||||||
'LSprofiles' => array(
|
'LSprofiles' => array(
|
||||||
'admin' => array (
|
'admin' => array (
|
||||||
'o=ls' => array (
|
'o=ls' => array (
|
||||||
|
@ -134,7 +139,6 @@ $GLOBALS['LSconfig'] = array(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'authObjectType' => 'LSpeople',
|
|
||||||
'subDnLabel' => 'Company',
|
'subDnLabel' => 'Company',
|
||||||
'subDn' => array(
|
'subDn' => array(
|
||||||
'== All ==' => array(
|
'== All ==' => array(
|
||||||
|
@ -157,7 +161,6 @@ $GLOBALS['LSconfig'] = array(
|
||||||
'cacheLSprofiles' => true,
|
'cacheLSprofiles' => true,
|
||||||
'cacheSearch' => true,
|
'cacheSearch' => true,
|
||||||
'globalSearch' => true,
|
'globalSearch' => true,
|
||||||
'authObjectTypeAttrPwd' => 'userPassword',
|
|
||||||
'recoverPassword' => array(
|
'recoverPassword' => array(
|
||||||
'mailAttr' => 'mail',
|
'mailAttr' => 'mail',
|
||||||
'recoveryHashAttr' => 'lsRecoveryHash',
|
'recoveryHashAttr' => 'lsRecoveryHash',
|
||||||
|
|
|
@ -74,7 +74,7 @@ function LSaccessRightsMatrixView() {
|
||||||
foreach(LSconfig :: get("LSobjects.$LSobject.attrs", array()) as $attr_name => $attr_config) {
|
foreach(LSconfig :: get("LSobjects.$LSobject.attrs", array()) as $attr_name => $attr_config) {
|
||||||
$raw_attr_rights = LSconfig :: get('rights', array(), 'array', $attr_config);
|
$raw_attr_rights = LSconfig :: get('rights', array(), 'array', $attr_config);
|
||||||
$attr_rights = array();
|
$attr_rights = array();
|
||||||
if ($LSobject == LSsession :: $ldapServer["authObjectType"])
|
if ($LSobject == LSsession :: get('authenticated_user_type'))
|
||||||
$attr_rights['self'] = LSconfig :: get('self', False, null, $raw_attr_rights);
|
$attr_rights['self'] = LSconfig :: get('self', False, null, $raw_attr_rights);
|
||||||
foreach(array_keys($LSprofiles) as $LSprofile) {
|
foreach(array_keys($LSprofiles) as $LSprofile) {
|
||||||
$attr_rights[$LSprofile] = LSconfig :: get($LSprofile, False, null, $raw_attr_rights);
|
$attr_rights[$LSprofile] = LSconfig :: get($LSprofile, False, null, $raw_attr_rights);
|
||||||
|
@ -90,7 +90,7 @@ function LSaccessRightsMatrixView() {
|
||||||
foreach(LSconfig :: get("LSobjects.$LSobject.LSrelation", array()) as $relation_name => $relation_config) {
|
foreach(LSconfig :: get("LSobjects.$LSobject.LSrelation", array()) as $relation_name => $relation_config) {
|
||||||
$raw_relation_rights = LSconfig :: get('rights', array(), 'array', $relation_config);
|
$raw_relation_rights = LSconfig :: get('rights', array(), 'array', $relation_config);
|
||||||
$relation_rights = array();
|
$relation_rights = array();
|
||||||
if ($LSobject == LSsession :: $ldapServer["authObjectType"])
|
if ($LSobject == LSsession :: get('authenticated_user_type'))
|
||||||
$relation_rights['self'] = LSconfig :: get('self', False, null, $raw_relation_rights);
|
$relation_rights['self'] = LSconfig :: get('self', False, null, $raw_relation_rights);
|
||||||
foreach(array_keys($LSprofiles) as $LSprofile) {
|
foreach(array_keys($LSprofiles) as $LSprofile) {
|
||||||
$relation_rights[$LSprofile] = LSconfig :: get($LSprofile, False, null, $raw_relation_rights);
|
$relation_rights[$LSprofile] = LSconfig :: get($LSprofile, False, null, $raw_relation_rights);
|
||||||
|
@ -112,7 +112,7 @@ function LSaccessRightsMatrixView() {
|
||||||
reset($LSobjects);
|
reset($LSobjects);
|
||||||
$LSobject = (isset($_REQUEST['LSobject']) && array_key_exists($_REQUEST['LSobject'], $LSobjects)?$_REQUEST['LSobject']:key($LSobjects));
|
$LSobject = (isset($_REQUEST['LSobject']) && array_key_exists($_REQUEST['LSobject'], $LSobjects)?$_REQUEST['LSobject']:key($LSobjects));
|
||||||
|
|
||||||
if ($LSobject == LSsession :: $ldapServer["authObjectType"])
|
if ($LSobject == LSsession :: get('authenticated_user_type'))
|
||||||
$LSprofiles = array_merge(array('self' => _('The user him-self')), $LSprofiles);
|
$LSprofiles = array_merge(array('self' => _('The user him-self')), $LSprofiles);
|
||||||
|
|
||||||
LSlog :: get_logger('LSaddon_LSaccessRightsMatrixView') -> debug($LSobjects);
|
LSlog :: get_logger('LSaddon_LSaccessRightsMatrixView') -> debug($LSobjects);
|
||||||
|
|
|
@ -87,6 +87,103 @@ class LSauth extends LSlog_staticLoggerClass {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a configuration parameter (or default value)
|
||||||
|
*
|
||||||
|
* @param[] $param The configuration parameter
|
||||||
|
* @param[] $default The default value (default : null)
|
||||||
|
* @param[] $cast Cast resulting value in specific type (default : disabled)
|
||||||
|
*
|
||||||
|
* @retval mixed The configuration parameter value or default value if not set
|
||||||
|
**/
|
||||||
|
private static function getConfig($param, $default=null, $cast=null) {
|
||||||
|
return LSconfig :: get($param, $default, $cast, self :: $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retreive auth object types info
|
||||||
|
* @return array Array of auth object type with type as key and type's parameters as value
|
||||||
|
*/
|
||||||
|
public static function getAuthObjectTypes() {
|
||||||
|
$objTypes = array();
|
||||||
|
foreach(self :: getConfig('LSobjects', array()) as $objType => $objParams) {
|
||||||
|
if (is_int($objType) && is_string($objParams)) {
|
||||||
|
// We just have the object type
|
||||||
|
$objTypes[$objType] = array('filter' => null, 'password_attribute' => 'userPassword');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$objTypes[$objType] = array(
|
||||||
|
'filter' => self :: getConfig("LSobjects.$objType.filter", null, 'string'),
|
||||||
|
'password_attribute' => self :: getConfig("LSobjects.$objType.password_attribute", 'userPassword', 'string'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// For retro-compatibility, also retreived old parameters:
|
||||||
|
$oldAuthObjectType = LSconfig :: get('authObjectType', null, 'string', LSsession :: $ldapServer);
|
||||||
|
if ($oldAuthObjectType && !array_key_exists($oldAuthObjectType, $objTypes)) {
|
||||||
|
$objTypes[$oldAuthObjectType] = array(
|
||||||
|
'filter' => LSconfig :: get('authObjectFilter', null, 'string', LSsession :: $ldapServer),
|
||||||
|
'password_attribute' => LSconfig :: get('authObjectTypeAttrPwd', 'userPassword', 'string', LSsession :: $ldapServer),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $objTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retreived LSobjects corresponding to a username
|
||||||
|
*
|
||||||
|
* @retval array|false Array of corresponding LSldapObject with object DN as key, or false in case of error
|
||||||
|
*/
|
||||||
|
public static function username2LSobjects($username) {
|
||||||
|
$user_objects = array();
|
||||||
|
foreach (self :: getAuthObjectTypes() as $objType => $objParams) {
|
||||||
|
if (!LSsession :: loadLSobject($objType)) {
|
||||||
|
LSerror :: addErrorCode('LSauth_03', $objType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$authobject = new $objType();
|
||||||
|
$result = $authobject -> searchObject(
|
||||||
|
$username,
|
||||||
|
LSsession :: getTopDn(),
|
||||||
|
$objParams['filter'],
|
||||||
|
array('withoutCache' => true, 'onlyAccessible' => false)
|
||||||
|
);
|
||||||
|
for($i=0; $i<count($result); $i++)
|
||||||
|
$user_objects[$result[$i] -> getDn()] = $result[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
$nbresult = count($user_objects);
|
||||||
|
if ($nbresult == 0) {
|
||||||
|
// incorrect login
|
||||||
|
self :: log_debug('Invalid username');
|
||||||
|
LSerror :: addErrorCode('LSauth_01');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ($nbresult > 1) {
|
||||||
|
// duplication of identity
|
||||||
|
self :: log_debug("More than one user detected for username '$username': ".implode(', ', array_keys($user_objects)));
|
||||||
|
if (!self :: getConfig('allow_multi_match', false, 'bool')) {
|
||||||
|
LSerror :: addErrorCode('LSauth_02');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $user_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user password attribute name
|
||||||
|
*
|
||||||
|
* @param[in] &object LSldapObject The user object
|
||||||
|
*
|
||||||
|
* @retval string|false The user password attribute name or false if not configured
|
||||||
|
*/
|
||||||
|
public static function getUserPasswordAttribute(&$object) {
|
||||||
|
$authObjectTypes = self :: getAuthObjectTypes();
|
||||||
|
$objType = $object -> getType();
|
||||||
|
if (array_key_exists($objType, $authObjectTypes))
|
||||||
|
return $authObjectTypes[$objType]['password_attribute'];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get LDAP credentials
|
* Get LDAP credentials
|
||||||
*
|
*
|
||||||
|
@ -188,7 +285,7 @@ LSerror :: defineError('LSauth_02',
|
||||||
_("LSauth : Impossible to identify you : Duplication of identities.")
|
_("LSauth : Impossible to identify you : Duplication of identities.")
|
||||||
);
|
);
|
||||||
LSerror :: defineError('LSauth_03',
|
LSerror :: defineError('LSauth_03',
|
||||||
_("LSauth : Could not load type of identifiable objects.")
|
_("LSauth : Could not load type of identifiable objects %{type}.")
|
||||||
);
|
);
|
||||||
LSerror :: defineError('LSauth_04',
|
LSerror :: defineError('LSauth_04',
|
||||||
_("LSauth : Can't load authentication method %{method}.")
|
_("LSauth : Can't load authentication method %{method}.")
|
||||||
|
|
|
@ -60,33 +60,18 @@ class LSauthMethod extends LSlog_staticLoggerClass {
|
||||||
* @retval LSldapObject|false The LSldapObject of the user authificated or false
|
* @retval LSldapObject|false The LSldapObject of the user authificated or false
|
||||||
*/
|
*/
|
||||||
public function authenticate() {
|
public function authenticate() {
|
||||||
if (LSsession :: loadLSobject(LSsession :: $ldapServer['authObjectType'])) {
|
$authobjects = LSauth :: username2LSobjects($this -> authData['username']);
|
||||||
$authobject = new LSsession :: $ldapServer['authObjectType']();
|
if (!$authobjects) {
|
||||||
$result = $authobject -> searchObject(
|
|
||||||
$this -> authData['username'],
|
|
||||||
LSsession :: getTopDn(),
|
|
||||||
(isset(LSsession :: $ldapServer['authObjectFilter'])?LSsession :: $ldapServer['authObjectFilter']:NULL),
|
|
||||||
array('withoutCache' => true, 'onlyAccessible' => false)
|
|
||||||
);
|
|
||||||
$nbresult=count($result);
|
|
||||||
|
|
||||||
if ($nbresult==0) {
|
|
||||||
// incorrect login
|
|
||||||
LSdebug('identifiant incorrect');
|
|
||||||
LSerror :: addErrorCode('LSauth_01');
|
LSerror :: addErrorCode('LSauth_01');
|
||||||
|
self :: log_debug("No user found for provided username '".$this -> authData['username']."'");
|
||||||
}
|
}
|
||||||
else if ($nbresult>1) {
|
elseif (count($authobjects) > 1) {
|
||||||
// duplication of identity
|
self :: log_debug('Multiple users match with provided username: '.implode(', ', array_keys($authobjects)));
|
||||||
LSerror :: addErrorCode('LSauth_02');
|
LSerror :: addErrorCode('LSauth_02');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
// Authentication succeeded
|
||||||
return $result[0];
|
return $authobjects[$matched[0]];
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LSerror :: addErrorCode('LSauth_03');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -51,32 +51,28 @@ class LSauthMethod_basic extends LSauthMethod {
|
||||||
* @retval LSldapObject|false The LSldapObject of the user authificated or false
|
* @retval LSldapObject|false The LSldapObject of the user authificated or false
|
||||||
*/
|
*/
|
||||||
public function authenticate() {
|
public function authenticate() {
|
||||||
$authobject = parent :: authenticate();
|
$authobjects = LSauth :: username2LSobjects($this -> authData['username']);
|
||||||
if ($authobject) {
|
if (!$authobjects) {
|
||||||
if ( $this -> checkUserPwd($authobject,$this -> authData['password']) ) {
|
|
||||||
// Authentication succeeded
|
|
||||||
return $authobject;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LSerror :: addErrorCode('LSauth_01');
|
LSerror :: addErrorCode('LSauth_01');
|
||||||
LSdebug('mdp incorrect');
|
self :: log_debug('Invalid username');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
$matched = array();
|
||||||
|
foreach(array_keys($authobjects) as $dn)
|
||||||
|
if ( LSldap :: checkBind($dn, $this -> authData['password']) )
|
||||||
|
$matched[] = $dn;
|
||||||
|
if (!$matched) {
|
||||||
|
LSerror :: addErrorCode('LSauth_01');
|
||||||
|
self :: log_debug('Invalid password');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return;
|
elseif (count($matched) > 1) {
|
||||||
|
self :: log_debug('Multiple users match with provided username and password: '.implode(', ', $matched));
|
||||||
|
LSerror :: addErrorCode('LSauth_02');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
// Authentication succeeded
|
||||||
/**
|
return $authobjects[$matched[0]];
|
||||||
* Test un couple LSobject/pwd
|
|
||||||
*
|
|
||||||
* Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
|
|
||||||
*
|
|
||||||
* @param[in] LSobject L'object "user" pour l'authentification
|
|
||||||
* @param[in] string Le mot de passe à tester
|
|
||||||
*
|
|
||||||
* @retval boolean True si l'authentification a reussi, false sinon.
|
|
||||||
**/
|
|
||||||
public static function checkUserPwd($object,$pwd) {
|
|
||||||
return LSldap :: checkBind($object -> getValue('dn'),$pwd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,9 +84,12 @@ class LSsession {
|
||||||
// Libs CSS files to load on page
|
// Libs CSS files to load on page
|
||||||
private static $LibsCssFiles = array();
|
private static $LibsCssFiles = array();
|
||||||
|
|
||||||
// L'objet de l'utilisateur connecté
|
// The LSldapObject of connected user
|
||||||
private static $LSuserObject = NULL;
|
private static $LSuserObject = NULL;
|
||||||
|
|
||||||
|
// The LSldapObject type of connected user
|
||||||
|
private static $LSuserObjectType = NULL;
|
||||||
|
|
||||||
// The LSauht object of the session
|
// The LSauht object of the session
|
||||||
private static $LSauthObject = false;
|
private static $LSauthObject = false;
|
||||||
|
|
||||||
|
@ -96,6 +99,39 @@ class LSsession {
|
||||||
// Initialized telltale
|
// Initialized telltale
|
||||||
private static $initialized = false;
|
private static $initialized = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get session info by key
|
||||||
|
*
|
||||||
|
* @param[in] $key string The info
|
||||||
|
*
|
||||||
|
* @retval mixed The info or null
|
||||||
|
*/
|
||||||
|
public static function get($key) {
|
||||||
|
switch($key) {
|
||||||
|
case 'top_dn':
|
||||||
|
return self :: getTopDn();
|
||||||
|
case 'root_dn':
|
||||||
|
return self :: getRootDn();
|
||||||
|
case 'sub_dn_name':
|
||||||
|
return self :: getSubDnName();
|
||||||
|
case 'sub_dn_label':
|
||||||
|
return self :: getSubDnLabel();
|
||||||
|
case 'authenticated_user_dn':
|
||||||
|
return self :: $dn;
|
||||||
|
case 'authenticated_user_type':
|
||||||
|
return self :: $LSuserObjectType;
|
||||||
|
case 'authenticated_user':
|
||||||
|
return self :: getLSuserObject();
|
||||||
|
case 'is_connected':
|
||||||
|
return self :: isConnected();
|
||||||
|
case 'global_search_enabled':
|
||||||
|
return self :: globalSearch();
|
||||||
|
case 'email_sender':
|
||||||
|
return self :: getEmailSender();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include PHP file
|
* Include PHP file
|
||||||
*
|
*
|
||||||
|
@ -569,11 +605,12 @@ class LSsession {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($_SESSION['LSsession']['dn']) && !isset($_GET['LSsession_recoverPassword'])) {
|
if(isset($_SESSION['LSsession']['LSuserObjectType']) && isset($_SESSION['LSsession']['dn']) && !isset($_GET['LSsession_recoverPassword'])) {
|
||||||
self :: log_debug('existing session');
|
self :: log_debug('existing session');
|
||||||
// --------------------- Session existante --------------------- //
|
// --------------------- Session existante --------------------- //
|
||||||
self :: $topDn = $_SESSION['LSsession']['topDn'];
|
self :: $topDn = $_SESSION['LSsession']['topDn'];
|
||||||
self :: $dn = $_SESSION['LSsession']['dn'];
|
self :: $dn = $_SESSION['LSsession']['dn'];
|
||||||
|
self :: $LSuserObjectType = $_SESSION['LSsession']['LSuserObjectType'];
|
||||||
self :: $rdn = $_SESSION['LSsession']['rdn'];
|
self :: $rdn = $_SESSION['LSsession']['rdn'];
|
||||||
self :: $ldapServerId = $_SESSION['LSsession']['ldapServerId'];
|
self :: $ldapServerId = $_SESSION['LSsession']['ldapServerId'];
|
||||||
self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
|
self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
|
||||||
|
@ -606,7 +643,7 @@ class LSsession {
|
||||||
self :: $_subDnLdapServer = ((isset($_SESSION['LSsession_subDnLdapServer']))?$_SESSION['LSsession_subDnLdapServer']:NULL);
|
self :: $_subDnLdapServer = ((isset($_SESSION['LSsession_subDnLdapServer']))?$_SESSION['LSsession_subDnLdapServer']:NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
|
if (!self :: loadLSobject(self :: $LSuserObjectType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,6 +731,7 @@ class LSsession {
|
||||||
if ($LSuserObject) {
|
if ($LSuserObject) {
|
||||||
// Authentication successful
|
// Authentication successful
|
||||||
self :: $LSuserObject = $LSuserObject;
|
self :: $LSuserObject = $LSuserObject;
|
||||||
|
self :: $LSuserObjectType = $LSuserObject -> getType();
|
||||||
self :: $dn = $LSuserObject->getValue('dn');
|
self :: $dn = $LSuserObject->getValue('dn');
|
||||||
self :: $rdn = $LSuserObject->getValue('rdn');
|
self :: $rdn = $LSuserObject->getValue('rdn');
|
||||||
if (isset(self :: $ldapServer['useUserCredentials']) && self :: $ldapServer['useUserCredentials']) {
|
if (isset(self :: $ldapServer['useUserCredentials']) && self :: $ldapServer['useUserCredentials']) {
|
||||||
|
@ -761,85 +799,97 @@ class LSsession {
|
||||||
* @retval array The recoveryPassword infos for template
|
* @retval array The recoveryPassword infos for template
|
||||||
**/
|
**/
|
||||||
private static function recoverPasswd($username, $recoveryHash) {
|
private static function recoverPasswd($username, $recoveryHash) {
|
||||||
$recoveryPasswordInfos=array();
|
// Check feature is enabled and LSmail available
|
||||||
if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
|
if (!isset(self :: $ldapServer['recoverPassword']) || !self :: loadLSaddon('mail')) {
|
||||||
$authobject = new self :: $ldapServer['authObjectType']();
|
LSerror :: addErrorCode('LSsession_18');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start LSauth
|
||||||
|
if (!LSauth :: start()) {
|
||||||
|
self :: log_error("recoverPasswd(): can't start LSauth -> stop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search user by recoveryHash or username
|
||||||
if (!empty($recoveryHash)) {
|
if (!empty($recoveryHash)) {
|
||||||
|
$users = array();
|
||||||
$filter = Net_LDAP2_Filter::create(
|
$filter = Net_LDAP2_Filter::create(
|
||||||
self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
|
self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
|
||||||
'equals',
|
'equals',
|
||||||
$recoveryHash
|
$recoveryHash
|
||||||
);
|
);
|
||||||
$result = $authobject -> listObjects($filter,self :: $topDn,array('onlyAccessible' => false));
|
foreach (LSauth :: getAuthObjectTypes() as $objType => $objParams) {
|
||||||
}
|
if (!self :: loadLSobject($objType))
|
||||||
elseif (!empty($username)) {
|
return false;
|
||||||
$result = $authobject -> searchObject(
|
$authobject = new $objType();
|
||||||
$username,
|
$users = array_merge(
|
||||||
self :: $topDn,
|
$users,
|
||||||
self :: $ldapServer['authObjectFilter'],
|
$authobject -> listObjects($filter, self :: $topDn, array('onlyAccessible' => false))
|
||||||
array('onlyAccessible' => false)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
elseif (!empty($username)) {
|
||||||
|
$users = LSauth :: username2LSobjects($username);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return $recoveryPasswordInfos;
|
self :: log_debug('recoverPasswd(): no username or recoveryHash provided.');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$nbresult=count($result);
|
// Check user found (and not duplicated)
|
||||||
|
$nbresult = count($users);
|
||||||
if ($nbresult == 0) {
|
if ($nbresult == 0) {
|
||||||
self :: log_debug('recoverPasswd(): incorrect hash/username');
|
self :: log_debug('recoverPasswd(): incorrect hash/username');
|
||||||
LSerror :: addErrorCode('LSsession_06');
|
LSerror :: addErrorCode('LSsession_06');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
elseif ($nbresult > 1) {
|
elseif ($nbresult > 1) {
|
||||||
self :: log_debug("recoverPasswd(): duplicated user found with hash/username '$username'");
|
self :: log_debug("recoverPasswd(): duplicated user found with hash='$recoveryHash' / username='$username'");
|
||||||
LSerror :: addErrorCode('LSsession_07');
|
LSerror :: addErrorCode('LSsession_07');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$rdn = $result[0] -> getValue('rdn');
|
$user = array_pop($users);
|
||||||
|
$rdn = $user -> getValue('rdn');
|
||||||
$username = $rdn[0];
|
$username = $rdn[0];
|
||||||
self :: log_debug("recoverPasswd(): user found, username = '$username'");
|
self :: log_debug("recoverPasswd(): user found, username = '$username'");
|
||||||
if (self :: $ldapServer['recoverPassword']) {
|
|
||||||
if (self :: loadLSaddon('mail')) {
|
|
||||||
self :: log_debug("recoverPasswd(): start recovering password");
|
self :: log_debug("recoverPasswd(): start recovering password");
|
||||||
$user=$result[0];
|
|
||||||
$emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
|
$emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
|
||||||
$emailAddress = $emailAddress[0];
|
$emailAddress = $emailAddress[0];
|
||||||
|
|
||||||
if (checkEmail($emailAddress)) {
|
if (!checkEmail($emailAddress)) {
|
||||||
|
LSerror :: addErrorCode('LSsession_19');
|
||||||
|
return;
|
||||||
|
}
|
||||||
self :: log_debug("recoverPasswd(): Email = '$emailAddress'");
|
self :: log_debug("recoverPasswd(): Email = '$emailAddress'");
|
||||||
self :: $dn = $user -> getDn();
|
self :: $dn = $user -> getDn();
|
||||||
|
|
||||||
// 1ère étape : envoie du recoveryHash
|
//
|
||||||
|
$recoveryPasswordInfos = array();
|
||||||
|
|
||||||
|
// First step : send recoveryHash
|
||||||
if (empty($recoveryHash)) {
|
if (empty($recoveryHash)) {
|
||||||
$hash = self :: recoverPasswdFirstStep($user);
|
$hash = self :: recoverPasswdFirstStep($user);
|
||||||
if ($hash) {
|
if ($hash) {
|
||||||
if (self :: recoverPasswdSendMail($emailAddress, 1, $hash)) {
|
if (self :: recoverPasswdSendMail($emailAddress, 1, $hash)) {
|
||||||
// Mail a bien été envoyé
|
// Recovery hash sent
|
||||||
$recoveryPasswordInfos['recoveryHashMail'] = $emailAddress;
|
$recoveryPasswordInfos['recoveryHashMail'] = $emailAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2nd étape : génération du mot de passe + envoie par mail
|
// Second step : generate and send new password
|
||||||
else {
|
else {
|
||||||
$pwd = self :: recoverPasswdSecondStep($user);
|
$pwd = self :: recoverPasswdSecondStep($user);
|
||||||
if ($pwd) {
|
if ($pwd) {
|
||||||
if (self :: recoverPasswdSendMail($emailAddress, 2, $pwd)) {
|
if (self :: recoverPasswdSendMail($emailAddress, 2, $pwd)) {
|
||||||
// Mail a bien été envoyé
|
// New password sent
|
||||||
$recoveryPasswordInfos['newPasswordMail'] = $emailAddress;
|
$recoveryPasswordInfos['newPasswordMail'] = $emailAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
LSerror :: addErrorCode('LSsession_19');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LSerror :: addErrorCode('LSsession_18');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $recoveryPasswordInfos;
|
return $recoveryPasswordInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,24 +981,25 @@ class LSsession {
|
||||||
* @retval string|False The new password on success or False
|
* @retval string|False The new password on success or False
|
||||||
**/
|
**/
|
||||||
private static function recoverPasswdSecondStep($user) {
|
private static function recoverPasswdSecondStep($user) {
|
||||||
$attr = $user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
|
$pwd_attr_name = LSauth :: getUserPasswordAttribute($user);
|
||||||
if ($attr instanceof LSattribute) {
|
if (array_key_exists($pwd_attr_name, $user -> attrs)) {
|
||||||
$mdp = generatePassword(
|
$pwd_attr = $user -> attrs[$pwd_attr_name];
|
||||||
$attr -> config['html_options']['chars'],
|
$pwd = generatePassword(
|
||||||
$attr -> config['html_options']['lenght']
|
$pwd_attr -> getConfig('html_options.chars'),
|
||||||
|
$pwd_attr -> getConfig('html_options.lenght'),
|
||||||
);
|
);
|
||||||
self :: log_debug("recoverPasswdSecondStep($user): new password = '$mdp'.");
|
self :: log_debug("recoverPasswdSecondStep($user): new password = '$pwd'.");
|
||||||
$lostPasswdForm = $user -> getForm('lostPassword');
|
$lostPasswdForm = $user -> getForm('lostPassword');
|
||||||
$lostPasswdForm -> setPostData(
|
$lostPasswdForm -> setPostData(
|
||||||
array(
|
array(
|
||||||
self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
|
self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
|
||||||
self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
|
$pwd_attr_name => array($pwd)
|
||||||
)
|
)
|
||||||
,true
|
,true
|
||||||
);
|
);
|
||||||
if($lostPasswdForm -> validate()) {
|
if($lostPasswdForm -> validate()) {
|
||||||
if ($user -> updateData('lostPassword')) {
|
if ($user -> updateData('lostPassword')) {
|
||||||
return $mdp;
|
return $pwd;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Erreur durant la mise à jour de l'objet
|
// Erreur durant la mise à jour de l'objet
|
||||||
|
@ -964,7 +1015,7 @@ class LSsession {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// l'attribut password n'existe pas
|
// l'attribut password n'existe pas
|
||||||
self :: log_error("recoverPasswdSecondStep($user): password attribute '$attr' does not exists.");
|
self :: log_error("recoverPasswdSecondStep($user): password attribute '$pwd_attr_name' does not exists.");
|
||||||
LSerror :: addErrorCode('LSsession_20',1);
|
LSerror :: addErrorCode('LSsession_20',1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -983,6 +1034,7 @@ class LSsession {
|
||||||
'topDn' => self :: $topDn,
|
'topDn' => self :: $topDn,
|
||||||
'dn' => self :: $dn,
|
'dn' => self :: $dn,
|
||||||
'rdn' => self :: $rdn,
|
'rdn' => self :: $rdn,
|
||||||
|
'LSuserObjectType' => self :: $LSuserObjectType,
|
||||||
'userLDAPcreds' => self :: $userLDAPcreds,
|
'userLDAPcreds' => self :: $userLDAPcreds,
|
||||||
'ldapServerId' => self :: $ldapServerId,
|
'ldapServerId' => self :: $ldapServerId,
|
||||||
'ldapServer' => self :: $ldapServer,
|
'ldapServer' => self :: $ldapServer,
|
||||||
|
@ -1000,14 +1052,17 @@ class LSsession {
|
||||||
* @retval mixed L'objet de l'utilisateur connecté ou false si il n'a pas put
|
* @retval mixed L'objet de l'utilisateur connecté ou false si il n'a pas put
|
||||||
* être créé
|
* être créé
|
||||||
*/
|
*/
|
||||||
public static function getLSuserObject($dn=null) {
|
public static function &getLSuserObject($dn=null) {
|
||||||
if ($dn) {
|
if ($dn) {
|
||||||
self :: $dn = $dn;
|
self :: $dn = $dn;
|
||||||
}
|
}
|
||||||
if (!self :: $LSuserObject) {
|
if (!self :: $LSuserObject) {
|
||||||
if (self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
|
if (self :: $LSuserObjectType && self :: loadLSobject(self :: $LSuserObjectType)) {
|
||||||
self :: $LSuserObject = new self :: $ldapServer['authObjectType']();
|
self :: $LSuserObject = new self :: $LSuserObjectType();
|
||||||
self :: $LSuserObject -> loadData(self :: $dn);
|
if (!self :: $LSuserObject -> loadData(self :: $dn)) {
|
||||||
|
self :: $LSuserObject = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
|
@ -1024,7 +1079,7 @@ class LSsession {
|
||||||
* @retval boolean True if user connected, false instead
|
* @retval boolean True if user connected, false instead
|
||||||
*/
|
*/
|
||||||
public static function isConnected() {
|
public static function isConnected() {
|
||||||
if (self :: $LSuserObject)
|
if (self :: getLSuserObject())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1041,16 +1096,17 @@ class LSsession {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifie l'utilisateur connecté à la volé
|
* Live change of the connected user
|
||||||
*
|
*
|
||||||
* @param[in] $object Mixed L'objet Ldap du nouvel utilisateur
|
* @param[in] $object LSldapObject The new connected user object
|
||||||
* le type doit correspondre à
|
|
||||||
* self :: $ldapServer['authObjectType']
|
|
||||||
*
|
*
|
||||||
* @retval boolean True en cas de succès, false sinon
|
* @retval boolean True on succes, false otherwise
|
||||||
*/
|
*/
|
||||||
public static function changeAuthUser($object) {
|
public static function changeAuthUser($object) {
|
||||||
if ($object instanceof self :: $ldapServer['authObjectType']) {
|
if($object instanceof LSldapObject)
|
||||||
|
return;
|
||||||
|
if(!in_array($object -> getType(), LSauth :: getAuthObjectTypes()))
|
||||||
|
return;
|
||||||
self :: $dn = $object -> getDn();
|
self :: $dn = $object -> getDn();
|
||||||
$rdn = $object -> getValue('rdn');
|
$rdn = $object -> getValue('rdn');
|
||||||
if(is_array($rdn)) {
|
if(is_array($rdn)) {
|
||||||
|
@ -1058,6 +1114,7 @@ class LSsession {
|
||||||
}
|
}
|
||||||
self :: $rdn = $rdn;
|
self :: $rdn = $rdn;
|
||||||
self :: $LSuserObject = $object;
|
self :: $LSuserObject = $object;
|
||||||
|
self :: $LSuserObjectType = $object -> getType();
|
||||||
|
|
||||||
if(self :: loadLSprofiles()) {
|
if(self :: loadLSprofiles()) {
|
||||||
self :: loadLSaccess();
|
self :: loadLSaccess();
|
||||||
|
@ -1065,7 +1122,6 @@ class LSsession {
|
||||||
$_SESSION['LSsession']=self :: getContextInfos();
|
$_SESSION['LSsession']=self :: getContextInfos();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue