src/Chat/Application/Security/MessageVoter.php line 28

Open in your IDE?
  1. <?php
  2. /**
  3.  * This file is part of the educat package.
  4.  *
  5.  * (c) Solvee
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace App\Chat\Application\Security;
  12. use App\Common\Model\Chat\MessageInterface;
  13. use App\Common\Model\Core\UserInterface;
  14. use App\Common\Security\AccountRole;
  15. use LogicException;
  16. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  17. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  18. use Symfony\Component\Security\Core\Security;
  19. /**
  20.  * Class MessageVoter
  21.  *
  22.  * @author JarosÅ‚aw Dylewski <jaroslaw.dylewski@interia.pl>
  23.  */
  24. class MessageVoter extends Voter
  25. {
  26.     public const CAN_SEND_MESSAGE         'can_send_message';
  27.     public const CAN_GET_MESSAGE          'can_get_message';
  28.     public const CAN_MARK_MESSAGE_AS_READ 'can_mark_message_as_read';
  29.     /** @var Security */
  30.     private Security $security;
  31.     /**
  32.      * MessageVoter constructor.
  33.      *
  34.      * @param Security $security
  35.      */
  36.     public function __construct(Security $security)
  37.     {
  38.         $this->security $security;
  39.     }
  40.     /**
  41.      * @param string $attribute
  42.      * @param mixed  $subject
  43.      *
  44.      * @return bool
  45.      */
  46.     protected function supports($attribute$subject)
  47.     {
  48.         if (!in_array(
  49.             $attribute,
  50.             [
  51.                 self::CAN_SEND_MESSAGE,
  52.                 self::CAN_GET_MESSAGE,
  53.                 self::CAN_MARK_MESSAGE_AS_READ,
  54.             ]
  55.         )) {
  56.             return false;
  57.         }
  58.         return $attribute && $subject instanceof MessageInterface;
  59.     }
  60.     /**
  61.      * @param string         $attribute
  62.      * @param mixed          $subject
  63.      * @param TokenInterface $token
  64.      *
  65.      * @return bool
  66.      */
  67.     protected function voteOnAttribute($attribute$subjectTokenInterface $token)
  68.     {
  69.         $user $token->getUser();
  70.         if (!$user instanceof UserInterface) {
  71.             return false;
  72.         }
  73.         switch ($attribute) {
  74.             case self::CAN_SEND_MESSAGE:
  75.                 return $this->canSendMessage($subject$user);
  76.             case self::CAN_GET_MESSAGE:
  77.                 return $this->canGetMessage($subject$user);
  78.             case self::CAN_MARK_MESSAGE_AS_READ:
  79.                 return $this->canMarkMessageAsRead($subject$user);
  80.             default:
  81.                 throw new LogicException();
  82.         }
  83.     }
  84.     /**
  85.      * @param MessageInterface $message
  86.      * @param UserInterface    $user
  87.      *
  88.      * @return bool
  89.      */
  90.     private function canSendMessage(MessageInterface $messageUserInterface $user): bool
  91.     {
  92.         return $this->isAdminOrMessageSender($message$user);
  93.     }
  94.     /**
  95.      * @param MessageInterface $message
  96.      * @param UserInterface    $user
  97.      *
  98.      * @return bool
  99.      */
  100.     private function canGetMessage(MessageInterface $messageUserInterface $user): bool
  101.     {
  102.         if ($this->security->isGranted(AccountRole::ADMIN)) {
  103.             return true;
  104.         }
  105.         return $message->getFrom() === $user || $message->getTo() === $user;
  106.     }
  107.     /**
  108.      * @param MessageInterface $message
  109.      * @param UserInterface    $user
  110.      *
  111.      * @return bool
  112.      */
  113.     private function canMarkMessageAsRead(MessageInterface $messageUserInterface $user): bool
  114.     {
  115.         if ($this->security->isGranted(AccountRole::ADMIN)) {
  116.             return true;
  117.         }
  118.         return $message->getTo() === $user;
  119.     }
  120.     /**
  121.      * @param MessageInterface $message
  122.      * @param UserInterface    $user
  123.      *
  124.      * @return bool
  125.      */
  126.     private function isAdminOrMessageSender(MessageInterface $messageUserInterface $user): bool
  127.     {
  128.         if ($this->security->isGranted(AccountRole::ADMIN)) {
  129.             return true;
  130.         }
  131.         return $message->getFrom() === $user;
  132.     }
  133. }