Continue work on ACL rewritting

* fix center resolver dispatcher
* add scope resolver
* tests for authorization helper
This commit is contained in:
2021-09-19 20:56:20 +02:00
parent 74598ee926
commit b6c58a5c31
18 changed files with 498 additions and 29 deletions

View File

@@ -24,6 +24,9 @@ use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\HasCenterInterface;
use Chill\MainBundle\Entity\HasScopeInterface;
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher;
use Chill\MainBundle\Security\Resolver\ScopeResolverInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
use Symfony\Component\Security\Core\Role\Role;
@@ -56,16 +59,24 @@ class AuthorizationHelper
protected CenterResolverDispatcher $centerResolverDispatcher;
protected ScopeResolverDispatcher $scopeResolverDispatcher;
protected LoggerInterface $logger;
public function __construct(
RoleHierarchyInterface $roleHierarchy,
ParameterBagInterface $parameterBag,
EntityManagerInterface $em,
CenterResolverDispatcher $centerResolverDispatcher
CenterResolverDispatcher $centerResolverDispatcher,
LoggerInterface $logger,
ScopeResolverDispatcher $scopeResolverDispatcher
) {
$this->roleHierarchy = $roleHierarchy;
$this->hierarchy = $parameterBag->get('security.role_hierarchy.roles');
$this->em = $em;
$this->centerResolverDispatcher = $centerResolverDispatcher;
$this->logger = $logger;
$this->scopeResolverDispatcher = $scopeResolverDispatcher;
}
/**
@@ -114,11 +125,32 @@ class AuthorizationHelper
*/
public function userHasAccess(User $user, $entity, $attribute)
{
if (NULL === $center = $this->centerResolverDispatcher->resolveCenter($entity)) {
return false;
}
$center = $this->centerResolverDispatcher->resolveCenter($entity);
if (is_iterable($center)) {
foreach ($center as $c) {
if ($this->userHasAccessForCenter($user, $c, $entity, $attribute)) {
return true;
}
}
return false;
} elseif ($center instanceof Center) {
return $this->userHasAccessForCenter($user, $center, $entity, $attribute);
} elseif (NULL === $center) {
return false;
} else {
throw new \UnexpectedValueException("could not resolver a center");
}
}
private function userHasAccessForCenter(User $user, Center $center, $entity, $attribute): bool
{
if (!$this->userCanReachCenter($user, $center)) {
$this->logger->debug("user cannot reach center of entity", [
'center_name' => $center->getName(),
'user' => $user->getUsername()
]);
return false;
}
@@ -132,24 +164,35 @@ class AuthorizationHelper
if ($this->isRoleReached($attribute, $roleScope->getRole())) {
//if yes, we have a right on something...
// perform check on scope if necessary
if ($entity instanceof HasScopeInterface) {
$scope = $entity->getScope();
if ($scope === NULL) {
return true;
}
if ($scope->getId() === $roleScope
->getScope()->getId()) {
return true;
}
if ($this->scopeResolverDispatcher->isConcerned($entity)) {
$scope = $this->scopeResolverDispatcher->resolveScope($entity);
if (NULL === $scope) {
return true;
} elseif (is_iterable($scope)) {
foreach ($scope as $s) {
if ($s === $roleScope->getScope()) {
return true;
}
}
} else {
if ($scope === $roleScope->getScope()) {
return true;
}
}
} else {
return true;
}
}
}
}
}
$this->logger->debug("user can reach center entity, but not role", [
'username' => $user->getUsername(),
'center' => $center->getName()
]);
return false;
}