| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <?php
- declare(strict_types=1);
- namespace App\Security\Voter;
- use App\Entity\Access\Access;
- use App\Entity\Core\BankAccount;
- use App\Entity\Core\File;
- use AppBundle\Entity\Organization\Organization;
- use AppBundle\Entity\Person\Person;
- use AppBundle\Enum\Core\FileTypeEnum;
- use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
- use Symfony\Component\Security\Core\Authorization\Voter\Voter;
- use Symfony\Bundle\SecurityBundle\Security;
- use Symfony\Component\Security\Core\User\UserInterface;
- /**
- * Contrôle l'accès à l'entité File
- */
- class FileVoter extends AbstractVoter
- {
- protected const FILE_READ = 'FILE_READ';
- protected const FILE_EDIT = 'FILE_EDIT';
- protected const FILE_CREATE = 'FILE_CREATE';
- protected const FILE_DELETE = 'FILE_DELETE';
- public function __construct(
- private Security $security
- ) {}
- protected function supports(string $attribute, $subject): bool
- {
- return $subject instanceof File && in_array($attribute, [self::FILE_READ, self::FILE_EDIT, self::FILE_DELETE]);
- }
- /**
- * Retourne True si l'utilisateur a le droit d'effectuer l'opération demandée
- *
- * @param string $attribute
- * @param mixed $subject
- * @param TokenInterface $token
- * @return bool
- */
- protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
- {
- if(!$this->isAvailabilityDatePassed($subject)) {
- // Le fichier n'est pas encore disponible TODO: à revoir
- return false;
- }
- switch ($attribute) {
- case self::FILE_READ:
- return $this->canView($subject);
- case self::FILE_EDIT:
- return $this->canEdit($subject, $user);
- case self::FILE_CREATE:
- return $this->canCreate($subject, $user);
- case self::FILE_DELETE:
- return $this->canDelete($subject, $user);
- }
- return false;
- }
- /**
- * Returns True if the current user has the right to GET this record
- *
- * @param $subject \AppBundle\Entity\Core\File
- * @param $user
- * @return boolean
- */
- public function canView(File $subject): bool
- {
- // File has public visibility
- if ($subject->getVisibility() === FileVisibilityEnum::EVERYBODY) {
- return true;
- }
- // Is this an internal request? (@see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/doc/internal_requests.md)
- $clientIp = $_SERVER['REMOTE_ADDR'];
- $internalRequestToken = $_SERVER['HTTP_INTERNAL_REQUESTS_TOKEN'] ?? '';
- if ($this->internalRequestsService->isAllowed($clientIp, $internalRequestToken)) {
- return true;
- }
- // If the user has not logged in, the file is not available
- if (!$this->user) {
- return false;
- }
- // If the logged user is in accessUser of File
- if ($subject->getAccessPersons()->count() !== 0) {
- foreach ($subject->getAccessPersons() as $accessPerson) {
- if ($user->getId() == $accessPerson->getId()) {
- return true;
- }
- }
- }
- /**
- * If the logged user is in accessRole of File
- */
- if(0 !== count($subject->getAccessRoles())
- &&(
- ($subject->getOrganization() instanceof Organization && $subject->getOrganization()->getId() === $this->accessService->getAccess()->getOrganization()->getId())
- || ($subject->getPerson() instanceof Person && $subject->getPerson()->getId() === $this->accessService->getAccess()->getPerson()->getId())
- )
- ){
- foreach ($subject->getAccessRoles() as $accessRole){
- if($this->accessService->hasRole($accessRole)){
- return true;
- }
- }
- }
- return false;
- }
- /**
- * @param $subject \AppBundle\Entity\Core\File
- * @param $user
- * @return boolean
- */
- public function canEdit($subject, $user)
- {
- /**
- * If user is not logged, the file is not available
- */
- if (!$user instanceof Person) {
- return false;
- } /**
- * If user has ROLE_FILE
- */
- elseif ($this->accessService->hasRole('ROLE_FILE')
- && (
- ($subject->getOrganization() instanceof Organization && $subject->getOrganization()->getId() === $this->accessService->getAccess()->getOrganization()->getId())
- || ($subject->getPerson() instanceof Person && $subject->getPerson()->getId() === $this->accessService->getAccess()->getPerson()->getId())
- )
- ) {
- return true;
- } /**
- * If proprietary person of file is same of logged user
- */
- elseif ($subject->getPerson() instanceof Person && $subject->getPerson()->getId() === $user->getId()) {
- return true;
- }
- return false;
- }
- /**
- * @param $subject File
- * @param $user
- * @return boolean
- */
- public function canCreate($subject, $user)
- {
- /**
- * If user is not logged, the file is not available
- */
- if (!$user instanceof Person) {
- return false;
- }
- return true;
- }
- /**
- * @param $subject File
- * @param $user
- * @return boolean
- */
- public function canDelete($subject, $user){
- return $this->canEdit($subject, $user);
- }
- /**
- * @param $subject
- * @return bool
- * @throws \Exception
- */
- private function isAvailabilityDatePassed($subject){
- $isAvailabilityDatePassed = true;
- $today = new \DateTime();
- if (!empty($subject->getAvailabilityDate()) && $subject->getAvailabilityDate() > $today) {
- $userHasRole = false;
- // Si l'utilisateur a les droits suffisant pour voir le fichier meme si la date n'est pas passé: exemple: liste des factures
- if($subject->getType() === FileTypeEnum::BILL && $this->roleServiceUtils->checkIfUserHasRoles($this->accessService->getRoles(), ['ROLE_BILLACCOUNTING'])){
- $userHasRole = true;
- }
- if(!$userHasRole)
- $isAvailabilityDatePassed = false;
- }
- return $isAvailabilityDatePassed;
- }
- }
|