From e24482e05f9564e5534f4dceb4f80b6762be3f98 Mon Sep 17 00:00:00 2001 From: Etienne Pallier Date: Tue, 19 Feb 2019 18:09:21 +0100 Subject: [PATCH] ldap refactorisation (2) --- README.md | 12 ++++++++---- src/Model/Table/LdapConnectionsTable.php | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- src/Template/Layout/default.ctp | 2 +- 3 files changed, 215 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 3b64477..41eeb7b 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,12 @@ Logiciel testé et validé sur les configurations suivantes : VERSION ACTUELLE -Date: 14/02/2019 -Version: 2.10.14 +Date: 19/02/2019 +Version: 2.10.15 Author: EP - (IRAP ONLY) LDAP refactorisation && optimisation (1) + (IRAP ONLY) LDAP refactorisation && optimisation (2) + - LDAP refactor pour ajouter mode LDAP authentifié + - Nouveau lien "What's New ?" en bas de page web (historique du projet) IMPORTANT: - Pour connaitre la version actuelle, taper "./VERSION" @@ -86,7 +88,9 @@ Messages à copier/coller en cas de besoin : CHANGEMENTS IMPORTANTS (MILESTONES) -Liste complète des évolutions: https://gitlab.irap.omp.eu/epallier/labinvent/commits/master +(Liste complète des évolutions: https://gitlab.irap.omp.eu/epallier/labinvent/commits/master) + +La liste ci-dessous n'est plus à jour, elle est désormais en ligne ici : https://tinyurl.com/labinvent#heading=h.2r55bflctpt5 ----------------------------------------------------------------------------------------------------------- 23/01/2019 Version: 2.10.1, 2, 3, 4, et 6 (EP) diff --git a/src/Model/Table/LdapConnectionsTable.php b/src/Model/Table/LdapConnectionsTable.php index bccf4c1..2ea4fc6 100755 --- a/src/Model/Table/LdapConnectionsTable.php +++ b/src/Model/Table/LdapConnectionsTable.php @@ -1,6 +1,18 @@ get() + * + */ + + + + use Cake\ORM\Table; use Cake\ORM\TableRegistry; use Cake\Auth\DefaultPasswordHasher; @@ -57,7 +69,7 @@ class LdapConnectionsTable extends AppTable private function buildFakeLdapUsersFromDB() { - $users = TableRegistry::get('Users')->find(); + $users = TableRegistry::getTableLocator()->get('Users')->find(); $ldapUsers = []; @@ -233,22 +245,75 @@ class LdapConnectionsTable extends AppTable } return $res; } - } catch (Exception $e) {} + } + catch (Exception $e) {} + return false; } + + /** + * @return $users_fetched or FALSE + */ + // REAL or FAKE LDAP + public function getAllLdapUsersNEW() + { + try { + if ($this->checkConfiguration()) { + + // REAL LDAP + if ($this->LDAP_USED) { + + // 1) Search users in CACHE (DB) + $users_fetched = $this->fetchAllUsersFromDB(); + + // 2) Not found in CACHE, so search users in LDAP + if ($users_fetched === FALSE) { + $users_fetched = $this->searchLdap($this->filter, []); + // CACHE the new user in DB for next time + if ($users_fetched != FALSE) $this->saveAllUsersInDB($users_fetched); + } + /* + $ldapConnection = ldap_connect($this->host, $this->port); + ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); + + // Binding optionnel + if ($this->ldap_authentified) $ldapbind = ldap_bind($ldapConnection, $this->bindDn, $this->bindPass) + or die("Could not bind to LDAP server.". ldap_error($ldapConnection) ); + + $results = ldap_search($ldapConnection, $this->baseDn, $this->filter); + + $res = ldap_get_entries($ldapConnection, $results); + */ + } + + // FAKE LDAP + else { + $users_fetched = $this->fakeLDAPUsers; + } + + // Noter que $user_fetched peut etre egal a FALSE (si rien trouvé) + return $users_fetched; + } + } + catch (Exception $e) {} + + // Pb, rien trouvé + return FALSE; + } + // TODO: avirer, VIEUX CODE, à remplacer par getLdap1UserOrAllUsersAttributes() // $userName = login - public function getUserAttributes($userName) + public function getUserAttributes($ldapConnection, $userName) { try { if ($this->checkConfiguration()) { if ($this->LDAP_USED) { - $ldapConnection = ldap_connect($this->host, $this->port); - ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); + //$ldapConnection = ldap_connect($this->host, $this->port); + //ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); $results = ldap_search($ldapConnection, $this->baseDn, '(' . $this->authenticationType . '=' . $userName . ')'); return ldap_get_entries($ldapConnection, $results); } else @@ -441,7 +506,6 @@ class LdapConnectionsTable extends AppTable /** * Return size of list users - */ public function getNbUsers() { $u = $this->getAllLdapUsers(); @@ -453,6 +517,7 @@ class LdapConnectionsTable extends AppTable } return $nbUsers; } + */ // Utilisateur du ldap qui n'est pas dans la table utilisateurs // => il a donc le role "Utilisateur" PAR DEFAUT @@ -476,9 +541,29 @@ class LdapConnectionsTable extends AppTable } + + /* + CALL + + $filter = "(&".$this->filter."(".$this->authenticationType . '=' . $user_login."))"; + //TODO: optimisation, refactoriser si comportement général + //$binddn .= ','.$this->baseDn; + $user_fetched = $this->searchLdap($filter, $just_these, $user_login, $user_password); + */ + + + // REAL LDAP only private function searchLdap($filter, $just_these, $user_login=NULL, $user_password=NULL) { + /* + * OLD CODE QUI MARCHE + $ldapConnection = ldap_connect($this->host, $this->port); + ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); + if (@ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password)) + return $this->getUserAttributes($user_login)[0]; + */ + // CONNEXION $ldapConnection = ldap_connect($this->host, $this->port) or die("Could not connect to $this->host (port $this->port)"); @@ -491,31 +576,33 @@ class LdapConnectionsTable extends AppTable // BINDING // - Authentified - if ($this->ldap_authentified) - $ldapbind = ldap_bind($ldapConnection, $this->bindDn, $this->bindPass); + if ($this->ldap_authentified) $ldapbind = ldap_bind($ldapConnection, $this->bindDn, $this->bindPass); // or die("Could not bind to LDAP server.". ldap_error($ldapConnection) ); - // - Anonymous - // En cas de LDAP anonyme, binding quand même pour vérifier le mot de passe de l'utilisateur. - // Sans cette ligne, on passe avec n'importe quel password !!! - else { + // - Anonymous + // En cas de LDAP anonyme, binding quand même pour vérifier le mot de passe de l'utilisateur. + // Sans cette ligne, on passe avec n'importe quel password !!! + else { $ldapbind = TRUE; // function ldap_bind ($link_identifier, $bind_rdn = null, $bind_password = null) //debug("log, pass= " . $user_login . ' ' . $user_password); //if ($user_login && $user_password) $ldapbind = ldap_bind($ldapConnection, $this->authenticationType.'='.$user_login, $user_password); - if ($user_login && $user_password) - $ldapbind = ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password); + if ($user_login && $user_password) $ldapbind = ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password); //debug("ldapbind " . $ldapbind); - } + } - // SEARCH - if ($ldapbind) { - //$search = $this->getLdapUserAttributes($ldapConnection, $filter, $just_these, $user_login); - $search = $this->getLdap1UserOrAllUsersAttributes($ldapConnection, $filter, $just_these); - if ($search === FALSE) die("Could not get user attributes from LDAP server, response was: " . ldap_error($ldapConnection) ); - //return $search[0]; - return $search; - } + // SEARCH + if ($ldapbind) { + + // OLD + $search = $this->getUserAttributes($ldapConnection, $user_login); + // NEW + //$search = $this->getLdap1UserOrAllUsersAttributes($ldapConnection, $filter, $just_these); + + if ($search === FALSE) die("Could not get user attributes from LDAP server, response was: " . ldap_error($ldapConnection) ); + //return $search[0]; + return $search; + } } @@ -526,14 +613,14 @@ class LdapConnectionsTable extends AppTable - // REAL LDAP only + /* private function checkAndFetchUserFromLdap($user_login, $user_password) { // Set LDAP parameters // - Liste des attributs à récupérer dans le ldap (vide = TOUS les attributs) $just_these = []; // TODO: vérifier si cette ligne est bien utile ou pas... (avant on faisait ça) - if (! $this->ldap_authentified) $just_these = array("cn"); + //if (! $this->ldap_authentified) $just_these = array("cn"); /* Examples : * @@ -547,7 +634,7 @@ class LdapConnectionsTable extends AppTable * $binddn="CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1,DC=univ-lyon1,DC=fr"; * ($binddn = "CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1,".$this->baseDn;) * $filter = "(&(objectClass=person)(memberOf:1.2.840.113556.1.4.1941:=cn=ucbl.osu.cral,ou=groups,ou=27,ou=sim,ou=univ-lyon1,dc=univ-lyon1,dc=fr))"; - */ + STAR/ // Construction du filtre avec le filtre de la base de données avec un & sur le login de l'utilisateur // Si aucun filtre n'est défini dans la base de données on aura juste (& ($this->authenticationType=$user_login)) // ex: "(&(objectClass=person)(memberOf:1.2.840.113556.1.4.1941:=cn=ucbl.osu.cral,ou=groups,ou=27,ou=sim,ou=univ-lyon1,dc=univ-lyon1,dc=fr)(sAMAccountName=$user_login))"; @@ -585,11 +672,12 @@ class LdapConnectionsTable extends AppTable } } - */ + STAR/ // Il y a eu un pb, utilisateur non reconnu return FALSE; } + */ // TODO: implement @@ -606,10 +694,10 @@ class LdapConnectionsTable extends AppTable * @param string $user_password * @return logged user LDAP attributes or FALSE if user not found in LDAP */ - public function ldapAuthentication($user_login, $user_password) { + /* + public function ldapAuthenticationOLD($user_login, $user_password) { try { if ($this->checkConfiguration()) { - if ($this->LDAP_USED) { if (strlen(trim($user_password)) == 0) return FALSE; @@ -617,10 +705,10 @@ class LdapConnectionsTable extends AppTable ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); if (@ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password)) { return $this->getUserAttributes($user_login)[0]; - /* + /STAR * } else { * return false; - */ + STAR/ } } else { $user = $this->getFakeLdapUser($user_login); @@ -640,11 +728,97 @@ class LdapConnectionsTable extends AppTable } catch (Exception $e) { //echo 'Exception LDAP : ', $e->getMessage(), "\n"; } - // Il y a eu un problème, l'utilisateur n'est pas reconnu return FALSE; } // end ldapAuthentication() + */ + /* + * @param string $user_login + * @param string $user_password + * @return logged user LDAP attributes or FALSE if user not found in LDAP + */ + public function ldapAuthentication($user_login, $user_password) { + + try { + if ($this->checkConfiguration()) { + + // REAL LDAP + if ($this->LDAP_USED) { + + // No connexion allowed without password + if (strlen(trim($user_password)) == 0) return FALSE; + + /* + // VIEUX CODE QUI MARCHE !!! + $ldapConnection = ldap_connect($this->host, $this->port); + ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); + if (@ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password)) { + return $this->getUserAttributes($user_login)[0]; + /STAR + * } else { + * return false; + STAR/ + } + */ + + // TODO: optimisation possible + // 1) Search user in CACHE (DB) + $user_fetched = $this->checkAndFetchUserFromDB($user_login, $user_password); + // 2) If not CACHED, search user in LDAP + if ($user_fetched === FALSE) { + + //$user_fetched = $this->checkAndFetchUserFromLdap($user_login, $user_password); + + $just_these = []; + // TODO: vérifier si cette ligne est bien utile ou pas... (avant on faisait ça) + //if (! $this->ldap_authentified) $just_these = array("cn"); + // Construction du filtre avec le filtre de la base de données avec un & sur le login de l'utilisateur + // Si aucun filtre n'est défini dans la base de données on aura juste (& ($this->authenticationType=$user_login)) + // ex: "(&(objectClass=person)(memberOf:1.2.840.113556.1.4.1941:=cn=ucbl.osu.cral,ou=groups,ou=27,ou=sim,ou=univ-lyon1,dc=univ-lyon1,dc=fr)(sAMAccountName=$user_login))"; + $filter = "(&".$this->filter."(".$this->authenticationType . '=' . $user_login."))"; + //TODO: optimisation, refactoriser si comportement général + //$binddn .= ','.$this->baseDn; + $user_fetched = $this->searchLdap($filter, $just_these, $user_login, $user_password); + // CACHE the new user in DB for next time + if ($user_fetched != FALSE) { + $this->saveNewUserInDB($user_fetched[0]); + return $user_fetched[0]; + } + } + //return $user_fetched; // Noter que $user_fetched peut etre egal a FALSE (si pas trouvé) + } + + // FAKE LDAP + else { + //debug($this->USE_LDAP); + //debug($this->baseDn); + $user = $this->getFakeLdapUser($user_login); + // debug($user); + if ($user === false) + return FALSE; + // $this->authenticationType peut valoir "uid" ou "cn"... (par défaut "uid" pour le fake ldap, à confirmer...) + // if ($user['uid'][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user; + // if ($user[$this->authenticationType][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user; + if ($user[$this->authenticationType][0] == $this->getTheFakeLdapUser()['login'] && $user['userpassword'][0] == $this->getTheFakeLdapUser()['pass']) + return $user; + if ( (new DefaultPasswordHasher())->check($user_password,$user['userpassword'][0]) ) + return $user; + // if ($user != false && $user['userpassword'][0] == $password) { + } + + } + + } catch (Exception $e) { + //echo 'Exception LDAP : ', $e->getMessage(), "\n"; + } + // Il y a eu un problème, l'utilisateur n'est pas reconnu + return FALSE; + + } // end ldapAuthentication() + + + } diff --git a/src/Template/Layout/default.ctp b/src/Template/Layout/default.ctp index 70d8fb2..be60e1f 100755 --- a/src/Template/Layout/default.ctp +++ b/src/Template/Layout/default.ctp @@ -110,7 +110,7 @@ $cakeDescription = 'Labinvent 2'; - (Activité récente sur le projet) + WHAT\'s NEW ?     (ROADMAP : Activité restant à réaliser)

-- libgit2 0.21.2