diff --git a/PUSH_MODIFS b/PUSH_MODIFS new file mode 100755 index 0000000..e9a12d2 --- /dev/null +++ b/PUSH_MODIFS @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# 1) Mise à jour du code source actuel +./UPDATE + +exit +# 2) Envoi de mes modifs (sur la branche en cours, a priori master) +git add . +git commit -m "Ajout de mes modifications" +git push + diff --git a/README.md b/README.md index e73f258..d25e15b 100644 --- a/README.md +++ b/README.md @@ -45,12 +45,14 @@ Logiciel testé et validé sur les configurations suivantes : VERSION ACTUELLE Date: 03/07/2020 -Version: 3.7.9.55 (en cours) +Version: 3.7.9.55 Author: EP Commentaire: - Fichier LICENSE (AGPL) - Conditions d'utilisation à accepter lors de l'installation - script ./INSTALLATION + - Mode "nolimit" dans la config ("Superadmin a tous les droits", depuis menu Tools) + - Ajout d'un "alias" pour décrire chaque action de chaque controleur - Amélioration page /pages/acls - Tests génériques automatiques pour (presque) toutes les actions de (presque) tous les controleurs principaux (Materiels, Suivis, Emprunts, Users) mais aussi du controleur "quelconque" SurCategories (pour vérifier que ça marche aussi !!!) diff --git a/database/update/db-update-2020-07-06.sh b/database/update/db-update-2020-07-06.sh new file mode 100755 index 0000000..0a806d5 --- /dev/null +++ b/database/update/db-update-2020-07-06.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +#myname=`basename $0 .sh` +myname=`basename $0` +myname=${myname%%.*} + +# Pour Mac OS recent (>=10.10, Yosemite), la syntaxe du SED est differente +# Il faut donc exécuter ce script de la manière suivante : +# ./macos-db-update.sh + + +function abort() { + echo "******************************************************" + echo "!!! Script $0 aborté à cause d'une erreur d'exécution !!!" + echo "******************************************************" + exit 1 +} + + +if [ ! -f ../../config/app.php ] ; then +echo "Vous devez executer ce script depuis le dossier database/update/" +exit 1 +fi + + +# Get login, pass, dbname, and hostname +username=$(grep "/\*d\*/'username'" ../../config/app.php | cut -d"'" -f4) || abort +password=$(grep "/\*d\*/'password'" ../../config/app.php | cut -d"'" -f4) || abort +database=$(grep "/\*d\*/'database'" ../../config/app.php | cut -d"'" -f4) || abort +host=$(grep "/\*d\*/'host'" ../../config/app.php | cut -d"'" -f4) || abort + + +#cp -p ./script_sql/db-update-2016-07-01-irap.sql ./script_sql/db-update-2016-07-01-irap-build.sql +cp -p ./script_sql/$myname.sql ./script_sql/$myname-build.sql || abort + +# Execute sql update script +sed -e "s/database/$database/" -i ./script_sql/$myname-build.sql || abort +mysql --user=$username --password=$password -h $host < ./script_sql/$myname-build.sql || abort + +# Delete temporary file and cakephp cache (-f avoids warning if no file) +rm -f ./script_sql/$myname-build.sql +sudo rm -f ../../tmp/cache/models/* +sudo rm -f ../../tmp/cache/persistent/* + +# Faire ca aussi si ca suffit pas... +#sudo chmod -R 777 ../../tmp +#sudo chmod -R 777 ../../vendor +#sudo chmod -R 777 ../../webroot + + +# PLUGIN update +# Installation plugin cakephp-dompdf +# (on va a la racine du projet) +#cd ../../ +#php composer.phar require daoandco/cakephp-dompdf +#bin/cake plugin assets symlink +#cd - diff --git a/database/update/script_sql/db-update-2020-07-06.sql b/database/update/script_sql/db-update-2020-07-06.sql new file mode 100755 index 0000000..a46f13f --- /dev/null +++ b/database/update/script_sql/db-update-2020-07-06.sql @@ -0,0 +1,5 @@ +use database; + +-- Table config +-- 06/07/20 : ajout mode "no limit" pour superadmin +ALTER TABLE `configurations` ADD `mode_nolimit` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'superadmin a tous les droits' AFTER `mode_debug`; \ No newline at end of file diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index 8a62a94..2bff346 100755 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -71,8 +71,9 @@ class AppController extends Controller // Permet à un test de forcer (si true) le re-chargement d'une entité (car modifiée en BD) protected static $RELOAD = FALSE; + // (EP 202007) passé dans la table configuration => "mode_nolimit" // Il suffit de passer ceci à true pour TOUT autoriser à superadmin - protected $SUPERADMIN_CAN_DO_EVERYTHING = false; // (prod) Par défaut (false), il se comporte un peu comme ADMIN + //protected $SUPERADMIN_CAN_DO_EVERYTHING = false; // (prod) Par défaut (false), il se comporte un peu comme ADMIN //protected $SUPERADMIN_CAN_DO_EVERYTHING = true; // (dev only) no limit, peut TOUT faire (attention, pas en prod svp !!!) protected $confLabinvent = null; @@ -148,6 +149,7 @@ class AppController extends Controller * ... */ + 'alias' => '', 'default' => 0, 'user' => 'default', 'resp' => 'default', @@ -179,6 +181,7 @@ class AppController extends Controller ]; // default_authorizations + /* const default_authorizations_adminonly = [ 'default' => 0, 'user' => -1, @@ -187,6 +190,7 @@ class AppController extends Controller 'adminp' => 'default', 'super' => 'default' ]; + */ /* * Tableau des autorisations pour les actions du controleur @@ -195,10 +199,11 @@ class AppController extends Controller * * On l'initialise déjà avec les actions autorisées par défaut * On le complètera ensuite pour les autres actions - */ //protected $is_authorized_action = []; // Pour tous les controleurs - protected $is_authorized_action = [ + */ + protected $is_authorized_action = []; + /* // autorisé pour tous : 'index' => self::default_authorizations, 'view' => self::default_authorizations, @@ -209,8 +214,8 @@ class AppController extends Controller 'delete' => self::default_authorizations_adminonly, // Uniquement pour le controleur de pages PagesController (1 seule action autorisée : display) //'display' => self::default_authorizations, - ]; + */ @@ -366,8 +371,19 @@ class AppController extends Controller //$roles_short = ['default', 'user', 'resp', 'admin', 'adminp', 'super']; $roles_short = ['user', 'resp', 'admin', 'adminp', 'super']; + $alias = ''; + $action_and_alias = explode('(',$action); + if (count($action_and_alias)==2) { + $action = trim($action_and_alias[0]); + $alias = substr($action_and_alias[1],0,-1); + } + //debug("action=$action, alias=$alias"); + // initialisation du tableau pour cette action pour le controleur spécifique en cours $this->is_authorized_action[$action] = self::default_authorizations; + // Ajout de l'alias dans le tableau des autorisations pour cette action + $this->is_authorized_action[$action]['alias'] = $alias; + // (raccourci) Reference vers le tableau $action_rules = &$this->is_authorized_action[$action]; @@ -515,6 +531,7 @@ class AppController extends Controller // WRAPPER sur tableau des autorisations is_authorized_action[] public function getAccessConditionForActionAndRole($action, $role) { + //debug($this->is_authorized_action[$action]); // Si pas de règle définie pour l'action => accès interdit if (!isset($this->is_authorized_action[$action][$role])) return -1; //throw new \ErrorException("L'action '$action' n'a pas de condition d'accès définie dans le controleur $this->name (role '$role') !!"); @@ -553,7 +570,8 @@ class AppController extends Controller $role_long = $this->getUserRole($user); $this->d("*************************** CONTROLEUR ".$this->name.", ACTION $action, ROLE $role_long, id=$id, related_matos_id=$related_matos_id"); //$this->d("********* USER :"); $this->d2($user); - if ($this->SUPERADMIN_CAN_DO_EVERYTHING) return TRUE; + //if ($this->SUPERADMIN_CAN_DO_EVERYTHING) return TRUE; + if ($this->confLabinvent->mode_nolimit) return TRUE; //if ($action=='statusTobearchived'); exit; //$m = ($m_id) ? $this->getCurrentMateriel($m_id) : null; @@ -587,6 +605,7 @@ class AppController extends Controller //debug("role is $role"); //$access_condition = $this->is_authorized_action[$action][$role]; $access_condition = $this->getAccessConditionForActionAndRole($action,$role); + $this->d("0) Condition (complète) (NOT desaliased) :"); $this->d($access_condition); //debug($this->is_authorized_action); //debug($this->is_authorized_action[$action]); //debug("access_condition"); debug($access_condition); @@ -642,6 +661,7 @@ class AppController extends Controller //$condition_on_status_result = $this->eval_condition_on_status($condition_on_status, $id, $action, $m); //$condition_on_status_result = $this->eval_condition_on_status($condition_on_status, $id, $action, $m); //$condition_on_status_result = $this->eval_condition_on_status($condition_on_status, $id, $action, $IS_RELATED_ENTITY_ID, $m); + //debug("condition");debug($condition_on_status); exit; $condition_on_status_result = $this->eval_condition_on_status($condition_on_status, $id, $action, $related_matos_id, $m); } $this->d("$condition_on_status evalué à "); $this->d2($condition_on_status_result); @@ -1561,6 +1581,9 @@ class AppController extends Controller if (is_null($this->confLabinvent)) throw new \Exception("EXCEPTION: La table 'configurations' de la base de données est vide"); // Initialisation des autorisations pour les actions du controleur + // 1) Initialisation des autorisations par défaut du parent (AppController) + $this->setDefaultAuthorizations(); + // 2) Ajout des autorisations spécifiques par le controleur courant $SPECIFIC_METHOD_EXISTS = false; if ($this->confLabinvent->labNameShort) { $labshortname = $this->confLabinvent->labNameShort; @@ -1583,6 +1606,52 @@ class AppController extends Controller // Méthode à spécialiser dans chaque controleur // Sinon, par défaut c'est celle-ci qui est utilisée et elle ne fait rien ! protected function setAuthorizations() {} + + // Actions autorisées par défaut pour TOUS les controleurs + protected function setDefaultAuthorizations() { + + // autorisé pour tous + $this->setAuthorizationsForAction('index (liste générale)', 0); + $this->setAuthorizationsForAction('view (vue détaillée)', 0); + $this->setAuthorizationsForAction('find (rechercher)', 0); + /* + $this->setAuthorizationsForAction('index', 0); + $this->setAuthorizationsForAction('view', 0); + $this->setAuthorizationsForAction('find', 0); + */ + + // admin(+) only : + $this->setAuthorizationsForAction('add(créer)', 0, [ + //$this->setAuthorizationsForAction('add', 0, [ + 'user' => -1, + 'resp' => -1, + ]); + $this->setAuthorizationsForAction('edit (modifier)', 0, [ + //$this->setAuthorizationsForAction('edit', 0, [ + 'user' => -1, + 'resp' => -1, + ]); + $this->setAuthorizationsForAction('delete (supprimer)', 0, [ + //$this->setAuthorizationsForAction('delete', 0, [ + 'user' => -1, + 'resp' => -1, + ]); + //debug($this->is_authorized_action);exit; + + } + + + + + + + + + + + + + protected function getCurrentUserName() { //debug($this->LdapAuth->user('id')); exit; diff --git a/src/Controller/ConfigurationsController.php b/src/Controller/ConfigurationsController.php index 0e14961..ab78e29 100644 --- a/src/Controller/ConfigurationsController.php +++ b/src/Controller/ConfigurationsController.php @@ -31,7 +31,10 @@ class ConfigurationsController extends AppController foreach (['add', 'index', 'find', 'delete'] as $action) unset($this->is_authorized_action[$action]); // Actions autorisées seulement à superadmin - foreach (['view', 'edit', 'debugOn', 'debugOff'] as $action) $this->setAuthorizationsForAction($action, -1, ['super'=>0]); + foreach (['view', 'edit', 'nolimit', 'debugOn', 'debugOff'] as $action) $this->setAuthorizationsForAction($action, -1, ['super'=>0]); + + // Actions autorisées à tous + foreach (['installOn', 'installOff'] as $action) $this->setAuthorizationsForAction($action, 0); } @@ -229,4 +232,26 @@ class ConfigurationsController extends AppController 'action' => 'tools' ]); } + + /** + * Activation/Désactivation du mode no limit (SA a tous les droits) + * Action à "bascule" ON/OFF (Si ON => OFF, si OFF => ON) + * + */ + public function nolimit() + { + //$this->SUPERADMIN_CAN_DO_EVERYTHING = ! $this->SUPERADMIN_CAN_DO_EVERYTHING; + $config = $this->Configurations->get(1); + $config->mode_nolimit = ! $config->mode_nolimit; + $verb = $config->mode_nolimit ? "activé":"désactivé"; + if ($this->Configurations->save($config)) { + $this->Flash->success(__("Le mode 'SuperAdmin a tous les droits' est $verb")); + } + return $this->redirect([ + 'controller' => 'pages', + 'action' => 'tools' + ]); + } + + } diff --git a/src/Controller/MaterielsController.php b/src/Controller/MaterielsController.php index 077b42b..6c71f55 100755 --- a/src/Controller/MaterielsController.php +++ b/src/Controller/MaterielsController.php @@ -280,13 +280,14 @@ class MaterielsController extends AppController { $this->setAuthorizations(); // 2) Puis on fait nos petites règles locales pour notre labo à nous tout seul + /* // - Adaptation de la règle pour "ajout par copie" - $this->setAuthorizationsForAction('add_by_copy', ['CREATED',0], [ + $this->setAuthorizationsForAction('add_by_copy', '', ['CREATED',0], [ 'user' => ['CREATED',1], 'resp' => 'default', ]); // - Adaptation de la règle pour "edit" (modif d'un matériel) - $this->setAuthorizationsForAction('edit', ['CREATED',0], [ + $this->setAuthorizationsForAction('edit', '', ['CREATED',0], [ 'user' => ['CREATED',1], //'user' => [0,1], //'user' => 0, @@ -296,6 +297,7 @@ class MaterielsController extends AppController { //$admin = 'default', //$super = 'default' // + champs techniques ]); + */ } // Méthode de définition des autorisations SPÉCIFIQUES au laboratoire CRAL protected function setAuthorizations_CRAL() { @@ -380,11 +382,11 @@ class MaterielsController extends AppController { // Action 'add' (ajout d'un nouveau matériel) => autorisé pour tous //$this->setAuthorizationsForAction('add', 0); - $this->setAuthorizationsForAction('add', 0); + $this->setAuthorizationsForAction('add (créer)', 0); //$this->setAuthorizationsForAction('view', 0); // Action 'add' (ajout d'un nouveau matériel par copie d'un autre) - $this->setAuthorizationsForAction('add_by_copy', ['CREATED',0], [ + $this->setAuthorizationsForAction('add_by_copy (ajout par copie)', ['CREATED',0], [ 'user' => ['CREATED',1], //'resp' => ['CREATED',0], //'resp' => 'default', @@ -412,7 +414,7 @@ class MaterielsController extends AppController { */ // Action 'edit' (modif d'un matériel) - $this->setAuthorizationsForAction('edit', ['CREATED',0], [ + $this->setAuthorizationsForAction('edit (modifier)', ['CREATED',0], [ 'user' => ['CREATED',1], 'resp' => 'user', //'resp' => -1, @@ -423,18 +425,19 @@ class MaterielsController extends AppController { ]); // Action 'delete' (suppression d'un matériel) - $this->setAuthorizationsForAction('delete', ['CREATED',1]); + $this->setAuthorizationsForAction('delete (supprimer)', ['CREATED',1]); // Action 'devalidate' ou 'invalidate' (repasser le matériel au statut 'CREATED', c'est à dire le dé-valider ou l'invalider) // (VALIDATED ou TBA ou ARCHIVED) => CREATED //$this->setAuthorizationsForAction('devalidate', - $this->setAuthorizationsForAction('statusCreated', ['NOT CREATED',0], [ + $this->setAuthorizationsForAction('statusCreated (dévalider)', ['NOT CREATED',0], [ 'user' => -1, // PAS AUTORISÉ 'resp' => ['NOT CREATED',1] ]); // Action 'updgrade' (avancement du statut d'un matériel) // CREATED => VALIDATED => TBA => ARCHIVED + /* $this->setAuthorizationsForAction('upgrade', ['NOT ARCHIVED',0], [ // En fait, l'action fait juste passer au statut "suivant" //$default = ['PREVIOUS',0], // le matériel doit avoir le statut "précédent" du statut actuel 'user' => ['VALIDATED',1], // SEULEMENT l'action "demande d'archivage" @@ -442,14 +445,15 @@ class MaterielsController extends AppController { //'resp' => 'Utilisateur' 'resp' => 'user' ]); + */ // Action 'updgrade' (avancement du statut d'un matériel) // - Validation d'un materiel (passe à VALIDATED) : CREATED => VALIDATED - $this->setAuthorizationsForAction('statusValidated', ['CREATED',0], [ + $this->setAuthorizationsForAction('statusValidated (valider)', ['CREATED',0], [ 'user' => -1, // interdit 'resp' => -1 // interdit ]); // - Demande d'archivage : VALIDATED => TBA - $this->setAuthorizationsForAction('statusTobearchived', ['VALIDATED',0], [ + $this->setAuthorizationsForAction("statusTobearchived (demander l'archivage)", ['VALIDATED',0], [ //$user = ['default',1], 'user' => ['VALIDATED',1], //$resp = ['default',1] @@ -457,14 +461,14 @@ class MaterielsController extends AppController { 'resp' => 'user' ]); // - Archivage : TBA => ARCHIVED - $this->setAuthorizationsForAction('statusArchived', ['TOBEARCHIVED',0], [ + $this->setAuthorizationsForAction('statusArchived (archiver)', ['TOBEARCHIVED',0], [ 'user' => -1, // interdit 'resp' => -1 // interdit ]); // Action 'printLabelRuban' (impression d'une étiquette) - $this->setAuthorizationsForAction('printLabelRuban', ['VALIDATED && conf.hasPrinter',0] ); - $this->setAuthorizationsForAction('setLabelIsPlaced', ['VALIDATED && conf.hasPrinter',0] ); + $this->setAuthorizationsForAction('printLabelRuban (imprimer étiquette)', ['VALIDATED && conf.hasPrinter',0] ); + $this->setAuthorizationsForAction('setLabelIsPlaced (déclarer étiquette collée)', ['VALIDATED && conf.hasPrinter',0] ); $this->setAuthorizationsForAction('setLabelIsNotPlaced', ['VALIDATED && conf.hasPrinter',0] ); /* $this->setAuthorizationsForAction('setLabelIsPlaced', 0); // autorisé sans condition @@ -482,13 +486,17 @@ class MaterielsController extends AppController { 'user' => -1 // interdit ]); $this->setAuthorizationsForAction('getDateGarantie', 0); // autorisé sans condition - + /* // Action 'ficheMateriel' $this->setAuthorizationsForAction('createDocFicheMateriel', 0); // Action 'ficheMaterielPdf' // DOMPDF $this->setAuthorizationsForAction('createDocFicheMaterielPdf', 0); + */ + + //debug($this->is_authorized_action);exit; + } // _setAuthorizations() diff --git a/src/Controller/PagesController.php b/src/Controller/PagesController.php index 02c3dd6..b4b77b7 100755 --- a/src/Controller/PagesController.php +++ b/src/Controller/PagesController.php @@ -277,13 +277,19 @@ class PagesController extends AppController //debug($level); $this->set(compact('level', 'info_levels', 'error_levels')); } - + if ($this->page=='acls') { $lab_name = $this->confLabinvent->labNameShort; if (!$lab_name) $lab_name = 'NOM_DU_LABO'; $this->set(compact('lab_name')); } + if ($this->page=='tools') { + // Mode 'SA a tous les droits' + $no_limit_mode = $this->confLabinvent->mode_nolimit; + $this->set(compact('no_limit_mode')); + } + //debug(implode('/', $path)); //debug(implode('/', array($page,$subpage))); diff --git a/src/Template/Pages/acls.ctp b/src/Template/Pages/acls.ctp index 6502be3..07b3d30 100755 --- a/src/Template/Pages/acls.ctp +++ b/src/Template/Pages/acls.ctp @@ -98,14 +98,19 @@ function displayAuthorizationsForController($c, $lab_name) { ?> - - + + + Html->link('Configuration générale de l\'application', [ 'controller' => 'configurations', 'action' => 'view', - 1 ]); echo ''; endif; @@ -128,8 +127,18 @@ if ($role == 'Super Administrateur') : ]); } echo ''; + + // SA a tous les droits, non mais... + echo ''; + $verb = $no_limit_mode ? 'Stopper':'Activer'; + echo $this->Html->link("$verb le mode 'Superadmin a tous les droits' (pour debug only)", [ + //'controller' => 'pages', + 'controller' => 'configurations', + 'action' => 'nolimit' + ]); + echo ''; -endif; +endif; // SA only ?> diff --git a/tests/Fixture/ConfigurationsFixture.php b/tests/Fixture/ConfigurationsFixture.php index b9d6b4a..6261d95 100644 --- a/tests/Fixture/ConfigurationsFixture.php +++ b/tests/Fixture/ConfigurationsFixture.php @@ -25,6 +25,7 @@ class ConfigurationsFixture extends TestFixture 'nom' => ['type' => 'string', 'length' => 45, 'null' => false, 'default' => null, 'comment' => 'obligatoire (et unique)', 'precision' => null, 'fixed' => null], 'mode_install' => ['type' => 'boolean', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null], 'mode_debug' => ['type' => 'boolean', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null], + 'mode_nolimit' => ['type' => 'boolean', 'length' => null, 'null' => false, 'default' => false, 'comment' => '', 'precision' => null], 'ldap_used' => ['type' => 'boolean', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null], 'ldap_host' => ['type' => 'text', 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null], 'ldap_port' => ['type' => 'string', 'length' => 10, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null], @@ -85,6 +86,7 @@ class ConfigurationsFixture extends TestFixture 'nom' => 'Lorem ipsum dolor sit amet', 'mode_install' => 0, 'mode_debug' => 0, + 'mode_nolimit' => 0, 'ldap_used' => 0, 'ldap_host' => 'Lorem ipsum dolor sit amet', -- libgit2 0.21.2