From a0ff55c0130297e0738344fb428381141f440e48 Mon Sep 17 00:00:00 2001 From: Kamil Madejski Date: Tue, 6 Oct 2020 16:54:16 +0200 Subject: [PATCH] EZP-31875: Added request matcher to recognize REST requests executed in AdminUI context (#1488) --- .../Resources/config/services/rest.yaml | 4 + .../Security/NonAdminRESTRequestMatcher.php | 36 +++++++ .../NonAdminRESTRequestMatcherTest.php | 99 +++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/lib/REST/Security/NonAdminRESTRequestMatcher.php create mode 100644 src/lib/Tests/REST/Security/NonAdminRESTRequestMatcherTest.php diff --git a/src/bundle/Resources/config/services/rest.yaml b/src/bundle/Resources/config/services/rest.yaml index 9dc1856d3a..4840fa6234 100644 --- a/src/bundle/Resources/config/services/rest.yaml +++ b/src/bundle/Resources/config/services/rest.yaml @@ -37,3 +37,7 @@ services: parent: ezpublish_rest.output.value_object_visitor.base tags: - { name: ezpublish_rest.output.value_object_visitor, type: EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Root } + + EzSystems\EzPlatformAdminUi\REST\Security\NonAdminRESTRequestMatcher: + arguments: + $siteAccessGroups: '%ezpublish.siteaccess.groups%' diff --git a/src/lib/REST/Security/NonAdminRESTRequestMatcher.php b/src/lib/REST/Security/NonAdminRESTRequestMatcher.php new file mode 100644 index 0000000000..1c482eebef --- /dev/null +++ b/src/lib/REST/Security/NonAdminRESTRequestMatcher.php @@ -0,0 +1,36 @@ +siteAccessGroups = $siteAccessGroups; + } + + public function matches(Request $request): bool + { + return + $request->attributes->get('is_rest_request') && + !$this->isAdminSiteAccess($request); + } + + private function isAdminSiteAccess(Request $request): bool + { + return (new IsAdmin($this->siteAccessGroups))->isSatisfiedBy($request->attributes->get('siteaccess')); + } +} diff --git a/src/lib/Tests/REST/Security/NonAdminRESTRequestMatcherTest.php b/src/lib/Tests/REST/Security/NonAdminRESTRequestMatcherTest.php new file mode 100644 index 0000000000..f3162edcaa --- /dev/null +++ b/src/lib/Tests/REST/Security/NonAdminRESTRequestMatcherTest.php @@ -0,0 +1,99 @@ +createMock(SiteAccess::class); + $siteAccessMock->name = 'admin'; + $adminRESTRequestMatcher = new NonAdminRESTRequestMatcher( + [ + 'admin_group' => [ + 'admin', + ], + ] + ); + + $request = $this->createMock(Request::class); + $request->attributes = $this->createMock(ParameterBag::class); + + $request->attributes + ->expects(self::at(0)) + ->method('get') + ->with('is_rest_request') + ->willReturn(true); + + $request->attributes + ->expects(self::at(1)) + ->method('get') + ->with('siteaccess') + ->willReturn($siteAccessMock); + + self::assertFalse($adminRESTRequestMatcher->matches($request)); + } + + public function testMatchNonRESTRequest(): void + { + $adminRESTRequestMatcher = new NonAdminRESTRequestMatcher([]); + + $request = $this->createMock(Request::class); + $request->attributes = $this->createMock(ParameterBag::class); + + $request->attributes + ->expects(self::at(0)) + ->method('get') + ->with('is_rest_request') + ->willReturn(false); + + self::assertFalse($adminRESTRequestMatcher->matches($request)); + } + + public function testMatchRESTRequestNotInAdminContext(): void + { + $siteAccessMock = $this->createMock(SiteAccess::class); + $siteAccessMock->name = 'admin'; + $nonAdminSiteAccessMock = $this->createMock(SiteAccess::class); + $nonAdminSiteAccessMock->name = 'ibexa'; + $adminRESTRequestMatcher = new NonAdminRESTRequestMatcher( + [ + 'admin_group' => [ + 'admin', + ], + 'another_group' => [ + 'ibexa', + ], + ] + ); + + $request = $this->createMock(Request::class); + $request->attributes = $this->createMock(ParameterBag::class); + + $request->attributes + ->expects(self::at(0)) + ->method('get') + ->with('is_rest_request') + ->willReturn(true); + + $request->attributes + ->expects(self::at(1)) + ->method('get') + ->with('siteaccess') + ->willReturn($nonAdminSiteAccessMock); + + self::assertTrue($adminRESTRequestMatcher->matches($request)); + } +}