<?php
namespace App\Security\Voter;
use App\DBAL\Types\RoleEnumType;
use App\DTO\UserRatingDTO;
use App\Entity\User;
use App\Service\CuratorService;
use App\Service\DutyService;
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 UserVoter extends Voter
{
const SHOW_PHONE = 'show_phone';
const SHOW_EMAIL = 'show_email';
const SHOW_FOLLOW_ME = 'show_follow_me';
const SHOW_RESUME = 'show_resume';
const EDIT_PROFILE = 'edit_profile';
const SHOW_DETAIL_RATING = 'show_detail_rating';
const SHOW_FULLY_STUDENT = 'show_fully_student';
const SEND_HOMEWORK = 'send_homework';
const NEUROCHAT_ACCESS = 'neurochat_access';
const NEUROSUPPORT_ACCESS = 'neurosupport_access';
const COORDINATOR_MESSAGE_SEND = 'coordinator_message_send';
const RESUME_ACCESS = 'resume_access';
private AuthorizationCheckerInterface $authorizationChecker;
private CuratorService $curatorService;
private DutyService $dutyService;
public function __construct(
AuthorizationCheckerInterface $authorizationChecker,
CuratorService $curatorService,
DutyService $dutyService
) {
$this->authorizationChecker = $authorizationChecker;
$this->curatorService = $curatorService;
$this->dutyService = $dutyService;
}
protected function supports($attribute, $subject)
{
return in_array($attribute, [
self::SHOW_PHONE, self::SHOW_EMAIL, self::SHOW_FOLLOW_ME, self::SHOW_RESUME, self::EDIT_PROFILE,
self::SHOW_DETAIL_RATING, self::SHOW_FULLY_STUDENT, self::SEND_HOMEWORK,
self::NEUROCHAT_ACCESS, self::NEUROSUPPORT_ACCESS, self::COORDINATOR_MESSAGE_SEND, self::RESUME_ACCESS,
]);
}
/**
* @param string $attribute
* @param User|UserRatingDTO|mixed $subject
*
* @return bool
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
/** @var User $user */
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
// ... (check conditions and return true to grant permission) ...
switch ($attribute) {
case self::SHOW_PHONE:
return $subject->getIsShowPhone() && ((bool) trim($subject->getPhone()));
break;
case self::SHOW_EMAIL:
return $subject->getIsShowEmail();
break;
case self::SHOW_FOLLOW_ME:
return $subject->getIsShowFollowMe() && ((bool) $subject->getFollowMeLinks()->count());
break;
case self::SHOW_RESUME:
return $subject->getIsShowResume() && ((bool) trim($subject->getResume()));
break;
case self::EDIT_PROFILE:
return $subject->getId() == $user->getId();
break;
case self::SHOW_DETAIL_RATING:
return $user == $subject
|| $user->hasRole(RoleEnumType::ROLE_CURATOR)
|| $user->hasRole(RoleEnumType::ROLE_MODERATOR)
|| $user->hasRole(RoleEnumType::ROLE_SUPER_ADMIN)
;
case self::SHOW_FULLY_STUDENT:
$user = $subject ?? $user;
$isStudent = (bool) ($user->hasRole(RoleEnumType::ROLE_STUDENT) || $user->hasRole(RoleEnumType::ROLE_VIP_STUDENT) || $user->hasRole(RoleEnumType::ROLE_VIP_VIDEO_STUDENT));
return (bool) ($isStudent && !$this->isDemo($user));
break;
case self::NEUROCHAT_ACCESS:
$user = $subject ?? $user;
return $user->hasProgramWithSupport()
&& (
(
$this->isDemo($user)
&& $user->hasRole(RoleEnumType::ROLE_NEUROCHAT_DEMO)
)
|| (
!$this->isDemo($user)
&& $this->authorizationChecker->isGranted('ROLE_NEUROCHAT_ACCESS', $user)
)
)
;
case self::NEUROSUPPORT_ACCESS:
$user = $subject ?? $user;
return (
$this->isDemo($user)
&& $user->hasRole(RoleEnumType::ROLE_NEUROSUPPORT_DEMO)
)
|| (
!$this->isDemo($user)
&& $this->authorizationChecker->isGranted('ROLE_NEUROSUPPORT_ACCESS', $user)
);
case self::SEND_HOMEWORK:
$user = $subject ?? $user;
return !$user->hasRole(RoleEnumType::ROLE_DEMO) || $user->hasRole(RoleEnumType::ROLE_DEMO_INTENSIVE);
case self::COORDINATOR_MESSAGE_SEND:
$user = $subject ?? $user;
return $this->dutyService->issetDutyCoordinators();
case self::RESUME_ACCESS:
return $user->hasRole(RoleEnumType::ROLE_RESUME_ACCESS)
|| $user->hasRole(RoleEnumType::ROLE_HR);
}
return false;
}
private function isDemo(User $user)
{
return $user->hasRole(RoleEnumType::ROLE_DEMO)
|| $user->hasRole(RoleEnumType::ROLE_INTRO_STUDENT)
|| $user->hasRole(RoleEnumType::ROLE_LIMITED_ACCESS)
|| $user->hasRole(RoleEnumType::ROLE_DEMO_INTENSIVE)
;
}
}