From 0de142507fae65d5d2b0a96c1c8d8ba0169d2ede Mon Sep 17 00:00:00 2001 From: Nathanael Noblet Date: Fri, 24 Apr 2020 11:47:39 -0600 Subject: [PATCH] Allow multiple firewalls Perhaps I'm not doing this correctly however, we need 2fa with multiple firewalls. There seems to be an issue with being able to support that. The provider is configured with the template to render, however the path is configured by the firewall. So when my email provider renders the 2fa it has no concept of where the check should be submitted to. If the template was configured on the firewall that'd be different. So what I've done is passed the check_path variable to the template so the form submission can submit to the correct location --- Controller/FormController.php | 4 ++ Resources/views/Authentication/form.html.twig | 2 +- Tests/Controller/FormControllerTest.php | 53 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Controller/FormController.php b/Controller/FormController.php index d0d75a10..159c17c6 100644 --- a/Controller/FormController.php +++ b/Controller/FormController.php @@ -98,6 +98,8 @@ protected function getTemplateVars(Request $request, TwoFactorTokenInterface $to $pendingTwoFactorProviders = $token->getTwoFactorProviders(); $displayTrustedOption = $this->trustedFeatureEnabled && (!$config->isMultiFactor() || 1 === count($pendingTwoFactorProviders)); $authenticationException = $this->getLastAuthenticationException($request->getSession()); + $checkPath = $config->getCheckPath(); + $isRoute = strpos($checkPath, '/') === false; return [ 'twoFactorProvider' => $token->getCurrentTwoFactorProvider(), @@ -110,6 +112,8 @@ protected function getTemplateVars(Request $request, TwoFactorTokenInterface $to 'isCsrfProtectionEnabled' => $config->isCsrfProtectionEnabled(), 'csrfParameterName' => $config->getCsrfParameterName(), 'csrfTokenId' => $config->getCsrfTokenId(), + 'checkPathRoute' => $isRoute ? $checkPath:null, + 'checkPathUrl' => $isRoute ? null:$checkPath, 'logoutPath' => $this->logoutUrlGenerator->getLogoutPath(), ]; } diff --git a/Resources/views/Authentication/form.html.twig b/Resources/views/Authentication/form.html.twig index 75d6ac74..5b0b59c7 100644 --- a/Resources/views/Authentication/form.html.twig +++ b/Resources/views/Authentication/form.html.twig @@ -18,7 +18,7 @@ especially when you're using different route names than the ones used here. {# Display current two-factor provider #}

-
+

firewallConfig + ->expects($this->any()) + ->method('getCheckPath') + ->willReturn('/2fa_check'); + + $this->stubTokenStorageHasTwoFactorToken(); + + $this->assertTemplateVars(function (array $templateVars) { + $this->assertArrayHasKey('twoFactorProvider', $templateVars); + $this->assertArrayHasKey('availableTwoFactorProviders', $templateVars); + $this->assertArrayHasKey('authenticationError', $templateVars); + $this->assertArrayHasKey('authenticationErrorData', $templateVars); + $this->assertArrayHasKey('displayTrustedOption', $templateVars); + $this->assertArrayHasKey('authCodeParameterName', $templateVars); + $this->assertArrayHasKey('trustedParameterName', $templateVars); + $this->assertArrayHasKey('isCsrfProtectionEnabled', $templateVars); + $this->assertArrayHasKey('csrfParameterName', $templateVars); + $this->assertArrayHasKey('csrfTokenId', $templateVars); + $this->assertArrayHasKey('checkPathRoute', $templateVars); + $this->assertArrayHasKey('checkPathUrl', $templateVars); + $this->assertArrayHasKey('logoutPath', $templateVars); + + $this->assertEquals(self::CURRENT_TWO_FACTOR_PROVIDER, $templateVars['twoFactorProvider']); + $this->assertEquals(['provider1', 'provider2'], $templateVars['availableTwoFactorProviders']); + $this->assertEquals(self::AUTH_CODE_PARAM_NAME, $templateVars['authCodeParameterName']); + $this->assertEquals(self::TRUSTED_PARAM_NAME, $templateVars['trustedParameterName']); + $this->assertFalse($templateVars['isCsrfProtectionEnabled']); + $this->assertEquals(self::CSRF_PARAMETER, $templateVars['csrfParameterName']); + $this->assertEquals(self::CSRF_TOKEN_ID, $templateVars['csrfTokenId']); + $this->assertEquals(self::LOGOUT_PATH, $templateVars['logoutPath']); + $this->assertEquals('/2fa_check', $templateVars['checkPathUrl']); + $this->assertNull($templateVars['checkPathRoute']); + + return true; + }); + + $this->controller->form($this->request); + } + + /** + * @test + */ + public function form_renderForm_renderTemplateWithTemplateVarsSetsRoutePath(): void + { + $this->firewallConfig + ->expects($this->any()) + ->method('getCheckPath') + ->willReturn('admin_2fa_check'); + $this->stubTokenStorageHasTwoFactorToken(); $this->assertTemplateVars(function (array $templateVars) { @@ -418,6 +467,8 @@ public function form_renderForm_renderTemplateWithTemplateVars(): void $this->assertArrayHasKey('isCsrfProtectionEnabled', $templateVars); $this->assertArrayHasKey('csrfParameterName', $templateVars); $this->assertArrayHasKey('csrfTokenId', $templateVars); + $this->assertArrayHasKey('checkPathRoute', $templateVars); + $this->assertArrayHasKey('checkPathUrl', $templateVars); $this->assertArrayHasKey('logoutPath', $templateVars); $this->assertEquals(self::CURRENT_TWO_FACTOR_PROVIDER, $templateVars['twoFactorProvider']); @@ -428,6 +479,8 @@ public function form_renderForm_renderTemplateWithTemplateVars(): void $this->assertEquals(self::CSRF_PARAMETER, $templateVars['csrfParameterName']); $this->assertEquals(self::CSRF_TOKEN_ID, $templateVars['csrfTokenId']); $this->assertEquals(self::LOGOUT_PATH, $templateVars['logoutPath']); + $this->assertEquals('admin_2fa_check', $templateVars['checkPathRoute']); + $this->assertNull($templateVars['checkPathUrl']); return true; });