Commit 3c35bcf17692e317ac3d11fc1fb4021abc51a2c1

Authored by Etienne Pallier
1 parent 0f0b5230
Exists in master and in 1 other branch dev

Gestion plus clean de la connexion

CHANGELOG
... ... @@ -484,6 +484,13 @@ rien ?
484 484 ======= CHANGES =======
485 485  
486 486 -------
  487 +23/12/2022 (EP) v5.7.0-3.10.1
  488 + - (i) Gestion bien plus clean de la connexion (ldap ou fake-ldap, avec cache systématique dans table users)
  489 + => Si new user (ldap) => ADDED dans cache
  490 + => Si user changed (ldap) => UPDATED dans cache
  491 + => Si user removed (ldap) => DELETED dans cache
  492 +
  493 +-------
487 494 23/12/2022 (EP) v5.6.1-3.10.1
488 495 - (i) Suppression contrainte unicité du nom-pnom dans table users
489 496 => car on peut autoriser 2 homonymes ou encore une meme personne (nom-pnom) avec 2 login différents
... ...
README.md
... ... @@ -53,7 +53,7 @@ Logiciel testé et validé sur les configurations suivantes :
53 53 --------------------------------------------------------------------------------------------
54 54  
55 55 Date: 23/12/2022
56   -Version: v5.6.1-3.10.1
  56 +Version: v5.7.0-3.10.1
57 57  
58 58  
59 59 HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes)
... ...
src/Controller/AppController.php
... ... @@ -805,11 +805,11 @@ class AppController extends Controller
805 805 public function isAuthorizedActionForCurrentUser($action, $id=null, $related_matos_id=null, $user=null) {
806 806 //return $this->isAuthorizedActionForRole($this->user_role, $action, $id);
807 807 //return $this->isAuthorizedActionForRole($this->getUserRole($user), $action, $id, $IS_RELATED_ENTITY_ID, $user);
808   - $this->d("IN isAuthorizedActionForCurrentUser(): controleur $this->name, action $action");
  808 + ####$this->d("IN isAuthorizedActionForCurrentUser(): controleur $this->name, action $action");
809 809 //return $this->isAuthorizedActionForRole($this->getUserRole($user), $action, $id, $related_matos_id, $user);
810 810 //return $this->isAuthorizedActionForCurrentUser($action, $id, $related_matos_id, $user);
811 811 $role_long = $this->getUserRole($user);
812   - $this->d("*************************** CONTROLEUR ".$this->name.", ACTION $action, ROLE $role_long, id=$id, related_matos_id=$related_matos_id");
  812 + ####$this->d("*************************** CONTROLEUR ".$this->name.", ACTION $action, ROLE $role_long, id=$id, related_matos_id=$related_matos_id");
813 813 //$this->d("********* USER :"); $this->d2($user);
814 814 //if ($this->SUPERADMIN_CAN_DO_EVERYTHING) return TRUE;
815 815 if ($this->confLabinvent->mode_nolimit) return TRUE;
... ... @@ -846,7 +846,7 @@ class AppController extends Controller
846 846 //debug("role is $role");
847 847 //$access_condition = $this->is_authorized_action[$action][$role];
848 848 $access_condition = $this->getAccessConditionForActionAndRole($action,$role);
849   - $this->d("0) Condition (complète) (NOT desaliased) :"); $this->d($access_condition);
  849 + ####$this->d("0) Condition (complète) (NOT desaliased) :"); $this->d($access_condition);
850 850 //debug($this->is_authorized_action);
851 851 //debug($this->is_authorized_action[$action]);
852 852 //debug("access_condition"); debug($access_condition);
... ... @@ -859,7 +859,7 @@ class AppController extends Controller
859 859 $access_condition = $this->is_authorized_action[$action][$role];
860 860 }
861 861 // - si -1 => acccès refusé
862   - $this->d("1) Condition (complète) (desaliased) :"); $this->d($access_condition);
  862 + ####$this->d("1) Condition (complète) (desaliased) :"); $this->d($access_condition);
863 863 //if ($action=='debugOff') debug($access_condition); exit;
864 864 if ($access_condition === -1) return FALSE;
865 865 if ($access_condition === 0) return TRUE;
... ... @@ -1832,7 +1832,7 @@ class AppController extends Controller
1832 1832 $SPECIFIC_METHOD_EXISTS = false;
1833 1833 if ($this->confLabinvent->labNameShort) {
1834 1834 $labshortname = $this->confLabinvent->labNameShort;
1835   - $this->d("lab name is set to $labshortname");
  1835 + ####$this->d("lab name is set to $labshortname");
1836 1836 $setAuthorizationsSpecific = "setAuthorizations_$labshortname";
1837 1837 // Si une méthode spécifique (dans le controleur courant) existe pour CE labo, on l'appelle à la place de la méthode générale
1838 1838 // Par exemple pour l'IRAP, ça sera $this=>setAuthorizations_IRAP() :
... ... @@ -1932,16 +1932,16 @@ class AppController extends Controller
1932 1932 // Affichages pour debug
1933 1933 //pr($event);
1934 1934  
1935   - $this->myDebug("step 1B (general): AppController.beforeFilter()");
  1935 + ####$this->myDebug("step 1B (general): AppController.beforeFilter()");
1936 1936  
1937 1937 $controllerName = $this->request->getParam('controller');
1938   - $this->myDebug("- controller passed : $controllerName");
  1938 + ####$this->myDebug("- controller passed : $controllerName");
1939 1939  
1940 1940 $passedArgs = $this->request->getParam('pass');
1941   - $this->myDebug("- args passed : ", $passedArgs);
  1941 + ####$this->myDebug("- args passed : ", $passedArgs);
1942 1942  
1943 1943 $query = $this->request->getQueryParams();
1944   - $this->myDebug("- query passed : ", $query);
  1944 + ####$this->myDebug("- query passed : ", $query);
1945 1945  
1946 1946 // Initialisations pour la suite
1947 1947 // - L'entité concernée par l'action
... ... @@ -1949,10 +1949,10 @@ class AppController extends Controller
1949 1949 $this->e = null;
1950 1950 // - L'action demandée et son id le cas échéant (nul par défaut, égal 0)
1951 1951 $this->a = $this->getActionPassed();
1952   - $this->myDebug("- action passed : ".$this->a);
  1952 + ####$this->myDebug("- action passed : ".$this->a);
1953 1953 //debug("- action passed : ".$this->a);
1954 1954 $this->e_id = $this->getIdPassed();
1955   - $this->myDebug("- id passed : ".$this->e_id);
  1955 + ####$this->myDebug("- id passed : ".$this->e_id);
1956 1956  
1957 1957 parent::beforeFilter($event);
1958 1958  
... ... @@ -1994,8 +1994,8 @@ class AppController extends Controller
1994 1994 // - pour le controleur spécifique,
1995 1995 // - et pour la vue
1996 1996 // Utilisateur connecté (identifié) ?
1997   - $this->myDebug("- Utilisateur connecté ? : ", $this->LdapAuth->user() ? "oui" : "non");
1998   - $this->myDebug($this->LdapAuth->user());
  1997 + ####$this->myDebug("- Utilisateur connecté ? : ", $this->LdapAuth->user() ? "oui" : "non");
  1998 + ####$this->myDebug($this->LdapAuth->user());
1999 1999 //if ($configuration->ldap_used && !$this->);
2000 2000 if ($this->LdapAuth->user()) {
2001 2001  
... ... @@ -2007,9 +2007,9 @@ class AppController extends Controller
2007 2007 //$this->user_role = $this->getUserRole();
2008 2008 $this->user_role = $this->getUserRole();
2009 2009 $profile = self::PROFILES["$this->user_role"];
2010   - $this->myDebug("- priviledgedUser is {$this->u}");
  2010 + ####$this->myDebug("- priviledgedUser is {$this->u}");
2011 2011 //debug("- priviledgedUser is {$this->u}"); exit;
2012   - $this->myDebug("- user_role is {$this->getUserRole()}", "- profile is: $profile");
  2012 + ####$this->myDebug("- user_role is {$this->getUserRole()}", "- profile is: $profile");
2013 2013 // L'utilisateur connecté (return null si pas connecté)
2014 2014 // $this->Auth->user('id');
2015 2015 //$this->userName = $this->getCurrentUserName();
... ... @@ -2080,7 +2080,7 @@ class AppController extends Controller
2080 2080 // Autoriser TOUTES les actions SANS authentification
2081 2081 //$this->LdapAuth->allow();
2082 2082  
2083   - $this->myDebug("- Actions allowed are: ", $this->LdapAuth->allowedActions);
  2083 + ####$this->myDebug("- Actions allowed are: ", $this->LdapAuth->allowedActions);
2084 2084  
2085 2085 /* (EP 20200427 migré dans initialize())
2086 2086 // Message d'erreur en cas de refus de connexion
... ... @@ -2819,7 +2819,7 @@ class AppController extends Controller
2819 2819  
2820 2820 parent::afterFilter($event);
2821 2821  
2822   - $this->myDebug("step ?? (general): AppController.afterFilter()");
  2822 + ####$this->myDebug("step ?? (general): AppController.afterFilter()");
2823 2823 // Tout le temps 'index', why ??N
2824 2824 //debug($this->request->getAttribute('params')['action']);
2825 2825 if (in_array($this->request->getAttribute('params')['action'], [
... ...
src/Controller/Component/LdapAuthComponent.php
... ... @@ -8,6 +8,7 @@ use Cake\ORM\TableRegistry;
8 8 class LdapAuthComponent extends AuthComponent
9 9 {
10 10  
  11 + // return FALSE if bad authentication, OR user if ok
11 12 public function connection()
12 13 {
13 14 try {
... ... @@ -15,7 +16,7 @@ class LdapAuthComponent extends AuthComponent
15 16 $login = $this->request->getData('ldap');
16 17 $password = $this->request->getData('password');
17 18 // return user or FALSE
18   - // calls src/Model/Table/LdapConnectionsTable.php/ldapAuthentication()
  19 + // calls /Model/Table/LdapConnectionsTable.php/ldapAuthentication()
19 20 return TableRegistry::getTableLocator()->get('LdapConnections')->ldapAuthentication($login, $password);
20 21 //return TableRegistry::get('LdapConnections')->ldapAuthentication($login, $password);
21 22 } catch (Exception $e) {
... ...
src/Controller/PagesController.php
... ... @@ -68,7 +68,7 @@ class PagesController extends AppController
68 68 */
69 69 public function initialize()
70 70 {
71   - $this->myDebug("step 0A (specific): PagesController.initialize()");
  71 + ####$this->myDebug("step 0A (specific): PagesController.initialize()");
72 72 parent::initialize();
73 73 $this->modelClass = false;
74 74 // On autorise l'action add SANS authentification (unauthenticated)
... ... @@ -78,7 +78,7 @@ class PagesController extends AppController
78 78  
79 79 // (20200424 EP)
80 80 public function beforeFilter(\Cake\Event\Event $event) {
81   - $this->myDebug("step 1A (specific): PagesController.beforeFilter()");
  81 + ####$this->myDebug("step 1A (specific): PagesController.beforeFilter()");
82 82 // On donne d'abord les autorisations par défaut de AppController
83 83 parent::beforeFilter($event);
84 84  
... ...
src/Controller/UsersController.php
... ... @@ -178,7 +178,7 @@ class UsersController extends AppController {
178 178 // ref: https://book.cakephp.org/4/fr/controllers/components/authentication.html#identifier-les-utilisateurs-et-les-connecter
179 179 public function login()
180 180 {
181   - $this->myDebug("step 2: UsersController.login()");
  181 + ####$this->myDebug("step 2: UsersController.login()");
182 182  
183 183 // Un utilisateur a essayé de se loguer
184 184 if ($this->request->is('post')) {
... ... @@ -186,6 +186,7 @@ class UsersController extends AppController {
186 186 // - sans LDAP
187 187 //$user = $this->Auth->identify();
188 188 // - avec LDAP (ou fake ldap)
  189 + // (calls /Controller/Component/LdapAuthComponent.php/connection())
189 190 $user = $this->LdapAuth->connection();
190 191 //var_dump($user);
191 192 //debug($user);
... ...
src/Model/Table/LdapConnectionsTable.php
... ... @@ -215,7 +215,7 @@ class LdapConnectionsTable extends AppTable
215 215 ],
216 216 */
217 217 DEFAULT_AUTH_TYPE => [
218   - $user[DEFAULT_AUTH_TYPE]
  218 + $user[DEFAULT_AUTH_TYPE]
219 219 ],
220 220 // Pass
221 221 'userpassword' => [
... ... @@ -229,6 +229,7 @@ class LdapConnectionsTable extends AppTable
229 229 return $this->_buildFakeLdapUsersFromDB();
230 230 }
231 231  
  232 + // return users list from DB table fakeldapusers, formatted as LDAP
232 233 private function _buildFakeLdapUsersFromDB()
233 234 {
234 235 //NEW
... ... @@ -369,7 +370,8 @@ class LdapConnectionsTable extends AppTable
369 370 ->find()
370 371 ->where(['id =' => 1])
371 372 ->first();
372   - // Activation forcée de l'option ldap_cached si LDAP_CACHE_ALWAYS_ON
  373 +
  374 + // Activation forcée de l'option ldap_cached si LDAP_CACHE_ALWAYS_ON
373 375 // (EP) Ca résoud un bug dû au fait que des infos sont cherchées dans la table users alors que le user n'y est pas...
374 376 if (LDAP_CACHE_ALWAYS_ON) $this->CONF->ldap_cached = true;
375 377 $config = $this->CONF;
... ... @@ -483,10 +485,8 @@ class LdapConnectionsTable extends AppTable
483 485 public function getFakeLdapUser($login)
484 486 {
485 487 foreach ($this->fakeLDAPUsers as $user) {
486   - /*
487   - debug($login);
488   - debug($user);
489   - */
  488 + //debug($login);
  489 + //debug($user[DEFAULT_AUTH_TYPE][0]);
490 490 //if ($login == $user[$this->authenticationType][0])
491 491 if ($login == $user[DEFAULT_AUTH_TYPE][0])
492 492 return $user;
... ... @@ -628,15 +628,16 @@ class LdapConnectionsTable extends AppTable
628 628 }
629 629  
630 630  
631   - // @return user from DB whith login = $userLogin (or NULL)
632   - private function _getUserFromDB($userLogin) {
  631 + // @return user from DB user table whith login = $userLogin (or NULL)
  632 + //private function _getUserFromDBByLogin) {
  633 + private function _getCachedUserByLogin($userLogin) {
633 634 //debug($userLogin); exit;
634 635 //$ldapUser = TableRegistry::getTableLocator()->get('Users')->find()
635 636 return $this->usersTable->find()
636   - ->where([
637   - 'username' => $userLogin
638   - ])
639   - ->first();
  637 + ->where([
  638 + 'username' => $userLogin
  639 + ])
  640 + ->first();
640 641 }
641 642  
642 643 /**
... ... @@ -653,12 +654,12 @@ class LdapConnectionsTable extends AppTable
653 654 * - a period (.) signifies ISO Y.M.D. => strtotime("11.12.10")
654 655 */
655 656 $date_now = date("Y-m-d H:i:s");
656   - $this->mydebugmsg("now :".$date_now);
  657 + ####$this->mydebugmsg("now :".$date_now);
657 658 $date_now = new \DateTime($date_now);
658 659  
659 660 $date_cached = $this->CONF->ldap_cache_last_update;
660 661 // Pourquoi j'ai pas les secondes qui s'affichent ???!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
661   - $this->mydebugmsg("cached :".$date_cached);
  662 + ####$this->mydebugmsg("cached :".$date_cached);
662 663 /* bugfixing $date_cached pour Inventirap (IRAP) (php5 ou vieux mysql ou pb de config ???) :
663 664 * Inventirap affiche l'année sur 2 chiffres : 'cached :05/06/19 15:36'
664 665 * Ma version perso affiche l'année sur 4 chiffres : 'cached :05/06/2019 15:36'
... ... @@ -672,16 +673,15 @@ class LdapConnectionsTable extends AppTable
672 673 //$year = '20'.substr($y,1,2); // '2019'
673 674 $date_cached = substr($date_cached,0,6)."20".substr($year,1,2).substr($date_cached,8); // '05/06/19 15:36';
674 675 }
675   - $this->mydebugmsg("cached2 :".$date_cached);
  676 + ####$this->mydebugmsg("cached2 :".$date_cached);
676 677 $date_cached = \DateTime::createFromFormat('d/m/Y H:i',$date_cached);
677 678 //debug("now :".$date_now->format('Y-m-d H:i:s') );
678 679 //debug("cached :".$date_cached->format('Y-m-d H:i:s') );
679   - $this->mydebugmsg("Temps écoulé depuis last save:");
680   - $this->mydebugmsg($date_now->diff($date_cached)->format('%i mn %s sec'));
  680 + ####$this->mydebugmsg("Temps écoulé depuis last save:"); $this->mydebugmsg($date_now->diff($date_cached)->format('%i mn %s sec'));
681 681  
682 682  
683 683 $date_cached->add(new \DateInterval('PT'.$this->CONF->ldap_cache_validity_duration.'M'));
684   - $this->mydebugmsg("date_cached (added) :".$date_cached->format('Y-m-d H:i:s') );
  684 + ####$this->mydebugmsg("date_cached (added) :".$date_cached->format('Y-m-d H:i:s') );
685 685  
686 686 /*
687 687 $date_now = $date_now->getTimestamp();
... ... @@ -722,8 +722,7 @@ class LdapConnectionsTable extends AppTable
722 722 debug($d == $now);
723 723 */
724 724  
725   - $this->mydebugmsg("expired ?");
726   - $this->mydebugmsg($date_cached < $date_now);
  725 + ####$this->mydebugmsg("expired ?"); $this->mydebugmsg($date_cached < $date_now);
727 726 return ($date_cached < $date_now);
728 727 //return TRUE;
729 728 }
... ... @@ -738,48 +737,124 @@ class LdapConnectionsTable extends AppTable
738 737 }
739 738  
740 739  
741   - private function _isUserAlreadyCached(array $user_logged) {
  740 + private function _isUserAlreadyCachedForLogin(array $user_login) {
742 741 //debug($user_logged);
743   - return $this->_getUserFromDB($user_logged[$this->authenticationType][0]) !== null;
  742 + //$user_login = $this->_getUserLogin($user_logged);
  743 + return $this->_getCachedUserByLogin($user_login) !== null;
744 744 }
745   -
  745 +
  746 + private function _getUserLogin(array $user) {
  747 + return $user[$this->authenticationType][0];
  748 + }
  749 +
  750 + // Return true if logged user $user_logged is exactly same user as cached user $user_cached
  751 + private function _isExactSameUser($userFromLDAP,$user_cached) {
  752 + $BOURRIN=false;
  753 + //$this->mydebugmsg("user already exists => update it");
  754 +
  755 + // Same email ?
  756 + if (
  757 + isset($userFromLDAP['mail'])
  758 + &&
  759 + ( $BOURRIN || ($user_cached->email != $userFromLDAP['mail'][0]) )
  760 + ) return false;
  761 +
  762 + // Same name AND firstname ?
  763 + if (
  764 + ( isset($userFromLDAP['sn']) && isset($userFromLDAP['givenname']) )
  765 + &&
  766 + strtolower($user_cached->nom) != strtolower( $userFromLDAP['sn'][0].' '.$userFromLDAP['givenname'][0] )
  767 + ) return false;
  768 +
  769 + // SAME user
  770 + return true;
  771 + }
  772 +
  773 + private function _addNewUserInCacheFromLdapUser($userFromLDAP) {
  774 + $this->usersTable->save($this->_getLDAPuserFormattedAsDB($userFromLDAP));
  775 + ####$this->mydebugmsg("added new user"); $this->mydebugmsg($userFromLDAP);
  776 + }
  777 +
  778 + private function _updateChangedUserInCacheFromLdapUser($userFromLDAP, $user_cached) {
  779 + $user_cached->email = $userFromLDAP['mail'][0];
  780 + // Tant qu'on y est, on met aussi à jour le nom et prenom
  781 + $user_cached->nom = $userFromLDAP['sn'][0].' '.$userFromLDAP['givenname'][0];
  782 + $this->usersTable->save($user_cached);
  783 + ####$this->mydebugmsg("updated changed user"); $this->mydebugmsg($userFromLDAP);
  784 + }
  785 +
746 786 /*
747   - * UPDATE users CACHE (save all (fake)LDAP users into "users" db table)
  787 + * UPDATE users CACHE
  788 + * (save all (fake)LDAP users into "users" db table)
748 789 * ONLY if necessary
749 790 */
750 791 //private function _updateLdapCacheIfNeeded() {
751 792 private function _updateUsersCacheIfNeeded(array $user_logged = null) {
752 793  
  794 + /* $user_logged looks like this (from fakeLDAP) :
  795 + [
  796 + 'sn' => [
  797 + (int) 0 => 'SuperAdmin'
  798 + ],
  799 + 'mail' => [
  800 + (int) 0 => 'superadmin@emailnew.com'
  801 + ],
  802 + 'givenname' => [
  803 + (int) 0 => 'Stephane'
  804 + ],
  805 + 'uid' => [
  806 + (int) 0 => 'superadminnew'
  807 + ],
  808 + 'userpassword' => [
  809 + (int) 0 => '$2y$10$LZzpws3oDidBcqO/Fy1RTedLLk3ENTmplny5J7bZ6R1PqFoGOw3Ma'
  810 + ]
  811 + ]
  812 + */
  813 +
753 814 // Si cache pas activé => return
754 815 //debug("C1");
755 816 //if (!LDAP_CACHE_ALWAYS_ON && !$this->CONF->ldap_cached) return;
  817 + /*
  818 + TODO:
  819 + EP 22/12/2022
  820 + DEAC
  821 + Je désactive cette ligne car on est bien OBLIGÉ d'utiliser un cache
  822 + Puisqu'on va toujours chercher la liste des users dans la table users
  823 + ET que c'est dans cette table qu'on trouve leurs rolez !!!
  824 +
756 825 if (! $this->CONF->ldap_cached) return;
  826 + */
  827 +
  828 + #
  829 + # 1) ADD or UPDATE user $user_logged (if not null), only if NEW or CHANGED
  830 + #
  831 +
  832 + if ($user_logged) {
  833 + //$user_cached = $this->_getUserCachedForUserLogged($user_logged);
  834 + $user_cached = $this->_getCachedUserByLogin($this->_getUserLogin($user_logged));
  835 + // NEW user ?
  836 + if (is_null($user_cached))
  837 + $this->_addNewUserInCacheFromLdapUser($user_logged);
  838 + // Existing user but CHANGED ?
  839 + elseif ( ! $this->_isExactSameUser($user_logged,$user_cached) )
  840 + $this->_updateChangedUserInCacheFromLdapUser($user_logged, $user_cached);
  841 + // UPDATE THIS user in CACHE (users table)
  842 + }
757 843  
758   - /*
759   - * On ne met à jour le cache des users QUE si :
760   - * - le user qui vient de se loguer n'est pas dans le cache
761   - * OU
762   - * - le cache est périmé
763   - *
764   - * Sinon => RETURN
765   - */
766   - //debug("C2");
767   - if (
768   - ! $this->_ldapCacheIsExpired()
769   - &&
770   - ! ( $user_logged && !$this->_isUserAlreadyCached($user_logged) )
771   - )
772   - return;
773   - DEBUG && debug("User pas dans DB users");
  844 + #
  845 + # 2) Update all users, only if CACHE expired
  846 + #
  847 + if (! $this->_ldapCacheIsExpired()) return;
  848 +
  849 + #DEBUG && debug("NEW User (pas dans DB users table)");
774 850  
775   - //debug("C3");
776 851 // Get all users from (fake)LDAP
777 852 $usersFromLDAP = $this->_getAllUsersFromLDAP();
778 853 // LDAP should return at least some users, otherwise ERROR
779 854 assert(!empty($usersFromLDAP));
780 855  
781 856 // Get all users from DB
782   - $usersFromDB = $this->_getAllUsersFromDB(FALSE);
  857 + $users_cached = $this->_getAllUsersFromDB(FALSE);
783 858  
784 859 // Add new(fake)ldap users (only) and update existing users
785 860 foreach ($usersFromLDAP as $userFromLDAP) {
... ... @@ -801,7 +876,9 @@ class LdapConnectionsTable extends AppTable
801 876 continue;
802 877 }
803 878  
804   - $userFromLDAPLogin = $userFromLDAP[$this->authenticationType][0];
  879 + //$userFromLDAPLogin = $userFromLDAP[$this->authenticationType][0];
  880 + $userFromLDAPLogin = $this->_getUserLogin($userFromLDAP);
  881 +
805 882 // (EP 5/6/19 : on n'a pas accès au password stocké dans le ldap, on ne peut donc pas le stocker dans le cache)
806 883 //$currentLdapUserPwd = $userFromLDAP['userpassword'][0];
807 884  
... ... @@ -809,83 +886,25 @@ class LdapConnectionsTable extends AppTable
809 886 // Do not save fake ldap user in DB
810 887 if ($userFromLDAPLogin == '_fake_ldap_user_') continue;
811 888  
812   - $userFromDB = $this->_getUserFromDB($userFromLDAPLogin);
813   -
814   - // 1) ADD NEW user
815   - if (is_null($userFromDB)) {
816   -
817   - //$this->mydebugmsg("user does not exist => add it to DB");
818   - // Ajout du nouvel utilisateur
819   - $this->usersTable->save($this->_getLDAPuserFormattedAsDB($userFromLDAP));
820   - //$this->usersTable->query("FLUSH TABLES");
821   -
822   - // Correction de son mot de passe
823   - /* (EP 5/6/19 : on n'a pas accès au password stocké dans le ldap, on ne peut donc pas le stocker dans le cache)
824   - $userFromDB = $this->_getUserFromDB($currentLdapUserLogin);
825   - assert(!is_null($userFromDB));
826   - //$this->mydebugmsg("UPDATE users SET password = '".$currentLdapUserPwd."' WHERE id = ".$userFromDB->id);
827   - //$this->usersTable->query("UPDATE users SET password = '".$userFromLDAP['userpassword'][0]."' WHERE id = ".$userFromDB->id);
828   - $this->_updateUserPassword($userFromDB->id, $currentLdapUserPwd);
829   - */
830   - /*
831   - $query = $this->usersTable->query();
832   - $query->update()
833   - ->set([ 'password' => $userFromLDAP['userpassword'][0] ])
834   - ->where(['id' => $userFromDB->id])
835   - ->execute();
836   - */
837   - //exit;
838   - } // NEW user
839   -
840   - // 2) UPDATE Existing user => only if email changed
841   - else {
842   - //TODO: a virer, only for test
843   - $BOURRIN=false;
844   - //$this->mydebugmsg("user already exists => update it");
845   -
846   - // 1) Update email (only if changed)
847   - if (
848   - isset($userFromLDAP['mail'])
849   - &&
850   - ( $BOURRIN || ($userFromDB->email != $userFromLDAP['mail'][0]) )
851   - ) {
852   - //$this->mydebugmsg("email diff ? ");
853   - //$this->mydebugmsg($userFromDB->email !== $userFromLDAP['mail'][0]);
854   - $userFromDB->email = $userFromLDAP['mail'][0];
855   - // Tant qu'on y est, on met aussi à jour le nom et prenom
856   - $userFromDB->nom = $userFromLDAP['sn'][0].' '.$userFromLDAP['givenname'][0];
857   - $this->usersTable->save($userFromDB);
858   - }
859   -
860   - // 2) Update password (only if changed)
861   - /* (EP 5/6/19 : on n'a pas accès au password stocké dans le ldap, on ne peut donc pas le stocker dans le cache)
862   - //debug("password = ".$userFromDB->password);
863   - //debug("userpassword = ".$userFromLDAP['userpassword'][0]);
864   - /STAR (EP 28/5/19) Sauvegarde du mot de passe : ATTENTION !
865   - * Si on utilise la methode save() de cakephp, le mot de passe n'est pas copié tel quel, mais re-crypté !!!
866   - * On doit donc le copier "à la hard" avec du code sql direct pour shunter la methode save()
867   - * Ceci n'est donc pas possible :
868   - $userFromDB->password = $userFromLDAP['userpassword'][0];
869   - $this->usersTable->save($userFromDB);
870   - STAR/
871   - // Par contre, ceci fonctionne :
872   - //debug("UPDATE users SET password = '".$userFromLDAP['userpassword'][0]."' WHERE id = ".$userFromDB->id);
873   - if ( $BOURRIN || ($userFromDB->password != $currentLdapUserPwd) ) {
874   - //$this->mydebugmsg("pass diff ? ");
875   - //$this->mydebugmsg($userFromDB->password !== $userFromLDAP['userpassword'][0]);
876   - //$this->usersTable->query("UPDATE users SET password = '".$userFromLDAP['userpassword'][0]."' WHERE id = ".$userFromDB->id);
877   - $this->_updateUserPassword($userFromDB->id, $currentLdapUserPwd);
878   - }
879   - */
880   - } // existing user => update
  889 + $user_cached = $this->_getCachedUserByLogin($userFromLDAPLogin);
  890 +
  891 + // (1) NEW user ? => ADD
  892 + if (is_null($user_cached))
  893 + $this->_addNewUserInCacheFromLdapUser($userFromLDAP);
  894 +
  895 + // (2) Existing user but CHANGED ? => UPDATE
  896 + elseif ( ! $this->_isExactSameUser($userFromLDAP,$user_cached) )
  897 + $this->_updateChangedUserInCacheFromLdapUser($userFromLDAP, $user_cached);
  898 +
881 899 }
882 900  
883   - // 3) DELETE old users (which are no more in LDAP)
  901 + // (3) DELETE old users (which are no more in LDAP)
884 902 // dangereux, et faire attention de ne pas supprimer le user superadmin ldap créé au début du projet...
885   - $DO_DELETE = false;
  903 + //$DO_DELETE = false;
  904 + $DO_DELETE = true;
886 905 // - Select only the login (['uid']) column
887 906 $usersFromLDAPLogins = array_column($usersFromLDAP, $this->authenticationType);
888   - $this->mydebugmsg($usersFromLDAPLogins);
  907 + ####$this->mydebugmsg($usersFromLDAPLogins);
889 908 /*
890 909 * Avec LDAP IRAP, on obtient pour $usersFromLDAPLogins, 0 à 439 (440 users) :
891 910 [
... ... @@ -910,7 +929,7 @@ class LdapConnectionsTable extends AppTable
910 929 */
911 930 // - Select only the [0] column
912 931 $usersFromLDAPLogins = array_column($usersFromLDAPLogins, 0);
913   - $this->mydebugmsg($usersFromLDAPLogins);
  932 + ####$this->mydebugmsg($usersFromLDAPLogins);
914 933 /*
915 934 * Avec LDAP IRAP, on obtient pour $usersFromLDAPLogins, 0 à 439 (440 users) :
916 935 [
... ... @@ -925,7 +944,7 @@ class LdapConnectionsTable extends AppTable
925 944 ...
926 945 ]
927 946 */
928   - foreach ($usersFromDB as $userFromDB) {
  947 + foreach ($users_cached as $user_cached) {
929 948 /*
930 949 debug("DELETE");
931 950 debug("look for $userFromDB->username");
... ... @@ -933,11 +952,11 @@ class LdapConnectionsTable extends AppTable
933 952 */
934 953 //debug($usersFromLDAP);
935 954 //$usersFromLDAPLogins = array_column($usersFromLDAP, 'uid');
936   - if (! in_array($userFromDB->username, $usersFromLDAPLogins)) {
  955 + if (! in_array($user_cached->username, $usersFromLDAPLogins)) {
937 956 // (6/6/19) 3 users found (superadmin, imoro, mimelhaine)
938   - $this->mydebugmsg("OLD user should be deleted:");
939   - $this->mydebugmsg($userFromDB->username);
940   - $DO_DELETE && $userFromDB->delete();
  957 + ####$this->mydebugmsg("OLD user should be deleted:"); $this->mydebugmsg($user_cached->username);
  958 + #$this->mydebugmsg($user_cached);
  959 + $DO_DELETE && $this->usersTable->delete($user_cached);
941 960 }
942 961 }
943 962  
... ... @@ -967,7 +986,7 @@ class LdapConnectionsTable extends AppTable
967 986 $this->_updateUsersCacheIfNeeded();
968 987  
969 988 // 1) Search user in DB
970   - $ldapUser = $this->_getUserFromDB($user_login);
  989 + $ldapUser = $this->_getUserFromDBByCachedLogir_login);
971 990 /S
972 991 $ldapUser = TableRegistry::getTableLocator()->get('Users')->find()
973 992 ->where([
... ... @@ -1069,81 +1088,60 @@ class LdapConnectionsTable extends AppTable
1069 1088 return FALSE;
1070 1089 }
1071 1090  
1072   -
1073   - // MAIN ENTRY POINT of this class
1074   - /*
1075   - * @param string $user_login
1076   - * @param string $user_password
1077   - * @return logged user LDAP attributes (FALSE if user not found in LDAP)
1078   - */
1079   - public function ldapAuthentication($user_login, $user_password) {
1080 1091  
1081   - // Bad configuration => FAIL
1082   - if (! $this->_checkAndGetConfiguration()) return FALSE;
1083   -
1084   - // Par défaut, on retourne FALSE (échec de connexion)
  1092 +
  1093 +
  1094 +
  1095 +
  1096 + private function _ldapAuthenticationREAL($user_login, $user_password) {
  1097 + // No connexion allowed without password
  1098 + if (strlen(trim($user_password)) == 0) return FALSE;
  1099 +
  1100 + /*
  1101 + // TODO: optimisation possible
  1102 + // 1) Search user in CACHE (DB)
  1103 + $user_fetched = $this->checkAndFetchLDAPUserFromDB($user_login, $user_password);
  1104 + $this->mydebugmsg("(1) user found in DB is:");
  1105 + $this->mydebugmsg($user_fetched);
  1106 + //TODO: A VIRER !!!
1085 1107 //$user_fetched = FALSE;
1086   -
1087   - // (EP 5/6/19 : on n'a pas accès au password stocké dans le ldap, on ne peut donc pas le stocker dans le cache)
1088   -
1089   - // 1 - REAL LDAP
1090   - //debug($this->LDAP_USED); exit;
1091   - if ($this->LDAP_USED) try {
1092   - // No connexion allowed without password
1093   - if (strlen(trim($user_password)) == 0) return FALSE;
1094   -
1095   - /*
1096   - // TODO: optimisation possible
1097   - // 1) Search user in CACHE (DB)
1098   - $user_fetched = $this->checkAndFetchLDAPUserFromDB($user_login, $user_password);
1099   - $this->mydebugmsg("(1) user found in DB is:");
1100   - $this->mydebugmsg($user_fetched);
1101   - //TODO: A VIRER !!!
1102   - //$user_fetched = FALSE;
1103   - // 2) If not CACHED, search user in LDAP
1104   - if ($user_fetched === FALSE) {
1105   - */
1106   - //$user_fetched = $this->checkAndFetchUserFromLdap($user_login, $user_password);
1107   - $just_these = [];
1108   - // TODO: vérifier si cette ligne est bien utile ou pas... (avant on faisait ça)
1109   - //if (! $this->ldap_authentified) $just_these = array("cn");
1110   - // Construction du filtre avec le filtre de la base de données avec un & sur le login de l'utilisateur
1111   - // Si aucun filtre n'est défini dans la base de données on aura juste (& ($this->authenticationType=$user_login))
1112   - // 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))";
1113   - $filter = '(&'.$this->filter.'('.$this->authenticationType.'='.$user_login.'))';
1114   - //TODO: optimisation, refactoriser si comportement général
1115   - //$binddn .= ','.$this->baseDn;
1116   - //$user_fetched = $this->_ldapSearch($filter, $just_these, $user_login, $user_password);
1117   - $user_fetched = $this->_ldapSearch($filter, $just_these);
1118   - //$this->mydebugmsg("(1) user found in LDAP is:");
1119   - //$this->mydebugmsg($user_fetched);
1120   - //$this->mydebugmsg($user_fetched[0]);
1121   - if ($user_fetched['count'] != 0) {
1122   - $user_fetched = $user_fetched[0];
1123   - if ($this->_ldapAuth($user_fetched["dn"], $user_password)) {
1124   - // CACHE the new user in DB for next time
1125   - ///$this->_saveNewUserInDB($user_fetched[0]);
1126   - // CACHE ALL ldap users
1127   - $this->_updateUsersCacheIfNeeded($user_fetched);
1128   - // return logged user (authentified)
1129   - return $user_fetched;
1130   - }
1131   - //return null;
1132   - //return FALSE;
  1108 + // 2) If not CACHED, search user in LDAP
  1109 + if ($user_fetched === FALSE) {
  1110 + */
  1111 + //$user_fetched = $this->checkAndFetchUserFromLdap($user_login, $user_password);
  1112 + $just_these = [];
  1113 + // TODO: vérifier si cette ligne est bien utile ou pas... (avant on faisait ça)
  1114 + //if (! $this->ldap_authentified) $just_these = array("cn");
  1115 + // Construction du filtre avec le filtre de la base de données avec un & sur le login de l'utilisateur
  1116 + // Si aucun filtre n'est défini dans la base de données on aura juste (& ($this->authenticationType=$user_login))
  1117 + // 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))";
  1118 + $filter = '(&'.$this->filter.'('.$this->authenticationType.'='.$user_login.'))';
  1119 + //TODO: optimisation, refactoriser si comportement général
  1120 + //$binddn .= ','.$this->baseDn;
  1121 + //$user_fetched = $this->_ldapSearch($filter, $just_these, $user_login, $user_password);
  1122 + $user_fetched = $this->_ldapSearch($filter, $just_these);
  1123 + //$this->mydebugmsg("(1) user found in LDAP is:");
  1124 + //$this->mydebugmsg($user_fetched);
  1125 + //$this->mydebugmsg($user_fetched[0]);
  1126 + if ($user_fetched['count'] != 0) {
  1127 + $user_fetched = $user_fetched[0];
  1128 + if ($this->_ldapAuth($user_fetched["dn"], $user_password)) {
  1129 + // CACHE the new user in DB for next time
  1130 + ///$this->_saveNewUserInDB($user_fetched[0]);
  1131 + // CACHE ALL ldap users
  1132 + ####$this->_updateUsersCacheIfNeeded($user_fetched);
  1133 + // return logged user (authentified)
  1134 + return $user_fetched;
1133 1135 }
1134   - return FALSE;
1135   - //return $user_fetched; // Noter que $user_fetched peut etre egal a FALSE (si pas trouvé)
1136   -
1137   - } catch (Exception $e) {
1138   - //echo 'Exception LDAP : ', $e->getMessage(), "\n";
1139   - debug('Exception LDAP : ');
1140   - debug($e->getMessage());
1141   - exit;
1142   - } // REAL LDAP
1143   -
1144   - // OU BIEN
1145   -
1146   - // 2 - FAKE LDAP used
  1136 + //return null;
  1137 + //return FALSE;
  1138 + }
  1139 + return FALSE;
  1140 + //return $user_fetched; // Noter que $user_fetched peut etre egal a FALSE (si pas trouvé)
  1141 + }
  1142 +
  1143 +
  1144 + private function _ldapAuthenticationFAKE($user_login, $user_password) {
1147 1145 //debug($this->baseDn);
1148 1146 $user_fetched = $this->getFakeLdapUser($user_login);
1149 1147 /*
... ... @@ -1153,8 +1151,7 @@ class LdapConnectionsTable extends AppTable
1153 1151 debug($user_fetched);
1154 1152 exit;
1155 1153 */
1156   - $this->mydebugmsg("(1) user found in FAKE LDAP is:");
1157   - $this->mydebugmsg($user_fetched);
  1154 + ####$this->mydebugmsg("(1) user found in FAKE LDAP is:"); $this->mydebugmsg($user_fetched);
1158 1155 /* Voici un exemple de ce qui est dans $user_fetched (fake ldap) :
1159 1156 [
1160 1157 'sn' => [
... ... @@ -1177,13 +1174,39 @@ class LdapConnectionsTable extends AppTable
1177 1174 // debug($user);
1178 1175 //if ($user === false) return FALSE;
1179 1176 if ($user_fetched !== false) {
  1177 +
  1178 + /* $user_fetched looks like this (from fakeLDAP) :
  1179 + [
  1180 + 'sn' => [
  1181 + (int) 0 => 'SuperAdmin'
  1182 + ],
  1183 + 'mail' => [
  1184 + (int) 0 => 'superadmin@emailnew.com'
  1185 + ],
  1186 + 'givenname' => [
  1187 + (int) 0 => 'Stephane'
  1188 + ],
  1189 + 'uid' => [
  1190 + (int) 0 => 'superadminnew'
  1191 + ],
  1192 + 'userpassword' => [
  1193 + (int) 0 => '$2y$10$LZzpws3oDidBcqO/Fy1RTedLLk3ENTmplny5J7bZ6R1PqFoGOw3Ma'
  1194 + ]
  1195 + ]
  1196 + */
  1197 +
1180 1198 // $this->authenticationType peut valoir "uid" ou "cn"... (par défaut "uid" pour le fake ldap, à confirmer...)
1181 1199 // if ($user['uid'][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user;
1182 1200 // if ($user[$this->authenticationType][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user;
1183   - // Est-ce le user FAKE LDAP par defaut (_fake_ldap_user_) ? si oui, on le laisse passer
  1201 +
  1202 + /* EP 23/12/22 On n'utilise plus ça
  1203 + *
  1204 + // Est-ce le user FAKE LDAP par defaut (_fake_ldap_user_) ? si oui, on le laisse passer
1184 1205 //if ($user_fetched[$this->authenticationType][0] == $this->_getTheFakeLdapUser()['login'] && $user_fetched['userpassword'][0] == $this->_getTheFakeLdapUser()['pass'])
1185 1206 if ($user_fetched[DEFAULT_AUTH_TYPE][0] == $this->_getTheFakeLdapUser()['login'] && $user_fetched['userpassword'][0] == $this->_getTheFakeLdapUser()['pass'])
1186 1207 return $user_fetched;
  1208 + */
  1209 +
1187 1210 /*
1188 1211 debug("user_password = ".$user_password);
1189 1212 debug("user found in db is ");
... ... @@ -1192,9 +1215,10 @@ class LdapConnectionsTable extends AppTable
1192 1215 debug($user_fetched['userpassword'][0]);
1193 1216 exit;
1194 1217 */
1195   - // Sinon, on regarde si c'est un user de la table fakeldapusers
  1218 +
  1219 + // Sinon, on regarde si c'est un user de la table fakeldapusers
1196 1220 if ( (new DefaultPasswordHasher())->check($user_password,$user_fetched['userpassword'][0]) ) {
1197   - $this->_updateUsersCacheIfNeeded($user_fetched);
  1221 + ####$this->_updateUsersCacheIfNeeded($user_fetched);
1198 1222 return $user_fetched;
1199 1223 }
1200 1224 }
... ... @@ -1206,19 +1230,54 @@ class LdapConnectionsTable extends AppTable
1206 1230 // On met à jour le cache des users (si nécessaire)
1207 1231 //if ($user_fetched !== FALSE) $this->_updateUsersCacheIfNeeded($user_fetched);
1208 1232 // Retourne le user authentifié ou bien FALSE
1209   - //return $user_fetched;
1210   -
1211   - } // ldapAuthentication()
1212   -
1213   -
  1233 + //return $user_fetched;
  1234 + }
1214 1235  
1215   -
1216   -
1217   -
1218   -} // fin de class LdapConnectionsTable
  1236 +
  1237 + // MAIN ENTRY POINT of this class
  1238 + /*
  1239 + * @param string $user_login
  1240 + * @param string $user_password
  1241 + * @return logged user LDAP attributes (FALSE if user not found in LDAP)
  1242 + */
  1243 + public function ldapAuthentication($user_login, $user_password) {
1219 1244  
  1245 + // Bad configuration => FAIL
  1246 + if (! $this->_checkAndGetConfiguration()) return FALSE;
  1247 +
  1248 + // Par défaut, on retourne FALSE (échec de connexion)
  1249 + //$user_fetched = FALSE;
  1250 +
  1251 + // (EP 5/6/19 : on n'a pas accès au password stocké dans le ldap, on ne peut donc pas le stocker dans le cache)
  1252 +
  1253 + #
  1254 + # 1 - REAL LDAP
  1255 + #
  1256 + if ($this->LDAP_USED)
  1257 + try {
  1258 + $user_fetched = $this->_ldapAuthenticationREAL($user_login, $user_password);
  1259 + }
  1260 + catch (Exception $e) {
  1261 + //echo 'Exception LDAP : ', $e->getMessage(), "\n";
  1262 + debug('Exception LDAP : ');
  1263 + debug($e->getMessage());
  1264 + exit;
  1265 + } // REAL LDAP
  1266 +
  1267 + #
  1268 + # 2 - FAKE LDAP used
  1269 + #
  1270 + else
  1271 + $user_fetched = $this->_ldapAuthenticationFAKE($user_login, $user_password);
1220 1272  
  1273 + if ($user_fetched !== FALSE)
  1274 + // Update Users cache if needed (especially for the logged user)
  1275 + $this->_updateUsersCacheIfNeeded($user_fetched);
  1276 +
  1277 + return $user_fetched;
1221 1278  
  1279 + } // ldapAuthentication()
  1280 +
1222 1281 /* Voici un exemple de ce qui est dans $user_fetched[0] (structure LDAP IRAP) :
1223 1282  
1224 1283 // ce qui est retourné par le fake ldap (imitation bien faite non ?)
... ... @@ -1440,6 +1499,7 @@ class LdapConnectionsTable extends AppTable
1440 1499 ]
1441 1500 */
1442 1501  
1443   -
  1502 +
  1503 +} // fin de class LdapConnectionsTable
1444 1504  
1445 1505 ?>
... ...
src/Template/Configurations/view.ctp
... ... @@ -181,7 +181,7 @@ function $this-&gt;MyHelper-&gt;echoSectionStop() {
181 181 ********
182 182 */
183 183  
184   - $this->MyHelper->echoSectionStart("Optmisation");
  184 + $this->MyHelper->echoSectionStart("Optimisation");
185 185 /* LDAP optimisation */
186 186 if (is_null($configurationObj->ldap_cache_last_update)) $ldap_cache_elapsed_time = '';
187 187 else {
... ... @@ -206,7 +206,7 @@ function $this-&gt;MyHelper-&gt;echoSectionStop() {
206 206 }
207 207 $this->MyHelper->displayElement(__('Optimisation liste utilisateurs (utilisation Cache en BD)'), h($configurationObj->ldap_cached)?"Oui":"Non" );
208 208 $this->MyHelper->displayElement(__('Durée validité cache (mn)'), h($configurationObj->ldap_cache_validity_duration));
209   - $this->MyHelper->displayElement(__('Date dernière mise à jour cache'), h($configurationObj->ldap_cache_last_update));
  209 + $this->MyHelper->displayElement(__('Date dernière mise à jour cache (UTC)'), h($configurationObj->ldap_cache_last_update));
210 210 $this->MyHelper->displayElement(__('Temps écoulé depuis dernière mise à jour'), $ldap_cache_elapsed_time);
211 211 $this->MyHelper->echoSectionStop();
212 212  
... ...