<?php
namespace App\Security\Voter\UserRequest;
use App\Entity\User;
use App\Manager\UserRightsManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use WebServiceCollectionBundle\Model\AtlasPce\UserRequestRequestModel;
class UserOwnsRequestVoter extends Voter
{
public const USER_OWNS_REQUEST = 'OWNS_REQUEST';
/**
* @var LoggerInterface
*/
protected $logger;
public function __construct(
LoggerInterface $logger
) {
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public function supports($attribute, $subject)
{
$isPostStatus = static::USER_OWNS_REQUEST === $attribute;
$isSubjectUrModel = ($subject instanceof UserRequestRequestModel);
return $isPostStatus && $isSubjectUrModel;
}
/**
* {@inheritdoc}
*/
public function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
switch ($attribute) {
case static::USER_OWNS_REQUEST:
return $this->isOwner($subject, $user);
}
throw new \LogicException('This code should not be reached!');
}
/**
* Test if a user is allowed to view a request.
*
* @param string $subject
* @param User $tokenAttributes
*
* @return bool
*/
protected function isOwner(UserRequestRequestModel $request, User $user): bool
{
$roles = $user->getRoles();
// Admin and managers can see everything
if (
in_array(UserRightsManagerInterface::ROLE_ADMIN, $roles)
|| in_array(UserRightsManagerInterface::ROLE_MANAGER, $roles)
) {
$this->logger->info('[UserOwnsRequestVoter] User {email} is admin, request {id} can have its status modified.', [
'email' => $user->getEmail(),
'id' => $request->getId(),
]);
return true;
}
$data = $request->getData();
$creatorId = !empty($data['userId']) ? (string) $data['userId'] : '';
// User created request
if ($creatorId === $user->getId()) {
$this->logger->info('[UserOwnsRequestVoter] User {email} {creatorId} created request {requestId}, it can have its status modified.', [
'email' => $user->getEmail(),
'requestId' => $request->getId(),
'creatorId' => $creatorId,
]);
return true;
}
$this->logger->info('[UserOwnsRequestVoter] User {email} is neither admin nor creator of request {id}, status cannot be modified.', [
'email' => $user->getEmail(),
'id' => $request->getId(),
'creatorId' => $creatorId,
'userId' => $user->getId(),
]);
return false;
}
}