fix(auth): Keep redirect URL during 2FA setup and challenge

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
pull/44745/head
Christoph Wurst 1 month ago
parent fc560d8ec9
commit 22dc27810e
No known key found for this signature in database
GPG Key ID: CC42AC2A7F0E56D8

@ -213,13 +213,14 @@ class TwoFactorChallengeController extends Controller {
* @NoCSRFRequired * @NoCSRFRequired
*/ */
#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')] #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')]
public function setupProviders(): StandaloneTemplateResponse { public function setupProviders(?string $redirect_url = null): StandaloneTemplateResponse {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user); $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
$data = [ $data = [
'providers' => $setupProviders, 'providers' => $setupProviders,
'logout_url' => $this->getLogoutUrl(), 'logout_url' => $this->getLogoutUrl(),
'redirect_url' => $redirect_url,
]; ];
return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest'); return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
@ -230,7 +231,7 @@ class TwoFactorChallengeController extends Controller {
* @NoCSRFRequired * @NoCSRFRequired
*/ */
#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')] #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')]
public function setupProvider(string $providerId) { public function setupProvider(string $providerId, ?string $redirect_url = null) {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
$providers = $this->twoFactorManager->getLoginSetupProviders($user); $providers = $this->twoFactorManager->getLoginSetupProviders($user);
@ -251,6 +252,7 @@ class TwoFactorChallengeController extends Controller {
$data = [ $data = [
'provider' => $provider, 'provider' => $provider,
'logout_url' => $this->getLogoutUrl(), 'logout_url' => $this->getLogoutUrl(),
'redirect_url' => $redirect_url,
'template' => $tmpl->fetchPage(), 'template' => $tmpl->fetchPage(),
]; ];
$response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest'); $response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
@ -264,11 +266,12 @@ class TwoFactorChallengeController extends Controller {
* @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
*/ */
#[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')] #[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')]
public function confirmProviderSetup(string $providerId) { public function confirmProviderSetup(string $providerId, ?string $redirect_url = null) {
return new RedirectResponse($this->urlGenerator->linkToRoute( return new RedirectResponse($this->urlGenerator->linkToRoute(
'core.TwoFactorChallenge.showChallenge', 'core.TwoFactorChallenge.showChallenge',
[ [
'challengeProviderId' => $providerId, 'challengeProviderId' => $providerId,
'redirect_url' => $redirect_url,
] ]
)); ));
} }

@ -134,8 +134,10 @@ class TwoFactorMiddleware extends Middleware {
public function afterException($controller, $methodName, Exception $exception) { public function afterException($controller, $methodName, Exception $exception) {
if ($exception instanceof TwoFactorAuthRequiredException) { if ($exception instanceof TwoFactorAuthRequiredException) {
$params = []; $params = [
if (isset($this->request->server['REQUEST_URI'])) { 'redirect_url' => $this->request->getParam('redirect_url'),
];
if (!isset($params['redirect_url']) && isset($this->request->server['REQUEST_URI'])) {
$params['redirect_url'] = $this->request->server['REQUEST_URI']; $params['redirect_url'] = $this->request->server['REQUEST_URI'];
} }
return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', $params)); return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', $params));

@ -33,6 +33,7 @@ declare(strict_types=1);
href="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.TwoFactorChallenge.setupProvider', href="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.TwoFactorChallenge.setupProvider',
[ [
'providerId' => $provider->getId(), 'providerId' => $provider->getId(),
'redirect_url' => $_['redirect_url'],
] ]
)) ?>"> )) ?>">
<?php <?php

@ -337,7 +337,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
$this->assertEquals($expected, $this->controller->solveChallenge('myprovider', 'token', '/url')); $this->assertEquals($expected, $this->controller->solveChallenge('myprovider', 'token', '/url'));
} }
public function testSetUpProviders() { public function testSetUpProviders(): void {
$user = $this->createMock(IUser::class); $user = $this->createMock(IUser::class);
$this->userSession->expects($this->once()) $this->userSession->expects($this->once())
->method('getUser') ->method('getUser')
@ -357,6 +357,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
$provider, $provider,
], ],
'logout_url' => 'logoutAttribute', 'logout_url' => 'logoutAttribute',
'redirect_url' => null,
], ],
'guest' 'guest'
); );
@ -392,7 +393,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
$this->assertEquals($expected, $response); $this->assertEquals($expected, $response);
} }
public function testSetUpProvider() { public function testSetUpProvider(): void {
$user = $this->createMock(IUser::class); $user = $this->createMock(IUser::class);
$this->userSession->expects($this->once()) $this->userSession->expects($this->once())
->method('getUser') ->method('getUser')
@ -426,6 +427,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
'provider' => $provider, 'provider' => $provider,
'logout_url' => 'logoutAttribute', 'logout_url' => 'logoutAttribute',
'template' => 'tmpl', 'template' => 'tmpl',
'redirect_url' => null,
], ],
'guest' 'guest'
); );
@ -435,13 +437,14 @@ class TwoFactorChallengeControllerTest extends TestCase {
$this->assertEquals($expected, $response); $this->assertEquals($expected, $response);
} }
public function testConfirmProviderSetup() { public function testConfirmProviderSetup(): void {
$this->urlGenerator->expects($this->once()) $this->urlGenerator->expects($this->once())
->method('linkToRoute') ->method('linkToRoute')
->with( ->with(
'core.TwoFactorChallenge.showChallenge', 'core.TwoFactorChallenge.showChallenge',
[ [
'challengeProviderId' => 'totp', 'challengeProviderId' => 'totp',
'redirect_url' => null,
]) ])
->willReturn('2fa/select/page'); ->willReturn('2fa/select/page');
$expected = new RedirectResponse('2fa/select/page'); $expected = new RedirectResponse('2fa/select/page');

Loading…
Cancel
Save