Skip to content

Commit

Permalink
bug #53172 [SecurityBundle] Prevent to login/logout without a request…
Browse files Browse the repository at this point in the history
… context (symfonyaml)

This PR was squashed before being merged into the 6.3 branch.

Discussion
----------

[SecurityBundle] Prevent to login/logout without a request context

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #53170
| License       | MIT

Using `Security::login()` in a context without request throws a type error
See all details in the issue symfony/symfony#53170

In this PR, we prevent to use `Security::login()` and `Security::logout()` without a request context, to avoid a fatal error.

Commits
-------

aaa9392dd7 [SecurityBundle] Prevent to login/logout without a request context
  • Loading branch information
Nyholm committed Dec 23, 2023
2 parents 6449980 + fb98e1f commit a185fa0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
11 changes: 9 additions & 2 deletions Security.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public function getFirewallConfig(Request $request): ?FirewallConfig
public function login(UserInterface $user, string $authenticatorName = null, string $firewallName = null): ?Response
{
$request = $this->container->get('request_stack')->getCurrentRequest();
if (null === $request) {
throw new LogicException('Unable to login without a request context.');
}

$firewallName ??= $this->getFirewallConfig($request)?->getName();

if (!$firewallName) {
Expand All @@ -86,15 +90,18 @@ public function login(UserInterface $user, string $authenticatorName = null, str
*/
public function logout(bool $validateCsrfToken = true): ?Response
{
$request = $this->container->get('request_stack')->getMainRequest();
if (null === $request) {
throw new LogicException('Unable to logout without a request context.');
}

/** @var TokenStorageInterface $tokenStorage */
$tokenStorage = $this->container->get('security.token_storage');

if (!($token = $tokenStorage->getToken()) || !$token->getUser()) {
throw new LogicException('Unable to logout as there is no logged-in user.');
}

$request = $this->container->get('request_stack')->getMainRequest();

if (!$firewallConfig = $this->container->get('security.firewall.map')->getFirewallConfig($request)) {
throw new LogicException('Unable to logout as the request is not behind a firewall.');
}
Expand Down
43 changes: 43 additions & 0 deletions Tests/SecurityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,28 @@ public function testLoginWithoutAuthenticatorThrows()
$security->login($user);
}

public function testLoginWithoutRequestContext()
{
$requestStack = new RequestStack();
$user = $this->createMock(UserInterface::class);

$container = $this->createMock(ContainerInterface::class);
$container
->expects($this->atLeastOnce())
->method('get')
->willReturnMap([
['request_stack', $requestStack],
])
;

$security = new Security($container, ['main' => null]);

$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Unable to login without a request context.');

$security->login($user);
}

public function testLogout()
{
$request = new Request();
Expand Down Expand Up @@ -458,6 +480,27 @@ public function testLogoutWithValidCsrf()
$this->assertEquals('a custom response', $response->getContent());
}

public function testLogoutWithoutRequestContext()
{
$requestStack = new RequestStack();

$container = $this->createMock(ContainerInterface::class);
$container
->expects($this->atLeastOnce())
->method('get')
->willReturnMap([
['request_stack', $requestStack],
])
;

$security = new Security($container, ['main' => null]);

$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Unable to logout without a request context.');

$security->logout();
}

private function createContainer(string $serviceId, object $serviceObject): ContainerInterface
{
return new ServiceLocator([$serviceId => fn () => $serviceObject]);
Expand Down

0 comments on commit a185fa0

Please sign in to comment.