2022-11-09 23:33:50 +01:00
< ? php
2023-06-11 18:59:07 +02:00
declare ( strict_types = 1 );
2022-11-29 21:21:26 +01:00
/*
* This file is part of Part - DB ( https :// github . com / Part - DB / Part - DB - symfony ) .
*
* Copyright ( C ) 2019 - 2022 Jan Böhmer ( https :// github . com / jbtronics )
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
2022-11-09 23:33:50 +01:00
namespace App\Security\Voter ;
2023-08-28 22:00:25 +02:00
use App\Services\UserSystem\VoterHelper ;
2023-06-11 14:55:06 +02:00
use Symfony\Bundle\SecurityBundle\Security ;
use App\Entity\Base\AbstractDBElement ;
2022-11-09 23:33:50 +01:00
use App\Entity\Parameters\AbstractParameter ;
use App\Entity\Parameters\AttachmentTypeParameter ;
use App\Entity\Parameters\CategoryParameter ;
use App\Entity\Parameters\CurrencyParameter ;
2022-12-18 20:34:25 +01:00
use App\Entity\Parameters\ProjectParameter ;
2022-11-09 23:33:50 +01:00
use App\Entity\Parameters\FootprintParameter ;
use App\Entity\Parameters\GroupParameter ;
use App\Entity\Parameters\ManufacturerParameter ;
use App\Entity\Parameters\MeasurementUnitParameter ;
use App\Entity\Parameters\PartParameter ;
use App\Entity\Parameters\StorelocationParameter ;
use App\Entity\Parameters\SupplierParameter ;
use App\Entity\UserSystem\User ;
2022-11-14 20:15:06 +01:00
use App\Services\UserSystem\PermissionManager ;
2022-11-09 23:33:50 +01:00
use Doctrine\ORM\EntityManagerInterface ;
2022-11-27 16:53:44 +01:00
use RuntimeException ;
2023-08-28 22:00:25 +02:00
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface ;
use Symfony\Component\Security\Core\Authorization\Voter\Voter ;
2022-11-09 23:33:50 +01:00
2023-08-28 22:00:25 +02:00
final class ParameterVoter extends Voter
2022-11-09 23:33:50 +01:00
{
2023-08-28 22:00:25 +02:00
public function __construct ( private readonly Security $security , private readonly VoterHelper $helper )
2022-11-09 23:33:50 +01:00
{
}
2023-08-28 22:00:25 +02:00
protected function voteOnAttribute ( string $attribute , $subject , TokenInterface $token ) : bool
2022-11-09 23:33:50 +01:00
{
//return $this->resolver->inherit($user, 'attachments', $attribute) ?? false;
2023-05-27 19:17:27 +02:00
if ( ! is_a ( $subject , AbstractParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
return false ;
}
2023-05-27 19:17:27 +02:00
if ( is_object ( $subject )) {
//If the attachment has no element (which should not happen), we deny access, as we can not determine if the user is allowed to access the associated element
$target_element = $subject -> getElement ();
2023-06-11 14:55:06 +02:00
if ( $target_element instanceof AbstractDBElement ) {
2023-06-11 14:15:46 +02:00
$operation = match ( $attribute ) {
'read' , 'view' => 'read' ,
'edit' , 'create' , 'delete' => 'edit' ,
'show_history' => 'show_history' ,
'revert_element' => 'revert_element' ,
default => throw new RuntimeException ( 'Unknown operation: ' . $attribute ),
};
2022-11-13 21:01:40 +01:00
2023-05-27 19:17:27 +02:00
return $this -> security -> isGranted ( $operation , $target_element );
}
2022-11-09 23:33:50 +01:00
}
2023-05-27 19:17:27 +02:00
//If we do not have a concrete element (or we just got a string as value), we delegate to the different categories
if ( is_a ( $subject , AttachmentTypeParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'attachment_types' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , CategoryParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'categories' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , CurrencyParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'currencies' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , ProjectParameter :: class , true )) {
2023-01-08 20:10:58 +01:00
$param = 'projects' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , FootprintParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'footprints' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , GroupParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'groups' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , ManufacturerParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'manufacturers' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , MeasurementUnitParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'measurement_units' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , PartParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'parts' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , StorelocationParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'storelocations' ;
2023-05-27 19:17:27 +02:00
} elseif ( is_a ( $subject , SupplierParameter :: class , true )) {
2022-11-09 23:33:50 +01:00
$param = 'suppliers' ;
2023-05-27 19:17:27 +02:00
} elseif ( $subject === AbstractParameter :: class ) {
//If the subject was deleted, we can not determine the type properly, so we just use the parts permission
$param = 'parts' ;
}
else {
2023-06-11 14:15:46 +02:00
throw new RuntimeException ( 'Encountered unknown Parameter type: ' . ( is_object ( $subject ) ? $subject :: class : $subject ));
2022-11-09 23:33:50 +01:00
}
2023-08-28 22:00:25 +02:00
return $this -> helper -> isGranted ( $token , $param , $attribute );
2022-11-09 23:33:50 +01:00
}
2023-04-15 19:33:39 +02:00
protected function supports ( string $attribute , $subject ) : bool
2022-11-09 23:33:50 +01:00
{
if ( is_a ( $subject , AbstractParameter :: class , true )) {
//These are the allowed attributes
2022-11-13 21:01:40 +01:00
return in_array ( $attribute , [ 'read' , 'edit' , 'delete' , 'create' , 'show_history' , 'revert_element' ], true );
2022-11-09 23:33:50 +01:00
}
//Allow class name as subject
return false ;
}
2023-06-11 18:59:07 +02:00
}