mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
apply new role on accompanying period
This commit is contained in:
parent
cf40f38463
commit
74598ee926
@ -146,14 +146,7 @@ class ScopePickerType extends AbstractType
|
|||||||
->setParameter('center', $center->getId())
|
->setParameter('center', $center->getId())
|
||||||
// role constraints
|
// role constraints
|
||||||
->andWhere($qb->expr()->in('rs.role', ':roles'))
|
->andWhere($qb->expr()->in('rs.role', ':roles'))
|
||||||
->setParameter(
|
->setParameter('roles', $roles)
|
||||||
'roles', \array_map(
|
|
||||||
function (Role $role) {
|
|
||||||
return $role->getRole();
|
|
||||||
},
|
|
||||||
$roles
|
|
||||||
)
|
|
||||||
)
|
|
||||||
// user contraint
|
// user contraint
|
||||||
->andWhere(':user MEMBER OF gc.users')
|
->andWhere(':user MEMBER OF gc.users')
|
||||||
->setParameter('user', $this->tokenStorage->getToken()->getUser());
|
->setParameter('user', $this->tokenStorage->getToken()->getUser());
|
||||||
|
@ -269,16 +269,12 @@ class AuthorizationHelper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param Role $role
|
* @return User[]
|
||||||
* @param Center $center
|
|
||||||
* @param Scope $circle
|
|
||||||
* @return Users
|
|
||||||
*/
|
*/
|
||||||
public function findUsersReaching(Role $role, Center $center, Scope $circle = null)
|
public function findUsersReaching(string $role, Center $center, Scope $circle = null): array
|
||||||
{
|
{
|
||||||
$parents = $this->getParentRoles($role);
|
$parents = $this->getParentRoles($role);
|
||||||
$parents[] = $role;
|
$parents[] = $role;
|
||||||
$parentRolesString = \array_map(function(Role $r) { return $r->getRole(); }, $parents);
|
|
||||||
|
|
||||||
$qb = $this->em->createQueryBuilder();
|
$qb = $this->em->createQueryBuilder();
|
||||||
$qb
|
$qb
|
||||||
@ -288,7 +284,7 @@ class AuthorizationHelper
|
|||||||
->join('gc.permissionsGroup', 'pg')
|
->join('gc.permissionsGroup', 'pg')
|
||||||
->join('pg.roleScopes', 'rs')
|
->join('pg.roleScopes', 'rs')
|
||||||
->where('gc.center = :center')
|
->where('gc.center = :center')
|
||||||
->andWhere($qb->expr()->in('rs.role', $parentRolesString))
|
->andWhere($qb->expr()->in('rs.role', $parents))
|
||||||
;
|
;
|
||||||
|
|
||||||
$qb->setParameter('center', $center);
|
$qb->setParameter('center', $center);
|
||||||
@ -322,21 +318,16 @@ class AuthorizationHelper
|
|||||||
* which are registered into Chill are taken into account.
|
* which are registered into Chill are taken into account.
|
||||||
*
|
*
|
||||||
* @param Role $role
|
* @param Role $role
|
||||||
* @return Role[] the role which give access to the given $role
|
* @return string[] the role which give access to the given $role
|
||||||
*/
|
*/
|
||||||
public function getParentRoles(Role $role)
|
public function getParentRoles($role): array
|
||||||
{
|
{
|
||||||
$parentRoles = [];
|
$parentRoles = [];
|
||||||
// transform the roles from role hierarchy from string to Role
|
// transform the roles from role hierarchy from string to Role
|
||||||
$roles = \array_map(
|
$roles = \array_keys($this->hierarchy);
|
||||||
function($string) {
|
|
||||||
return new Role($string);
|
|
||||||
},
|
|
||||||
\array_keys($this->hierarchy)
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($roles as $r) {
|
foreach ($roles as $r) {
|
||||||
$childRoles = $this->roleHierarchy->getReachableRoleNames([$r->getRole()]);
|
$childRoles = $this->roleHierarchy->getReachableRoleNames([$r]);
|
||||||
|
|
||||||
if (\in_array($role, $childRoles)) {
|
if (\in_array($role, $childRoles)) {
|
||||||
$parentRoles[] = $r;
|
$parentRoles[] = $r;
|
||||||
|
@ -5,7 +5,7 @@ namespace Chill\MainBundle\Security\Authorization;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
||||||
|
|
||||||
class DefaultVoterHelper implements VoterHelperInterface
|
final class DefaultVoterHelper implements VoterHelperInterface
|
||||||
{
|
{
|
||||||
protected AuthorizationHelper $authorizationHelper;
|
protected AuthorizationHelper $authorizationHelper;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ final class DefaultVoterHelperGenerator implements VoterGeneratorInterface
|
|||||||
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addCheckFor($subject, $attributes): self
|
public function addCheckFor(?string $subject, array $attributes): self
|
||||||
{
|
{
|
||||||
$this->configuration[] = [$attributes, $subject];
|
$this->configuration[] = [$attributes, $subject];
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ interface VoterGeneratorInterface
|
|||||||
* @param array $attributes an array of attributes
|
* @param array $attributes an array of attributes
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addCheckFor(string $class, array $attributes): self;
|
public function addCheckFor(?string $class, array $attributes): self;
|
||||||
|
|
||||||
public function build(): VoterHelperInterface;
|
public function build(): VoterHelperInterface;
|
||||||
}
|
}
|
||||||
|
@ -446,16 +446,9 @@ class AuthorizationHelperTest extends KernelTestCase
|
|||||||
public function testGetParentRoles()
|
public function testGetParentRoles()
|
||||||
{
|
{
|
||||||
$parentRoles = $this->getAuthorizationHelper()
|
$parentRoles = $this->getAuthorizationHelper()
|
||||||
->getParentRoles(new Role('CHILL_INHERITED_ROLE_1'));
|
->getParentRoles('CHILL_INHERITED_ROLE_1');
|
||||||
|
|
||||||
$this->assertContains(
|
$this->assertContains('CHILL_MASTER_ROLE', $parentRoles,
|
||||||
'CHILL_MASTER_ROLE',
|
|
||||||
\array_map(
|
|
||||||
function(Role $role) {
|
|
||||||
return $role->getRole();
|
|
||||||
},
|
|
||||||
$parentRoles
|
|
||||||
),
|
|
||||||
"Assert that `CHILL_MASTER_ROLE` is a parent of `CHILL_INHERITED_ROLE_1`");
|
"Assert that `CHILL_MASTER_ROLE` is a parent of `CHILL_INHERITED_ROLE_1`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ services:
|
|||||||
autowire: true
|
autowire: true
|
||||||
|
|
||||||
# do not autowire the directory Security/Resolver
|
# do not autowire the directory Security/Resolver
|
||||||
Chill\MainBundle\Security\Authorization\DefaultVoterFactory:
|
Chill\MainBundle\Security\Authorization\DefaultVoterHelperFactory:
|
||||||
autowire: true
|
autowire: true
|
||||||
|
|
||||||
# do not autowire the directory Security/Resolver
|
# do not autowire the directory Security/Resolver
|
||||||
Chill\MainBundle\Security\Authorization\VoterFactoryInterface: '@Chill\MainBundle\Security\Authorization\DefaultVoterFactory'
|
Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface: '@Chill\MainBundle\Security\Authorization\DefaultVoterHelperFactory'
|
||||||
|
|
||||||
chill.main.security.authorization.helper:
|
chill.main.security.authorization.helper:
|
||||||
class: Chill\MainBundle\Security\Authorization\AuthorizationHelper
|
class: Chill\MainBundle\Security\Authorization\AuthorizationHelper
|
||||||
|
@ -73,7 +73,7 @@ class AccompanyingCourseController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $period);
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);
|
||||||
|
|
||||||
$em->persist($period);
|
$em->persist($period);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
@ -92,6 +92,8 @@ class AccompanyingCourseController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function indexAction(AccompanyingPeriod $accompanyingCourse): Response
|
public function indexAction(AccompanyingPeriod $accompanyingCourse): Response
|
||||||
{
|
{
|
||||||
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
|
||||||
|
|
||||||
// compute some warnings
|
// compute some warnings
|
||||||
// get persons without household
|
// get persons without household
|
||||||
$withoutHousehold = [];
|
$withoutHousehold = [];
|
||||||
@ -131,6 +133,8 @@ class AccompanyingCourseController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function editAction(AccompanyingPeriod $accompanyingCourse): Response
|
public function editAction(AccompanyingPeriod $accompanyingCourse): Response
|
||||||
{
|
{
|
||||||
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
|
||||||
|
|
||||||
return $this->render('@ChillPerson/AccompanyingCourse/edit.html.twig', [
|
return $this->render('@ChillPerson/AccompanyingCourse/edit.html.twig', [
|
||||||
'accompanyingCourse' => $accompanyingCourse
|
'accompanyingCourse' => $accompanyingCourse
|
||||||
]);
|
]);
|
||||||
@ -146,6 +150,8 @@ class AccompanyingCourseController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function historyAction(AccompanyingPeriod $accompanyingCourse): Response
|
public function historyAction(AccompanyingPeriod $accompanyingCourse): Response
|
||||||
{
|
{
|
||||||
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
|
||||||
|
|
||||||
return $this->render('@ChillPerson/AccompanyingCourse/history.html.twig', [
|
return $this->render('@ChillPerson/AccompanyingCourse/history.html.twig', [
|
||||||
'accompanyingCourse' => $accompanyingCourse
|
'accompanyingCourse' => $accompanyingCourse
|
||||||
]);
|
]);
|
||||||
|
@ -23,7 +23,10 @@
|
|||||||
namespace Chill\PersonBundle\Controller;
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||||
|
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Doctrine\DBAL\Exception;
|
use Doctrine\DBAL\Exception;
|
||||||
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Form\AccompanyingPeriodType;
|
use Chill\PersonBundle\Form\AccompanyingPeriodType;
|
||||||
@ -53,21 +56,24 @@ class AccompanyingPeriodController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
protected $validator;
|
protected $validator;
|
||||||
|
|
||||||
/**
|
protected AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository;
|
||||||
* AccompanyingPeriodController constructor.
|
|
||||||
*
|
public function __construct(
|
||||||
* @param EventDispatcherInterface $eventDispatcher
|
AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository,
|
||||||
* @param ValidatorInterface $validator
|
EventDispatcherInterface $eventDispatcher,
|
||||||
*/
|
ValidatorInterface $validator
|
||||||
public function __construct(EventDispatcherInterface $eventDispatcher, ValidatorInterface $validator)
|
) {
|
||||||
{
|
$this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository;
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listAction(int $person_id): Response
|
/**
|
||||||
|
* @ParamConverter("person", options={"id"="person_id"})
|
||||||
|
*/
|
||||||
|
public function listAction(Person $person): Response
|
||||||
{
|
{
|
||||||
$person = $this->_getPerson($person_id);
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $person);
|
||||||
|
|
||||||
$event = new PrivacyEvent($person, [
|
$event = new PrivacyEvent($person, [
|
||||||
'element_class' => AccompanyingPeriod::class,
|
'element_class' => AccompanyingPeriod::class,
|
||||||
@ -75,9 +81,10 @@ class AccompanyingPeriodController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
|
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
|
||||||
|
|
||||||
$accompanyingPeriods = $person->getAccompanyingPeriodsOrdered();
|
$accompanyingPeriods = $this->accompanyingPeriodACLAwareRepository
|
||||||
|
->findByPerson($person, AccompanyingPeriodVoter::SEE);
|
||||||
|
|
||||||
return $this->render('ChillPersonBundle:AccompanyingPeriod:list.html.twig', [
|
return $this->render('@ChillPerson/AccompanyingPeriod/list.html.twig', [
|
||||||
'accompanying_periods' => $accompanyingPeriods,
|
'accompanying_periods' => $accompanyingPeriods,
|
||||||
'person' => $person
|
'person' => $person
|
||||||
]);
|
]);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\DependencyInjection;
|
namespace Chill\PersonBundle\DependencyInjection;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||||
@ -258,14 +259,26 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
*/
|
*/
|
||||||
protected function prependRoleHierarchy(ContainerBuilder $container)
|
protected function prependRoleHierarchy(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$container->prependExtensionConfig('security', array(
|
$container->prependExtensionConfig('security', [
|
||||||
'role_hierarchy' => array(
|
'role_hierarchy' => [
|
||||||
'CHILL_PERSON_UPDATE' => array('CHILL_PERSON_SEE'),
|
PersonVoter::UPDATE => [PersonVoter::SEE],
|
||||||
'CHILL_PERSON_CREATE' => array('CHILL_PERSON_SEE'),
|
PersonVoter::CREATE => [PersonVoter::SEE],
|
||||||
PersonVoter::LISTS => [ ChillExportVoter::EXPORT ],
|
PersonVoter::LISTS => [ChillExportVoter::EXPORT],
|
||||||
PersonVoter::STATS => [ ChillExportVoter::EXPORT ]
|
PersonVoter::STATS => [ChillExportVoter::EXPORT],
|
||||||
)
|
// accompanying period
|
||||||
));
|
AccompanyingPeriodVoter::SEE_DETAILS => [AccompanyingPeriodVoter::SEE],
|
||||||
|
AccompanyingPeriodVoter::CREATE => [AccompanyingPeriodVoter::SEE_DETAILS],
|
||||||
|
AccompanyingPeriodVoter::DELETE => [AccompanyingPeriodVoter::SEE_DETAILS],
|
||||||
|
AccompanyingPeriodVoter::EDIT => [AccompanyingPeriodVoter::SEE_DETAILS],
|
||||||
|
// give all ACL for FULL
|
||||||
|
AccompanyingPeriodVoter::FULL => [
|
||||||
|
AccompanyingPeriodVoter::SEE_DETAILS,
|
||||||
|
AccompanyingPeriodVoter::CREATE,
|
||||||
|
AccompanyingPeriodVoter::EDIT,
|
||||||
|
AccompanyingPeriodVoter::DELETE
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
namespace Chill\PersonBundle\Menu;
|
namespace Chill\PersonBundle\Menu;
|
||||||
|
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,11 +47,15 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
*/
|
*/
|
||||||
protected $translator;
|
protected $translator;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$showAccompanyingPeriod,
|
ParameterBagInterface $parameterBag,
|
||||||
|
Security $security,
|
||||||
TranslatorInterface $translator
|
TranslatorInterface $translator
|
||||||
) {
|
) {
|
||||||
$this->showAccompanyingPeriod = $showAccompanyingPeriod;
|
$this->showAccompanyingPeriod = $parameterBag->get('chill_person.accompanying_period');
|
||||||
|
$this->security = $security;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +91,9 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order' => 99999
|
'order' => 99999
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($this->showAccompanyingPeriod === 'visible') {
|
if ($this->showAccompanyingPeriod === 'visible'
|
||||||
|
&& $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person'])
|
||||||
|
) {
|
||||||
$menu->addChild($this->translator->trans('Accompanying period list'), [
|
$menu->addChild($this->translator->trans('Accompanying period list'), [
|
||||||
'route' => 'chill_person_accompanying_period_list',
|
'route' => 'chill_person_accompanying_period_list',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
final class AccompanyingPeriodACLAwareRepository
|
||||||
|
{
|
||||||
|
private AccompanyingPeriodRepository $accompanyingPeriodRepository;
|
||||||
|
private Security $security;
|
||||||
|
private AuthorizationHelper $authorizationHelper;
|
||||||
|
private CenterResolverDispatcher $centerResolverDispatcher;
|
||||||
|
|
||||||
|
public function __construct(AccompanyingPeriodRepository $accompanyingPeriodRepository, Security $security, AuthorizationHelper $authorizationHelper, CenterResolverDispatcher $centerResolverDispatcher)
|
||||||
|
{
|
||||||
|
$this->accompanyingPeriodRepository = $accompanyingPeriodRepository;
|
||||||
|
$this->security = $security;
|
||||||
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
|
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findByPerson(
|
||||||
|
Person $person,
|
||||||
|
string $role,
|
||||||
|
?array $orderBy = [],
|
||||||
|
int $limit = null,
|
||||||
|
int $offset = null
|
||||||
|
): array {
|
||||||
|
dump(__METHOD__);
|
||||||
|
$qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap');
|
||||||
|
$scopes = $this->authorizationHelper
|
||||||
|
->getReachableCircles($this->security->getUser(), $role,
|
||||||
|
$this->centerResolverDispatcher->resolveCenter($person));
|
||||||
|
|
||||||
|
if (0 === count($scopes)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->join('ap.participations', 'participation')
|
||||||
|
->where($qb->expr()->eq('participation.person', ':person'))
|
||||||
|
->setParameter('person', $person)
|
||||||
|
;
|
||||||
|
// add join condition for scopes
|
||||||
|
$orx = $qb->expr()->orX();
|
||||||
|
foreach ($scopes as $key => $scope) {
|
||||||
|
$orx->add($qb->expr()->in('ap.scopes', ':scope_'.$key));
|
||||||
|
$qb->setParameter('scope_'.$key, $scope);
|
||||||
|
}
|
||||||
|
$qb->andWhere($orx);
|
||||||
|
|
||||||
|
return $qb->getQuery()->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -59,6 +59,11 @@ final class AccompanyingPeriodRepository implements ObjectRepository
|
|||||||
return $this->findOneBy($criteria);
|
return $this->findOneBy($criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
|
||||||
|
{
|
||||||
|
return $this->repository->createQueryBuilder($alias, $indexBy);
|
||||||
|
}
|
||||||
|
|
||||||
public function getClassName()
|
public function getClassName()
|
||||||
{
|
{
|
||||||
return AccompanyingPeriod::class;
|
return AccompanyingPeriod::class;
|
||||||
|
@ -60,7 +60,7 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
|||||||
$countryCode);
|
$countryCode);
|
||||||
$this->addACLClauses($qb, 'p');
|
$this->addACLClauses($qb, 'p');
|
||||||
|
|
||||||
return $this->getQueryResult($qb, $simplify, $limit, $start);
|
return $this->getQueryResult($qb, 'p', $simplify, $limit, $start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +119,7 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
|||||||
$countryCode);
|
$countryCode);
|
||||||
$this->addACLClauses($qb, 'p');
|
$this->addACLClauses($qb, 'p');
|
||||||
|
|
||||||
return $this->getCountQueryResult($qb);
|
return $this->getCountQueryResult($qb,'p');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,63 +4,92 @@ namespace Chill\PersonBundle\Security\Authorization;
|
|||||||
|
|
||||||
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\MainBundle\Entity\Center;
|
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
|
class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
|
||||||
{
|
{
|
||||||
protected AuthorizationHelper $helper;
|
|
||||||
|
|
||||||
public const SEE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE';
|
public const SEE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE';
|
||||||
|
/**
|
||||||
|
* details are for seeing:
|
||||||
|
*
|
||||||
|
* * SocialIssues
|
||||||
|
*/
|
||||||
|
public const SEE_DETAILS = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS';
|
||||||
|
public const CREATE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE';
|
||||||
|
public const EDIT = 'CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE';
|
||||||
|
public const DELETE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AuthorizationHelper $helper
|
* Give all the right above
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthorizationHelper $helper)
|
public const FULL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_FULL';
|
||||||
{
|
|
||||||
$this->helper = $helper;
|
public const ALL = [
|
||||||
|
self::SEE,
|
||||||
|
self::SEE_DETAILS,
|
||||||
|
self::CREATE,
|
||||||
|
self::EDIT,
|
||||||
|
self::DELETE,
|
||||||
|
self::FULL,
|
||||||
|
];
|
||||||
|
|
||||||
|
private VoterHelperInterface $voterHelper;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
Security $security,
|
||||||
|
VoterHelperFactoryInterface $voterHelperFactory
|
||||||
|
) {
|
||||||
|
$this->security = $security;
|
||||||
|
$this->voterHelper = $voterHelperFactory
|
||||||
|
->generate(self::class)
|
||||||
|
->addCheckFor(null, [self::CREATE])
|
||||||
|
->addCheckFor(AccompanyingPeriod::class, self::ALL)
|
||||||
|
->addCheckFor(Person::class, [self::SEE])
|
||||||
|
->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function supports($attribute, $subject)
|
protected function supports($attribute, $subject)
|
||||||
{
|
{
|
||||||
return $subject instanceof AccompanyingPeriod;
|
return $this->voterHelper->supports($attribute, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
|
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||||
{
|
{
|
||||||
if (!$token->getUser() instanceof User) {
|
if (!$token->getUser() instanceof User) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO take scopes into account
|
if ($subject instanceof AccompanyingPeriod) {
|
||||||
if (count($subject->getPersons()) === 0) {
|
if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) {
|
||||||
return true;
|
// only creator can see, edit, delete, etc.
|
||||||
}
|
if ($subject->getCreatedBy() === $token->getUser()
|
||||||
foreach ($subject->getPersons() as $person) {
|
|| NULL === $subject->getCreatedBy()) {
|
||||||
// give access as soon as on center is reachable
|
|
||||||
if ($this->helper->userHasAccess($token->getUser(), $person->getCenter(), $attribute)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if confidential, only the referent can see it
|
||||||
|
if ($subject->isConfidential()) {
|
||||||
|
return $token->getUser() === $subject->getUser();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAttributes()
|
return $this->voterHelper->voteOnAttribute($attribute, $subject, $token);
|
||||||
{
|
|
||||||
return [
|
|
||||||
self::SEE
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRoles()
|
public function getRoles()
|
||||||
{
|
{
|
||||||
return $this->getAttributes();
|
return self::ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRolesWithoutScope()
|
public function getRolesWithoutScope()
|
||||||
@ -70,7 +99,6 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRole
|
|||||||
|
|
||||||
public function getRolesWithHierarchy()
|
public function getRolesWithHierarchy()
|
||||||
{
|
{
|
||||||
return [ 'Person' => $this->getRoles() ];
|
return [ 'Accompanying period' => $this->getRoles() ];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,19 +40,11 @@ class PersonVoter extends AbstractChillVoter implements ProvideRoleHierarchyInte
|
|||||||
const LISTS = 'CHILL_PERSON_LISTS';
|
const LISTS = 'CHILL_PERSON_LISTS';
|
||||||
const DUPLICATE = 'CHILL_PERSON_DUPLICATE';
|
const DUPLICATE = 'CHILL_PERSON_DUPLICATE';
|
||||||
|
|
||||||
protected AuthorizationHelper $helper;
|
|
||||||
|
|
||||||
protected CenterResolverDispatcher $centerResolverDispatcher;
|
|
||||||
|
|
||||||
protected VoterHelperInterface $voter;
|
protected VoterHelperInterface $voter;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthorizationHelper $helper,
|
|
||||||
CenterResolverDispatcher $centerResolverDispatcher,
|
|
||||||
VoterHelperFactoryInterface $voterFactory
|
VoterHelperFactoryInterface $voterFactory
|
||||||
) {
|
) {
|
||||||
$this->helper = $helper;
|
|
||||||
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
|
||||||
$this->voter = $voterFactory
|
$this->voter = $voterFactory
|
||||||
->generate(self::class)
|
->generate(self::class)
|
||||||
->addCheckFor(Center::class, [self::STATS, self::LISTS, self::DUPLICATE])
|
->addCheckFor(Center::class, [self::STATS, self::LISTS, self::DUPLICATE])
|
||||||
|
@ -12,9 +12,8 @@ services:
|
|||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
Chill\PersonBundle\Controller\AccompanyingPeriodController:
|
Chill\PersonBundle\Controller\AccompanyingPeriodController:
|
||||||
arguments:
|
autowire: true
|
||||||
$eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
|
autoconfigure: true
|
||||||
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
|
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
Chill\PersonBundle\Controller\PersonAddressController:
|
Chill\PersonBundle\Controller\PersonAddressController:
|
||||||
|
@ -19,14 +19,7 @@ services:
|
|||||||
# - { name: 'chill.menu_builder' }
|
# - { name: 'chill.menu_builder' }
|
||||||
#
|
#
|
||||||
Chill\PersonBundle\Menu\PersonMenuBuilder:
|
Chill\PersonBundle\Menu\PersonMenuBuilder:
|
||||||
arguments:
|
autowire: true
|
||||||
$showAccompanyingPeriod: '%chill_person.accompanying_period%'
|
autoconfigure: true
|
||||||
$translator: '@Symfony\Contracts\Translation\TranslatorInterface'
|
|
||||||
tags:
|
tags:
|
||||||
- { name: 'chill.menu_builder' }
|
- { name: 'chill.menu_builder' }
|
||||||
|
|
||||||
# Chill\PersonBundle\Menu\AccompanyingCourseMenuBuilder:
|
|
||||||
# arguments:
|
|
||||||
# $translator: '@Symfony\Contracts\Translation\TranslatorInterface'
|
|
||||||
# tags:
|
|
||||||
# - { name: 'chill.menu_builder' }
|
|
||||||
|
@ -7,8 +7,7 @@ services:
|
|||||||
- { name: chill.role }
|
- { name: chill.role }
|
||||||
|
|
||||||
Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter:
|
Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter:
|
||||||
arguments:
|
autowire: true
|
||||||
- "@chill.main.security.authorization.helper"
|
|
||||||
tags:
|
tags:
|
||||||
- { name: security.voter }
|
- { name: security.voter }
|
||||||
- { name: chill.role }
|
- { name: chill.role }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user