<?php
namespace App\Security\Voter;
use App\Entity\DeviceGroup;
use App\Entity\Plan;
use App\Entity\User;
use App\Entity\Workspace;
use App\Repository\DeviceGroupRepository;
use App\Repository\UserRepository;
use App\Utils\Commons;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class PlanPricingVoter extends Voter
{
/**
* @var UserRepository
*/
private $userRepository;
/**
* @var DeviceGroupRepository
*/
private $deviceGroupRepository;
/**
* @var Commons
*/
private $commons;
/**
* @var array
*/
private $permissions;
private $security;
/**
* Constructor.
* @param UserRepository $userRepository
* @param Security $security
*/
public function __construct(
Commons $commons,
UserRepository $userRepository,
DeviceGroupRepository $deviceGroupRepository,
Security $security
)
{
$this->permissions = [];
$this->commons = $commons;
$this->security = $security;
$this->userRepository = $userRepository;
$this->deviceGroupRepository = $deviceGroupRepository;
}
// these strings are just invented: you can use anything
const VIEW_PLAN_USER_GROUP = 'VIEW_PLAN_USER_GROUP';
const VIEW_PLAN_SANDBOX_MODE = 'VIEW_PLAN_SANDBOX_MODE';
const VIEW_PLAN_DATA_EXPORT = 'VIEW_PLAN_DATA_EXPORT';
const VIEW_PLAN_2FA_AUTH = 'VIEW_PLAN_2FA_AUTH';
const VIEW_PLAN_INDIVIDUAL_DEVICE_FIELDS = 'VIEW_PLAN_INDIVIDUAL_DEVICE_FIELDS';
const VIEW_PLAN_SCHEDULED_ROLLOUTS = 'VIEW_PLAN_SCHEDULED_ROLLOUTS';
const VIEW_PLAN_BLOCKCHAIN_DEVICE_LOG = 'VIEW_PLAN_BLOCKCHAIN_DEVICE_LOG';
const VIEW_PLAN_NAMED_USERS = 'VIEW_PLAN_NAMED_USERS';
const VIEW_PLAN_MAPBOX = 'VIEW_PLAN_MAPBOX';
protected function supports($attribute, $subject)
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, [
self::VIEW_PLAN_USER_GROUP,
self::VIEW_PLAN_SANDBOX_MODE,
self::VIEW_PLAN_DATA_EXPORT,
self::VIEW_PLAN_2FA_AUTH,
self::VIEW_PLAN_INDIVIDUAL_DEVICE_FIELDS,
self::VIEW_PLAN_SCHEDULED_ROLLOUTS,
self::VIEW_PLAN_BLOCKCHAIN_DEVICE_LOG,
self::VIEW_PLAN_NAMED_USERS,
self::VIEW_PLAN_MAPBOX,
])) {
return false;
}
// only vote on `User` objects
// if (!$subject instanceof User) {
// return false;
// }
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
if ($this->security->isGranted('ROLE_BACKEND_USER')) {
return true;
}
$user = $token->getUser();
$this->permissions = $this->commons->getUserPermissions($user);
if (!$user instanceof User) {
// the user must be logged in; if not, deny access
return false;
}
$plan = $token->getUser()->getWorkSpace()->getPlan();
switch ($attribute) {
case self::VIEW_PLAN_USER_GROUP:
return $this->canViewUserGroup($plan);
case self::VIEW_PLAN_SANDBOX_MODE:
return $this->canViewSandBoxMode($plan);
case self::VIEW_PLAN_DATA_EXPORT:
return $this->canViewDataExport($plan);
case self::VIEW_PLAN_2FA_AUTH:
return $this->canView2FAAuth($plan);
case self::VIEW_PLAN_INDIVIDUAL_DEVICE_FIELDS:
return $this->canViewIndividualDeviceField($plan);
case self::VIEW_PLAN_SCHEDULED_ROLLOUTS:
return $this->canViewScheduledRollouts($plan);
case self::VIEW_PLAN_BLOCKCHAIN_DEVICE_LOG:
return $this->canViewBlockchainDeviceLog($plan);
case self::VIEW_PLAN_NAMED_USERS:
return $this->canViewNamedUsers($user->getWorkspace(), $user);
case self::VIEW_PLAN_MAPBOX:
return $this->canViewMapbox($plan);
;
}
throw new \LogicException('This code should not be reached!');
}
private function canViewUserGroup(Plan $plan)
{
return $plan->getUserGroups();
}
private function canViewSandBoxMode(Plan $plan)
{
return $plan->getSandboxMode();
}
private function canViewDataExport(Plan $plan)
{
return $plan->getDataExport();
}
private function canView2FAAuth(Plan $plan)
{
return $plan->getAuth2fa();
}
private function canViewIndividualDeviceField(Plan $plan)
{
return $plan->getIndividualDeviceFields();
}
private function canViewScheduledRollouts(Plan $plan)
{
return $plan->getScheduledRollouts();
}
private function canViewBlockchainDeviceLog(Plan $plan)
{
return $plan->getBlockchainDeviceLog();
}
private function canViewNamedUsers(Workspace $workspace, User $user)
{
$users = $this->userRepository->findAllUsersByRole($user->getId(), $workspace->getId())->getQuery()->getArrayResult();
$flag = false;
if(count($users) < $workspace->getPlan()->getNamedUsers()){
$flag = true;
}
return $flag;
}
private function canViewMapbox(Plan $plan)
{
// if (!$plan->getMapBox()) {
// return false;
// }
//
// if ($this->security->isGranted('ROLE_ADMIN')) {
// return true;
// }
//
// if (array_key_exists('deviceGroup', $this->permissions)) {
// if (in_array('Edit', $this->permissions['deviceGroup'])) {
// return true;
// }
// }
return $plan->getMapBox();
}
/**
* @param User|null $user
* @param $subject
* @return bool
*/
private function isOwner(User $user, $subject): bool
{
if (!is_object($subject)) {
$subject = $this->deviceGroupRepository->findOneBy(["id" => intval($subject)]);
}
if (!$subject instanceof DeviceGroup) {
return false;
}
return $user->getWorkspace()->getId() === $subject->getWorkspace()->getId();
}
/** Return True if have Edit Permission else return false
* @return bool
*/
private function canEdit(): bool
{
}
}