mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
569 lines
20 KiB
PHP
569 lines
20 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Tests\Security\Authorization;
|
|
|
|
use Chill\MainBundle\Entity\Center;
|
|
use Chill\MainBundle\Entity\HasCenterInterface;
|
|
use Chill\MainBundle\Entity\HasCentersInterface;
|
|
use Chill\MainBundle\Entity\HasScopeInterface;
|
|
use Chill\MainBundle\Entity\HasScopesInterface;
|
|
use Chill\MainBundle\Entity\Scope;
|
|
use Chill\MainBundle\Entity\User;
|
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
|
use Chill\MainBundle\Test\PrepareCenterTrait;
|
|
use Chill\MainBundle\Test\PrepareScopeTrait;
|
|
use Chill\MainBundle\Test\PrepareUserTrait;
|
|
use Prophecy\PhpUnit\ProphecyTrait;
|
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
|
use function in_array;
|
|
|
|
/**
|
|
* @internal
|
|
* @coversNothing
|
|
*/
|
|
final class AuthorizationHelperTest extends KernelTestCase
|
|
{
|
|
use PrepareCenterTrait;
|
|
|
|
use PrepareScopeTrait;
|
|
|
|
use PrepareUserTrait;
|
|
|
|
use ProphecyTrait;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
self::bootKernel();
|
|
}
|
|
|
|
public function dataProvider_getReachableCenters()
|
|
{
|
|
$this->setUp();
|
|
$centerA = $this->prepareCenter(1, 'center A');
|
|
$centerB = $this->prepareCenter(2, 'center B');
|
|
$scopeA = $this->prepareScope(1, 'scope default');
|
|
$scopeB = $this->prepareScope(2, 'scope B');
|
|
$scopeC = $this->prepareScope(3, 'scope C');
|
|
|
|
$userA = $this->prepareUser([
|
|
[
|
|
'center' => $centerA,
|
|
'permissionsGroup' => [
|
|
['scope' => $scopeB, 'role' => 'CHILL_ROLE_1'],
|
|
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
|
|
],
|
|
],
|
|
[
|
|
'center' => $centerB,
|
|
'permissionsGroup' => [
|
|
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
|
|
['scope' => $scopeC, 'role' => 'CHILL_ROLE_2'],
|
|
],
|
|
],
|
|
]);
|
|
|
|
$ah = $this->getAuthorizationHelper();
|
|
|
|
return [
|
|
// without scopes
|
|
[
|
|
true,
|
|
in_array($centerA, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_1',
|
|
null
|
|
), true),
|
|
'center A should be available for userA, with role 1 ',
|
|
],
|
|
[
|
|
true,
|
|
in_array($centerA, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_2',
|
|
null
|
|
), true),
|
|
'center A should be available for userA, with role 2 ',
|
|
],
|
|
[
|
|
true,
|
|
in_array($centerB, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_2',
|
|
null
|
|
), true),
|
|
'center A should be available for userA, with role 2 ',
|
|
],
|
|
[
|
|
false,
|
|
in_array($centerB, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_1',
|
|
null
|
|
), true),
|
|
'center B should NOT be available for userA, with role 1 ',
|
|
],
|
|
// with scope
|
|
[
|
|
true,
|
|
in_array($centerA, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_1',
|
|
$scopeB
|
|
), true),
|
|
'center A should be available for userA, with role 1, scopeC ',
|
|
],
|
|
[
|
|
false,
|
|
in_array($centerA, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_2',
|
|
$scopeC
|
|
), true),
|
|
'center A should NOT be available for userA, with role 2, scopeA ',
|
|
],
|
|
[
|
|
true,
|
|
in_array($centerB, $ah->getReachableCenters(
|
|
$userA,
|
|
'CHILL_ROLE_2',
|
|
$scopeA
|
|
), true),
|
|
'center B should be available for userA, with role 2, scopeA ',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function dataProvider_getReachableScopes()
|
|
{
|
|
$centerA = $this->prepareCenter(1, 'center A');
|
|
$centerB = $this->prepareCenter(2, 'center B');
|
|
$scopeA = $this->prepareScope(1, 'scope default');
|
|
$scopeB = $this->prepareScope(2, 'scope B');
|
|
$scopeC = $this->prepareScope(3, 'scope C');
|
|
|
|
$userA = $this->prepareUser([
|
|
[
|
|
'center' => $centerA,
|
|
'permissionsGroup' => [
|
|
['scope' => $scopeB, 'role' => 'CHILL_ROLE_1'],
|
|
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
|
|
],
|
|
],
|
|
[
|
|
'center' => $centerB,
|
|
'permissionsGroup' => [
|
|
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
|
|
['scope' => $scopeC, 'role' => 'CHILL_ROLE_2'],
|
|
['scope' => $scopeB, 'role' => 'CHILL_ROLE_2'],
|
|
],
|
|
],
|
|
]);
|
|
|
|
return [
|
|
[
|
|
true,
|
|
$scopeA,
|
|
$userA,
|
|
'CHILL_ROLE_2',
|
|
$centerA,
|
|
'Assert that a scope is found within accessible scopes',
|
|
],
|
|
[
|
|
false,
|
|
$scopeB,
|
|
$userA,
|
|
'CHILL_ROLE_2',
|
|
$centerA,
|
|
'Assert that a scope not reachable is NOT found within accessible scopes',
|
|
],
|
|
[
|
|
false,
|
|
$scopeB,
|
|
$userA,
|
|
'CHILL_ROLE_1',
|
|
$centerB,
|
|
'Assert that a scope not reachable is not found within accessible scopes.'
|
|
. ' Trying on filter centering',
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @group legacy
|
|
*/
|
|
public function testGetParentRoles()
|
|
{
|
|
$parentRoles = $this->getAuthorizationHelper()
|
|
->getParentRoles('CHILL_INHERITED_ROLE_1');
|
|
|
|
$this->assertContains(
|
|
'CHILL_MASTER_ROLE',
|
|
$parentRoles,
|
|
'Assert that `CHILL_MASTER_ROLE` is a parent of `CHILL_INHERITED_ROLE_1`'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider dataProvider_getReachableCenters
|
|
*/
|
|
public function testGetReachableCenters(mixed $test, mixed $result, mixed $msg)
|
|
{
|
|
$this->assertEquals($test, $result, $msg);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider dataProvider_getReachableScopes
|
|
*
|
|
* @param bool $expectedResult
|
|
* @param string $message
|
|
*/
|
|
public function testGetReachableScopes(
|
|
$expectedResult,
|
|
Scope $testedScope,
|
|
User $user,
|
|
string $role,
|
|
Center $center,
|
|
$message
|
|
) {
|
|
$reachableScopes = $this->getAuthorizationHelper()
|
|
->getReachableScopes($user, $role, $center);
|
|
|
|
$this->assertEquals(
|
|
$expectedResult,
|
|
in_array($testedScope, $reachableScopes, true),
|
|
$message
|
|
);
|
|
}
|
|
|
|
public function testtestUserHasAccessUserShouldHaveAccessEntityWithScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasScopeInterface::class);
|
|
$entity->getCenter()->willReturn($center);
|
|
$entity->getScope()->willReturn($scope);
|
|
|
|
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
/**
|
|
* Test function userCanReach of helper.
|
|
*
|
|
* A user can not reachcenter =>W the function should return false
|
|
*/
|
|
public function testUserCanReachCenterUserShouldNotReach()
|
|
{
|
|
$centerA = $this->prepareCenter(1, 'center');
|
|
$centerB = $this->prepareCenter(2, 'centerB');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $centerA, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'ANY_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
|
|
$this->assertFalse($helper->userCanReachCenter($user, $centerB));
|
|
}
|
|
|
|
/**
|
|
* Test function userCanReach of helper.
|
|
*
|
|
* A user can reach center => the function should return true.
|
|
*/
|
|
public function testUserCanReachCenterUserShouldReach()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'ANY_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
|
|
$this->assertTrue($helper->userCanReachCenter($user, $center));
|
|
}
|
|
|
|
public function testUserHasAccessEntityMultiScope()
|
|
{
|
|
$centerA = $this->prepareCenter(1, 'center');
|
|
$centerB = $this->prepareCenter(1, 'centerB');
|
|
$scopeA = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $centerA, 'permissionsGroup' => [
|
|
['scope' => $scopeA, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement(HasCentersInterface::class);
|
|
$entity->willImplement(HasScopesInterface::class);
|
|
$entity->getCenters()->willReturn([$centerA, $centerB]);
|
|
$entity->getScopes()->willReturn([$scopeA, $scopeB]);
|
|
|
|
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testUserHasAccessMultiCenterEntityWithoutScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$centerB = $this->prepareCenter(1, 'centerB');
|
|
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scopeB, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement(HasCentersInterface::class);
|
|
$entity->getCenters()->willReturn([$center, $centerB]);
|
|
|
|
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testUserHasAccessShouldHaveAccessEntityWithoutScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->getCenter()->willReturn($center);
|
|
|
|
$this->assertTrue($helper->userHasAccess(
|
|
$user,
|
|
$entity->reveal(),
|
|
'CHILL_ROLE'
|
|
));
|
|
}
|
|
|
|
public function testUserHasAccessShouldHaveAccessWithInheritanceEntityWithoutScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'CHILL_MASTER_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->getCenter()->willReturn($center);
|
|
|
|
$this->assertTrue($helper->userHasAccess(
|
|
$user,
|
|
$entity->reveal(),
|
|
'CHILL_INHERITED_ROLE_1'
|
|
));
|
|
}
|
|
|
|
public function testUserHasAccessUserHasNoCenterEntityWithScope()
|
|
{
|
|
$centerA = $this->prepareCenter(1, 'center'); //the user will have this center
|
|
$centerB = $this->prepareCenter(2, 'centerB'); //the entity will have another center
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $centerA, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasScopeInterface::class);
|
|
$entity->getCenter()->willReturn($centerB);
|
|
$entity->getScope()->willReturn($scope);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testuserHasAccessUserHasNoRoleEntityWithoutScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'ANY_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->getCenter()->willReturn($center);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testUserHasAccessUserHasNoRoleEntityWithScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasScopeInterface::class);
|
|
$entity->getCenter()->willReturn($center);
|
|
$entity->getScope()->willReturn($scope);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'ANOTHER_ROLE'));
|
|
}
|
|
|
|
/**
|
|
* test that a user has no access on a entity, but is granted on the same role
|
|
* on another center.
|
|
*/
|
|
public function testUserHasAccessUserHasNoRoleUserHasRoleOnAnotherCenterEntityWithoutScope()
|
|
{
|
|
$centerA = $this->prepareCenter(1, 'center');
|
|
$centerB = $this->prepareCenter(2, 'centerB');
|
|
$scope = $this->prepareScope(1, 'default');
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $centerA, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'ANY_ROLE'],
|
|
],
|
|
[
|
|
'centerB' => $centerB, 'permissionsGroup' => [
|
|
['scope' => $scope, 'role' => 'ANY_ROLE'],
|
|
['scope' => $scope, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement('\\' . \Chill\MainBundle\Entity\HasCenterInterface::class);
|
|
$entity->getCenter()->willReturn($centerA);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testUserHasAccessUserHasNoScopeEntityWithScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$scopeA = $this->prepareScope(1, 'default'); //the entity will have this scope
|
|
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scopeB, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement(HasCenterInterface::class);
|
|
$entity->willImplement(HasScopeInterface::class);
|
|
$entity->getCenter()->willReturn($center);
|
|
$entity->getScope()->willReturn($scopeA);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testUserHasNoAccessEntityMultiScope()
|
|
{
|
|
$centerA = $this->prepareCenter(1, 'center');
|
|
$centerB = $this->prepareCenter(1, 'centerB');
|
|
$scopeA = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$scopeC = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $centerA, 'permissionsGroup' => [
|
|
['scope' => $scopeA, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement(HasCentersInterface::class);
|
|
$entity->willImplement(HasScopesInterface::class);
|
|
$entity->getCenters()->willReturn([$centerA, $centerB]);
|
|
$entity->getScopes()->willReturn([$scopeB, $scopeC]);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
public function testUserHasNoAccessMultiCenterEntityWithoutScope()
|
|
{
|
|
$center = $this->prepareCenter(1, 'center');
|
|
$centerB = $this->prepareCenter(1, 'centerB');
|
|
$centerC = $this->prepareCenter(1, 'centerC');
|
|
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
|
$user = $this->prepareUser([
|
|
[
|
|
'center' => $center, 'permissionsGroup' => [
|
|
['scope' => $scopeB, 'role' => 'CHILL_ROLE'],
|
|
],
|
|
],
|
|
]);
|
|
$helper = $this->getAuthorizationHelper();
|
|
$entity = $this->prophesize();
|
|
$entity->willImplement(HasCentersInterface::class);
|
|
$entity->getCenters()->willReturn([$centerB, $centerC]);
|
|
|
|
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
|
}
|
|
|
|
/**
|
|
* @return \Chill\MainBundle\Security\Authorization\AuthorizationHelper
|
|
*/
|
|
private function getAuthorizationHelper()
|
|
{
|
|
return self::$container
|
|
->get(AuthorizationHelper::class);
|
|
}
|
|
}
|