From b47287c848ae99f412f84fd15e50fc42335c0245 Mon Sep 17 00:00:00 2001 From: Christian Scheb Date: Mon, 1 Jun 2020 12:55:27 +0200 Subject: [PATCH] Add test cases for PUBLIC_ACCESS (cherry picked from commit 9961ed41fec20cf58e941230aca7612e14a55266) --- .../TwoFactorAccessDeciderTest.php | 40 ++++++++++++++++--- Tests/TestCase.php | 15 +++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php b/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php index e9946cb9..8fd39b11 100644 --- a/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php +++ b/Tests/Security/Authorization/TwoFactorAccessDeciderTest.php @@ -12,6 +12,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Symfony\Component\Security\Http\AccessMapInterface; +use Symfony\Component\Security\Http\Firewall\AccessListener; use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator; @@ -20,6 +21,7 @@ class TwoFactorAccessDeciderTest extends TestCase private const BASE_URL = '/app_dev.php'; private const LOGOUT_PATH = '/logout'; private const LOGOUT_PATH_WITH_BASE_URL = self::BASE_URL.self::LOGOUT_PATH; + private const ACCESS_MAP_ATTRIBUTES = [TwoFactorInProgressVoter::IS_AUTHENTICATED_2FA_IN_PROGRESS]; /** * @var MockObject|Request @@ -36,6 +38,11 @@ class TwoFactorAccessDeciderTest extends TestCase */ private $accessMap; + /** + * @var string[] + */ + private $attributes; + /** * @var MockObject|AccessDecisionManagerInterface */ @@ -64,15 +71,17 @@ protected function setUp(): void $this->accessDecisionManager = $this->createMock(AccessDecisionManagerInterface::class); $this->httpUtils = $this->createMock(HttpUtils::class); $this->logoutUrlGenerator = $this->createMock(LogoutUrlGenerator::class); + $this->accessDecider = new TwoFactorAccessDecider($this->accessMap, $this->accessDecisionManager, $this->httpUtils, $this->logoutUrlGenerator); + } - // Stub an access rule + private function stubAccessMapReturnsAttributes(array $attributes): void + { + $this->attributes = $attributes; $this->accessMap ->expects($this->any()) ->method('getPatterns') ->with($this->request) - ->willReturn([[TwoFactorInProgressVoter::IS_AUTHENTICATED_2FA_IN_PROGRESS], 'https']); - - $this->accessDecider = new TwoFactorAccessDecider($this->accessMap, $this->accessDecisionManager, $this->httpUtils, $this->logoutUrlGenerator); + ->willReturn([$attributes, 'https']); } private function whenGeneratedLogoutPath(string $generatedLogoutPath): void @@ -96,7 +105,7 @@ private function whenPathAccess(bool $accessGranted): void $this->accessDecisionManager ->expects($this->any()) ->method('decide') - ->with($this->isInstanceOf(TokenInterface::class), [TwoFactorInProgressVoter::IS_AUTHENTICATED_2FA_IN_PROGRESS], $this->request) + ->with($this->isInstanceOf(TokenInterface::class), $this->attributes, $this->request) ->willReturn($accessGranted); } @@ -114,6 +123,7 @@ private function whenIsLogoutPath(bool $accessGranted): void */ public function isAccessible_pathAccessGranted_returnTrue(): void { + $this->stubAccessMapReturnsAttributes(self::ACCESS_MAP_ATTRIBUTES); $this->whenPathAccess(true); $this->whenIsLogoutPath(false); @@ -121,11 +131,29 @@ public function isAccessible_pathAccessGranted_returnTrue(): void $this->assertTrue($returnValue); } + /** + * @test + */ + public function isAccessible_isPublic_returnTrue(): void + { + $this->requireSymfony5_1(); + + $this->stubAccessMapReturnsAttributes([AccessListener::PUBLIC_ACCESS]); + $this->whenRequestBaseUrl(''); + $this->whenGeneratedLogoutPath(self::LOGOUT_PATH); + $this->whenPathAccess(false); + $this->whenIsLogoutPath(false); + + $returnValue = $this->accessDecider->isAccessible($this->request, $this->token); + $this->assertTrue($returnValue); + } + /** * @test */ public function isAccessible_isLogoutPathNoBasePath_returnTrue(): void { + $this->stubAccessMapReturnsAttributes(self::ACCESS_MAP_ATTRIBUTES); $this->whenRequestBaseUrl(''); $this->whenGeneratedLogoutPath(self::LOGOUT_PATH); $this->whenPathAccess(false); @@ -140,6 +168,7 @@ public function isAccessible_isLogoutPathNoBasePath_returnTrue(): void */ public function isAccessible_isLogoutPathWithBasePath_returnTrue(): void { + $this->stubAccessMapReturnsAttributes(self::ACCESS_MAP_ATTRIBUTES); $this->whenRequestBaseUrl(self::BASE_URL); $this->whenGeneratedLogoutPath(self::LOGOUT_PATH_WITH_BASE_URL); $this->whenPathAccess(false); @@ -154,6 +183,7 @@ public function isAccessible_isLogoutPathWithBasePath_returnTrue(): void */ public function isAccessible_isNotAccessible_returnFalse(): void { + $this->stubAccessMapReturnsAttributes(self::ACCESS_MAP_ATTRIBUTES); $this->whenRequestBaseUrl(''); $this->whenGeneratedLogoutPath(self::LOGOUT_PATH); $this->whenPathAccess(false); diff --git a/Tests/TestCase.php b/Tests/TestCase.php index f87ad496..8ed00c25 100644 --- a/Tests/TestCase.php +++ b/Tests/TestCase.php @@ -5,7 +5,22 @@ namespace Scheb\TwoFactorBundle\Tests; use PHPUnit\Framework\TestCase as PHPUnitTestCase; +use Symfony\Component\HttpKernel\Kernel; +// phpcs:ignore Symfony.NamingConventions.ValidClassName abstract class TestCase extends PHPUnitTestCase { + private const SYMFONY_5_1 = 50100; + + protected function requireSymfony5_1() + { + $this->requireSymfonyVersion(self::SYMFONY_5_1); + } + + private function requireSymfonyVersion(int $version) + { + if (Kernel::VERSION_ID < $version) { + $this->markTestSkipped("This Symfony version doesn't support authenticators."); + } + } }