Update visibility of charges and checkout owner and targets based on accounting voters

This commit is contained in:
2026-01-30 14:51:04 +01:00
parent 49a6119d02
commit d6ca50d627
3 changed files with 9 additions and 9 deletions
@@ -38,7 +38,6 @@ class ChargeApiResource
/**
* The Checkout to which this Charge item belongs to.
*/
#[API\ApiProperty(writable: false, security: 'is_granted("IS_AUTHENTICATED_FULLY")')]
#[API\ApiFilter(GatewayFilter::class, properties: ['checkout.gateway'])]
#[API\ApiFilter(Filter\SearchFilter::class, properties: ['checkout.trackings.value'])]
public CheckoutApiResource $checkout;
@@ -70,6 +69,7 @@ class ChargeApiResource
* The Accounting receiving the money after a successful payment.
*/
#[Assert\NotBlank()]
#[API\ApiProperty(security: 'is_granted("ACCOUNTING_VIEW", object.target)')]
#[API\ApiFilter(Filter\SearchFilter::class, strategy: 'exact')]
public AccountingApiResource $target;
@@ -50,10 +50,7 @@ class CheckoutApiResource
/**
* The Accounting paying for the charges.
*/
#[API\ApiProperty(
security: 'is_granted("ACCOUNTING_VIEW", object.origin)',
securityPostDenormalize: 'is_granted("ACCOUNTING_EDIT", previous_object.origin)'
)]
#[API\ApiProperty(security: 'is_granted("ACCOUNTING_VIEW", object.origin)')]
#[Assert\NotBlank()]
public AccountingApiResource $origin;
+7 -4
View File
@@ -6,8 +6,10 @@ use ApiPlatform\Metadata\IriConverterInterface;
use App\ApiResource\Accounting\AccountingApiResource;
use App\ApiResource\User\UserApiResource;
use App\Entity\User\User;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
class AccountingVoter extends Voter
{
@@ -17,6 +19,7 @@ class AccountingVoter extends Voter
public const VIEW = 'ACCOUNTING_VIEW';
public function __construct(
private Security $security,
private IriConverterInterface $iriConverter,
) {}
@@ -44,11 +47,11 @@ class AccountingVoter extends Voter
return false;
}
private function voteOn(string $attribute, mixed $subject, ?User $user): bool
private function voteOn(string $attribute, mixed $subject, ?UserInterface $user): bool
{
switch ($attribute) {
case self::EDIT:
return $user->hasRoles(['ROLE_ADMIN'])
return $this->security->isGranted('ROLE_ADMIN', $user)
|| $this->isOwnerOf($subject, $user);
case self::VIEW:
return true;
@@ -57,7 +60,7 @@ class AccountingVoter extends Voter
return false;
}
private function voteOnUser(string $attribute, UserApiResource $owner, ?User $user): bool
private function voteOnUser(string $attribute, UserApiResource $owner, ?UserInterface $user): bool
{
if (!$user instanceof User) {
return false;
@@ -66,7 +69,7 @@ class AccountingVoter extends Voter
switch ($attribute) {
case self::EDIT:
case self::VIEW:
return $user->hasRoles(['ROLE_ADMIN'])
return $this->security->isGranted('ROLE_ADMIN', $user)
|| $this->isOwnerOf($owner, $user);
}