src/AppBundle/Security/DictionaryVoter.php line 19

Open in your IDE?
  1. <?php
  2. namespace AppBundle\Security;
  3. use AppBundle\CSPro\User\User;
  4. use AppBundle\CSPro\User\Role;
  5. use AppBundle\CSPro\User\RoleDictionaryPermissions;
  6. use AppBundle\CSPro\Dictionary;
  7. use Symfony\Component\Security\Core\Security;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  10. use Psr\Log\LoggerInterface;
  11. /**
  12.  * Description of DictionaryVoter
  13.  *
  14.  * @author savy
  15.  */
  16. class DictionaryVoter extends Voter {
  17.     public const DICTIONARY_OPERATIONS 'data_all';
  18.     public const DATA_DOWNLOAD 'data_all';
  19.     public const SYNC_UPLOAD 'dictionary_sync_upload';
  20.     public const SYNC_DOWNLOAD 'dictionary_sync_download';
  21.     public function __construct(Security $security, private LoggerInterface $logger) {
  22.         $this->security $security;
  23.     }
  24.     protected function supports($attribute$subject) : bool{
  25.         // if the attribute isn't one we support, return false
  26.         if (!in_array($attribute, [self::DICTIONARY_OPERATIONSself::SYNC_UPLOADself::SYNC_DOWNLOADself::DATA_DOWNLOAD])) {
  27.             return false;
  28.         }
  29.         return true;
  30.     }
  31.     protected function voteOnAttribute($attribute$subjectTokenInterface $token) : bool {
  32.         $user $token->getUser();
  33.         //  $this->logger->debug('dictionary voter voteOnAttribute: ' . print_r($user, true));
  34.         if (!$user instanceof User) {
  35.             // the user must be logged in; if not, deny access
  36.             return false;
  37.         }
  38.         $dictName $subject;
  39.         return match ($attribute) {
  40.             self::DICTIONARY_OPERATIONS => $this->canAddOrDeleteDictionaries($user$attribute),
  41.             self::DATA_DOWNLOAD => $this->canDownloadData($user$attribute),
  42.             self::SYNC_UPLOAD => $this->canSyncUploadData($dictName$user),
  43.             self::SYNC_DOWNLOAD => $this->canSyncDownloadData($dictName$user),
  44.             default => throw new \LogicException('This code should not be reached!'),
  45.         };
  46.     }
  47.     private function canAddOrDeleteDictionaries(User $user$attribute) {
  48.         $roleName 'ROLE_' strtoupper($attribute);
  49.         if ($this->security->isGranted('ROLE_ADMIN') || $this->security->isGranted('ROLE_STANDARD_USER') || $this->security->isGranted($roleName)) {
  50.             return true;
  51.         } else {
  52.             $this->logger->debug('User does not have data_all permissions');
  53.             return false;
  54.         }
  55.     }
  56.     private function canDownloadData(User $user$attribute) {
  57.         $roleName 'ROLE_' strtoupper($attribute);
  58.         if ($this->security->isGranted('ROLE_ADMIN') || $this->security->isGranted('ROLE_STANDARD_USER') || $this->security->isGranted($roleName)) {
  59.             return true;
  60.         } else {
  61.             $this->logger->debug('User does not have data_all permissions');
  62.             return false;
  63.         }
  64.     }
  65.     //built-in standard users and administrators can sync upload data. for other roles check permissions based on the dictionary
  66.     private function canSyncUploadData($dictNameUser $user) {
  67.         //if $dictName is empty return false 
  68.         if (empty($dictName))
  69.             return false;
  70.         if ($this->security->isGranted('ROLE_ADMIN') || $user->getRoleId() == User::STANDARD_USER) {//built-in administrator or standard users
  71.             return true;
  72.         } else {
  73.             $role $user->getUserRole();
  74.             $dictionaryPermissions = new RoleDictionaryPermissions();
  75.             if (isset($role)) {
  76.                 $this->logger->debug('dictionary voter: checking permissions sync upload ' $dictName);
  77.                 $dictionaryPermissions $role->rolePermissions->getDictionaryPermissions($dictName);
  78.                 return $dictionaryPermissions->canSyncUpload();
  79.             }
  80.             $this->logger->debug('dictionary voter: denied canSyncUploadData ' $dictName);
  81.             return false;
  82.         }
  83.     }
  84.     //built-in administrators can download sync spec and standard users cannot. For other users with any other role check permissions based on dictionary name
  85.     private function canSyncDownloadData($dictNameUser $user) {
  86.         //if $dictName is empty return false 
  87.         if (empty($dictName))
  88.             return false;
  89.         if ($this->security->isGranted('ROLE_ADMIN') || $user->getRoleId() == User::STANDARD_USER) {//built-in administrator
  90.             return true;
  91.         } else {
  92.             $role $user->getUserRole();
  93.             $dictionaryPermissions = new RoleDictionaryPermissions();
  94.             if (isset($role)) {
  95.                 $this->logger->debug('dictionary voter: checking permissions sync download ' $dictName);
  96.                 $dictionaryPermissions $role->rolePermissions->getDictionaryPermissions($dictName);
  97.                 return $dictionaryPermissions->canSyncDownload();
  98.             }
  99.             $this->logger->debug('dictionary voter: denied canSyncUploadData ' $dictName);
  100.             return false;
  101.         }
  102.     }
  103. }