Commit 097baaeb authored by David Surville's avatar David Surville
Browse files

Refonte des pages de gestion des comptes locaux et de la création/oubli du mot de passe

parent 64bce4a6
Loading
Loading
Loading
Loading
+91 −64
Original line number Diff line number Diff line
<?php

use Laminas\Router\Http\Literal;
use Laminas\Router\Http\Segment;
use UnicaenPrivilege\Guard\PrivilegeController;
use UnicaenUtilisateur\Controller\UtilisateurController;
use UnicaenUtilisateur\Controller\UtilisateurControllerFactory;
use UnicaenUtilisateur\Form\User\InitCompteForm;
use UnicaenUtilisateur\Form\User\PasswordEnregistrementForm;
use UnicaenUtilisateur\Form\User\PasswordRecuperationForm;
use UnicaenUtilisateur\Form\User\PasswordRecuperationFormFactory;
use UnicaenUtilisateur\Form\User\UserForm;
use UnicaenUtilisateur\Form\User\UserFormFactory;
use UnicaenUtilisateur\Form\User\UserHydrator;
@@ -16,8 +20,8 @@ use UnicaenUtilisateur\Service\Role\RoleService;
use UnicaenUtilisateur\Service\Role\RoleServiceFactory;
use UnicaenUtilisateur\Service\User\UserService;
use UnicaenUtilisateur\Service\User\UserServiceFactory;
use Laminas\Router\Http\Literal;
use Laminas\Router\Http\Segment;
use UnicaenUtilisateur\View\Helper\UserRole;
use UnicaenUtilisateur\View\Helper\UserRoleFactory;

return [

@@ -37,9 +41,8 @@ return [
                [
                    'controller' => UtilisateurController::class,
                    'action' => [
                        'changer-mot-de-passe',
                    ],
                    'roles' => [
                        'enregistrer-mot-de-passe',
                        'recuperer-mot-de-passe',
                    ],
                ],
                [
@@ -140,6 +143,29 @@ return [
                            ],
                        ],
                    ],
                    'enregistrer-mot-de-passe' => [
                        'type' => Segment::class,
                        'options' => [
                            'route' => '/enregistrer-mot-de-passe/:token',
                            'defaults' => [
                                'controller' => UtilisateurController::class,
                                'action' => 'enregistrer-mot-de-passe',
                            ],
                            'constraints' => [
                                'utilisateur' => '[a-z0-9-]+',
                            ],
                        ],
                    ],
                    'recuperer-mot-de-passe' => [
                        'type' => Literal::class,
                        'options' => [
                            'route' => '/recuperer-mot-de-passe',
                            'defaults' => [
                                'controller' => UtilisateurController::class,
                                'action' => 'recuperer-mot-de-passe',
                            ],
                        ],
                    ],
                    'exporter' => [
                        'type' => Literal::class,
                        'options' => [
@@ -317,11 +343,12 @@ return [
    'form_elements' => [
        'invokables' => [
            UserRechercheForm::class => UserRechercheForm::class,
            InitCompteForm::class => InitCompteForm::class,
            PasswordEnregistrementForm::class => PasswordEnregistrementForm::class,
        ],
        'factories' => [
            UserForm::class => UserFormFactory::class,
            UserRoleForm::class => UserRoleFormFactory::class,
            PasswordRecuperationForm::class => PasswordRecuperationFormFactory::class
        ],
    ],

+78 −18
Original line number Diff line number Diff line
@@ -12,11 +12,13 @@ use UnicaenApp\View\Model\CsvModel;
use UnicaenPrivilege\Service\Perimetre\PerimetreServiceAwareTrait;
use UnicaenUtilisateur\Entity\Db\RoleInterface;
use UnicaenUtilisateur\Exception\RuntimeException;
use UnicaenUtilisateur\Form\User\InitCompteFormAwareTrait;
use UnicaenUtilisateur\Form\User\PasswordEnregistrementFormAwareTrait;
use UnicaenUtilisateur\Form\User\PasswordRecuperationFormAwareTrait;
use UnicaenUtilisateur\Form\User\UserFormAwareTrait;
use UnicaenUtilisateur\Form\User\UserRechercheFormAwareTrait;
use UnicaenUtilisateur\Form\User\UserRoleFormAwareTrait;
use UnicaenUtilisateur\Form\User\UserRolePerimetreFormAwareTrait;
use UnicaenUtilisateur\Form\Validator\Password;
use UnicaenUtilisateur\Provider\Identity\IdentityServiceAwareTrait;
use UnicaenUtilisateur\Service\RechercheIndividu\RechercheIndividuResultatInterface;
use UnicaenUtilisateur\Service\RechercheIndividu\RechercheIndividuServiceInterface;
@@ -33,6 +35,8 @@ class UtilisateurController extends AbstractActionController
    use PerimetreServiceAwareTrait;
    use RoleServiceAwareTrait;
    use UserServiceAwareTrait;
    use PasswordEnregistrementFormAwareTrait;
    use PasswordRecuperationFormAwareTrait;
    use UserFormAwareTrait;
    use UserRechercheFormAwareTrait;
    use UserRoleFormAwareTrait;
@@ -144,7 +148,7 @@ class UtilisateurController extends AbstractActionController
            if ($form->isValid()) {
                try {
                    $utilisateur = $form->getData();
                    $this->userService->createLocal($utilisateur, $data['nom']);
                    $this->userService->createUser($utilisateur, $data['nom']);
                    $this->flashMessenger()->addSuccessMessage(sprintf("Utilisateur <strong>%s</strong> créé avec succès. Un courrier électronique vient d'être envoyé à l'utilisateur pour l'initialisation de son mot de passe", $utilisateur->getDisplayName()));
                } catch (RuntimeException $e) {
                    $this->flashMessenger()->addErrorMessage(sprintf("Une erreur est survenu lors de la création de l'utilisateur <strong>%s</strong>.", $utilisateur->getDisplayName()));
@@ -163,29 +167,85 @@ class UtilisateurController extends AbstractActionController
        return $view;
    }

    public function changerMotDePasseAction()
    public function enregistrerMotDePasseAction()
    {
        $utilisateur = $this->userService->getRequestedUser($this, 'user');
        $title = "Enregistrement de votre mot de passe";
        $token = $this->params()->fromRoute('token');
        $reset = $utilisateur->getPasswordResetToken();
        $view = new ViewModel();
        $view->setVariable('title', $title);

        $form = $this->getInitCompteForm();
        $form->setAttribute('action', $this->url()->fromRoute('unicaen-utilisateur/changer-mot-de-passe', ['user' => $utilisateur->getId(), 'token' => $utilisateur->getPasswordResetToken()], ['force_canonical' => true], true));
        // recherche du token spécifié dans table utilisateur
        $user = $this->userService->findByPasswordResetToken($token, false);
        if ($user === null) {
            // token inexistant
            $view->setVariable('result', 'unknown_token');
            $view->setTemplate('unicaen-utilisateur/utilisateur/changer-password-result');

        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = $request->getPost();
            $this->userService->updatePassword($utilisateur, $data);
            $this->flashMessenger()->addSuccessMessage("Mot de passe changé avec succés");
            return $this->redirect()->toRoute('home', [], [], true);
            return $view;
        }

        return new ViewModel([
            'utilisateur' => $utilisateur,
            'token' => $token,
            'form' => $form,
        // vérification expiration du token
        $date = $this->userService->extractDateFromResetPasswordToken($user->getPasswordResetToken());
        if ($date < date_create()) {
            // token expiré, on l'efface
            $this->userService->clearUserPasswordResetToken($user);
            $view->setVariable('result', 'dead_token');
            $view->setTemplate('unicaen-utilisateur/utilisateur/changer-password-result');

        ]);
            return $view;
        }

        $form = $this->passwordEnregistrementForm;
        $form->setUsername($user->getUsername());
        if ($data = $this->params()->fromPost()) {
            $form->setData($data);
            if ($form->isValid()) {
                try {
                    $this->userService->updatePassword($user, $data['password']);
                    $view->setVariable('result', 'success');
                } catch (\Exception $e) {
                    $view->setVariable('result', 'error');
                }

                $view->setTemplate('unicaen-utilisateur/utilisateur/changer-password-result');
                return $view;
            }
        }

        $view->setVariables(['form' => $form, 'specialCharacters' => implode("&nbsp;&nbsp;", (new Password())->getSpecialCharacters())]);
        $view->setTemplate('unicaen-utilisateur/utilisateur/changer-password-form');

        return $view;
    }

    public function recupererMotDePasseAction()
    {
        $title = "Oubli de votre mot de passe";
        $view = new ViewModel();
        $view->setVariable('title', $title);

        $form = $this->passwordRecuperationForm;
        if ($data = $this->params()->fromPost()) {
            $form->setData($data);
            if ($form->isValid()) {
                // recherche du token spécifié dans table utilisateur
                $user = $this->userService->findByUsername($data['username']);
                try {
                    $this->userService->recoverPassword($user);
                    $view->setVariable('result', 'success');
                } catch (\Exception $e) {
                    $view->setVariable('result', 'error');
                }

                $view->setTemplate('unicaen-utilisateur/utilisateur/recuperer-password-result');
                return $view;
            }
        }

        $view->setVariable('form', $form);
        $view->setTemplate('unicaen-utilisateur/utilisateur/recuperer-password-form');

        return $view;

    }

+7 −1
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ namespace UnicaenUtilisateur\Controller;
use Application\Provider\IdentityProvider;
use Psr\Container\ContainerInterface;
use UnicaenPrivilege\Service\Perimetre\PerimetreService;
use UnicaenUtilisateur\Form\User\PasswordEnregisstrementForm;
use UnicaenUtilisateur\Form\User\PasswordEnregistrementForm;
use UnicaenUtilisateur\Form\User\PasswordRecuperationForm;
use UnicaenUtilisateur\Form\User\UserForm;
use UnicaenUtilisateur\Form\User\UserRechercheForm;
use UnicaenUtilisateur\Form\User\UserRoleForm;
@@ -39,7 +42,8 @@ class UtilisateurControllerFactory
        $perimetreService = $container->get(PerimetreService::class);
        $roleService = $container->get(RoleService::class);
        $userService = $container->get(UserService::class);
        $initCompte = $container->get('FormElementManager')->get(InitCompteForm::class);
        $passwordEnregistrementForm = $container->get('FormElementManager')->get(PasswordEnregistrementForm::class);
        $passwordRecuperationForm = $container->get('FormElementManager')->get(PasswordRecuperationForm::class);
        $userForm = $container->get('FormElementManager')->get(UserForm::class);
        $userRechercheForm = $container->get('FormElementManager')->get(UserRechercheForm::class);
        $userRoleForm = $container->get('FormElementManager')->get(UserRoleForm::class);
@@ -66,6 +70,8 @@ class UtilisateurControllerFactory
        $controller->setRoleService($roleService);
        $controller->setUserService($userService);
        $controller->setSearchServices($rechercheServices);
        $controller->setPasswordEnregistrementForm($passwordEnregistrementForm);
        $controller->setPasswordRecuperationForm($passwordRecuperationForm);
        $controller->setUserForm($userForm);
        $controller->setUserRechercheForm($userRechercheForm);
        $controller->setUserRoleForm($userRoleForm);
+0 −30
Original line number Diff line number Diff line
<?php

namespace UnicaenUtilisateur\Form\User;

trait InitCompteFormAwareTrait {

    /** @var InitCompteForm */
    private $initCompteForm;

    /**
     * @return InitCompteForm
     */
    public function getInitCompteForm()
    {
        return $this->initCompteForm;
    }

    /**
     * @param InitCompteForm $initCompteForm
     * @return InitCompteForm
     */
    public function setInitCompteForm($initCompteForm)
    {
        $this->initCompteForm = $initCompteForm;
        
        return $this->initCompteForm;
    }


}
+85 −19
Original line number Diff line number Diff line
@@ -2,16 +2,21 @@

namespace UnicaenUtilisateur\Form\User;

use Laminas\Filter\StringTrim;
use Laminas\Filter\StripTags;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Csrf;
use Laminas\Form\Element\Password;
use Laminas\Form\Element\Text;
use Laminas\Form\Form;
use Laminas\InputFilter\Factory;
use Laminas\Validator\Callback;
use Laminas\Validator\Identical;
use Laminas\Validator\NotEmpty;
use Laminas\Validator\Regex;
use UnicaenUtilisateur\Form\Validator\Password as PasswordValidator;

class InitCompteForm extends Form
class PasswordEnregistrementForm extends Form
{

    /** @var string */
@@ -34,7 +39,10 @@ class InitCompteForm extends Form
            'type' => Text::class,
            'name' => 'username',
            'options' => [
                'label' => "Nom d'utilisateur / Username * :",
                'label' => "Nom d'utilisateur (Username) :",
                'label_attributes' => [
                    'class' => 'required',
                ],
            ],
            'attributes' => [
                'id' => 'username',
@@ -43,48 +51,67 @@ class InitCompteForm extends Form

        $this->add([
            'type' => Password::class,
            'name' => 'password1',
            'name' => 'password',
            'options' => [
                'label' => "Mot de passe / Password :",
                'label' => "Mot de passe (Password) :",
                'label_attributes' => [
                    'class' => 'required',
                ],
            ],
            'attributes' => [
                'id' => 'password1',
                'id' => 'password',
            ],
        ]);
        //password2

        $this->add([
            'type' => Password::class,
            'name' => 'password2',
            'options' => [
                'label' => "Confirmation du mot de passe / Password confirmation * :",
                'label' => "Confirmation du mot de passe (Password confirmation) :",
                'label_attributes' => [
                    'class' => 'required',
                ],
            ],
            'attributes' => [
                'id' => 'password2',
            ],
        ]);
        //submit

        $this->add(new Csrf('security'));

        $this->add([
            'type' => Button::class,
            'name' => 'bouton',
            'name' => 'enregistrer',
            'options' => [
                'label' => '<i class="fas fa-save"></i> Enregistrer / Save',
                'label' => '<i class="fas fa-save"></i> Enregistrer (Save)',
                'label_options' => [
                    'disable_html_escape' => true,
                ],
            ],
            'attributes' => [
                'type' => 'submit',
                'class' => 'btn btn-primary',
                'class' => 'btn btn-primary mt-2',
            ],
        ]);

        $this->setInputFilter((new Factory())->createInputFilter([
            'username' => [
                'required' => true,
                'validators' => [[
                'filters' => [
                    ['name' => StringTrim::class],
                    ['name' => StripTags::class],
                ],
                'validators' => [
                    [
                        'name' => NotEmpty::class,
                        'options' => [
                            'messages' => [
                                NotEmpty::IS_EMPTY => "Veuillez saisir votre nom d'utilisateur / Please enter your username."
                            ],
                            'break_chain_on_failure' => true,
                        ],
                    ],
                    [
                        'name' => Callback::class,
                        'options' => [
                            'messages' => [
@@ -94,26 +121,65 @@ class InitCompteForm extends Form
                                return ($value === $this->username);
                            },
                        ],
                ]],
                    ]
                ],

            ],
            'password1' => [

            'password' => [
                'required' => true,
                'filters' => [
                    ['name' => StringTrim::class],
                ],
                'validators' => [
                    [
                        'name' => Regex::class,
                        'name' => NotEmpty::class,
                        'options' => [
                            'pattern' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*_])(?=.{8,})/',
                            'messages' => [
                                Regex::NOT_MATCH => "Le mot de passe choisi ne respecte pas les consignes de sécurité / This password is not consistent with the security constraints.",
                                NotEmpty::IS_EMPTY => "Veuillez saisir un mot de passe / Please enter your password."
                            ],
                            'break_chain_on_failure' => true,
                        ],
                    ],],
                    ],
                    [
                        'name' => PasswordValidator::class,
                        'options' => [
                            'min' => 8,
                            'upper' => true,
                            'lower' => true,
                            'digit' => true,
                            'special' => true,
                            'message' => "Le format du mot de passe saisi n'est pas correct / The format of the entered password is not correct. "
                        ],
                    ],
                ],
            ],

            'password2' => [
                'required' => true,
                'filters' => [
                    ['name' => StringTrim::class],
                ],
                'validators' => [
                    new Identical('password1'),
                    [
                        'name' => NotEmpty::class,
                        'options' => [
                            'messages' => [
                                NotEmpty::IS_EMPTY => "Veuillez confirmer le mot de passe / Please confirm your password."
                            ],
                            'break_chain_on_failure' => true,
                        ],
                    ],
                    [
                        'name' => Identical::class,
                        'options' => [
                            'token' => 'password',
                            'messages' => [
                                Identical::NOT_SAME => "Les deux mots de passe ne correspondent pas / The two passwords do not match."
                            ],
                            'break_chain_on_failure' => true,
                        ],
                    ],
                ],
            ],
        ]));
Loading