Skip to content

Commit 03822b4

Browse files
hellomedianicolas-grekas
authored andcommitted
[Security] Make login redirection logic available to programmatic login
1 parent 3b80d2e commit 03822b4

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* Add `_stateless` attribute to the request when firewall is stateless
99
* Add `StatelessAuthenticatorFactoryInterface` for authenticators targeting `stateless` firewalls only and that don't require a user provider
1010
* Modify "icon.svg" to improve accessibility for blind/low vision users
11+
* Make `Security::login()` return the authenticator response
1112

1213
6.2
1314
---

Security.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ public function getFirewallConfig(Request $request): ?FirewallConfig
5656
* @param UserInterface $user The user to authenticate
5757
* @param string|null $authenticatorName The authenticator name (e.g. "form_login") or service id (e.g. SomeApiKeyAuthenticator::class) - required only if multiple authenticators are configured
5858
* @param string|null $firewallName The firewall name - required only if multiple firewalls are configured
59+
*
60+
* @return Response|null The authenticator success response if any
5961
*/
60-
public function login(UserInterface $user, string $authenticatorName = null, string $firewallName = null): void
62+
public function login(UserInterface $user, string $authenticatorName = null, string $firewallName = null): ?Response
6163
{
6264
$request = $this->container->get('request_stack')->getCurrentRequest();
6365
$firewallName ??= $this->getFirewallConfig($request)?->getName();
@@ -69,7 +71,8 @@ public function login(UserInterface $user, string $authenticatorName = null, str
6971
$authenticator = $this->getAuthenticator($authenticatorName, $firewallName);
7072

7173
$this->container->get('security.user_checker')->checkPreAuth($user);
72-
$this->container->get('security.user_authenticator')->authenticateUser($user, $authenticator, $request);
74+
75+
return $this->container->get('security.user_authenticator')->authenticateUser($user, $authenticator, $request);
7376
}
7477

7578
/**

Tests/SecurityTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,57 @@ public function testLogin()
169169
$security->login($user);
170170
}
171171

172+
public function testLoginReturnsAuthenticatorResponse()
173+
{
174+
$request = new Request();
175+
$authenticator = $this->createMock(AuthenticatorInterface::class);
176+
$requestStack = $this->createMock(RequestStack::class);
177+
$firewallMap = $this->createMock(FirewallMap::class);
178+
$firewall = new FirewallConfig('main', 'main');
179+
$user = $this->createMock(UserInterface::class);
180+
$userChecker = $this->createMock(UserCheckerInterface::class);
181+
$userAuthenticator = $this->createMock(UserAuthenticatorInterface::class);
182+
183+
$container = $this->createMock(ContainerInterface::class);
184+
$container
185+
->expects($this->atLeastOnce())
186+
->method('get')
187+
->willReturnMap([
188+
['request_stack', $requestStack],
189+
['security.firewall.map', $firewallMap],
190+
['security.user_authenticator', $userAuthenticator],
191+
['security.user_checker', $userChecker],
192+
])
193+
;
194+
195+
$requestStack->expects($this->once())->method('getCurrentRequest')->willReturn($request);
196+
$firewallMap->expects($this->once())->method('getFirewallConfig')->willReturn($firewall);
197+
$userChecker->expects($this->once())->method('checkPreAuth')->with($user);
198+
$userAuthenticator->expects($this->once())->method('authenticateUser')
199+
->with($user, $authenticator, $request)
200+
->willReturn(new Response('authenticator response'));
201+
202+
$firewallAuthenticatorLocator = $this->createMock(ServiceProviderInterface::class);
203+
$firewallAuthenticatorLocator
204+
->expects($this->once())
205+
->method('getProvidedServices')
206+
->willReturn(['security.authenticator.custom.dev' => $authenticator])
207+
;
208+
$firewallAuthenticatorLocator
209+
->expects($this->once())
210+
->method('get')
211+
->with('security.authenticator.custom.dev')
212+
->willReturn($authenticator)
213+
;
214+
215+
$security = new Security($container, ['main' => $firewallAuthenticatorLocator]);
216+
217+
$response = $security->login($user);
218+
219+
$this->assertInstanceOf(Response::class, $response);
220+
$this->assertEquals('authenticator response', $response->getContent());
221+
}
222+
172223
public function testLoginWithoutAuthenticatorThrows()
173224
{
174225
$request = new Request();

0 commit comments

Comments
 (0)