Bonjour,

Je viens de finir ma propre gestion d'utilisateur avec symfony 4, au fait le principe et que j'active ou je desactive le compte d'un utilisateur avec une checkbox, sur ça tous se passe très bien.
Mon problème est que quand je desactive un compte si l'utilisateur est connecté j'aimerai qu'il soit deconnecté une fois que j'ai desactivé le compte.
Et c'est là que je ne sais pas comment m'y prendre. J'ai chercher sur google mais je ne trouve pas de documents récent sur cela.

Ce que je fais

Décrivez ici votre code ou ce que vous cherchez à faire

Entourez votre code pour bien le mettre en forme

Ce que je veux

Décrivez ici ce que vous cherchez à obtenir

Ce que j'obtiens

Décrivez ici vos erreurs ou ce que vous obtenez à la place de ce que vous attendez :(

11 réponses


Digivia
Réponse acceptée

Hello,

Perso, la manière la plus simple que j'ai trouvé sur SF4 est de tester le compte dans le Guard, pour vérifier s'il est bien connecté. Ce n'est pas le plus élégant, mais c'est efficace...
Tu peux aussi le faire avec un EventListener sur un Event du Kernel.

Bonjour.

j'active ou je desactive le compte d'un utilisateur avec une checkbox, sur ça tous se passe très bien.

Oui mais encore ?
Est-ce que le fait que tu coches la case a un impact au niveau de l'utilisateur dans la base de données de manière à ce que si tu désactives le compte de l'utilisateur qu'il ne puisse pas se connecter lors de ses prochaines tentatives de connexion ?
Si tu veux déconnecter l'utilisateur immédiatement, il te faut utiliser les Websockets, il te faut donc essayer avec ceci : Gos Web Socket Bundle.

CedLP
Auteur

Oui cela a un impact, si je desactive et que je deconnecte l'utilisateur bah il peut plus se reconnecter.au fait j'avais vu sur un forum que il fallais utiliser le kernel mais sur symfony 4 y a pas de Doc mais c'est sur le 2.
Mais merci je vais voir ce Bundle alors d'abord

CedLP
Auteur

Justement c'est ce que j'ai vu pour symfony 2 dans des forum il touche au Event Kernel mais j'ai jamais éssayé cela vu que j'ai direct debuté avec le 4 haha mais je vai svoir cela :) en tous cas tu me donne déjà une bonne piste

CedLP
Auteur

Bon si ça interesse quelqu'un j'ai reussi à resoudre mon problème avec un event kernel.

<?php

namespace App\Listener;

use App\Entity\Users;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\Security\Core\Security;

/**
 * Class KernelRequestListener
 *
 * @package AppBundle\Listener
 */
class KernelRequestListener
{
    const DEBUG_ROUTE_NAMES = [
        '_twig_error_test',
        '_wdt',
        '_profiler_home',
        '_profiler_search',
        '_profiler_search_bar',
        '_profiler_search_results',
        '_profiler',
        '_profiler_router',
        '_profiler_exception',
        '_profiler_exception_css',
        '_profiler_open_file',
        'app_login',
        'app_logout',
        'forgotten_password',
        'reset-password',
    ];

    /** @var Security $security */
    private $security;

    /** @var Router $router */
    private $router;

    /**
     * KernelRequestListener constructor.
     *
     * @param Security $security
     * @param Router   $router
     */
    public function __construct(
        Security $security,
        Router $router
    ) {
        $this->security = $security;
        $this->router = $router;
    }

    /**
     * @param GetResponseEvent $event
     */
    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        $route = $request->get('_route');
        if ($event->isMasterRequest()
            && !in_array($route, self::DEBUG_ROUTE_NAMES)
            && $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')
            && $this->security->isGranted(Users::ROLE_SUPER_ADMIN)

        ) {
            /** @var Users $user */
            $user = $this->security->getUser();
            if (!$user->isEnabled()) {
                $event->setResponse(new RedirectResponse($this->router->generate('app_logout')));
            }
        }

        return;
    }
}

voila le code et vous adabpter juste à votre situation

Petite question, tu veux que ça ne s'applique qu'aux users ayant le role super admin?
Après, définir les routes en dur c'est pas forcément le plus opportum, si jamais tu changes le nom d'une de tes routes, ça ne fonctionne plus...
C'est un peu le défaut des Event Listener, on ne pense pas forcément à les upgrader...
Tu peux les définir dans ton .env et les pousser dans le constructeur de ton Event Listener.
Perso, j'ai préféré faire ça dans mon Guard, tout ce qui touche à la sécu est centralisé comme ça...

Voici le code de mon Guard (fonction supports) :

/**
     * Login authenticator supports login form / and disable user in admin
     *
     * @param Request $request
     * @return bool
     */
    public function supports(Request $request): bool
    {
        // Form login submitted
        if ('app_login' === $request->attributes->get('_route') && $request->isMethod('POST')) {
            return true;
        }
        // Get User
        /** @var User $user */
        $user = $this->security->getUser();

        // Account expired
        if (null !== $user && $user->isAccountExpired()) {
            throw new CustomUserMessageAuthenticationException('security.account.expired', ['expired' => true]);
        }

        // Account disabled
        if (null !== $user && !$user->isEnabled()) {
            $this->security->getToken()->setAuthenticated(false);
            throw new CustomUserMessageAuthenticationException('security.account.disabled');
        }
        return false;
    }

La fonction supports est appelée par le firewall et doit déterminer si le Guard doit être activé. Du coup à chaque page sécurisée elle est appellée. Cette fonction n'est à l'origine pas prévue pour cela, c'est pour cela que ce n'est pas la méthode la plus élégante. Mais c'est très efficace et on reste dans la fonction du Guard, l'authentification.

CedLP
Auteur

Salut Digiva,

Au fait pour la condition sur le code c'été juste pour un test mais cela ne s'applique qu'àun superadmin mais aussi aux autres utilisateurs.
Merci pour ton retour, je vois aussi que c'est un peu mieu de tous centralisé comme tu le dis et en ce qui concerne les routes, j'y avait pas encore pensé. Je suis encore novice aussi dans symfony mais j'essaie de bien m'intégrer.
Au fait dis tu ne saurais pas par hazard si il existe un bundle qui permet d'uploader des fichier excel afin qu'il entre directement dans la base de donnée.
Et une autre pour des translation dynamique. genre les fichier de translation on ne les utilisent plus mais on prend les translation depuis la base de donnée.

Pour les Bundles reconnus par Symfony, il te suffit de regarder ici : Symfony Recipes Server.

CedLP
Auteur

Merci Lartak c'est sympa :) je vais voir si je peux y trouver ce que je cherche.
Comment on marque le sujet à résolut ? lol

Comment on marque le sujet à résolut ? lol

Sur la droite de chaque commentaire, il y a le bouton : .

Il te suffit de cliquer sur celui qui se trouve à côté du commentaire de celui qui t'a permis de résoudre ton sujet ou de ceux qui t'on permis de le résoudre.
Ton sujet sera donc marqué comme résolu et le(s) commentaire(s) sera/seront placé(s) en priorité dans le listing des commentaires.