Skip to content

Commit

Permalink
Add the TokenDeauthenticatedListener (see #5788)
Browse files Browse the repository at this point in the history
Description
-----------

Implements #475 

Commits
-------

070250c Add TokenDeauthenticatedListener
3455097 Add missing test
e455ea7 No PHP 8 features please
a0e7278 CS
1f675a6 Merge branch '5.1' into feature/deauthenticated-event
00e46ad Merge branch '5.1' into feature/deauthenticated-event
4e3a8cc CS

Co-authored-by: Leo Feyer <1192057+leofeyer@users.noreply.github.com>
  • Loading branch information
bytehead and leofeyer committed Mar 13, 2023
1 parent 9b64119 commit 2c16abe
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
7 changes: 7 additions & 0 deletions core-bundle/config/listener.yaml
Expand Up @@ -539,6 +539,13 @@ services:
- kernel.event_listener
- { name: monolog.logger, channel: contao.access }

contao.listener.security.token_deauthenticated:
class: Contao\CoreBundle\EventListener\Security\TokenDeauthenticatedListener
arguments:
- '@contao.repository.remember_me'
tags:
- kernel.event_listener

contao.listener.security.two_factor_frontend:
class: Contao\CoreBundle\EventListener\Security\TwoFactorFrontendListener
arguments:
Expand Down
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\CoreBundle\EventListener\Security;

use Contao\CoreBundle\Repository\RememberMeRepository;
use Contao\User;
use Symfony\Component\Security\Http\Event\TokenDeauthenticatedEvent;

class TokenDeauthenticatedListener
{
public function __construct(private RememberMeRepository $rememberMeRepository)
{
}

public function __invoke(TokenDeauthenticatedEvent $tokenDeauthenticatedEvent): void
{
$user = $tokenDeauthenticatedEvent->getOriginalToken()->getUser();

if (!$user instanceof User) {
return;
}

$this->rememberMeRepository->deleteByUserIdentifier($user->getUserIdentifier());
}
}
12 changes: 12 additions & 0 deletions core-bundle/src/Repository/RememberMeRepository.php
Expand Up @@ -67,4 +67,16 @@ public function persist(RememberMe ...$entities): void

$this->_em->flush();
}

public function deleteByUserIdentifier(string $userIdentifier): void
{
$qb = $this->_em->createQueryBuilder();
$qb
->delete($this->_entityName, 'rm')
->where('rm.userIdentifier = :userIdentifier')
->setParameter('userIdentifier', $userIdentifier)
;

$qb->getQuery()->execute();
}
}
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\CoreBundle\Tests\EventListener\Security;

use Contao\CoreBundle\EventListener\Security\TokenDeauthenticatedListener;
use Contao\CoreBundle\Repository\RememberMeRepository;
use Contao\TestCase\ContaoTestCase;
use Contao\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\TokenDeauthenticatedEvent;

class TokenDeauthenticatedListenerTest extends ContaoTestCase
{
public function testDeletesRelatedRememberMeRecords(): void
{
$user = $this->createMock(User::class);
$user
->expects($this->exactly(2))
->method('getUserIdentifier')
->willReturn('foobar')
;

$token = $this->createMock(TokenInterface::class);
$token
->expects($this->once())
->method('getUser')
->willReturn($user)
;

$repository = $this->createMock(RememberMeRepository::class);
$repository
->expects($this->once())
->method('deleteByUserIdentifier')
->with($user->getUserIdentifier())
;

$event = new TokenDeauthenticatedEvent($token, $this->createMock(Request::class));

$listener = new TokenDeauthenticatedListener($repository);
$listener($event);
}

public function testDoesNothingIfThereIsNoContaoUser(): void
{
$token = $this->createMock(TokenInterface::class);
$repository = $this->createMock(RememberMeRepository::class);

$event = new TokenDeauthenticatedEvent($token, $this->createMock(Request::class));

$listener = new TokenDeauthenticatedListener($repository);
$listener($event);

$this->expectNotToPerformAssertions();
}
}

0 comments on commit 2c16abe

Please sign in to comment.