mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
AuthorizationHelper: compare center and scope based on id, not on equality
For an unknown reason, in some circumstances, the use of the `===` comparator does not work when comparing Center instances and Scope instances. Then, we compare them based on the id.
This commit is contained in:
parent
2ce29f36ff
commit
d3b68f8f8f
@ -33,7 +33,13 @@ use function get_class;
|
|||||||
*/
|
*/
|
||||||
class AuthorizationHelper implements AuthorizationHelperInterface
|
class AuthorizationHelper implements AuthorizationHelperInterface
|
||||||
{
|
{
|
||||||
public function __construct(private readonly CenterResolverManagerInterface $centerResolverManager, private readonly LoggerInterface $logger, private readonly ScopeResolverDispatcher $scopeResolverDispatcher, private readonly UserACLAwareRepositoryInterface $userACLAwareRepository, private readonly ParentRoleHelper $parentRoleHelper) {}
|
public function __construct(
|
||||||
|
private readonly CenterResolverManagerInterface $centerResolverManager,
|
||||||
|
private readonly LoggerInterface $logger,
|
||||||
|
private readonly ScopeResolverDispatcher $scopeResolverDispatcher,
|
||||||
|
private readonly UserACLAwareRepositoryInterface $userACLAwareRepository,
|
||||||
|
private readonly ParentRoleHelper $parentRoleHelper
|
||||||
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter an array of centers, return only center which are reachable.
|
* Filter an array of centers, return only center which are reachable.
|
||||||
@ -233,7 +239,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
|||||||
return $this->parentRoleHelper->isRoleReached($childRole, $parentRole);
|
return $this->parentRoleHelper->isRoleReached($childRole, $parentRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function userHasAccessForCenter(User $user, Center $center, $entity, $attribute): bool
|
private function userHasAccessForCenter(User $user, Center $center, mixed $entity, $attribute): bool
|
||||||
{
|
{
|
||||||
if (!$this->userCanReachCenter($user, $center)) {
|
if (!$this->userCanReachCenter($user, $center)) {
|
||||||
$this->logger->debug('user cannot reach center of entity', [
|
$this->logger->debug('user cannot reach center of entity', [
|
||||||
@ -243,10 +249,11 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($user->getGroupCenters() as $groupCenter) {
|
foreach ($user->getGroupCenters() as $groupCenter) {
|
||||||
//filter on center
|
// filter on center
|
||||||
if ($groupCenter->getCenter() === $center) {
|
// in some case, the center can be the same, but have different object hashes,
|
||||||
|
// we cannot compare the objects: we must compare the ids here
|
||||||
|
if ($groupCenter->getCenter()->getId() === $center->getId()) {
|
||||||
$permissionGroup = $groupCenter->getPermissionsGroup();
|
$permissionGroup = $groupCenter->getPermissionsGroup();
|
||||||
//iterate on roleScopes
|
//iterate on roleScopes
|
||||||
foreach ($permissionGroup->getRoleScopes() as $roleScope) {
|
foreach ($permissionGroup->getRoleScopes() as $roleScope) {
|
||||||
@ -263,7 +270,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
|||||||
|
|
||||||
if (is_iterable($scope)) {
|
if (is_iterable($scope)) {
|
||||||
foreach ($scope as $s) {
|
foreach ($scope as $s) {
|
||||||
if ($roleScope->getScope() === $s) {
|
if ($roleScope->getScope()->getId() === $s->getId()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Test;
|
namespace Chill\MainBundle\Test;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A trait to prepare center.
|
* A trait to prepare center.
|
||||||
*
|
*
|
||||||
@ -25,23 +27,17 @@ trait PrepareCenterTrait
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* prepare a mocked center, with and id and name given.
|
* prepare a mocked center, with and id and name given.
|
||||||
*
|
|
||||||
* @param int $id
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return \Chill\MainBundle\Entity\Center
|
|
||||||
*/
|
*/
|
||||||
protected function prepareCenter($id, $name)
|
protected function prepareCenter(int $id, string $name): Center
|
||||||
{
|
{
|
||||||
if (null === $this->centerProphet) {
|
$center = new Center();
|
||||||
$this->centerProphet = new \Prophecy\Prophet();
|
$center->setName($name);
|
||||||
}
|
|
||||||
|
|
||||||
$center = $this->centerProphet->prophesize();
|
$reflectionClass = new \ReflectionClass($center);
|
||||||
$center->willExtend('\\' . \Chill\MainBundle\Entity\Center::class);
|
$reflectionId = $reflectionClass->getProperty('id');
|
||||||
$center->getId()->willReturn($id);
|
$reflectionId->setAccessible(true);
|
||||||
$center->getName()->willReturn($name);
|
$reflectionId->setValue($center, $id);
|
||||||
|
|
||||||
return $center->reveal();
|
return $center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,8 @@ final class AuthorizationHelperTest extends KernelTestCase
|
|||||||
|
|
||||||
public function dataProvider_getReachableCenters()
|
public function dataProvider_getReachableCenters()
|
||||||
{
|
{
|
||||||
$this->setUp();
|
self::bootKernel();
|
||||||
|
|
||||||
$centerA = $this->prepareCenter(1, 'center A');
|
$centerA = $this->prepareCenter(1, 'center A');
|
||||||
$centerB = $this->prepareCenter(2, 'center B');
|
$centerB = $this->prepareCenter(2, 'center B');
|
||||||
$scopeA = $this->prepareScope(1, 'scope default');
|
$scopeA = $this->prepareScope(1, 'scope default');
|
||||||
@ -311,9 +312,9 @@ final class AuthorizationHelperTest extends KernelTestCase
|
|||||||
public function testUserHasAccessEntityMultiScope()
|
public function testUserHasAccessEntityMultiScope()
|
||||||
{
|
{
|
||||||
$centerA = $this->prepareCenter(1, 'center');
|
$centerA = $this->prepareCenter(1, 'center');
|
||||||
$centerB = $this->prepareCenter(1, 'centerB');
|
$centerB = $this->prepareCenter(2, 'centerB');
|
||||||
$scopeA = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
$scopeA = $this->prepareScope(3, 'other'); //the user will be granted this scope
|
||||||
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
$scopeB = $this->prepareScope(4, 'other'); //the user will be granted this scope
|
||||||
$user = $this->prepareUser([
|
$user = $this->prepareUser([
|
||||||
[
|
[
|
||||||
'center' => $centerA, 'permissionsGroup' => [
|
'center' => $centerA, 'permissionsGroup' => [
|
||||||
@ -331,6 +332,24 @@ final class AuthorizationHelperTest extends KernelTestCase
|
|||||||
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUserHasAccessEntityIsCenter()
|
||||||
|
{
|
||||||
|
$centerA = $this->prepareCenter(1, 'center');
|
||||||
|
$centerB = $this->prepareCenter(2, 'centerB');
|
||||||
|
$user = $this->prepareUser([
|
||||||
|
[
|
||||||
|
'center' => $centerA, 'permissionsGroup' => [
|
||||||
|
['scope' => null, 'role' => 'CHILL_ROLE'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$helper = $this->getAuthorizationHelper();
|
||||||
|
|
||||||
|
$this->assertFalse($helper->userHasAccess($user, $centerB, 'CHILL_ROLE'));
|
||||||
|
$this->assertTrue($helper->userHasAccess($user, $centerA, 'CHILL_ROLE'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testUserHasAccessMultiCenterEntityWithoutScope()
|
public function testUserHasAccessMultiCenterEntityWithoutScope()
|
||||||
{
|
{
|
||||||
$center = $this->prepareCenter(1, 'center');
|
$center = $this->prepareCenter(1, 'center');
|
||||||
@ -515,10 +534,10 @@ final class AuthorizationHelperTest extends KernelTestCase
|
|||||||
public function testUserHasNoAccessEntityMultiScope()
|
public function testUserHasNoAccessEntityMultiScope()
|
||||||
{
|
{
|
||||||
$centerA = $this->prepareCenter(1, 'center');
|
$centerA = $this->prepareCenter(1, 'center');
|
||||||
$centerB = $this->prepareCenter(1, 'centerB');
|
$centerB = $this->prepareCenter(2, 'centerB');
|
||||||
$scopeA = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
$scopeA = $this->prepareScope(3, 'other'); //the user will be granted this scope
|
||||||
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
$scopeB = $this->prepareScope(4, 'other'); //the user will be granted this scope
|
||||||
$scopeC = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
$scopeC = $this->prepareScope(5, 'other'); //the user will be granted this scope
|
||||||
$user = $this->prepareUser([
|
$user = $this->prepareUser([
|
||||||
[
|
[
|
||||||
'center' => $centerA, 'permissionsGroup' => [
|
'center' => $centerA, 'permissionsGroup' => [
|
||||||
@ -539,9 +558,9 @@ final class AuthorizationHelperTest extends KernelTestCase
|
|||||||
public function testUserHasNoAccessMultiCenterEntityWithoutScope()
|
public function testUserHasNoAccessMultiCenterEntityWithoutScope()
|
||||||
{
|
{
|
||||||
$center = $this->prepareCenter(1, 'center');
|
$center = $this->prepareCenter(1, 'center');
|
||||||
$centerB = $this->prepareCenter(1, 'centerB');
|
$centerB = $this->prepareCenter(2, 'centerB');
|
||||||
$centerC = $this->prepareCenter(1, 'centerC');
|
$centerC = $this->prepareCenter(3, 'centerC');
|
||||||
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
$scopeB = $this->prepareScope(4, 'other'); //the user will be granted this scope
|
||||||
$user = $this->prepareUser([
|
$user = $this->prepareUser([
|
||||||
[
|
[
|
||||||
'center' => $center, 'permissionsGroup' => [
|
'center' => $center, 'permissionsGroup' => [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user