Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>backport/44745/stable29
* @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'); | ||||
* @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); | ||||
$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'); | ||||
* @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, | |||||
] | ] | ||||
)); | )); | ||||
} | } |
public function afterException($controller, $methodName, Exception $exception) { | public function afterException($controller, $methodName, Exception $exception) { | ||||
if ($exception instanceof TwoFactorAuthRequiredException) { | if ($exception instanceof TwoFactorAuthRequiredException) { | ||||
$params = []; | |||||
if (isset($this->request->server['REQUEST_URI'])) { | |||||
$params = [ | |||||
'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)); |
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 |
$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') | ||||
$provider, | $provider, | ||||
], | ], | ||||
'logout_url' => 'logoutAttribute', | 'logout_url' => 'logoutAttribute', | ||||
'redirect_url' => null, | |||||
], | ], | ||||
'guest' | 'guest' | ||||
); | ); | ||||
$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') | ||||
'provider' => $provider, | 'provider' => $provider, | ||||
'logout_url' => 'logoutAttribute', | 'logout_url' => 'logoutAttribute', | ||||
'template' => 'tmpl', | 'template' => 'tmpl', | ||||
'redirect_url' => null, | |||||
], | ], | ||||
'guest' | 'guest' | ||||
); | ); | ||||
$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'); |