Commit bc14f1eb68f05746985ee77a5f2ed4a5c1fdf2b0

Authored by Etienne Pallier
1 parent 6381eddc
Exists in master and in 2 other branches dev, dev-IRAP

LDAP CACHED v3

README.md
... ... @@ -53,11 +53,11 @@ Logiciel testé et validé sur les configurations suivantes :
53 53  
54 54 VERSION ACTUELLE
55 55  
56   -Date: 24/05/2019
57   -Version: 2.12.24
  56 +Date: 03/06/2019
  57 +Version: 2.12.25
58 58 Author: EP
59 59 Commentaire:
60   - LDAP CACHED (optimisé) v1
  60 + LDAP CACHED v3
61 61  
62 62 IMPORTANT :
63 63 - Pour connaitre la version actuelle, taper "./VERSION"
... ...
TESTS.sh
1 1 # Souvent necessaire pour que les tests se passent bien:
  2 +#rm -rf tmp/cache/*/*
2 3 sudo chmod o+w tmp/cache/persistent/myapp_cake_core_translations_*
3 4  
  5 +
4 6 vendor/bin/phpunit || vendor/phpunit/phpunit/phpunit
5 7  
6 8 # Si ca ne marche pas, essayer plutot:
... ...
config/bootstrap.php
... ... @@ -103,7 +103,8 @@ if (!Configure::read('debug')) {
103 103 * Set server timezone to UTC. You can change it to another timezone of your
104 104 * choice but using UTC makes time calculations / conversions easier.
105 105 */
106   -date_default_timezone_set('UTC');
  106 +//date_default_timezone_set('UTC');
  107 +date_default_timezone_set('Europe/Paris');
107 108  
108 109 /**
109 110 * Configure the mbstring extension to use the correct encoding.
... ...
database/update/db-update-2019-06-03.sh 0 → 100755
... ... @@ -0,0 +1,57 @@
  1 +#!/bin/bash
  2 +
  3 +#myname=`basename $0 .sh`
  4 +myname=`basename $0`
  5 +myname=${myname%%.*}
  6 +
  7 +# Pour Mac OS recent (>=10.10, Yosemite), la syntaxe du SED est differente
  8 +# Il faut donc exécuter ce script de la manière suivante :
  9 +# ./macos-db-update.sh <ce_script.sh>
  10 +
  11 +
  12 +function abort() {
  13 + echo "******************************************************"
  14 + echo "!!! Script $0 aborté à cause d'une erreur d'exécution !!!"
  15 + echo "******************************************************"
  16 + exit 1
  17 +}
  18 +
  19 +
  20 +if [ ! -f ../../config/app.php ] ; then
  21 +echo "Vous devez executer ce script depuis le dossier database/update/"
  22 +exit 1
  23 +fi
  24 +
  25 +
  26 +# Get login, pass, dbname, and hostname
  27 +username=$(grep "/\*d\*/'username'" ../../config/app.php | cut -d"'" -f4) || abort
  28 +password=$(grep "/\*d\*/'password'" ../../config/app.php | cut -d"'" -f4) || abort
  29 +database=$(grep "/\*d\*/'database'" ../../config/app.php | cut -d"'" -f4) || abort
  30 +host=$(grep "/\*d\*/'host'" ../../config/app.php | cut -d"'" -f4) || abort
  31 +
  32 +
  33 +#cp -p ./script_sql/db-update-2016-07-01-irap.sql ./script_sql/db-update-2016-07-01-irap-build.sql
  34 +cp -p ./script_sql/$myname.sql ./script_sql/$myname-build.sql || abort
  35 +
  36 +# Execute sql update script
  37 +sed -e "s/database/$database/" -i ./script_sql/$myname-build.sql || abort
  38 +mysql --user=$username --password=$password -h $host < ./script_sql/$myname-build.sql || abort
  39 +
  40 +# Delete temporary file and cakephp cache (-f avoids warning if no file)
  41 +rm -f ./script_sql/$myname-build.sql
  42 +sudo rm -f ../../tmp/cache/models/*
  43 +sudo rm -f ../../tmp/cache/persistent/*
  44 +
  45 +# Faire ca aussi si ca suffit pas...
  46 +#sudo chmod -R 777 ../../tmp
  47 +#sudo chmod -R 777 ../../vendor
  48 +#sudo chmod -R 777 ../../webroot
  49 +
  50 +
  51 +# PLUGIN update
  52 +# Installation plugin cakephp-dompdf
  53 +# (on va a la racine du projet)
  54 +#cd ../../
  55 +#php composer.phar require daoandco/cakephp-dompdf
  56 +#bin/cake plugin assets symlink
  57 +#cd -
... ...
database/update/script_sql/db-update-2019-06-03.sql 0 → 100755
... ... @@ -0,0 +1,13 @@
  1 +use database;
  2 +
  3 +CREATE TABLE `fakeldapusers` (
  4 + `id` int(11) NOT NULL AUTO_INCREMENT,
  5 + `sn` varchar(45) DEFAULT NULL,
  6 + `givenname` varchar(45) DEFAULT NULL,
  7 + `uid` varchar(45) DEFAULT NULL,
  8 + `mail` varchar(45) DEFAULT NULL,
  9 + `userpassword` varchar(255) DEFAULT NULL
  10 +) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  11 +
  12 +-- ALTER TABLE `fakeldapusers`
  13 +-- MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=73;
0 14 \ No newline at end of file
... ...
src/Controller/AppController.php
... ... @@ -381,6 +381,7 @@ class AppController extends Controller
381 381 'action' => 'home'
382 382 ]
383 383 ]);
  384 +
384 385 // On charge la configuration
385 386 /*
386 387 $this->confLabinvent = TableRegistry::getTableLocator()->get('Configurations')->find()
... ...
src/Controller/MaterielsController.php
... ... @@ -247,6 +247,7 @@ class MaterielsController extends AppController
247 247  
248 248 $this->userFromSession = $userFromSession;
249 249 $configuration = $this->confLabinvent;
  250 + // ex: 'uid'
250 251 $this->userCname = $userFromSession[$configuration->ldap_authenticationType][0];
251 252 /*
252 253 * $role = TableRegistry::get('Users')->find()
... ... @@ -1054,8 +1055,7 @@ class MaterielsController extends AppController
1054 1055 $id
1055 1056 ]);
1056 1057 } else {
1057   - debug("(EP debug): ");
1058   - debug($materiel->errors());
  1058 + $this->myDebug($materiel->errors());
1059 1059 $this->Flash->error(__("Le matériel n'a pas pu être $action"."."));
1060 1060 }
1061 1061 } // if POST
... ...
src/Controller/UsersController.php
... ... @@ -13,6 +13,25 @@ use Cake\ORM\TableRegistry;
13 13 class UsersController extends AppController
14 14 {
15 15  
  16 + public $paginate = [
  17 + 'contain' => [
  18 + 'GroupesMetiers',
  19 + 'GroupesThematiques',
  20 + 'SurCategories'
  21 + ],
  22 + 'limit' => 20,
  23 + 'order' => [
  24 + 'Users.nom' => 'asc'
  25 + ]
  26 + ];
  27 +
  28 + public function initialize()
  29 + {
  30 + parent::initialize();
  31 + $this->loadComponent('Paginator');
  32 + }
  33 +
  34 +
16 35 // "l'" utilisateur (et non pas "le utilisateur")
17 36 protected function getArticle()
18 37 {
... ... @@ -95,20 +114,34 @@ class UsersController extends AppController
95 114 */
96 115 public function index()
97 116 {
  117 +
  118 + //$priviledgedUsers = $this->Users->find()->where(['role !=' => 'Utilisateur']);
  119 +
  120 + /*
98 121 $this->paginate = [
99 122 'contain' => [
100 123 'GroupesMetiers',
101 124 'GroupesThematiques',
102 125 'SurCategories'
  126 + ],
  127 + 'limit' => 12,
  128 + 'order' => [
  129 + 'Users.nom' => 'asc'
103 130 ]
104 131 ];
  132 + */
  133 +
  134 + // ALL users
105 135 $users = $this->paginate($this->Users);
  136 + // Only priviledged users
  137 + //$users = $this->paginate($priviledgedUsers);
106 138  
107 139 // Affichage informations disponible pour l'utilisateur connecté
108 140 $this->myDebug($this->LdapAuth->user());
109 141  
110   - $this->set('nbUsers', $this->Users->find('all')
111   - ->count());
  142 + $this->set('nbUsers', $this->Users->find()->count());
  143 + //$this->set('nbUsers', $this->Users->find('all')->count());
  144 + //$this->set('nbUsers', $priviledgedUsers->count());
112 145  
113 146 $this->set(compact('users'));
114 147 $this->set('_serialize', [
... ...
src/Model/Entity/Fakeldapuser.php 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +<?php
  2 +namespace App\Model\Entity;
  3 +
  4 +use Cake\ORM\Entity;
  5 +use Cake\Auth\DefaultPasswordHasher;
  6 +
  7 +/**
  8 + * User Entity.
  9 + *
  10 + * @property int $id
  11 + * @property string $sn
  12 + * @property string $givenname
  13 + * @property string $uid
  14 + * @property string $userpassword
  15 + * @property string $mail
  16 + */
  17 +class Fakeldapuser extends Entity
  18 +{
  19 +
  20 + /**
  21 + * Fields that can be mass assigned using newEntity() or patchEntity().
  22 + *
  23 + * Note that when '*' is set to true, this allows all unspecified fields to
  24 + * be mass assigned. For security purposes, it is advised to set '*' to false
  25 + * (or remove it), and explicitly make individual fields accessible as needed.
  26 + *
  27 + * @var array
  28 + */
  29 + protected $_accessible = [
  30 + '*' => true,
  31 + 'id' => false
  32 + ];
  33 +
  34 + // Fonction de hachage de mot de passe
  35 + protected function _setPassword($password)
  36 + {
  37 + return (new DefaultPasswordHasher())->hash($password);
  38 + }
  39 +}
... ...
src/Model/Entity/User.php
... ... @@ -8,6 +8,8 @@ use Cake\Auth\DefaultPasswordHasher;
8 8 * User Entity.
9 9 *
10 10 * @property int $id
  11 + * @property \Cake\I18n\Time $created
  12 + * @property \Cake\I18n\Time $modified
11 13 * @property string $nom
12 14 * @property string $username
13 15 * @property string $password
... ...
src/Model/Table/FakeldapusersTable.php 0 → 100644
... ... @@ -0,0 +1,106 @@
  1 +<?php
  2 +namespace App\Model\Table;
  3 +
  4 +use Cake\ORM\RulesChecker;
  5 +use Cake\ORM\Table;
  6 +use Cake\Validation\Validator;
  7 +use Cake\ORM\TableRegistry;
  8 +
  9 +/**
  10 + * FAKE LDAP Model
  11 + *
  12 + */
  13 +class FakeldapusersTable extends AppTable
  14 +{
  15 +
  16 + /**
  17 + * Initialize method
  18 + *
  19 + * @param array $config
  20 + * The configuration for the Table.
  21 + * @return void
  22 + */
  23 + public function initialize(array $config)
  24 + {
  25 + parent::initialize($config);
  26 +
  27 + $this->setTable('fakeldapusers');
  28 + $this->setDisplayField('id');
  29 + $this->setPrimaryKey('id');
  30 + }
  31 +
  32 + /**
  33 + * Default validation rules.
  34 + *
  35 + * @param \Cake\Validation\Validator $validator
  36 + * Validator instance.
  37 + * @return \Cake\Validation\Validator
  38 + */
  39 + public function validationDefault(Validator $validator)
  40 + {
  41 + $validator->integer('id')->allowEmpty('id', 'create');
  42 +
  43 + $validator->notEmpty('sn', 'Un nom est nécessaire')->add('sn', 'valid', [
  44 + 'rule' => [
  45 + 'check_string'
  46 + ],
  47 + 'message' => 'Le champ doit être valide.',
  48 + 'provider' => 'table'
  49 + ]);
  50 +
  51 + $validator->notEmpty('uid', 'Un login est nécessaire')
  52 + ->add('uid', 'valid', [
  53 + 'rule' => [
  54 + 'check_string'
  55 + ],
  56 + 'message' => 'Le champ doit être valide.',
  57 + 'provider' => 'table'
  58 + ])
  59 + ->add('uid', 'unique', [
  60 + 'rule' => 'validateUnique',
  61 + 'provider' => 'table'
  62 + ]);
  63 +
  64 + $validator->allowEmpty('userpassword');
  65 +
  66 + $configuration = TableRegistry::get('Configurations')->find()
  67 + ->where([
  68 + 'id =' => 1
  69 + ])
  70 + ->first();
  71 + if ($configuration->ldap_used) {
  72 + $validator->allowEmpty('mail');
  73 + } else {
  74 + $validator->email('mail')->notEmpty('email', 'Un adresse mail est nécessaire');
  75 + }
  76 +
  77 + return $validator;
  78 + }
  79 +
  80 + /**
  81 + * Returns a rules checker object that will be used for validating
  82 + * application integrity.
  83 + *
  84 + * @param \Cake\ORM\RulesChecker $rules
  85 + * The rules object to be modified.
  86 + * @return \Cake\ORM\RulesChecker
  87 + */
  88 + public function buildRules(RulesChecker $rules)
  89 + {
  90 + $rules->add($rules->isUnique([
  91 + 'uid'
  92 + ]));
  93 + // $rules->add($rules->isUnique(['email']));
  94 + return $rules;
  95 + }
  96 +
  97 + function beforeSave($event, $entity, $options)
  98 + {
  99 + /*
  100 + if (! empty($entity->get('newname')) && ! empty($entity->get('newgivenname'))) {
  101 + $entity->set('nom', $entity->get('newname') . ' ' . $entity->get('newgivenname'));
  102 + }
  103 + */
  104 + return true;
  105 + }
  106 +}
... ...
src/Model/Table/LdapConnectionsTable.php
... ... @@ -11,7 +11,7 @@ use App\Model\Entity\User;
11 11 class LdapConnectionsTable extends AppTable
12 12 {
13 13  
14   - private $DEBUG_MODE = TRUE;
  14 + private $DEBUG_MODE; // read from config
15 15  
16 16 // (EP 23/5/19) Optimisation:
17 17 // Les utilisateurs sont stockés dans un cache (BD)
... ... @@ -126,21 +126,23 @@ class LdapConnectionsTable extends AppTable
126 126 $usersTable = TableRegistry::getTableLocator()->get('Users');
127 127  
128 128 $user = $usersTable->newEntity();
129   - $user->nom = $user_from_LDAP['sn'].' '.$user_from_LDAP['givenname'];
  129 + $user->nom = $user_from_LDAP['sn'][0].' '.$user_from_LDAP['givenname'][0];
130 130 //$user->username = $user_from_LDAP['uid'];
131   - $user->username = $user_from_LDAP[$this->authenticationType];
132   - $user->email = $user_from_LDAP['mail'];
  131 + $user->username = $user_from_LDAP[$this->authenticationType][0];
  132 + $user->email = $user_from_LDAP['mail'][0];
133 133 // Par defaut, role = UTILISATEUR
134 134 $user->role = 'Utilisateur';
135 135 // C'est la version "cryptée" qui doit etre stockée
136   - $user->password = $user_from_LDAP['userpassword'];
  136 + $user->password = $user_from_LDAP['userpassword'][0];
137 137 return $user;
138 138  
139 139 }
140 140  
141 141 private function _getDBusersFormattedAsLDAP($usersfromDB) {
142   - foreach ($usersfromDB as $userfromDB) $userfromDB = $this->_getDBuserFormattedAsLDAP($userfromDB);
143   - return $usersfromDB;
  142 + $usersFormattedAsLDAP = [];
  143 + foreach ($usersfromDB as $userfromDB)
  144 + $usersFormattedAsLDAP[] = $this->_getDBuserFormattedAsLDAP($userfromDB);
  145 + return $usersFormattedAsLDAP;
144 146 }
145 147  
146 148  
... ... @@ -171,6 +173,31 @@ class LdapConnectionsTable extends AppTable
171 173 ]
172 174 ];
173 175 }
  176 + private function _getFakeDBuserFormattedAsLDAP($user) {
  177 + return [
  178 + // Nom
  179 + 'sn' => [
  180 + $user['sn']
  181 + ],
  182 + // Email
  183 + 'mail' => [
  184 + $user['mail']
  185 + ],
  186 + // Pnom
  187 + 'givenname' => [
  188 + $user['givenname']
  189 + ],
  190 + // Login ("uid" for IRAP, "samaccountname" for CRAL)
  191 + //'uid' => [
  192 + $this->authenticationType => [
  193 + $user['uid']
  194 + ],
  195 + // Pass
  196 + 'userpassword' => [
  197 + $user['userpassword']
  198 + ]
  199 + ];
  200 + }
174 201  
175 202 private function buildFakeLdapUsers()
176 203 {
... ... @@ -179,9 +206,12 @@ class LdapConnectionsTable extends AppTable
179 206  
180 207 private function buildFakeLdapUsersFromDB()
181 208 {
182   - $users = TableRegistry::getTableLocator()->get('Users')->find();
  209 + //NEW
  210 + //$users = TableRegistry::getTableLocator()->get('Users')->find();
  211 + $users = TableRegistry::getTableLocator()->get('Fakeldapusers')->find();
183 212  
184 213 $ldapUsers = [];
  214 + //$ldapUsers = $users->toArray();
185 215  
186 216 foreach ($users as $user) {
187 217 //debug($user);
... ... @@ -213,7 +243,9 @@ class LdapConnectionsTable extends AppTable
213 243 '[repository]' => 'Users'
214 244  
215 245 */
216   - $ldapUsers[] = $this->_getDBuserFormattedAsLDAP($user);
  246 + //NEW
  247 + //$ldapUsers[] = $this->_getDBuserFormattedAsLDAP($user);
  248 + $ldapUsers[] = $this->_getFakeDBuserFormattedAsLDAP($user);
217 249 /*
218 250 $names = explode(" ", $user['nom']);
219 251 $givenName = isset($names[1]) ? $names[1] : " ";
... ... @@ -262,6 +294,7 @@ class LdapConnectionsTable extends AppTable
262 294 'fakeldapuser@domain.fr'
263 295 ],
264 296 // $this->authenticationType => [$prefix.'username'],
  297 + //'uid' => [
265 298 $this->authenticationType => [
266 299 $this->getTheFakeLdapUser()['login']
267 300 ],
... ... @@ -277,17 +310,23 @@ class LdapConnectionsTable extends AppTable
277 310  
278 311 private function checkConfiguration()
279 312 {
280   - $this->CONF = TableRegistry::getTableLocator()->get('Configurations')
  313 + $this->configurationsTable = TableRegistry::getTableLocator()->get('Configurations');
  314 + $this->CONF = $this->configurationsTable
281 315 ->find()
282 316 ->where(['id =' => 1])
283 317 ->first();
284   - $config = $this->CONF;
  318 +
  319 + $config = $this->CONF;
285 320  
286 321 $this->usersTable = TableRegistry::getTableLocator()->get('Users');
287 322  
288 323 $this->DEBUG_MODE = $config->mode_debug;
289 324 $this->LDAP_USED = $config->ldap_used;
290 325 if (! $this->LDAP_USED) {
  326 +
  327 + // Seulement pour tester le mode ldap_cached en mode FAKE LDAP:
  328 + //$this->CONF->ldap_cached = TRUE;
  329 +
291 330 $this->authenticationType = $config->ldap_authenticationType;
292 331 if (empty($this->fakeLDAPUsers))
293 332 $this->fakeLDAPUsers = $this->buildFakeLdapUsers();
... ... @@ -356,12 +395,16 @@ class LdapConnectionsTable extends AppTable
356 395  
357 396  
358 397 // @return ldap users from DB users table
359   - private function _getAllLdapUsersFromDB() {
  398 + private function _getAllLdapUsersFromDB($do_update=TRUE) {
360 399  
361   - $this->_updateLdapCacheIfNeeded();
  400 + if ($do_update) $this->_updateLdapCacheIfNeeded();
362 401 return $this->usersTable->find();
363 402 }
  403 +
364 404  
  405 + private function _getAllLdapUsersFromLDAP() {
  406 + return $this->LDAP_USED ? $this->searchLdap($this->filter, []) : $this->fakeLDAPUsers;
  407 + }
365 408  
366 409 /**
367 410 * @return $users_fetched or FALSE
... ... @@ -371,10 +414,13 @@ class LdapConnectionsTable extends AppTable
371 414 {
372 415 if (! $this->checkConfiguration()) return FALSE;
373 416  
  417 + // By default, nothing found, ERROR
  418 + $users_fetched = FALSE;
  419 +
374 420 // LDAP optimized (cached)
375 421 if ($this->CONF->ldap_cached) {
376 422 $users_fetched = $this->_getAllLdapUsersFromDB();
377   - return ($this->_getDBusersFormattedAsLDAP($users_fetched));
  423 + $users_fetched = $this->_getDBusersFormattedAsLDAP($users_fetched);
378 424 }
379 425  
380 426 // LDAP direct (no optimization)
... ... @@ -383,34 +429,38 @@ class LdapConnectionsTable extends AppTable
383 429 //if ($this->checkConfiguration()) {
384 430  
385 431 // REAL LDAP
386   - if ($this->LDAP_USED) {
  432 + //if ($this->LDAP_USED) {
387 433  
  434 + /*
388 435 // 1) Search users in CACHE (DB)
389 436 $users_fetched = $this->fetchAllUsersFromDB();
390 437  
391 438 // 2) Not found in CACHE, so search users in LDAP
392 439 if ($users_fetched === FALSE) {
393   - $users_fetched = $this->searchLdap($this->filter, []);
394   - // CACHE the new user in DB for next time
395   - if ($users_fetched !== FALSE) $this->saveAllUsersInDB($users_fetched);
396   - }
  440 + */
  441 + $users_fetched = $this->_getAllLdapUsersFromLDAP();
  442 + //$users_fetched = $this->searchLdap($this->filter, []);
  443 + // CACHE the new user in DB for next time
  444 + //if ($users_fetched !== FALSE) $this->saveAllUsersInDB($users_fetched);
  445 + //}
397 446  
398   - }
  447 + //}
399 448  
  449 + /*
400 450 // FAKE LDAP
401 451 else {
402 452 $users_fetched = $this->fakeLDAPUsers;
403 453 }
  454 + */
404 455  
405 456 // Noter que $user_fetched peut etre egal a FALSE (si rien trouvé)
406   - return $users_fetched;
  457 + //return $users_fetched;
407 458 //}
408 459 }
409 460 catch (Exception $e) {}
410 461 }
411 462  
412   - // Pb, rien trouvé
413   - return FALSE;
  463 + return $users_fetched;
414 464 }
415 465  
416 466  
... ... @@ -423,6 +473,11 @@ class LdapConnectionsTable extends AppTable
423 473 public function getFakeLdapUser($login)
424 474 {
425 475 foreach ($this->fakeLDAPUsers as $user) {
  476 + /*
  477 + debug($login);
  478 + debug($user);
  479 + */
  480 + //if ($login == $user['uid'][0])
426 481 if ($login == $user[$this->authenticationType][0])
427 482 return $user;
428 483 }
... ... @@ -442,7 +497,8 @@ class LdapConnectionsTable extends AppTable
442 497 $this->mydebugmsg("ldap users 0 and 1:");
443 498 $this->mydebugmsg($u[0]);
444 499 $this->mydebugmsg($u[1]);
445   - // (EP) Refactorisation pour éviter code redondant du temps des stagiaires...
  500 + // (EP) Refactorisation pour éviter code redondant du "bon vieux" temps des stagiaires...
  501 + // Il suffit souvent de réfléchir un peu pour résumer 10 lignes en 1 seule...
446 502 $nb_users = $this->LDAP_USED ? $u['count'] : sizeof($u)-1;
447 503 for ($i = 0; $i < $nb_users; $i ++)
448 504 // $utilisateurs["Pallier Etienne"] = ["email"]
... ... @@ -552,13 +608,15 @@ class LdapConnectionsTable extends AppTable
552 608 {
553 609 return [
554 610 'login' => '_fake_ldap_user_',
555   - 'pass' => '_fake_ldap_user_pass'
  611 + //'pass' => '_fake_ldap_user_pass'
  612 + 'pass' => '$2y$10$Vx8E8VirQGnoLYpn7qqNAO4UhTJMyrUVCzkcy0Obh3ceABuxMxk.q'
556 613 ];
557 614 }
558 615  
559 616  
560 617 // @return user from DB whith login = $userLogin (or NULL)
561 618 private function _getUser($userLogin) {
  619 + //debug($userLogin);
562 620 return $this->usersTable->find()
563 621 //$ldapUser = TableRegistry::getTableLocator()->get('Users')->find()
564 622 ->where([
... ... @@ -573,46 +631,181 @@ class LdapConnectionsTable extends AppTable
573 631 * - TRUE if cache is expired (outdated or 1st special row is missing)
574 632 */
575 633 private function _ldapCacheIsExpired() {
  634 + if (is_null($this->CONF->ldap_cache_last_update)) return TRUE;
  635 +
  636 + /* About strtotime("") :
  637 + * - forward slash (/) signifies American M/D/Y formatting => strtotime("11/12/10")
  638 + * - a dash (-) signifies European D-M-Y => strtotime("11-12-10"))
  639 + * - a period (.) signifies ISO Y.M.D. => strtotime("11.12.10")
  640 + */
576 641 // ldap_cache_last_update is not set OR is expired => return state as expired
577   - return ( is_null($this->CONF->ldap_cache_last_update) || ($this->CONF->ldap_cache_last_update + $this->ldap_cache_validity_duration < now()) );
  642 + $date_now = date("Y-m-d H:i:s");
  643 + //debug("now :".$date_now);
  644 + $date_now = new \DateTime($date_now);
  645 + $date_cached = $this->CONF->ldap_cache_last_update;
  646 + // Pourquoi j'ai pas les secondes qui s'affichent ???!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  647 + //debug("cached :".$date_cached);
  648 + $date_cached = \DateTime::createFromFormat('d/m/Y H:i',$date_cached);
  649 + //debug("now :".$date_now->format('Y-m-d H:i:s') );
  650 + //debug("cached :".$date_cached->format('Y-m-d H:i:s') );
  651 +
  652 + $date_cached->add(new \DateInterval('PT'.$this->CONF->ldap_cache_validity_duration.'M'));
  653 + //debug("date_cached (added) :".$date_cached->format('Y-m-d H:i:s') );
  654 +
  655 + /*
  656 + $date_now = $date_now->getTimestamp();
  657 + $date_cached = $date_cached->getTimestamp();
  658 + debug("now :".$date_now);
  659 + debug("cached :".$date_cached);
  660 + $date_now = strtotime($date_now);
  661 + $date_cached = strtotime($date_cached);
  662 + debug("now :". date("Y-m-d H:i:s", $date_now));
  663 + debug("cached :". date("Y-m-d H:i:s", $date_cached));
  664 +
  665 + //debug($this->CONF->ldap_cache_last_update ." plus ".$this->CONF->ldap_cache_validity_duration." minutes < $now ?");
  666 + debug($date_cached ." plus ".$this->CONF->ldap_cache_validity_duration." minutes < $date_now ?");
  667 + $last_save_date_plus_delay = strtotime( "+".$this->CONF->ldap_cache_validity_duration." minutes", strtotime($this->CONF->ldap_cache_last_update) );
  668 + */
  669 +
  670 + //debug("decalage ?");
  671 + //debug($date_cached < $date_now);
  672 +
  673 + // TEST
  674 + /*
  675 + $now = new \DateTime("2019-05-29 15:32:00");
  676 + debug("now :".$now->format('Y-m-d H:i:s') );
  677 + $d = $this->CONF->ldap_cache_last_update;
  678 + $d = \DateTime::createFromFormat('d/m/Y H:i',$d);
  679 + debug("d :".$d->format('Y-m-d H:i:s') );
  680 +
  681 + $d->add(new \DateInterval('PT1M'));
  682 + debug("d :".$d->format('Y-m-d H:i:s') );
  683 + debug($d > $now);
  684 +
  685 + $d->sub(new \DateInterval('PT2M'));
  686 + debug("d :".$d->format('Y-m-d H:i:s') );
  687 + debug($d < $now);
  688 +
  689 + $d->add(new \DateInterval('PT1M'));
  690 + debug("d :".$d->format('Y-m-d H:i:s') );
  691 + debug($d == $now);
  692 + */
  693 +
  694 + //return TRUE;
  695 + return ($date_cached < $date_now);
578 696 }
579 697  
  698 +
  699 + private function _updateUserPassword($userId, $newPwd) {
  700 + $query = $this->usersTable->query();
  701 + $query->update()
  702 + ->set(['password' => $newPwd])
  703 + ->where(['id' => $userId])
  704 + ->execute();
  705 + }
  706 +
  707 +
580 708 // REAL LDAP only
581 709 // Save all LDAP users into "users" db table
582 710 private function _updateLdapCacheIfNeeded() {
583 711  
584 712 // return if cache is not expired
585 713 if (! $this->_ldapCacheIsExpired()) return;
  714 + //$this->mydebugmsg("expiré");
586 715  
587 716 // Get all users from LDAP
588   - $ldapUsersFromLDAP = $this->getAllLdapUsers();
  717 + $ldapUsersFromLDAP = $this->_getAllLdapUsersFromLDAP();
589 718  
590 719 // Get all users from DB
591   - $ldapUsersFromDB = $this->_getAllLdapUsersFromDB();
  720 + $ldapUsersFromDB = $this->_getAllLdapUsersFromDB(FALSE);
592 721  
593 722 // Add new users (only) and update existing users
594 723 foreach ($ldapUsersFromLDAP as $ldapUserFromLDAP) {
595   - $ldapUserFromDB = $this->_getUser($ldapUserFromLDAP[$this->authenticationType]);
  724 + //$this->mydebugmsg("current user is ".$ldapUserFromLDAP['uid'][0]);
  725 + $currentLdapUserLogin = $ldapUserFromLDAP[$this->authenticationType][0];
  726 + $currentLdapUserPwd = $ldapUserFromLDAP['userpassword'][0];
  727 + //$this->mydebugmsg("current user is ".$currentLdapUserLogin);
  728 + // Do not save fake ldap user in DB
  729 + if ($currentLdapUserLogin == '_fake_ldap_user_') continue;
  730 + $ldapUserFromDB = $this->_getUser($currentLdapUserLogin);
  731 +
596 732 // New user => add it to DB
597   - if (is_null($ldapUserFromDB))
  733 + if (is_null($ldapUserFromDB)) {
  734 + //$this->mydebugmsg("user does not exist => add it to DB");
  735 + // Ajout du nouvel utilisateur
598 736 $this->usersTable->save($this->_getLDAPuserFormattedAsDB($ldapUserFromLDAP));
599   - // Existing user => update it (only email and password)
  737 + //$this->usersTable->query("FLUSH TABLES");
  738 + // Correction de son mot de passe
  739 + $ldapUserFromDB = $this->_getUser($currentLdapUserLogin);
  740 + assert(!is_null($ldapUserFromDB));
  741 + //$this->mydebugmsg("UPDATE users SET password = '".$currentLdapUserPwd."' WHERE id = ".$ldapUserFromDB->id);
  742 + //$this->usersTable->query("UPDATE users SET password = '".$ldapUserFromLDAP['userpassword'][0]."' WHERE id = ".$ldapUserFromDB->id);
  743 + $this->_updateUserPassword($ldapUserFromDB->id, $currentLdapUserPwd);
  744 + /*
  745 + $query = $this->usersTable->query();
  746 + $query->update()
  747 + ->set([ 'password' => $ldapUserFromLDAP['userpassword'][0] ])
  748 + ->where(['id' => $ldapUserFromDB->id])
  749 + ->execute();
  750 + */
  751 + //exit;
  752 + }
  753 +
  754 + // Existing user => update it if changed (only email and password)
600 755 else {
601   - $ldapUserFromDB->email = $ldapUserFromLDAP['mail'];
602   - $ldapUserFromDB->password = $ldapUserFromLDAP['userpassword'];
603   - $this->usersTable->save($ldapUserFromDB);
  756 + //TODO: a virer, only for test
  757 + $BOURRIN=TRUE;
  758 + //$this->mydebugmsg("user already exists => update it");
  759 + // 1) Update email (only if changed)
  760 + if ( ($ldapUserFromDB->email != $ldapUserFromLDAP['mail'][0]) || $BOURRIN ) {
  761 + //$this->mydebugmsg("email diff ? ");
  762 + //$this->mydebugmsg($ldapUserFromDB->email !== $ldapUserFromLDAP['mail'][0]);
  763 + $ldapUserFromDB->email = $ldapUserFromLDAP['mail'][0];
  764 + $this->usersTable->save($ldapUserFromDB);
  765 + }
  766 + // 2) Update password (only if changed)
  767 + //debug("password = ".$ldapUserFromDB->password);
  768 + //debug("userpassword = ".$ldapUserFromLDAP['userpassword'][0]);
  769 + /* (EP 28/5/19) Sauvegarde du mot de passe : ATTENTION !
  770 + * Si on utilise la methode save() de cakephp, le mot de passe n'est pas copié tel quel, mais re-crypté !!!
  771 + * On doit donc le copier "à la hard" avec du code sql direct pour shunter la methode save()
  772 + * Ceci n'est donc pas possible :
  773 + $ldapUserFromDB->password = $ldapUserFromLDAP['userpassword'][0];
  774 + $this->usersTable->save($ldapUserFromDB);
  775 + */
  776 + // Par contre, ceci fonctionne :
  777 + //debug("UPDATE users SET password = '".$ldapUserFromLDAP['userpassword'][0]."' WHERE id = ".$ldapUserFromDB->id);
  778 + if ( ($ldapUserFromDB->password != $currentLdapUserPwd) || $BOURRIN ) {
  779 + //$this->mydebugmsg("pass diff ? ");
  780 + //$this->mydebugmsg($ldapUserFromDB->password !== $ldapUserFromLDAP['userpassword'][0]);
  781 + //$this->usersTable->query("UPDATE users SET password = '".$ldapUserFromLDAP['userpassword'][0]."' WHERE id = ".$ldapUserFromDB->id);
  782 + $this->_updateUserPassword($ldapUserFromDB->id, $currentLdapUserPwd);
  783 + }
604 784 }
605 785 }
606 786  
607 787 // Delete old users (which are no more in LDAP)
608 788 foreach ($ldapUsersFromDB as $ldapUserFromDB) {
609   - if (! in_array($ldapUserFromDB->username, $ldapUsersFromLDAP))
610   - $ldapUserFromDB->delete();
  789 + /*
  790 + debug("DELETE");
  791 + debug("look for $ldapUserFromDB->username");
  792 + debug("in ");
  793 + */
  794 + //debug($ldapUsersFromLDAP);
  795 + //$ldapUsersLoginFromLDAP = array_column($ldapUsersFromLDAP, 'uid');
  796 + $ldapUsersLoginFromLDAP = array_column($ldapUsersFromLDAP, $this->authenticationType);
  797 + $ldapUsersLoginFromLDAP = array_column($ldapUsersLoginFromLDAP, '0');
  798 + //debug($ldapUsersLoginFromLDAP);
  799 + if (! in_array($ldapUserFromDB->username, $ldapUsersLoginFromLDAP)) {
  800 + debug("OLD user should be deleted:");
  801 + debug($ldapUserFromDB->username);
  802 + //$ldapUserFromDB->delete();
  803 + }
611 804 }
612 805  
613   - // Update LDAP cache last update time
614   - $this->CONF->ldap_cache_last_update = now();
615   - $this->CONF->save();
  806 + // Update LDAP cache last update time (= NOW)
  807 + $this->CONF->ldap_cache_last_update = date("Y-m-d H:i:s"); // 2019-05-28 03:25:34
  808 + $this->configurationsTable->save($this->CONF);
616 809  
617 810 }
618 811  
... ... @@ -786,6 +979,7 @@ class LdapConnectionsTable extends AppTable
786 979 // $this->authenticationType peut valoir "uid" ou "cn"... (par défaut "uid" pour le fake ldap, à confirmer...)
787 980 // if ($user['uid'][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user;
788 981 // if ($user[$this->authenticationType][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user;
  982 + //if ($user['uid'][0] == $this->getTheFakeLdapUser()['login'] && $user['userpassword'][0] == $this->getTheFakeLdapUser()['pass'])
789 983 if ($user[$this->authenticationType][0] == $this->getTheFakeLdapUser()['login'] && $user['userpassword'][0] == $this->getTheFakeLdapUser()['pass'])
790 984 return $user;
791 985 if ( (new DefaultPasswordHasher())->check($user_password,$user['userpassword'][0]) )
... ... @@ -818,13 +1012,23 @@ class LdapConnectionsTable extends AppTable
818 1012 if (! $this->checkConfiguration()) return FALSE;
819 1013  
820 1014 // LDAP optimized
821   - $this->CONF->ldap_cached = FALSE;
  1015 + //$this->CONF->ldap_cached = FALSE;
822 1016 if ($this->CONF->ldap_cached) {
823 1017 $ldap_user = $this->_getLdapUserFromDB($user_login);
824   - // login FAIL because user not found
  1018 + // login FAIL because user not found
825 1019 if ($ldap_user === FALSE) return FALSE;
  1020 + /*
  1021 + debug("user_password = ".$user_password);
  1022 + debug("user found in db is ");
  1023 + debug($ldap_user);
  1024 + debug($ldap_user['userpassword'][0]);
  1025 + */
826 1026 // check password and return user if ok or FALSE if fail
827   - return ( (new DefaultPasswordHasher())->check($user_password,$ldap_user['userpassword'][0]) );
  1027 + // check($user_password EN CLAIR, $ldap_user['userpassword'][0]) CRYPTED) {
  1028 + if ( (new DefaultPasswordHasher())->check($user_password,$ldap_user['userpassword'][0]) ) {
  1029 + //debug("YES");
  1030 + return $ldap_user;
  1031 + }
828 1032 }
829 1033  
830 1034 // normal LDAP (no optimization)
... ... @@ -888,6 +1092,12 @@ class LdapConnectionsTable extends AppTable
888 1092 //debug($this->USE_LDAP);
889 1093 //debug($this->baseDn);
890 1094 $user_fetched = $this->getFakeLdapUser($user_login);
  1095 + /*
  1096 + debug($user_login);
  1097 + debug($user_password);
  1098 + debug($user_fetched);
  1099 + exit;
  1100 + */
891 1101 $this->mydebugmsg("(1) user found in FAKE LDAP is:");
892 1102 $this->mydebugmsg($user_fetched);
893 1103 /* Voici un exemple de ce qui est dans $user_fetched (fake ldap) :
... ... @@ -917,9 +1127,16 @@ class LdapConnectionsTable extends AppTable
917 1127 // if ($user[$this->authenticationType][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user;
918 1128 if ($user_fetched[$this->authenticationType][0] == $this->getTheFakeLdapUser()['login'] && $user_fetched['userpassword'][0] == $this->getTheFakeLdapUser()['pass'])
919 1129 return $user_fetched;
920   - if ( (new DefaultPasswordHasher())->check($user_password,$user_fetched['userpassword'][0]) )
921   - return $user_fetched;
922   - // if ($user != false && $user['userpassword'][0] == $password) {
  1130 + /*
  1131 + debug("user_password = ".$user_password);
  1132 + debug("user found in db is ");
  1133 + debug($user_fetched);
  1134 + debug($user_fetched['userpassword'][0]);
  1135 + exit;
  1136 + */
  1137 + if ( (new DefaultPasswordHasher())->check($user_password,$user_fetched['userpassword'][0]) )
  1138 + return $user_fetched;
  1139 + // if ($user != false && $user['userpassword'][0] == $password) {
923 1140 }
924 1141 }
925 1142  
... ...
src/Model/Table/MaterielsTable.php
... ... @@ -65,6 +65,7 @@ class MaterielsTable extends AppTable
65 65 //$this->setDisplayField('id');
66 66 //$this->setPrimaryKey('id');
67 67  
  68 + // So that 'created' and 'updated' fields are filled
68 69 $this->addBehavior('Timestamp');
69 70  
70 71 $this->belongsTo('SurCategories', [
... ...
src/Model/Table/UsersTable.php
... ... @@ -40,6 +40,9 @@ class UsersTable extends AppTable
40 40 $this->belongsTo('SurCategories', [
41 41 'foreignKey' => 'sur_categorie_id'
42 42 ]);
  43 +
  44 + // So that 'created' and 'updated' fields are filled
  45 + $this->addBehavior('Timestamp');
43 46 }
44 47  
45 48 /**
... ...
src/Template/Configurations/edit.ctp
... ... @@ -247,9 +247,11 @@ function echoSection($title, $section) {
247 247 echo $this->Form->control('ldap_cached', [
248 248 'label' => "Optimisation accès LDAP (utilisation cache en BD)"
249 249 ]);
  250 + /*
250 251 echo $this->Form->control('ldap_cache_last_update', [
251 252 'label' => 'Date de dernière mise à jour du cache LDAP'
252 253 ]);
  254 + */
253 255 echo $this->Form->control('ldap_cache_validity_duration', [
254 256 'label' => 'Durée de validité du cache LDAP (mn)'
255 257 ]);
... ...
src/Template/Element/menu_index.ctp
... ... @@ -77,6 +77,7 @@ if ($bol == true) {
77 77 }
78 78 }
79 79 // Add "+" icone
  80 + if (!strstr($t, 'utilisateur'))
80 81 echo $this->Html->link('<i class="icon-plus"></i> ' . $t, [
81 82 'action' => 'add'
82 83 ], [
... ...
src/Template/Materiels/view.ctp
... ... @@ -353,7 +353,7 @@ $CAN_PRINT_LABEL = $IS_VALIDATED &amp;&amp; $configuration-&gt;hasPrinter &amp;&amp; $USER_IS_ADMIN
353 353 }
354 354  
355 355 // BOUTON Copier (seulement pour les materiels qui sont CREATED et pour les ADMINet+ ou USER owner)
356   - if ($CAN_COPY) $echoActionButton($this->Html, 'icon-plus', $bStyle, ' Copier ce matériel', '', 'add', $materiel->id, [], "Copier ce matériel");
  356 + if ($CAN_COPY) $echoActionButton($this->Html, 'icon-plus', $bStyle2, ' Copier ce matériel', '', 'add', $materiel->id, [], "Copier ce matériel");
357 357  
358 358 // BOUTON ETIQUETTE (si imprimante disponible)
359 359 if ($CAN_PRINT_LABEL) {
... ...
src/Template/Pages/tools.ctp
... ... @@ -32,9 +32,10 @@ if (in_array($role, [
32 32 }
33 33  
34 34 echo '<tr><td>';
35   -echo $this->Html->link('Gérer les utilisateurs privilégiés', [
  35 +//echo $this->Html->link('Gérer les utilisateurs privilégiés', [
  36 +echo $this->Html->link('Gérer les utilisateurs', [
36 37 'controller' => 'users',
37   - 'sort' => 'nom'
  38 + //'sort' => 'nom'
38 39 ]);
39 40 echo '</td></tr>';
40 41  
... ...
src/Template/Users/edit.ctp
... ... @@ -4,9 +4,15 @@
4 4 <?php $LDAP_USED = $configuration->ldap_used; ?>
5 5 <fieldset>
6 6 <h2>
7   - <i class="icon-edit"></i> Editer un utilisateur privilégié
  7 + <i class="icon-edit"></i> Editer un utilisateur
8 8 </h2>
9 9 <?php
  10 + /*
  11 + * (EP 3/6/19: voir aussi mes remarques ci-apres)
  12 + * Inutile de pouvoir changer d'utilisateur,
  13 + * On repasse par la liste des utilisateurs pour ça
  14 + */
  15 + /*
10 16 $options = [];
11 17 echo $this->Form->control('nom', [
12 18 'options' => $options,
... ... @@ -14,23 +20,52 @@
14 20 'disabled' => true,
15 21 'div' => 'input required'
16 22 ]);
  23 + */
  24 + echo $this->Form->control('nom', [
  25 + 'label' => 'Nom',
  26 + //'div' => 'input required'
  27 + 'readonly' => true,
  28 + ]);
17 29  
18 30 $READONLY = $LDAP_USED ? true : false;
19 31  
20 32 echo $this->Form->control('username', [
21 33 'label' => 'Login',
22   - 'div' => 'input required',
23   - 'readonly' => $READONLY
  34 + // (EP 3/6/19: voir ma remarque ci-dessous)
  35 + // Qu'on soit en LDAP ou fake LDAP, on ne doit PAS pouvoir modifier le username (mais seulement depuis le (fake-)LDAP)
  36 + //'div' => 'input required',
  37 + //'readonly' => $READONLY
  38 + 'readonly' => true,
24 39 ]);
25 40  
  41 + /* EP 3/6/19:
  42 + * Si on n'utilise pas le LDAP,
  43 + * alors on utilise la table fakeldapusers en tant que LDAP.
  44 + * Il n'y a pas d'autre alternative !
  45 + * Donc, si on veut modifier le mot de pass d'un user,
  46 + * Il faut le faire dans la table fakeldapusers (car la table users sert seulement de cache du ldap, c'est tout, ça n'est pas un original mais une COPIE du ldap)
  47 + * (comme on ferait avec un vrai LDAP : on modifierait le pwd dans le LDAP).
  48 + *
  49 + * TODO:
  50 + * Du coup, il faudra ajouter des vues permettant d'administrer le FAKE LDAP (la table fakeldapusers) :
  51 + * - (view, index) voir un ou les user(s)
  52 + * - (add) ajouter un user
  53 + * - (edit) editer un user, ET mettre à jour son pwd !
  54 + * - (delete) supprimer un user, ET mettre à jour son pwd !
  55 + */
  56 + /*
26 57 if (! $LDAP_USED) {
27 58 echo $this->Form->control('password');
28 59 }
  60 + */
29 61  
30 62 echo $this->Form->control('email', [
31 63 'label' => 'E-mail',
32   - 'div' => 'input required',
33   - 'readonly' => $READONLY
  64 + // (EP 3/6/19: voir ma remarque ci-dessus)
  65 + // Qu'on soit en LDAP ou fake LDAP, on ne doit PAS pouvoir modifier le mail (mais seulement depuis le (fake-)LDAP)
  66 + //'div' => 'input required',
  67 + //'readonly' => $READONLY
  68 + 'readonly' => true
34 69 ]);
35 70  
36 71 echo $this->Form->control('role', [
... ... @@ -41,7 +76,7 @@
41 76 'Administration' => 'Administration',
42 77 'Responsable' => 'Responsable',
43 78 'Utilisateur' => 'Utilisateur'
44   - ]
  79 + ],
45 80 ]);
46 81 echo $this->Form->control('groupes_metier_id', [
47 82 'label' => $configuration->nom_groupe_metier,
... ...
src/Template/Users/index.ctp
1 1  
2 2 <div class="users index">
3   -<?php echo '<h2><i class="icon-list"></i> Liste des utilisateurs privilégiés ('.$nbUsers.')</h2>'; ?>
  3 +<?php echo '<h2><i class="icon-list"></i> Liste des utilisateurs ('.$nbUsers.')</h2>'; ?>
4 4 <table style="border-collapse: separate; border-spacing: 0;">
5 5 <thead>
6 6 <tr>
... ... @@ -17,10 +17,12 @@
17 17 <?php foreach ($users as $user): ?>
18 18 <tr>
19 19 <td class="actions" style="padding: 6px 0; text-align: left;">
20   - <?php if($role == 'Super Administrateur') { ?>
21   - <?= $this->Html->link(__('<i class="icon-pencil"></i>'), ['action' => 'edit', $user->id], ['title' => 'Editer', 'style' => 'margin: 0 2px', 'escape' => false ]) ?>
22   - <?= $this->Form->postLink(__('<i class="icon-trash"></i>'), ['action' => 'delete', $user->id], ['title' => 'Supprimer', 'style' => 'margin: 0 2px', 'escape' => false, 'confirm' => __('Êtes-vous sur de vouloir supprimer l\'utilisateur {0} ?', $user->nom)]) ?>
23   - <?php } ?>
  20 + <?php
  21 + if($role == 'Super Administrateur') {
  22 + echo $this->Html->link(__('<i class="icon-pencil"></i>'), ['action' => 'edit', $user->id], ['title' => 'Editer', 'style' => 'margin: 0 2px', 'escape' => false ]);
  23 + //echo $this->Form->postLink(__('<i class="icon-trash"></i>'), ['action' => 'delete', $user->id], ['title' => 'Supprimer', 'style' => 'margin: 0 2px', 'escape' => false, 'confirm' => __('Êtes-vous sur de vouloir supprimer l\'utilisateur {0} ?', $user->nom)]);
  24 + }
  25 + ?>
24 26 </td>
25 27 <td class="smallText"><?= $this->Html->link($user->nom, ['action' => 'view', $user->id]) ?></td>
26 28 <td class="smallText"><?= h($user->role) ?></td>
... ...
src/Template/Users/view.ctp
... ... @@ -18,6 +18,13 @@
18 18 'escape' => false,
19 19 'onclick' => 'return true;'
20 20 ]);
  21 + /*
  22 + * (EP 3/6/19)
  23 + * Voir ma remarque dans la vue edit.ctp
  24 + * La table users n'est qu'un CACHE du LDAP ou du fake ldap (pas d'autre alternative).
  25 + * On ne doit donc pas pouvoir supprimer un user de cette table, mais seulement depuis le LDAP (ou fake ldap, c'est à dire table fakeldapusers)
  26 + */
  27 + /*
21 28 echo $this->Form->postLink(__('<i class="icon-trash"></i> Supprimer cet utilisateur'), [
22 29 'action' => 'delete',
23 30 $user->id
... ... @@ -26,6 +33,7 @@
26 33 'escape' => false,
27 34 'confirm' => __('Êtes-vous sur de vouloir supprimer ?', $user->nom)
28 35 ]);
  36 + */
29 37 }
30 38  
31 39 $displayElement(__('Nom'), h($user->nom));
... ...
tests/Fixture/ConfigurationsFixture.php
... ... @@ -77,20 +77,33 @@ class ConfigurationsFixture extends TestFixture
77 77 'nom' => 'Lorem ipsum dolor sit amet',
78 78 'mode_install' => 0,
79 79 'mode_debug' => 0,
  80 +
80 81 'ldap_used' => 0,
81 82 'ldap_host' => 'Lorem ipsum dolor sit amet',
82 83 'ldap_port' => 'Lorem ip',
83   - 'ldap_authenticationType' => 'cn',
  84 + //'ldap_authenticationType' => 'cn',
  85 + 'ldap_authenticationType' => 'uid',
84 86 'ldap_baseDn' => 'Lorem ipsum dolor sit amet',
85 87 'ldap_filter' => 'Lorem ipsum dolor sit amet',
  88 +
  89 + 'ldap_cached' => 1,
  90 + 'ldap_cache_validity_duration' => 1,
  91 +
  92 + // FPDF
  93 + //'pdf_engine' => 'FPDF',
  94 + // DOM_PDF
  95 + 'pdf_engine' => 'DOMPDF',
  96 +
86 97 'labName' => 'TestLong',
87 98 'labNameShort' => 'TEST',
88 99 'labPresent' => 'de ',
89 100 'labUmr' => 'Lorem ipsum dolor sit amet',
  101 +
90 102 'hasPrinter' => 0,
91 103 'nom_groupe_thematique' => 'Lorem ipsum dolor sit amet',
92 104 'nom_groupe_metier' => 'Lorem ipsum dolor sit amet',
93   - 'envoi_mail_management_dev' => 1,
  105 +
  106 + 'envoi_mail_management_dev' => 1,
94 107 'sender_mail' => 'ezarear@localhost.com',
95 108 'emailGuest1' => 'Lorem ipsum dolor sit amet',
96 109 'emailGuest2' => 'Lorem ipsum dolor sit amet',
... ... @@ -102,11 +115,14 @@ class ConfigurationsFixture extends TestFixture
102 115 'emailGuest8' => 'Lorem ipsum dolor sit amet',
103 116 'emailGuest9' => 'Lorem ipsum dolor sit amet',
104 117 'emailGuest10' => 'Lorem ipsum dolor sit amet',
105   - 'test' => 1,
  118 +
  119 + 'test' => 1,
  120 +
106 121 'prix_inventaire_administratif' => 800,
107   -
108   - 'metrologie' => 1,
109   - 'procedure_sur_accueil' => 1,
  122 + //'prix_inventaire_administratif' => 1000,
  123 +
  124 + 'metrologie' => 1,
  125 + 'procedure_sur_accueil' => 1,
110 126  
111 127 ],
112 128 ];
... ...
tests/Fixture/FakeldapusersFixture.php 0 → 100644
... ... @@ -0,0 +1,110 @@
  1 +<?php
  2 +namespace App\Test\Fixture;
  3 +
  4 +use Cake\TestSuite\Fixture\TestFixture;
  5 +
  6 +/**
  7 + * UsersFixture
  8 + *
  9 + */
  10 +class FakeldapusersFixture extends TestFixture
  11 +{
  12 +
  13 + /**
  14 + * Fields
  15 + *
  16 + * @var array
  17 + */
  18 + // @codingStandardsIgnoreStart
  19 + public $fields = [
  20 + 'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
  21 + 'sn' => ['type' => 'string', 'length' => 45, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
  22 + 'givenname' => ['type' => 'string', 'length' => 45, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
  23 + 'uid' => ['type' => 'string', 'length' => 26, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
  24 + 'userpassword' => ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
  25 + 'mail' => ['type' => 'string', 'length' => 45, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
  26 + '_constraints' => [
  27 + 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
  28 + 'login_UNIQUE' => ['type' => 'unique', 'columns' => ['uid'], 'length' => []],
  29 + ],
  30 + '_options' => [
  31 + 'engine' => 'InnoDB',
  32 + 'collation' => 'latin1_swedish_ci'
  33 + ],
  34 + ];
  35 + // @codingStandardsIgnoreEnd
  36 +
  37 + /**
  38 + * Records
  39 + *
  40 + * @var array
  41 + */
  42 + public $records = [
  43 +
  44 + // Superadmin
  45 + [
  46 + 'id' => 1,
  47 + //'sn' => 'test1 test2',
  48 + //'sn' => 'user1 SUPER',
  49 + 'sn' => 'user1',
  50 + 'givenname' => 'SUPER',
  51 + //'username' => 'testa',
  52 + 'uid' => 'user1_SUPER',
  53 + 'userpassword' => '$2y$10$VtYdA8Evkc.K.VpvqmF9wui5hc9ep19f8ukWBeFBIlunXSHPqw.K2',
  54 + //'email' => 'testa@test.fr',
  55 + 'mail' => 'user1_SUPER@test.fr',
  56 + ],
  57 +
  58 + // Adminplus
  59 + [
  60 + 'id' => 2,
  61 + //'sn' => 'test3 test4',
  62 + //'sn' => 'user2 ADMINP',
  63 + 'sn' => 'user2',
  64 + 'givenname' => 'ADMINP',
  65 + //'uid' => 'testz',
  66 + 'uid' => 'user2_ADMINPLUS',
  67 + 'userpassword' => '$2y$10$VtYdA8Evkc.K.VpvqmF9wui5hc9ep19f8ukWBeFBIlunXSHPqw.K2',
  68 + 'mail' => 'testz@test.fr',
  69 + ],
  70 +
  71 + // Admin
  72 + [
  73 + 'id' => 3,
  74 + //'sn' => 'test5 test6',
  75 + //'sn' => 'user3 ADMIN',
  76 + 'sn' => 'user3',
  77 + 'givenname' => 'ADMIN',
  78 + //'uid' => 'teste',
  79 + 'uid' => 'user3_ADMIN',
  80 + 'userpassword' => '$2y$10$VtYdA8Evkc.K.VpvqmF9wui5hc9ep19f8ukWBeFBIlunXSHPqw.K2',
  81 + 'mail' => 'teste@test.fr',
  82 + ],
  83 +
  84 + // Responsable
  85 + [
  86 + 'id' => 4,
  87 + //'sn' => 'test7 test8',
  88 + //'sn' => 'user4 RESP',
  89 + 'sn' => 'user4',
  90 + 'givenname' => 'RESP',
  91 + //'uid' => 'testr',
  92 + 'uid' => 'user4_RESP',
  93 + 'userpassword' => '$2y$10$VtYdA8Evkc.K.VpvqmF9wui5hc9ep19f8ukWBeFBIlunXSHPqw.K2',
  94 + 'mail' => 'testr@test.fr',
  95 + ],
  96 +
  97 + // User (simple user, authentified, but no priviledge)
  98 + [
  99 + 'id' => 5,
  100 + //'sn' => 'test9 test0',
  101 + //'sn' => 'user5 USER',
  102 + 'sn' => 'user5',
  103 + 'givenname' => 'USER',
  104 + //'uid' => 'testt',
  105 + 'uid' => 'user5_USER',
  106 + 'userpassword' => '$2y$10$VtYdA8Evkc.K.VpvqmF9wui5hc9ep19f8ukWBeFBIlunXSHPqw.K2',
  107 + 'mail' => 'testt@test.fr',
  108 + ],
  109 + ];
  110 +}
... ...
tests/Fixture/UsersFixture.php
... ... @@ -64,7 +64,7 @@ class UsersFixture extends TestFixture
64 64 'email' => 'user1_SUPER@test.fr',
65 65 'role' => 'Super Administrateur',
66 66 'groupes_metier_id' => 1,
67   - 'groupe_thematique_id' => 1
  67 + 'groupe_thematique_id' => 1
68 68 ],
69 69  
70 70 // Adminplus
... ... @@ -98,8 +98,8 @@ class UsersFixture extends TestFixture
98 98 // Responsable
99 99 [
100 100 'id' => 4,
101   - //'nom' => 'test7 test8',
102   - 'nom' => 'user4 RESP',
  101 + //'nom' => 'test7 test8',
  102 + 'nom' => 'user4 RESP',
103 103 //'username' => 'testr',
104 104 'username' => 'user4_RESP',
105 105 'password' => '$2y$10$VtYdA8Evkc.K.VpvqmF9wui5hc9ep19f8ukWBeFBIlunXSHPqw.K2',
... ...
tests/TestCase/Controller/EmpruntsControllerTest.php
... ... @@ -24,6 +24,7 @@ class EmpruntsControllerTest extends General
24 24 'app.sous_categories',
25 25 'app.groupes_thematiques',
26 26 'app.groupes_metiers',
  27 + 'app.fakeldapusers',
27 28 'app.users',
28 29 'app.organismes',
29 30 'app.sites',
... ...
tests/TestCase/Controller/General.php
... ... @@ -86,10 +86,12 @@ class General extends IntegrationTestCase {
86 86  
87 87 // Definition DIFFERENTE de celle de AppController
88 88 public function getUserRole() {
  89 + //return $this->ControllerMateriels->getUserRole();
89 90 if (! $this->CURRENT_ROLE) {
90 91 $user = TableRegistry::get('Users')->find()->where([
91 92 //'username' => 'user1_SUPER'
92   - 'username' => $this->_session['Auth']['User']['cn'][0]
  93 + //'username' => $this->_session['Auth']['User']['cn'][0]
  94 + 'username' => $this->_session['Auth']['User']['uid'][0]
93 95 ])->first();
94 96 // Unpriviledged user
95 97 $role = $user ? $user['role'] : "Utilisateur";
... ... @@ -97,9 +99,10 @@ class General extends IntegrationTestCase {
97 99 }
98 100 return $this->CURRENT_ROLE;
99 101 }
100   - // MEME Definition de celle de AppController (mais n'utilise la meme fonction getUserRole())
  102 + // MEME Definition de celle de AppController (mais n'utilise pas la meme fonction getUserRole())
101 103 public function userHasRole($expectedRole, $ORMORE=false) {
102 104 $role = $this->getUserRole();
  105 + //debug($role);
103 106 if (! $ORMORE) return ($role == $expectedRole);
104 107 return ($this->getRoleLevel($role) >= $this->getRoleLevel($expectedRole));
105 108 }
... ... @@ -170,9 +173,14 @@ class General extends IntegrationTestCase {
170 173 'givenname' => [
171 174 0 => $givenName
172 175 ],
  176 + /*
173 177 'cn' => [
174 178 0 => $cn
175 179 ],
  180 + */
  181 + 'uid' => [
  182 + 0 => $cn
  183 + ],
176 184 'userpassword' => [
177 185 0 => 'test'
178 186 ]
... ...
tests/TestCase/Controller/MaterielsControllerTest.php
... ... @@ -34,6 +34,7 @@ class MaterielsControllerTest extends General {
34 34 'app.sous_categories',
35 35 'app.groupes_thematiques',
36 36 'app.groupes_metiers',
  37 + 'app.fakeldapusers',
37 38 'app.users',
38 39 'app.organismes',
39 40 'app.sites',
... ... @@ -540,6 +541,7 @@ class MaterielsControllerTest extends General {
540 541 // AVANT add
541 542 $this->get('/materiels/index');
542 543 // USER ne voit pas les materiels ARCHIVED
  544 + //debug($this->USER_IS_ADMIN_AT_LEAST());
543 545 $nbmat = $this->USER_IS_ADMIN_AT_LEAST() ? 7 : 6;
544 546 $this->assertResponseContains("Liste des matériels (".$nbmat.")", $role);
545 547 //$this->post('/materiels/add', $this->newMaterielWithAllMandatoryFields);
... ...
tests/TestCase/Controller/PagesControllerTest.php
... ... @@ -29,6 +29,7 @@ class PagesControllerTest extends General
29 29 * @var array
30 30 */
31 31 public $fixtures = [
  32 + 'app.fakeldapusers',
32 33 'app.users',
33 34 'app.configurations',
34 35 ];
... ...
tests/TestCase/Controller/SuivisControllerTest.php
... ... @@ -24,6 +24,7 @@ class SuivisControllerTest extends General
24 24 'app.sous_categories',
25 25 'app.groupes_thematiques',
26 26 'app.groupes_metiers',
  27 + 'app.fakeldapusers',
27 28 'app.users',
28 29 'app.organismes',
29 30 'app.sites',
... ...
tests/TestCase/Controller/SurCategoriesControllerTest.php
... ... @@ -29,6 +29,7 @@ class SurCategoriesControllerTest extends General
29 29 * @var array
30 30 */
31 31 public $fixtures = [
  32 + 'app.fakeldapusers',
32 33 'app.users',
33 34 'app.configurations',
34 35 'app.sur_categories',
... ...
tests/TestCase/Controller/UsersControllerTest.php
... ... @@ -17,6 +17,7 @@ class UsersControllerTest extends General
17 17 * @var array
18 18 */
19 19 public $fixtures = [
  20 + 'app.fakeldapusers',
20 21 'app.users',
21 22 'app.groupes_metiers',
22 23 'app.materiels',
... ...
tests/TestCase/Model/Table/MaterielsTableTest.php
... ... @@ -30,6 +30,7 @@ class MaterielsTableTest extends TestCase
30 30 'app.sous_categories',
31 31 'app.groupes_thematiques',
32 32 'app.groupes_metiers',
  33 + 'app.fakeldapusers',
33 34 'app.users',
34 35 'app.organismes',
35 36 'app.sites',
... ...