<?php
namespace App\Security\Content;
use App\Entity\Content\Blog;
use \Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class BlogVoter extends Voter
{
const VIEW = 'BLOG_VIEW';
const VIEW_ANY = 'BLOG_VIEW_ANY';
const CREATE = 'BLOG_CREATE';
const EDIT = 'BLOG_EDIT';
const EDIT_ANY = 'BLOG_EDIT_ANY';
const PRINT = 'BLOG_PRINT';
const DELETE = 'BLOG_DELETE';
/**
* UserVoter constructor.
*/
public function __construct(private readonly AccessDecisionManagerInterface $decisionManager)
{
}
/**
* @param string $attribute
* @param mixed $subject
*/
protected function supports($attribute, $subject): bool
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, [
self::VIEW,
self::VIEW_ANY,
self::CREATE,
self::EDIT,
self::EDIT_ANY,
self::PRINT,
self::DELETE,
], true)) {
return false;
}
// only vote on Property objects inside this voter
return !($subject && !$subject instanceof Blog);
}
/**
* @param string $attribute
* @param mixed $subject
*
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
if ($this->decisionManager->decide($token, ['ROLE_SUPER_ADMIN'])) {
return true;
}
$user = $token->getUser();
if (!$user instanceof UserInterface) {
// the user must be logged in; if not, deny access
return false;
}
return match ($attribute) {
self::VIEW_ANY => $this->canViewAny($user),
self::VIEW => $this->canView($subject, $user),
self::CREATE => $this->canCreate($user),
self::EDIT => $this->canEdit($user),
self::EDIT_ANY => $this->canEditAny($subject, $user),
self::DELETE => $this->canDelete($subject, $user),
default => throw new \LogicException('This code should not be reached!'),
};
}
/**
* Check if logged in User can view Property
*
*
*/
private function canView(UserInterface $subject, UserInterface $user): bool
{
if ($this->canEdit($user)) {
return true;
}
return $this->isOwner($subject, $user);
}
/**
* Check if logged in User can view Property
*
*
*/
private function canViewAny(UserInterface $user): bool
{
return (bool) $user->hasRight(self::VIEW_ANY);
}
/**
* Check if logged in User can create Property
*
*
*/
private function canCreate(UserInterface $user): bool
{
if ($user->hasRight(self::CREATE)) {
return true;
}
return $user->hasRole('ROLE_ADMIN');
}
/**
* Check if logged in User can edit Property
*
*
*/
private function canEdit(UserInterface $user): bool
{
return (bool) $user->hasRight(self::EDIT);
}
/**
* Check if logged in User can print Property
*
*
*/
private function canEditAny(UserInterface $subject, UserInterface $user): bool
{
if ($user->hasRight(self::EDIT_ANY)) {
return true;
}
return $this->isOwner($subject, $user);
}
/**
* Check if logged in User can delete Property
*
*
*/
private function canDelete(UserInterface $subject, UserInterface $user): bool
{
if ($user->hasRight(self::DELETE)) {
return true;
}
return $this->isOwner($subject, $user);
}
/**
* Check if User if Owner of Subject/Property
*
*/
private function isOwner(UserInterface $subject, UserInterface $user): bool
{
return $user->getId() === $subject->getId();
}
}