28 nov. 2022 | Connexion

Blog

Symfony - EasyAdmin - Changement du mot de passe Utilisateur

Symfony - EasyAdmin - Changement du mot de passe Utilisateur

Développement web
Symfony PHP MySQL

il y a 1 mois citizenz7 0 commentaire 158 lectures

Certes, il existe un excellent bundle symfonycasts/reset-password-bundle (https://github.com/symfonycasts/reset-password-bundle) qui permet aux utilisateurs de régénérer un mot de passe en cas de perte.
Mais si on veut permettre à l'utilisateur connecté de changer son propre mot de passe depuis EasyAdmin, comment faire ?

Et bien cela est relativement simple et ça se passe en 2 étapes :

1/ EasyAdmin UserCrudController.php
Dans EasyAdmin vous avez surement généré un Crud controller pour votre entité User (src/Controller/Admin/UserCrudController.php)
Dans ce fichier, insérez la partie relative au mot de passe :

Field::new('password', 'Changer le mot de passe ?')
    ->setColumns(2)
    ->onlyOnForms()
    ->setFormType(PasswordType::class),

Ici, j'utilise Field (n'oubliez pas d'importer la class use EasyCorp\Bundle\EasyAdminBundle\Field\Field)
Je lui dis, pour des questions esthétiques, de ne s'afficher que sur 2 col (Bootstrap), de ne s'afficher que sur les formulaires (pas en page Index, ni dans Details) et j'utilise le setFormType avec PasswordType::class (n'oubliez pas d'importer la class), tout comme dans les Form classiques de Symfony. Cela permettra d'avoir un champ qui remplace les caractères par des points, etc.

2/ EasyAdmin EventSubscriber
La deuxième (et dernière) étape consiste à créer un EventSubscriber (src/EventSubscriber/EasyAdminSubscriberUserPasswordChange.php). L'eventSubscriber est une classe qui définit une ou plusieurs méthodes qui écoutent un ou plusieurs événements.
Aussi notre EventSubsciber va "capter" ou "écouter" ce qui se passe sur la partie User d'EasyAdmin, et notamment la partie mot de passe.
Il s'agira de définir à quel moment écouter et quoi écouter.
Ici, on va écouter tout ce qui concerne l'ajout de l'utilisateur mais aussi l'update éventuel de données de l'utilisateurs grâce à BeforeEntityPersistedEvent et BeforeEntityUpdatedEvent.

Voici donc ci-dessous le fichier en question. En gros, il va "écouter" s'il s'agit d'une création ou d'un update et agir selon le contexte, soit en settant directement le mot de passe, soit en récupérant le mot de passe pour le "hasher" et l'enregistrer dans la base de données : persist() et flush()

<?php

namespace App\EventSubscriber;

use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityPersistedEvent;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

class EasyAdminSubscriberUserPasswordChange implements EventSubscriberInterface
{
    private EntityManagerInterface $entityManager;
    private UserPasswordHasherInterface $passwordHasher;

    public function __construct(EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordHasher)
    {
        $this->entityManager = $entityManager;
        $this->passwordHasher = $passwordHasher;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            BeforeEntityPersistedEvent::class => ['addUser'],
            BeforeEntityUpdatedEvent::class => ['updateUser'],
        ];
    }

    public function updateUser(BeforeEntityUpdatedEvent $event): void
    {
        $entity = $event->getEntityInstance();

        if (!($entity instanceof User)) {
            return;
        }
        $this->setPassword($entity);
    }


    public function addUser(BeforeEntityPersistedEvent $event): void
    {
        $entity = $event->getEntityInstance();

        if (!($entity instanceof User)) {
            return;
        }
        $this->setPassword($entity);
    }

    public function setPassword(User $entity): void
    {
        $pass = $entity->getPassword();

        $entity->setPassword(
            $this->passwordHasher->hashPassword(
                $entity,
                $pass
            )
        );

        $this->entityManager->persist($entity);
        $this->entityManager->flush();
    }
}

0 commentaire


Nb d'articles actifs : 40 | Nb de commentaires : 16 | Nb de catégories : 7 | Nb de tags : 32 | Nb total de lectures : 118 918
2022 citizenz.info • Some rights reserved GPLv3 • Version 3.3.4

N'empêche que chez nous, on sait construire ! Les aqueducs, c'est quand même un petit peu plus classe que vos murs en merde séchée… Enfin, je dis ça, je dis tout ! (Caius Camillus, Kaamelott, Livre I, 56 : Le Dernier Empereur)