<?php
namespace App\Security;
use App\Entity\Profile;
use App\Entity\User;
use LogicException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ProfileVoter extends Voter
{
// these strings are just invented: you can use anything
public const USER_CAN_VIEW_PROFILE = 'view';
public const USER_CAN_EDIT_PROFILE = 'edit';
public const USER_CAN_ACT_ON_BEHALF_OF_PROFILE = 'act_on_behalf_of';
protected function supports($attribute, $subject)
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, [self::USER_CAN_VIEW_PROFILE, self::USER_CAN_EDIT_PROFILE, self::USER_CAN_ACT_ON_BEHALF_OF_PROFILE])) {
return false;
}
// only vote on Profile objects inside this voter
if (!$subject instanceof Profile) {
return false;
}
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
/** @var Profile $profile */
$profile = $subject;
switch ($attribute) {
case self::USER_CAN_VIEW_PROFILE:
return $this->canView($profile, $user);
case self::USER_CAN_EDIT_PROFILE:
return $this->canEdit($profile, $user);
case self::USER_CAN_ACT_ON_BEHALF_OF_PROFILE:
return $this->canActOnBehalfOf($profile, $user);
}
throw new LogicException('This code should not be reached!');
}
private function canView(Profile $profile, User $user)
{
return true;
}
private function canEdit(Profile $profile, User $user)
{
return $user === $profile->getUser();
}
private function canActOnBehalfOf(Profile $profile, User $user)
{
return $user === $profile->getUser();
}
}