feat: redirect to the deeplink after the form login

This commit is contained in:
fromme committed 2026-10-16 08:38:05 +02:00
1 parent 0e2021e96d
commit 18fb3382c6
2 files changed
+96 -4

No files matched your search

+67 -4
View File
@@ -24,6 +24,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken;
#[AllowMockObjectsWithoutExpectations]
class BpnAuthenticatorTest extends TestCase
@@ -137,6 +138,48 @@ class BpnAuthenticatorTest extends TestCase
$this->assertFalse($user->isDisabled());
}
public function testTheLoginLeadsToTheDeeplinkTheUserCameFrom(): void
{
$request = $this->createRequest();
$request->getSession()->set('_security.main.target_path', 'https://team.example.com/administrative/assignment/detail/abc');
$response = $this->createAuthenticator()->onAuthenticationSuccess($request, $this->createToken(), 'main');
$this->assertSame('https://team.example.com/administrative/assignment/detail/abc', $response->headers->get('Location'));
// used once: a later login in the same session starts from the default route again
$this->assertFalse($request->getSession()->has('_security.main.target_path'));
}
public function testWithoutADeeplinkTheLoginLeadsToTheDefaultRoute(): void
{
$response = $this->createAuthenticator()->onAuthenticationSuccess($this->createRequest(), $this->createToken(), 'main');
$this->assertSame('/default-route', $response->headers->get('Location'));
}
public function testAnHtmxRequestIsNotKeptAsTheDeeplink(): void
{
// a modal opened after the session expired: the firewall saved its url just before
$request = $this->createRequest();
$request->headers->set('HX-Request', 'true');
$request->getSession()->set('_security.main.target_path', 'https://team.example.com/admin/system/fee/edit/1');
$this->createAuthenticator()->start($request);
$this->assertFalse($request->getSession()->has('_security.main.target_path'));
}
public function testAPageRequestIsKeptAsTheDeeplink(): void
{
$request = $this->createRequest();
$request->getSession()->set('_security.main.target_path', 'https://team.example.com/administrative/assignment');
$response = $this->createAuthenticator()->start($request);
$this->assertSame('/login', $response->headers->get('Location'));
$this->assertTrue($request->getSession()->has('_security.main.target_path'));
}
private function createCrmAttributes(): CrmAttributesResponse
{
return (new CrmAttributesResponse())->setAttributeGroups([new CrmAttributeGroup()]);
@@ -148,17 +191,25 @@ class BpnAuthenticatorTest extends TestCase
$this->apiClient->method('getCrmAttributes')->willReturn($crmAttributes);
}
private function loadUser(): ?User
private function createAuthenticator(): BpnAuthenticator
{
$authenticator = new BpnAuthenticator(
$this->createStub(UrlGeneratorInterface::class),
$urlGenerator = $this->createStub(UrlGeneratorInterface::class);
$urlGenerator->method('generate')->willReturnCallback(
static fn (string $route): string => 'app_security_login' === $route ? '/login' : '/default-route'
);
return new BpnAuthenticator(
$urlGenerator,
$this->createStub(EntityManagerInterface::class),
$this->apiClient,
$this->createStub(LoggerInterface::class),
$this->userDataHandler,
$this->createStub(RequiredTeamerCheckRegistry::class),
);
}
private function createRequest(): Request
{
$request = new Request(request: [
'_username' => '[email protected]',
'_password' => 'secret',
@@ -166,7 +217,19 @@ class BpnAuthenticatorTest extends TestCase
]);
$request->setSession(new Session(new MockArraySessionStorage()));
$passport = $authenticator->authenticate($request);
return $request;
}
private function createToken(): PostAuthenticationToken
{
$user = (new User())->setRoles(['ROLE_TEAM_ADMIN']);
return new PostAuthenticationToken($user, 'main', $user->getRoles());
}
private function loadUser(): ?User
{
$passport = $this->createAuthenticator()->authenticate($this->createRequest());
/** @var UserBadge $badge */
$badge = $passport->getBadge(UserBadge::class);