<?php
namespace MedBrief\MSR\Security\Voter;
use MedBrief\MSR\Entity\InterpartyDisclosure;
use MedBrief\MSR\Entity\Project;
use Override;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
class InterpartyDisclosureVoter extends Voter
{
public const UPDATE = 'UPDATE';
public const VIEW = 'VIEW';
public const CANCEL = 'CANCEL';
public const REACTIVATE = 'REACTIVATE';
public const PUSH = 'PUSH';
public const FORCE_EXPIRY_DATE = 'FORCE_EXPIRY_DATE';
public const VIEW_THIRD_PARTY_ACCESS_REPORT = 'VIEW_THIRD_PARTY_ACCESS_REPORT';
public function __construct(private readonly AuthorizationCheckerInterface $authorizationChecker)
{
}
#[Override]
protected function supports($attribute, $subject): bool
{
return in_array($attribute, [
self::UPDATE,
self::VIEW,
self::CANCEL,
self::REACTIVATE,
self::PUSH,
self::FORCE_EXPIRY_DATE,
self::VIEW_THIRD_PARTY_ACCESS_REPORT,
])
&& $subject instanceof InterpartyDisclosure;
}
#[Override]
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
/** @var InterpartyDisclosure $interpartyDisclosure */
$interpartyDisclosure = $subject;
$project = $interpartyDisclosure->getProject();
// ... (check conditions and return true to grant permission) ...
return match ($attribute) {
self::UPDATE => $this->canUpdate($user, $project),
self::VIEW => $this->canView($user, $project),
self::CANCEL => $this->canCancel($user, $project),
self::REACTIVATE => $this->canReactivate($user, $project),
self::PUSH => $this->canPush($user),
self::FORCE_EXPIRY_DATE => $this->canForceExpiryDate($user),
self::VIEW_THIRD_PARTY_ACCESS_REPORT => $this->canThirdPartyAccessView($user, $project),
default => false,
};
}
protected function canUpdate(UserInterface $user, Project $project): bool
{
// MEDBRIEF ADMIN
if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
return true;
}
// CLIENT SUPER ADMIN
if ($this->authorizationChecker->isGranted('ROLE_ACCOUNT_' . $project->getAccount()->getId() . '_SUPERADMINISTRATOR')) {
return true;
}
// CLIENT ADMIN
if ($this->authorizationChecker->isGranted('ROLE_ACCOUNT_' . $project->getAccount()->getId() . '_ADMINISTRATOR')) {
return true;
}
// MATTER LEVEL PROJECT MANAGER
if ($this->authorizationChecker->isGranted('ROLE_PROJECT_' . $project->getId() . '_PROJECTMANAGER')) {
return true;
}
// MANAGER ON A PROJECT/MATTER
return $project->getManager() && $project->getManager() === $user;
}
protected function canView(UserInterface $user, Project $project): bool
{
// If the user can update, then they can also view.
return $this->canUpdate($user, $project);
}
/**
* Grants permission to users to access the 'Third party disclosure access modal'
*
* @param UserInterface $user
* @param Project $project
*/
protected function canThirdPartyAccessView(UserInterface $user, Project $project): bool
{
// If the user can update, then they can also view third party access.
return $this->canUpdate($user, $project);
}
protected function canCancel(UserInterface $user, Project $project): bool
{
// If the user can update, then they can also cancel.
return $this->canUpdate($user, $project);
}
protected function canReactivate(UserInterface $user, Project $project): bool
{
// If the user can update, then they can also reactivate.
return $this->canUpdate($user, $project);
}
protected function canPush(UserInterface $user): bool
{
// MEDBRIEF ADMIN
return $this->authorizationChecker->isGranted('ROLE_ADMIN');
}
protected function canForceExpiryDate(UserInterface $user): bool
{
// MEDBRIEF SUPER ADMIN
return $this->authorizationChecker->isGranted('ROLE_SUPER_ADMIN');
}
}