Commit f98e0439 authored by THEO GUILLON's avatar THEO GUILLON
Browse files

Merge branch...

Merge branch '383-ameioration-de-la-gestion-des-exceptions-pour-l-experience-utilisateur-corrections-diverses' into '1.2.0'

Resolve "Améioration de la gestion des exceptions pour l'expérience utilisateur, corrections diverses liées aux tests (d'intégraton d'accès et fonctionnels automatisés)"

See merge request libriciel/pole-citoyens/web-DPO/web-DPO!354
parents d4dbbc5a 9cfa0495
......@@ -141,6 +141,10 @@ require ROOT . DS . 'vendors'. DS .'autoload.php';
spl_autoload_unregister(['App', 'load']);
spl_autoload_register(['App', 'load'], true, true);
// Gestion spéciale des exceptions pour qu'elles deviennent des messages flash dans l'interface
App::uses('UserFriendlyExceptionHandler', 'Lib');
UserFriendlyExceptionHandler::setUp();
//Configuration du plugin Cakeflow
Configure::write('Cakeflow.app', 'webdelib');
......
......@@ -54,7 +54,7 @@ class ReferersComponent extends Component {
$sessionKey = "{$this->settings['sessionKeyPrefix']}.{$here}";
$stored = $this->Session->read($sessionKey);
if (('/' !== $referer || null === $stored) && $stored !== $referer && $here !== $referer) {
if (('/' !== $referer || null === $stored) && $stored !== $referer && $here !== $referer && $controller->request->param('requested') === false) {
$this->Session->write($sessionKey, $referer);
}
......
......@@ -93,6 +93,8 @@ class FichesController extends AppController
} elseif ($action === 'ajax_update_listing_soustraitant') {
$this->Droits->assertAuthorized([ListeDroit::GESTION_SOUSTRAITANT_TRAITEMENT]);
$this->Droits->assertNotSu();
} elseif ($action === 'show') {
$this->Droits->assertNotSu();
}
/*elseif (in_array($action, $anyone) === false) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
......@@ -1094,15 +1096,7 @@ class FichesController extends AppController
*/
public function show($id)
{
$findTraitement = $this->Fiche->find('count',[
'conditions' => [
'id' => $id
]
]);
if (!$id || $findTraitement != 1) {
$this->Session->setFlash(__d('default', 'default.flasherrorTraitementInexistant'), 'flasherror');
$this->redirect($this->Referers->get());
}
$this->Droits->assertRecordAuthorized('Fiche', $id);
$this->requestAction([
'controller' => 'pannel',
......@@ -1119,7 +1113,7 @@ class FichesController extends AppController
'valeur'
]
]);
$this->set('title', __d('fiche', 'fiche.titreApercuFiche') . $nameTraitement['Valeur']['valeur']);
$this->set('title', __d('fiche', 'fiche.titreApercuFiche') . Hash::get($nameTraitement, 'Valeur.valeur'));
$fiche = $this->Fiche->find('first', [
'conditions' => [
......
......@@ -587,8 +587,6 @@ class PannelController extends AppController {
* @version V1.0.0
*/
public function supprimerLaNotif($idFiche) {
$this->Droits->assertRecordAuthorized('Fiche', $idFiche);
$success = true;
$this->Notification->begin();
......
......@@ -39,8 +39,8 @@ class RecettesController extends AppController {
'order' => ['Service.libelle']
],
'Soustraitant' => [
'fields' => ['Soustraitant.raisonsociale'],
'order' => ['Soustraitant.raisonsociale']
'fields' => ['Soustraitant.raisonsocialestructure'],
'order' => ['Soustraitant.raisonsocialestructure']
],
'Typage' => [
'fields' => ['Typage.libelle'],
......
......@@ -97,6 +97,7 @@ class RolesController extends AppController {
]
]);
$roleDPO_id = null;
foreach ($roles as $role) {
if ($this->_roleIsDpoRole($role['Role']['id']) === true) {
$roleDPO_id = $role['Role']['id'];
......
......@@ -1138,7 +1138,7 @@ class UsersController extends AppController {
public function ajax_password() {
// @fixme: vérifier que l'on soit en ajax
$this->autoRender = false;
$password = $this->request->data['password'];
$password = Hash::get($this->request->data, 'password');
$json = [
'entropie' => PasswordStrengthMeterAnssi::entropy($password),
'force' => PasswordStrengthMeterAnssi::strength($password),
......
<?php
App::uses('CakeRequest', 'Network');
App::uses('CakeResponse', 'Network');
App::uses('CakeSession', 'Model/Datasource');
App::uses('Configure', 'Core');
/**
* La classe UserFriendlyExceptionHandler permet de remplacer le gestionnaire d'exceptions pour transformer celles-ci
* en messages flash lorsque l'exception est de type 403 (ForbiddenException) ou 404 (MissingActionException,
* MissingControllerException, MissingPluginException ou NotFoundException).
*
* Usage, dans le fichier bootstrap.php:
* App::uses('UserFriendlyExceptionHandler', 'Lib');
* UserFriendlyExceptionHandler::setUp();
*/
class UserFriendlyExceptionHandler
{
public static function setUp() {
$originalExceptionHandler = Configure::read('Exception.handler');
Configure::write('Exception.handler', function ($exception) use ($originalExceptionHandler) {
static::customExceptionHandler($exception, $originalExceptionHandler);
});
}
public static function customExceptionHandler($exception, $originalExceptionHandler) {
$request = new CakeRequest();
if ($request->is('ajax') === true) {
$originalExceptionHandler($exception);
}
$message = $exception->getMessage();
if ($exception instanceof ForbiddenException) {
if ($message === 'Forbidden') {
$message = 'Vous n\'avez pas le droit d\'acceder à cette page';
}
} elseif ($exception instanceof MissingActionException) {
if (preg_match('/^Action .* could not be found/', $message) === 1) {
$message = 'Page non trouvée';
}
} elseif ($exception instanceof MissingControllerException) {
if (preg_match('/^Controller class .* could not be found/', $message) === 1) {
$message = 'Page non trouvée';
}
} elseif ($exception instanceof MissingPluginException) {
if (preg_match('/^Plugin .* could not be found/', $message) === 1) {
$message = 'Page non trouvée';
}
} elseif ($exception instanceof NotFoundException) {
if ($message === 'Not Found') {
$message = 'Enregistrement non trouvé';
}
} else {
$originalExceptionHandler($exception);
}
$connected = empty(CakeSession::read('Auth.User.id')) === false;
$superadmin = $connected && CakeSession::read('Su');
$current = Router::url(null, false);
$redirect = CakeSession::read('Auth.redirect');
if ($connected === false) {
$redirect = '/users/login';
} elseif ($redirect === null) {
$redirect = $request->referer(true);
}
// @see app/Config/routes.php et app/Controller/PannelController.php
if ($connected === true && $redirect === null && in_array($current, ['/', '/pannel', '/pannel/index']) === false) {
if ($superadmin === true) {
$redirect = '/pannel/superadmin';
} else {
$redirect = '/pannel/index';
}
}
if ($redirect !== null && $redirect !== $current) {
$count = count(Hash::extract((array)CakeSession::read(), 'Message.flash.{n}'));
//$exceptions = Hash::extract(CakeSession::read(), 'Message.flash.{n}[element=/error/]');
$flash = ['message' => $message, 'element' => 'flasherror'];
CakeSession::write(sprintf("Message.flash.%d", $count), $flash);
$response = new CakeResponse();
$response->header('Location', Router::url($redirect, true));
$response->statusCode(302);
$response->send();
} else {
$originalExceptionHandler($exception);
}
}
}
......@@ -591,21 +591,6 @@ msgstr "Ajout d'un sous-traitant"
msgid "fiche.emptySelectTypeFile"
msgstr "Séléctionnez un type pour le fichier"
###############################################################################
msgid ""
msgstr ""
"Project-Id-Version: web-DPO 1.2\n"
"PO-Revision-Date: 2020-04-03 12:00+0100\n"
"Last-Translator: Théo GUILLON <theo.guillon@libriciel.coop>\n"
"Language-Team: Théo GUILLON <theo.guillon@libriciel.coop>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n>1);\n"
# ======================================================================================================================
msgid "fiche.champRt_structure_raisonsociale"
......@@ -758,4 +743,4 @@ msgid "fiche.champFixDpoStructureSoustraitant"
msgstr "Téléphone fixe du DPO de la structure du sous-traitant"
msgid "fiche.champPortableDpoStructureSoustraitant"
msgstr "Téléphone portable du DPO de la structure du sous-traitant"
\ No newline at end of file
msgstr "Téléphone portable du DPO de la structure du sous-traitant"
......@@ -572,7 +572,7 @@ class Fiche extends AppModel implements LinkedOrganisationInterface {
* l'organisation + champ propre au formulaire + informations du DPO +
* information sur le déclarant au moment de la création du traitement
*/
foreach (json_decode($tabId, true) as $key => $id) {
foreach ((array)json_decode($tabId, true) as $key => $id) {
$donnees['traitement'][$key] = $this->_preparationGenerationValeurTraitement($id, $donnees['traitement'][$key], $historique);
}
......
......@@ -383,15 +383,15 @@ class PannelControllerTest extends ControllerTestCase
[200, 'Rédacteur.rjaune', '/pannel/supprimerLaNotif/1'],
[200, 'Valideur.cnoir', '/pannel/supprimerLaNotif/1'],
[200, 'Consultant.mrose', '/pannel/supprimerLaNotif/1'],
// Un utilisateur mono-collectivité ne peut pas accéder à l'enregistrement d'une autre collectivité
[403, 'Administrateur.findigo', '/pannel/supprimerLaNotif/1'],
[403, 'DPO.hvermeil', '/pannel/supprimerLaNotif/1'],
// Un utilisateur mono-collectivité peut accéder à l'enregistrement d'une autre collectivité
[200, 'Administrateur.findigo', '/pannel/supprimerLaNotif/1'],
[200, 'DPO.hvermeil', '/pannel/supprimerLaNotif/1'],
// 1.2. Enregistrement inexistant
[404, 'Administrateur.ibleu', '/pannel/supprimerLaNotif/666'],
[404, 'DPO.nroux', '/pannel/supprimerLaNotif/666'],
[404, 'Rédacteur.rjaune', '/pannel/supprimerLaNotif/666'],
[404, 'Valideur.cnoir', '/pannel/supprimerLaNotif/666'],
[404, 'Consultant.mrose', '/pannel/supprimerLaNotif/666'],
[200, 'Administrateur.ibleu', '/pannel/supprimerLaNotif/666'],
[200, 'DPO.nroux', '/pannel/supprimerLaNotif/666'],
[200, 'Rédacteur.rjaune', '/pannel/supprimerLaNotif/666'],
[200, 'Valideur.cnoir', '/pannel/supprimerLaNotif/666'],
[200, 'Consultant.mrose', '/pannel/supprimerLaNotif/666'],
// 2. Utilisateurs ne pouvant pas accéder à la fonctionnalité
// 1.1. Enregistrement existant
[403, 'Superadministrateur.superadmin', '/pannel/supprimerLaNotif/1'],
......
......@@ -30,6 +30,7 @@ class RegistresControllerTest extends ControllerTestCase
'app.Service',
'app.Soustraitant',
'app.TraitementRegistre',
'app.Typage',
'app.User',
'app.Valeur',
];
......@@ -162,13 +163,14 @@ class RegistresControllerTest extends ControllerTestCase
public function dataAccessRegistreActivite() {
return [
// Tous les utilisateurs peuvent accéder à la fonctionnalité
[302, 'Superadministrateur.superadmin', '/registres/registreActivite'],
// Utilisateurs pouvant accéder à la fonctionnalité
[302, 'Administrateur.ibleu', '/registres/registreActivite'],
[302, 'DPO.nroux', '/registres/registreActivite'],
[302, 'Rédacteur.rjaune', '/registres/registreActivite'],
[302, 'Valideur.cnoir', '/registres/registreActivite'],
[302, 'Consultant.mrose', '/registres/registreActivite'],
// Utilisateurs ne pouvant pas accéder à la fonctionnalité
[403, 'Superadministrateur.superadmin', '/registres/registreActivite'],
];
}
......@@ -181,13 +183,14 @@ class RegistresControllerTest extends ControllerTestCase
public function dataAccessRegistreSoustraitance() {
return [
// Tous les utilisateurs peuvent accéder à la fonctionnalité
[302, 'Superadministrateur.superadmin', '/registres/registreSoustraitance'],
// Utilisateurs pouvant accéder à la fonctionnalité
[302, 'Administrateur.ibleu', '/registres/registreSoustraitance'],
[302, 'DPO.nroux', '/registres/registreSoustraitance'],
[302, 'Rédacteur.rjaune', '/registres/registreSoustraitance'],
[302, 'Valideur.cnoir', '/registres/registreSoustraitance'],
[302, 'Consultant.mrose', '/registres/registreSoustraitance'],
// Utilisateurs ne pouvant pas accéder à la fonctionnalité
[403, 'Superadministrateur.superadmin', '/registres/registreSoustraitance'],
];
}
......
......@@ -241,6 +241,27 @@ class ListeDroitFixture extends CakeTestFixture {
'created' => '2020-06-10 00:15:34.567556',
'modified' => '2020-06-10 00:15:34.567556'
),
array(
'id' => 33,
'libelle' => 'Consulter tous les traitements dans l\'entité',
'value' => 33,
'created' => '2020-06-10 00:15:34.567556',
'modified' => '2020-06-10 00:15:34.567556'
),
array(
'id' => 34,
'libelle' => 'Gestion des co-responsables lors de la déclaration d\'un traitement',
'value' => 34,
'created' => '2020-06-10 00:15:34.567556',
'modified' => '2020-06-10 00:15:34.567556'
),
array(
'id' => 35,
'libelle' => 'Gestion des sous-traitants lors de la déclaration d\'un traitement',
'value' => 35,
'created' => '2020-06-10 00:15:34.567556',
'modified' => '2020-06-10 00:15:34.567556'
),
);
}
......@@ -1817,6 +1817,51 @@ class RoleDroitFixture extends CakeTestFixture {
'role_id' => 25,
'liste_droit_id' => 32
),
array(
'id' => 361,
'role_id' => 5,
'liste_droit_id' => 33
),
array(
'id' => 362,
'role_id' => 5,
'liste_droit_id' => 34
),
array(
'id' => 363,
'role_id' => 5,
'liste_droit_id' => 35
),
array(
'id' => 364,
'role_id' => 10,
'liste_droit_id' => 33
),
array(
'id' => 365,
'role_id' => 10,
'liste_droit_id' => 34
),
array(
'id' => 366,
'role_id' => 10,
'liste_droit_id' => 35
),
array(
'id' => 367,
'role_id' => 15,
'liste_droit_id' => 33
),
array(
'id' => 368,
'role_id' => 15,
'liste_droit_id' => 34
),
array(
'id' => 369,
'role_id' => 15,
'liste_droit_id' => 35
),
);
}
......@@ -19,79 +19,157 @@ class SoustraitantFixture extends CakeTestFixture {
public $records = array(
array(
'id' => 1,
'raisonsociale' => 'Commission nationale de l\'informatique et des libertés',
'siret' => '75000000000000',
'ape' => '8411Z',
'telephone' => null,
'fax' => null,
'adresse' => null,
'email' => null,
'raisonsocialestructure' => 'Commission nationale de l\'informatique et des libertés',
'siretstructure' => '75000000000000',
'apestructure' => '8411Z',
'telephonestructure' => null,
'faxstructure' => null,
'adressestructure' => null,
'emailstructure' => null,
'civiliteresponsable' => null,
'prenomresponsable' => null,
'nomresponsable' => null,
'emailresponsable' => null,
'telephoneresponsable' => null,
'fonctionresponsable' => null,
'civility_dpo' => null,
'prenom_dpo' => null,
'nom_dpo' => null,
'numerocnil_dpo' => null,
'email_dpo' => null,
'telephonefixe_dpo' => null,
'telephoneportable_dpo' => null,
'createdbyorganisation' => null,
'created' => '2020-06-10 00:20:42',
'modified' => '2020-06-10 00:21:14'
),
array(
'id' => 2,
'raisonsociale' => 'Commission nationale de concertation',
'siret' => '83000000000000',
'ape' => '8411Z',
'telephone' => null,
'fax' => null,
'adresse' => null,
'email' => null,
'raisonsocialestructure' => 'Commission nationale de concertation',
'siretstructure' => '83000000000000',
'apestructure' => '8411Z',
'telephonestructure' => null,
'faxstructure' => null,
'adressestructure' => null,
'emailstructure' => null,
'civiliteresponsable' => null,
'prenomresponsable' => null,
'nomresponsable' => null,
'emailresponsable' => null,
'telephoneresponsable' => null,
'fonctionresponsable' => null,
'civility_dpo' => null,
'prenom_dpo' => null,
'nom_dpo' => null,
'numerocnil_dpo' => null,
'email_dpo' => null,
'telephonefixe_dpo' => null,
'telephoneportable_dpo' => null,
'createdbyorganisation' => null,
'created' => '2020-06-10 00:20:45',
'modified' => '2020-06-10 00:21:16'
),
array(
'id' => 4,
'raisonsociale' => 'Commission nationale du débat public',
'siret' => '08100000000000',
'ape' => '8411Z',
'telephone' => null,
'fax' => null,
'adresse' => null,
'email' => null,
'raisonsocialestructure' => 'Commission nationale du débat public',
'siretstructure' => '08100000000000',
'apestructure' => '8411Z',
'telephonestructure' => null,
'faxstructure' => null,
'adressestructure' => null,
'emailstructure' => null,
'civiliteresponsable' => null,
'prenomresponsable' => null,
'nomresponsable' => null,
'emailresponsable' => null,
'telephoneresponsable' => null,
'fonctionresponsable' => null,
'civility_dpo' => null,
'prenom_dpo' => null,
'nom_dpo' => null,
'numerocnil_dpo' => null,
'email_dpo' => null,
'telephonefixe_dpo' => null,
'telephoneportable_dpo' => null,
'createdbyorganisation' => null,
'created' => '2020-06-10 00:20:50',
'modified' => '2020-06-10 00:20:50'
),
array(
'id' => 5,
'raisonsociale' => 'Commune d\'Assas',
'siret' => '16100000000000',
'ape' => '8411Z',
'telephone' => null,
'fax' => null,
'adresse' => null,
'email' => null,
'raisonsocialestructure' => 'Commune d\'Assas',
'siretstructure' => '16100000000000',
'apestructure' => '8411Z',
'telephonestructure' => null,
'faxstructure' => null,
'adressestructure' => null,
'emailstructure' => null,
'createdbyorganisation' => 1,
'civiliteresponsable' => null,
'prenomresponsable' => null,
'nomresponsable' => null,
'emailresponsable' => null,
'telephoneresponsable' => null,
'fonctionresponsable' => null,
'civility_dpo' => null,
'prenom_dpo' => null,
'nom_dpo' => null,
'numerocnil_dpo' => null,
'email_dpo' => null,
'telephonefixe_dpo' => null,
'telephoneportable_dpo' => null,
'created' => '2020-06-10 00:21:02',
'modified' => '2020-06-10 00:21:30'
),
array(
'id' => 6,
'raisonsociale' => 'Commune de Castelnau-le-Lez',
'siret' => '24100000000000',
'ape' => '8411Z',
'telephone' => null,
'fax' => null,
'adresse' => null,
'email' => null,
'raisonsocialestructure' => 'Commune de Castelnau-le-Lez',
'siretstructure' => '24100000000000',
'apestructure' => '8411Z',
'telephonestructure' => null,
'faxstructure' => null,
'adressestructure' => null,
'emailstructure' => null,
'createdbyorganisation' => 1,
'civiliteresponsable' => null,
'prenomresponsable' => null,
'nomresponsable' => null,
'emailresponsable' => null,
'telephoneresponsable' => null,
'fonctionresponsable' => null,
'civility_dpo' => null,
'prenom_dpo' => null,
'nom_dpo' => null,
'numerocnil_dpo' => null,
'email_dpo' => null,
'telephonefixe_dpo' => null,
'telephoneportable_dpo' => null,
'created' => '2020-06-10 00:21:05',
'modified' => '2020-06-10 00:21:33'
),
array(
'id' => 8,
'raisonsociale' => 'Commune du Crès',
'siret' => '40100000000000',
'ape' => '8411Z',
'telephone' => null,
'fax' => null,
'adresse' => null,
'email' => null,
'raisonsocialestructure' => 'Commune du Crès',
'siretstructure' => '40100000000000',
'apestructure' => '8411Z',
'telephonestructure' => null,
'faxstructure' => null,
'adressestructure' => null,
'emailstructure' => null,
'createdbyorganisation' => 1,
'civiliteresponsable' => null,
'prenomresponsable' => null,
'nomresponsable' => null,
'emailresponsable' => null,
'telephoneresponsable' => null,
'fonctionresponsable' => null,
'civility_dpo' => null,
'prenom_dpo' => null,
'nom_dpo' => null,
'numerocnil_dpo' => null,
'email_dpo' => null,
'telephonefixe_dpo' => null,
'telephoneportable_dpo' => null,
'created' => '2020-06-10 00:21:12',
'modified' => '2020-06-10 00:21:12'
),
......
......@@ -202,7 +202,7 @@ $line = 1;
$checked = $val == $this->request->data("{$modelName}.{$fieldName}") ? ' checked="checked"' : '';
echo '<div class="radio">
<input type="radio" id="'.$options['name'].$key.'" name="data['.$modelName.']['.$fieldName.']" value="'.$val.'" '.$checked.'>
'.$val.'
<label for="'.$options['name'].$key.'">'.$val.'</label>
</div>';
}
?>
......@@ -447,4 +447,4 @@ $line = 1;
};
});
})(jQuery);
</script>
\ No newline at end of file
</script>