<?php
namespace App\Security\Voter;
use App\Entity\Order;
use App\Entity\User;
use App\Repository\CompanyRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
class OrderVoter extends Voter
{
public const EDIT = 'ORDER_EDIT';
public const VIEW = 'ORDER_VIEW';
public const DELETE = 'ORDER_DELETE';
public const NOT_ANONYMIZE = 'ORDER_NOT_ANONYMIZE';
public const VIEW_MERCHANT = 'VIEW_MERCHANT';
public const VIEW_INPROGRESS = 'ORDER_VIEW_INPROGRESS';
/**
* Limitace na spolecnost pri nacitani v repositari
*/
public const REPO_DONT_LIMIT_COMPANY = 'ORDER_REPO_NO_LIMIT_COMPANY';
public const REPO_DONT_LIMIT_OWNER = 'ORDER_REPO_NO_LIMIT_OWNER';
public const VIEW_ICONS_ORDER_LIST = 'VIEW_ICONS_ORDER_LIST';
public const VIEW_INVOICING_MERCHANT = 'VIEW_INVOICING_MERCHANT';
public const VIEW_INVOICING_EMITENT = 'VIEW_INVOICING_EMITENT';
/**
* @var Security
*/
protected $_security;
/**
* @var CompanyRepository
*/
protected $_companyRepository;
/**
* @param Security $_security
* @param CompanyRepository $companyRepository
*/
public function __construct(Security $_security, CompanyRepository $companyRepository)
{
$this->_security = $_security;
$this->_companyRepository = $companyRepository;
}
protected function supports(string $attribute, $subject): bool
{
return in_array($attribute, [
self::EDIT,
self::VIEW,
self::REPO_DONT_LIMIT_COMPANY,
self::REPO_DONT_LIMIT_OWNER,
self::VIEW_INPROGRESS,
self::DELETE,
self::VIEW_MERCHANT,
self::NOT_ANONYMIZE,
self::VIEW_ICONS_ORDER_LIST,
self::VIEW_INVOICING_EMITENT,
self::VIEW_INVOICING_MERCHANT
]);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
if ($this->_security->isGranted(User::ROLE_ADMIN)) {
return true;
}
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
$order = $subject;
// ... (check conditions and return true to grant permission) ...
switch ($attribute) {
case self::EDIT:
return $this->canEdit($user, $order);
case self::VIEW:
return $this->canView($user, $order);
case self::REPO_DONT_LIMIT_COMPANY:
return $this->dontLimitByCompany($user, $order);
case self::REPO_DONT_LIMIT_OWNER:
return $this->dontLimitByOwner($user, $order);
case self::DELETE:
return $this->canDelete($user, $order);
case self::VIEW_MERCHANT:
return $this->canViewMerchant($user, $order);
case self::NOT_ANONYMIZE:
return $this->isNotAnonymize($user, $order);
case self::VIEW_ICONS_ORDER_LIST:
return $this->viewIconsOrderList($user);
case self::VIEW_INPROGRESS:
return $this->canViewInProgress($user, $order);
case self::VIEW_INVOICING_EMITENT:
return $this->isEmitentInvoicing($user);
case self::VIEW_INVOICING_MERCHANT:
return $this->isMerchantInvoicing($user);
}
return false;
}
/**
* @param UserInterface $user
* @param Order|null $order
* @return false
*/
protected function canViewMerchant(UserInterface $user, $order): bool
{
if($user->hasRole(User::ROLE_COMPANY_ADMIN)){
return false;
}
if($user->hasRole(User::ROLE_COMPANY_USER)){
return false;
}
if($user->hasRole(User::ROLE_MERCHANT)){
return true;
}
return true;
}
/**
* @param UserInterface $user
* @param Order|null $order
* @return false
*/
protected function isNotAnonymize(UserInterface $user, ?Order $order): bool
{
// pokud neni nastavena anonymiziace na uzivateli vracim true
if($user->isAnonymize() === false){
return true;
}
if($user->hasRole(User::ROLE_MERCHANT)){
if(isset($order) && $order->getEmail() == $user->getEmail()){
return true;
}
}
// pokud je nastavena 1 na anonymized u uzivatele
return false;
}
/**
* @param User $user
* @return bool
*/
protected function viewIconsOrderList(UserInterface $user): bool
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
if ($user->hasRole(User::ROLE_COMPANY_USER)) {
return true;
}
return false;
}
/**
* @param UserInterface $user
* @param Order $order
* @return false
*/
protected function canDelete(UserInterface $user, Order $order)
{
if($order->isSigned() != false || $order->isPaid() != false || $order->isSent() != false){
return false;
}
if($user->hasRole(User::ROLE_COMPANY_ADMIN)){
return true;
}
if(($user->hasRole(User::ROLE_COMPANY_USER)) &&
$user->getId() == $order->getUser()->getId()
){
return true;
}
if($user->hasRole(User::ROLE_MERCHANT)){
return false;
}
return false;
}
/**
* @param UserInterface $user
* @param Order $order
* @return false
*/
protected function canEdit(UserInterface $user, Order $order)
{
$companyIds = [];
if(is_null($user->getCompany()) == false) {
$companyIds = $this->_companyRepository->getConnectedCompanies($user->getCompany()->getId());
}
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
if (
is_null($order->getCompany()) == false && is_null($user->getCompany()) == false &&
in_array($order->getCompany()->getId(), $companyIds) === true
) {
return true;
}
}
if ($user->hasRole(User::ROLE_MERCHANT)) {
if (is_null($order->getCompany()) == false &&
is_null($user->getCompany()) == false &&
in_array($order->getCompany()->getId(), $companyIds) === true &&
$order->getUser()->getId() == $user->getId()
) {
return true;
}
}
return false;
}
/**
* @param UserInterface $user
* @param Order $order
* @return false
*/
protected function canView(UserInterface $user, Order $order)
{
$companyIds = [];
if(is_null($user->getCompany()) == false) {
$companyIds = $this->_companyRepository->getConnectedCompanies($user->getCompany()->getId());
}
if (
$user->hasRole(User::ROLE_COMPANY_USER) ||
$user->hasRole(User::ROLE_COMPANY_ADMIN)
) {
if (is_null($order->getCompany()) == false &&
is_null($user->getCompany()) == false &&
in_array($order->getCompany()->getId(), $companyIds) === true
) {
return true;
}
}
if($user->hasRole(User::ROLE_MERCHANT)){
if($order->getEmail() == $user->getEmail()){
return true;
}
}
return false;
}
/**
* @param UserInterface $user
* @param Order|null $order
* @return false
*/
protected function dontLimitByCompany(UserInterface $user, $order)
{
if($user->hasRole(User::ROLE_MERCHANT)){
return true;
}
return false;
}
/**
* @param UserInterface $user
* @param Order|null $order
* @return false
*/
protected function dontLimitByOwner(UserInterface $user, $order)
{
// neomezuj pokud je admin || company_user || company_admin
// omezi pokud jsi
if(
$user->hasRole(User::ROLE_COMPANY_USER) ||
$user->hasRole(User::ROLE_COMPANY_ADMIN)
){
return true;
}
return false;
}
protected function canViewInProgress(UserInterface $user, $order)
{
if(
$user->hasRole(User::ROLE_MERCHANT) ||
$user->hasRole(User::ROLE_COMPANY_USER) ||
$user->hasRole(User::ROLE_COMPANY_ADMIN)
){
return true;
}
return false;
}
protected function isMerchantInvoicing(UserInterface $user){
if(
$user->hasRole(User::ROLE_MERCHANT) &&
($user->hasRole(User::ROLE_COMPANY_USER) == false && $user->hasRole(User::ROLE_COMPANY_ADMIN) == false)
){
return true;
}
return false;
}
protected function isEmitentInvoicing(UserInterface $user){
if(
$user->hasRole(User::ROLE_COMPANY_USER) ||
$user->hasRole(User::ROLE_COMPANY_ADMIN)
){
return true;
}
return false;
}
}