<?php
//------------------------------------------------------------------------------
// src/Security/ExportVoter.php
//------------------------------------------------------------------------------
namespace App\Security;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use App\Entity\Access;
use App\Entity\Config\Config;
use App\Entity\Config\Module;
use App\Entity\HR\AccessFunction;
use App\Entity\Security\Acl;
use App\Entity\Security\AclPermission;
use App\Services\Config\ModuleTools;
class ExportVoter extends Voter
{
//--------------------------------------------------------------------------------
// is_granted constants
const IS_ACTIVE = "export_is_active";
const EXPORT_ANY = "export_data";
const EXPORT_INVOICE = "export_invoices";
const EXPORT_INVOICE_SOCIETY = "export_invoices_society";
const EXPORT_INVOICE_ANY = "export_invoices_any";
const EXPORT_DEVIS = "export_devis";
const EXPORT_DEVIS_SOCIETY = "export_devis_society";
const EXPORT_DEVIS_ANY = "export_devis_any";
const EXPORT_COMMAND = "export_commands";
const EXPORT_COMMAND_SOCIETY = "export_commands_society";
const EXPORT_COMMAND_ANY = "export_commands_any";
const EXPORT_TASK = "export_tasks";
const EXPORT_TASK_SOCIETY = "export_tasks_society";
const EXPORT_TASK_ANY = "export_tasks_any";
const EXPORT_MISSION = "export_missions";
const EXPORT_MISSION_SOCIETY = "export_missions_society";
const EXPORT_MISSION_ANY = "export_missions_any";
const EXPORT_IND = "export_individuals";
const EXPORT_IND_SOCIETY = "export_individuals_society";
const EXPORT_IND_ANY = "export_individuals_any";
const EXPORT_RFI = "export_rfi";
const EXPORT_RFI_SOCIETY = "export_rfi_society";
const EXPORT_RFI_ANY = "export_rfi_any";
const EXPORT_ANOMALY = "export_anomaly";
const EXPORT_ANOMALY_SOCIETY = "export_anomaly_society";
const EXPORT_ANOMALY_ANY = "export_anomaly_any";
const EXPORT_INSTALLMENT = "export_installment";
const EXPORT_INSTALLMENT_SOCIETY = "export_installment_society";
const EXPORT_INSTALLMENT_ANY = "export_installment_any";
const EXPORT_EQUIPMENT = "export_equipment";
const EXPORT_EQUIPMENT_SOCIETY = "export_equipment_society";
const EXPORT_EQUIPMENT_ANY = "export_equipment_any";
// Plan.io Tasks #3621 #3653
const EXPORT_IKEA_SERVICE_ORDER = "export_ikea_service_orders";
const EXPORT_IKEA_SERVICE_ORDER_SOCIETY = "export_ikea_service_orders_society";
const EXPORT_IKEA_SERVICE_ORDER_ANY = "export_ikea_service_orders_any";
const EXPORT_SALARY = "export_salary";
const EXPORT_SALARY_SOCIETY = "export_salary_society";
const EXPORT_SALARY_ANY = "export_salary_any";
const EXPORT_DEMAND = "export_demand";
const EXPORT_DEMAND_SOCIETY = "export_demand_society";
const EXPORT_DEMAND_ANY = "export_demand_any";
// Task plan.io #3889 : No right for society
const EXPORT_ITASK = "export_itask";
const EXPORT_ITASK_ANY = "export_itask_any";
// Task plan.io #4426
const EXPORT_COST = "export_cost";
const EXPORT_COST_SOCIETY = "export_cost_society";
const EXPORT_COST_ANY = "export_cost_any";
const IS_GRANTED_CONSTANTS = array(
self::IS_ACTIVE,
self::EXPORT_ANY,
self::EXPORT_INVOICE,
self::EXPORT_INVOICE_SOCIETY,
self::EXPORT_INVOICE_ANY,
self::EXPORT_DEVIS,
self::EXPORT_DEVIS_SOCIETY,
self::EXPORT_DEVIS_ANY,
self::EXPORT_COMMAND,
self::EXPORT_COMMAND_SOCIETY,
self::EXPORT_COMMAND_ANY,
self::EXPORT_TASK,
self::EXPORT_TASK_SOCIETY,
self::EXPORT_TASK_ANY,
self::EXPORT_MISSION,
self::EXPORT_MISSION_SOCIETY,
self::EXPORT_MISSION_ANY,
self::EXPORT_IND,
self::EXPORT_IND_SOCIETY,
self::EXPORT_IND_ANY,
self::EXPORT_RFI,
self::EXPORT_RFI_SOCIETY,
self::EXPORT_RFI_ANY,
self::EXPORT_ANOMALY,
self::EXPORT_ANOMALY_SOCIETY,
self::EXPORT_ANOMALY_ANY,
self::EXPORT_INSTALLMENT,
self::EXPORT_INSTALLMENT_SOCIETY,
self::EXPORT_INSTALLMENT_ANY,
self::EXPORT_EQUIPMENT,
self::EXPORT_EQUIPMENT_SOCIETY,
self::EXPORT_EQUIPMENT_ANY,
// Plan.io Tasks #3621 #3653
self::EXPORT_IKEA_SERVICE_ORDER,
self::EXPORT_IKEA_SERVICE_ORDER_SOCIETY,
self::EXPORT_IKEA_SERVICE_ORDER_ANY,
self::EXPORT_SALARY,
self::EXPORT_SALARY_SOCIETY,
self::EXPORT_SALARY_ANY,
self::EXPORT_DEMAND,
self::EXPORT_DEMAND_SOCIETY,
self::EXPORT_DEMAND_ANY,
self::EXPORT_ITASK,
self::EXPORT_ITASK_ANY,
self::EXPORT_COST,
self::EXPORT_COST_SOCIETY,
self::EXPORT_COST_ANY,
);
//--------------------------------------------------------------------------------
// acl constants
const ACL_PERM_EXPORT_INVOICE = "invoice_export";
const ACL_PERM_EXPORT_INVOICE_SOCIETY = "invoice_export_society";
const ACL_PERM_EXPORT_DEVIS = "devis_export";
const ACL_PERM_EXPORT_DEVIS_SOCIETY = "devis_export_society";
const ACL_PERM_EXPORT_COMMAND = "command_export";
const ACL_PERM_EXPORT_COMMAND_SOCIETY = "command_export_society";
const ACL_PERM_EXPORT_TASK = "task_export";
const ACL_PERM_EXPORT_TASK_SOCIETY = "task_export_society";
const ACL_PERM_EXPORT_MISSION = "mission_export";
const ACL_PERM_EXPORT_MISSION_SOCIETY = "mission_export_society";
const ACL_PERM_EXPORT_IND = "ind_export";
const ACL_PERM_EXPORT_IND_SOCIETY = "ind_export_society";
const ACL_PERM_EXPORT_RFI = "webapp_doc_export_rfi";
const ACL_PERM_EXPORT_RFI_SOCIETY = "webapp_doc_export_rfi_society";
const ACL_PERM_EXPORT_ANOMALY = "webapp_doc_export_anomaly";
const ACL_PERM_EXPORT_ANOMALY_SOCIETY = "webapp_doc_export_anomaly_society";
const ACL_PERM_EXPORT_INSTALLMENT = "installment_export";
const ACL_PERM_EXPORT_INSTALLMENT_SOCIETY = "installment_export_society";
const ACL_PERM_EXPORT_EQUIPMENT = "equipment_export";
const ACL_PERM_EXPORT_EQUIPMENT_SOCIETY = "equipment_export_society";
// Plan.io Tasks #3621 #3653
const ACL_PERM_EXPORT_IKEA_SERVICE_ORDER = "ikea_service_order_export";
const ACL_PERM_EXPORT_IKEA_SERVICE_ORDER_SOCIETY = "ikea_service_order_export_society";
// Plan.io Task #3884
const ACL_PERM_EXPORT_SALARY = "salary_export";
const ACL_PERM_EXPORT_SALARY_SOCIETY = "salary_export_society";
// Plan.io Task #3889
const ACL_PERM_EXPORT_DEMAND = "demand_export";
const ACL_PERM_EXPORT_DEMAND_SOCIETY = "demand_export_society";
// Plan.io Task #3889
const ACL_PERM_EXPORT_ITASK = "itask_export";
// Plan.io Task #4426
const ACL_PERM_EXPORT_COST = "cost_export";
const ACL_PERM_EXPORT_COST_SOCIETY = "cost_export_society";
//--------------------------------------------------------------------------------
public function __construct(ManagerRegistry $doctrine, ModuleTools $moduleTools)
{
$this->em = $doctrine->getManager();
$this->moduleTools = $moduleTools;
$this->aclRepository = $this->em->getRepository(Acl::class);
$this->aclPermissionRepository = $this->em->getRepository(AclPermission::class);
}
// Plan.io Task #4453 [See AccessVoter for details]
public function supportsAttribute(string $attribute): bool
{
return in_array($attribute, self::IS_GRANTED_CONSTANTS, true);
}
protected function supports(string $attribute, $subject = null): bool
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, self::IS_GRANTED_CONSTANTS))
{
return false;
}
return true;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof Access)
{
// the user must be logged in; if not, deny access
return false;
}
// The user must have a function; if not deny access
$function = $user->getFunction();
if ($function === null) return false;
// Plan.io Task #3710 : Get current group
$currentGroup = $user->getSocietyGroup();
if ($currentGroup === null)
return false;
// Module activated ?
if ($this->moduleTools->isInactiveByCode($currentGroup, Module::MODULE_EXPORT))
{
return false;
}
// No subject for this voter
switch ($attribute)
{
case self::IS_ACTIVE:
return true;
case self::EXPORT_ANY:
return $this->canExportAnyGeneric($user, $function);
case self::EXPORT_INVOICE:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_INVOICE);
case self::EXPORT_INVOICE_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_INVOICE_SOCIETY);
case self::EXPORT_INVOICE_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_INVOICE, self::ACL_PERM_EXPORT_INVOICE_SOCIETY);
case self::EXPORT_DEVIS:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_DEVIS);
case self::EXPORT_DEVIS_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_DEVIS_SOCIETY);
case self::EXPORT_DEVIS_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_DEVIS, self::ACL_PERM_EXPORT_DEVIS_SOCIETY);
case self::EXPORT_COMMAND:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_COMMAND);
case self::EXPORT_COMMAND_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_COMMAND_SOCIETY);
case self::EXPORT_COMMAND_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_COMMAND, self::ACL_PERM_EXPORT_COMMAND_SOCIETY);
case self::EXPORT_TASK:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_TASK);
case self::EXPORT_TASK_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_TASK_SOCIETY);
case self::EXPORT_TASK_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_TASK, self::ACL_PERM_EXPORT_TASK_SOCIETY);
case self::EXPORT_MISSION:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_MISSION);
case self::EXPORT_MISSION_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_MISSION_SOCIETY);
case self::EXPORT_MISSION_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_MISSION, self::ACL_PERM_EXPORT_MISSION_SOCIETY);
case self::EXPORT_IND:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_IND);
case self::EXPORT_IND_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_IND_SOCIETY);
case self::EXPORT_IND_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_IND, self::ACL_PERM_EXPORT_IND_SOCIETY);
case self::EXPORT_RFI:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_RFI);
case self::EXPORT_RFI_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_RFI_SOCIETY);
case self::EXPORT_RFI_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_RFI, self::ACL_PERM_EXPORT_RFI_SOCIETY);
case self::EXPORT_ANOMALY:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_ANOMALY);
case self::EXPORT_ANOMALY_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_ANOMALY_SOCIETY);
case self::EXPORT_ANOMALY_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_ANOMALY, self::ACL_PERM_EXPORT_ANOMALY_SOCIETY);
case self::EXPORT_INSTALLMENT:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_INSTALLMENT);
case self::EXPORT_INSTALLMENT_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_INSTALLMENT_SOCIETY);
case self::EXPORT_INSTALLMENT_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_INSTALLMENT, self::ACL_PERM_EXPORT_INSTALLMENT_SOCIETY);
case self::EXPORT_EQUIPMENT:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_EQUIPMENT);
case self::EXPORT_EQUIPMENT_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_EQUIPMENT_SOCIETY);
case self::EXPORT_EQUIPMENT_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_EQUIPMENT, self::ACL_PERM_EXPORT_EQUIPMENT_SOCIETY);
// Plan.io Tasks #3621 #3653 : Begin
case self::EXPORT_IKEA_SERVICE_ORDER:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_IKEA_SERVICE_ORDER);
case self::EXPORT_IKEA_SERVICE_ORDER_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_IKEA_SERVICE_ORDER_SOCIETY);
case self::EXPORT_IKEA_SERVICE_ORDER_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_IKEA_SERVICE_ORDER, self::ACL_PERM_EXPORT_IKEA_SERVICE_ORDER_SOCIETY);
// Plan.io Tasks #3621 #3653 : End
case self::EXPORT_SALARY:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_SALARY);
case self::EXPORT_SALARY_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_SALARY_SOCIETY);
case self::EXPORT_SALARY_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_SALARY, self::ACL_PERM_EXPORT_SALARY_SOCIETY);
case self::EXPORT_DEMAND:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_DEMAND);
case self::EXPORT_DEMAND_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_DEMAND_SOCIETY);
case self::EXPORT_DEMAND_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_DEMAND, self::ACL_PERM_EXPORT_DEMAND_SOCIETY);
case self::EXPORT_ITASK:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_ITASK);
case self::EXPORT_ITASK_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_ITASK, null);
case self::EXPORT_COST:
return $this->canExport($user, $function, self::ACL_PERM_EXPORT_COST);
case self::EXPORT_COST_SOCIETY:
return $this->canExportSociety($user, $function, self::ACL_PERM_EXPORT_COST_SOCIETY);
case self::EXPORT_COST_ANY:
return $this->canExportAny($user, $function, self::ACL_PERM_EXPORT_COST, self::ACL_PERM_EXPORT_COST_SOCIETY);
}
throw new \LogicException('This code should not be reached!');
}
private function canExportAnyGeneric(Access $user, AccessFunction $function)
{
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_INVOICE, self::ACL_PERM_EXPORT_INVOICE_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_DEVIS, self::ACL_PERM_EXPORT_DEVIS_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_COMMAND, self::ACL_PERM_EXPORT_COMMAND_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_TASK, self::ACL_PERM_EXPORT_TASK_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_MISSION, self::ACL_PERM_EXPORT_MISSION_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_IND, self::ACL_PERM_EXPORT_IND_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_RFI, self::ACL_PERM_EXPORT_RFI_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_ANOMALY, self::ACL_PERM_EXPORT_ANOMALY_SOCIETY))
return true;
// Plan.io Tasks #3621 #3653
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_IKEA_SERVICE_ORDER, self::ACL_PERM_EXPORT_IKEA_SERVICE_ORDER_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_SALARY, self::ACL_PERM_EXPORT_SALARY_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_DEMAND, self::ACL_PERM_EXPORT_DEMAND_SOCIETY))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_ITASK, null))
return true;
if ($this->canExportAny($user, $function, self::ACL_PERM_EXPORT_COST, self::ACL_PERM_EXPORT_COST_SOCIETY))
return true;
return false;
}
private function canExport(Access $user, AccessFunction $function, $aclPermConstant)
{
// Get Acl_Permission
$aclPerm = $this->aclPermissionRepository->findOneByName($aclPermConstant);
if ($aclPerm === null) return false;
// Get Acl
$acl = $this->aclRepository->findOneBy(array(
'function' => $function,
'permission' => $aclPerm
));
if ($acl === null) return false;
// Since only one acl type can exist
// we can return the result of the acl_permission
return $acl->getValue();
}
private function canExportSociety(Access $user, AccessFunction $function, $aclPermConstant)
{
// Get Acl_Permission
$aclPerm = $this->aclPermissionRepository->findOneByName($aclPermConstant);
if ($aclPerm === null) return false;
// Get Acl
$acl = $this->aclRepository->findOneBy(array(
'function' => $function,
'permission' => $aclPerm
));
if ($acl === null) return false;
// Since only one acl type can exist
// we can return the result of the acl_permission
// Further filtering is done in the Controller
return $acl->getValue();
}
private function canExportAny(Access $user, AccessFunction $function, $aclPermConstant, $aclPermConstantSociety)
{
// Three Acl_Permission may exist
$aclPerm = $this->aclPermissionRepository->findOneByName($aclPermConstant);
$aclPermSociety = $this->aclPermissionRepository->findOneByName($aclPermConstantSociety);
// If all are null, exit
if ($aclPerm === null && $aclPermSociety === null)
return false;
// Get First one
if ($aclPerm !== null)
{
$acl = $this->aclRepository->findOneBy(array(
'function' => $function,
'permission' => $aclPerm
));
if ($acl !== null)
{
if ($acl->getValue())
{
// A single positive answer is enough
return true;
}
}
}
// If we are here it means that nothing good has been found
// Load second permission
if ($aclPermSociety !== null)
{
$acl = $this->aclRepository->findOneBy(array(
'function' => $function,
'permission' => $aclPermSociety
));
if ($acl !== null)
{
if ($acl->getValue())
{
// A single positive answer is enough
return true;
}
}
}
// If we are here, all hope is lost
return false;
}
}