Skip to content

Commit

Permalink
EZP-31875: Added request matcher to recognize REST requests executed …
Browse files Browse the repository at this point in the history
…in AdminUI context (#1488)
  • Loading branch information
kmadejski authored Oct 6, 2020
1 parent 099bc42 commit a0ff55c
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/bundle/Resources/config/services/rest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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%'
36 changes: 36 additions & 0 deletions src/lib/REST/Security/NonAdminRESTRequestMatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\REST\Security;

use EzSystems\EzPlatformAdminUi\Specification\SiteAccess\IsAdmin;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;

final class NonAdminRESTRequestMatcher implements RequestMatcherInterface
{
/** @var string[][] */
private $siteAccessGroups;

public function __construct(array $siteAccessGroups)
{
$this->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'));
}
}
99 changes: 99 additions & 0 deletions src/lib/Tests/REST/Security/NonAdminRESTRequestMatcherTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\Tests\REST\Security;

use eZ\Publish\Core\MVC\Symfony\SiteAccess;
use EzSystems\EzPlatformAdminUi\REST\Security\NonAdminRESTRequestMatcher;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;

class NonAdminRESTRequestMatcherTest extends TestCase
{
public function testMatchRESTRequestInAdminContext(): void
{
$siteAccessMock = $this->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));
}
}

0 comments on commit a0ff55c

Please # to comment.