From 2a309066ac49e7da5b5b8eafafacdaa54ed3bb5a Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 7 May 2026 14:32:31 +0200 Subject: [PATCH 1/4] enhance AclUpsertEvent to include previous permissions and metadata, update related methods in PermissionManager and repositories --- src/Event/AclUpsertEvent.php | 26 ++++++++++++++++++- .../DoctrinePermissionRepository.php | 3 +++ .../PermissionRepositoryInterface.php | 1 + src/Security/PermissionManager.php | 15 +++++++++-- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Event/AclUpsertEvent.php b/src/Event/AclUpsertEvent.php index 11270a7..7d51d36 100644 --- a/src/Event/AclUpsertEvent.php +++ b/src/Event/AclUpsertEvent.php @@ -8,7 +8,16 @@ class AclUpsertEvent extends AclEvent { public const NAME = 'acl.upsert'; - public function __construct(int $userType, ?string $userId, string $objectType, ?string $objectId, private readonly int $permissions) + public function __construct( + int $userType, + ?string $userId, + string $objectType, + ?string $objectId, + private readonly int $permissions, + private readonly array $metadata, + private readonly ?int $previousPermissions, + private readonly ?array $previousMetadata, + ) { parent::__construct($userType, $userId, $objectType, $objectId); } @@ -17,4 +26,19 @@ public function getPermissions(): int { return $this->permissions; } + + public function getPreviousPermissions(): ?int + { + return $this->previousPermissions; + } + + public function getMetadata(): array + { + return $this->metadata; + } + + public function getPreviousMetadata(): ?array + { + return $this->previousMetadata; + } } diff --git a/src/Repository/DoctrinePermissionRepository.php b/src/Repository/DoctrinePermissionRepository.php index 0e23500..389d0fe 100644 --- a/src/Repository/DoctrinePermissionRepository.php +++ b/src/Repository/DoctrinePermissionRepository.php @@ -117,6 +117,7 @@ public function updateOrCreateAce( array $metadata = [], ?string $parentId = null, bool $append = false, + ?AccessControlEntryInterface &$previousAce = null, ): AccessControlEntryInterface { $ace = $this->findAce($userType, $userId, $objectType, $objectId, $parentId); @@ -128,6 +129,8 @@ public function updateOrCreateAce( $ace->setObjectType($objectType); $ace->setObjectId($objectId); $ace->setParentId($parentId); + } else { + $previousAce = clone $ace; } if ($append) { diff --git a/src/Repository/PermissionRepositoryInterface.php b/src/Repository/PermissionRepositoryInterface.php index bc6601d..9218710 100644 --- a/src/Repository/PermissionRepositoryInterface.php +++ b/src/Repository/PermissionRepositoryInterface.php @@ -50,6 +50,7 @@ public function updateOrCreateAce( array $metadata = [], ?string $parentId = null, bool $append = false, + ?AccessControlEntryInterface &$previousAce = null, ): AccessControlEntryInterface; /** diff --git a/src/Security/PermissionManager.php b/src/Security/PermissionManager.php index 1e5b345..4d6b625 100644 --- a/src/Security/PermissionManager.php +++ b/src/Security/PermissionManager.php @@ -185,6 +185,7 @@ public function updateOrCreateAce( array $metadata = [], ?string $parentId = null, bool $append = false, + ?AccessControlEntryInterface &$previousAce = null, ): ?AccessControlEntryInterface { $ace = $this->repository->updateOrCreateAce( $userType, @@ -194,12 +195,22 @@ public function updateOrCreateAce( $permissions, $metadata, $parentId, - $append + $append, + $previousAce, ); unset($this->cache[$this->getCacheKey($userType, $userId, $objectType, $objectId)]); - $this->eventDispatcher->dispatch(new AclUpsertEvent($userType, $userId, $objectType, $objectId, $permissions), AclUpsertEvent::NAME); + $this->eventDispatcher->dispatch(new AclUpsertEvent( + $userType, + $userId, + $objectType, + $objectId, + $permissions, + $metadata, + $previousAce?->getMask(), + $previousAce?->getMetadata() + ), AclUpsertEvent::NAME); return $ace; } From 80ca27849b173ea46c3ee1996d1e29feb0884713 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 7 May 2026 15:27:33 +0200 Subject: [PATCH 2/4] enhance AclEvent and related classes to support previous permissions and metadata in ACL operations --- src/Event/AclDeleteEvent.php | 2 +- src/Event/AclEvent.php | 21 ++++++++++++------- src/Event/AclUpsertEvent.php | 18 ++++------------ .../DoctrinePermissionRepository.php | 2 ++ .../PermissionRepositoryInterface.php | 1 + src/Security/PermissionManager.php | 12 +++++++++-- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/Event/AclDeleteEvent.php b/src/Event/AclDeleteEvent.php index bf2135a..91da763 100644 --- a/src/Event/AclDeleteEvent.php +++ b/src/Event/AclDeleteEvent.php @@ -6,5 +6,5 @@ class AclDeleteEvent extends AclEvent { - public const NAME = 'acl.delete'; + public const string NAME = 'acl.delete'; } diff --git a/src/Event/AclEvent.php b/src/Event/AclEvent.php index 44af191..acd5f76 100644 --- a/src/Event/AclEvent.php +++ b/src/Event/AclEvent.php @@ -8,7 +8,14 @@ abstract class AclEvent extends Event { - public function __construct(protected int $userType, protected ?string $userId, protected string $objectType, protected ?string $objectId) + public function __construct( + protected readonly int $userType, + protected readonly ?string $userId, + protected readonly string $objectType, + protected readonly ?string $objectId, + protected readonly ?int $previousPermissions, + protected readonly ?array $previousMetadata, + ) { } @@ -27,18 +34,18 @@ public function getObjectType(): string return $this->objectType; } - public function setObjectType(string $objectType): void + public function getObjectId(): ?string { - $this->objectType = $objectType; + return $this->objectId; } - public function getObjectId(): ?string + public function getPreviousPermissions(): ?int { - return $this->objectId; + return $this->previousPermissions; } - public function setObjectId(?string $objectId): void + public function getPreviousMetadata(): ?array { - $this->objectId = $objectId; + return $this->previousMetadata; } } diff --git a/src/Event/AclUpsertEvent.php b/src/Event/AclUpsertEvent.php index 7d51d36..6e78aa7 100644 --- a/src/Event/AclUpsertEvent.php +++ b/src/Event/AclUpsertEvent.php @@ -6,7 +6,7 @@ class AclUpsertEvent extends AclEvent { - public const NAME = 'acl.upsert'; + public const string NAME = 'acl.upsert'; public function __construct( int $userType, @@ -15,11 +15,11 @@ public function __construct( ?string $objectId, private readonly int $permissions, private readonly array $metadata, - private readonly ?int $previousPermissions, - private readonly ?array $previousMetadata, + ?int $previousPermissions, + ?array $previousMetadata, ) { - parent::__construct($userType, $userId, $objectType, $objectId); + parent::__construct($userType, $userId, $objectType, $objectId, $previousPermissions, $previousMetadata); } public function getPermissions(): int @@ -27,18 +27,8 @@ public function getPermissions(): int return $this->permissions; } - public function getPreviousPermissions(): ?int - { - return $this->previousPermissions; - } - public function getMetadata(): array { return $this->metadata; } - - public function getPreviousMetadata(): ?array - { - return $this->previousMetadata; - } } diff --git a/src/Repository/DoctrinePermissionRepository.php b/src/Repository/DoctrinePermissionRepository.php index 389d0fe..a4ae317 100644 --- a/src/Repository/DoctrinePermissionRepository.php +++ b/src/Repository/DoctrinePermissionRepository.php @@ -152,6 +152,7 @@ public function deleteAce( string $objectType, ?string $objectId, ?string $parentId = null, + ?AccessControlEntryInterface &$previousAce = null, ): bool { $userId = AccessControlEntryInterface::USER_WILDCARD === $userId ? null : $userId; @@ -165,6 +166,7 @@ public function deleteAce( ]); if ($ace instanceof AccessControlEntry) { + $previousAce = $ace; $this->em->remove($ace); $this->em->flush(); diff --git a/src/Repository/PermissionRepositoryInterface.php b/src/Repository/PermissionRepositoryInterface.php index 9218710..6de6fd4 100644 --- a/src/Repository/PermissionRepositoryInterface.php +++ b/src/Repository/PermissionRepositoryInterface.php @@ -62,5 +62,6 @@ public function deleteAce( string $objectType, ?string $objectId, ?string $parentId = null, + ?AccessControlEntryInterface &$previousAce = null, ): bool; } diff --git a/src/Security/PermissionManager.php b/src/Security/PermissionManager.php index 4d6b625..b7c3a6d 100644 --- a/src/Security/PermissionManager.php +++ b/src/Security/PermissionManager.php @@ -232,9 +232,17 @@ public function deleteAce( $userId, $objectType, $objectId, - $parentId + $parentId, + $previousAce, )) { - $this->eventDispatcher->dispatch(new AclDeleteEvent($userType, $userId, $objectType, $objectId), AclDeleteEvent::NAME); + $this->eventDispatcher->dispatch(new AclDeleteEvent( + $userType, + $userId, + $objectType, + $objectId, + $previousAce->getMask(), + $previousAce->getMetadata(), + ), AclDeleteEvent::NAME); } unset($this->cache[$this->getCacheKey($userType, $userId, $objectType, $objectId)]); From e079478e7435bd8ea90de26bc81a47c34a0c3a61 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 7 May 2026 15:28:01 +0200 Subject: [PATCH 3/4] cs fix --- src/Controller/PermissionController.php | 3 +-- src/Event/AclEvent.php | 3 +-- src/Event/AclUpsertEvent.php | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Controller/PermissionController.php b/src/Controller/PermissionController.php index 824ad27..c66699f 100644 --- a/src/Controller/PermissionController.php +++ b/src/Controller/PermissionController.php @@ -27,8 +27,7 @@ public function __construct( private readonly PermissionManager $permissionManager, private readonly EntityManagerInterface $em, private readonly ObjectMapping $objectMapping, - ) - { + ) { } private function validateAuthorization(string $attribute, Request $request): array diff --git a/src/Event/AclEvent.php b/src/Event/AclEvent.php index acd5f76..b9423e6 100644 --- a/src/Event/AclEvent.php +++ b/src/Event/AclEvent.php @@ -15,8 +15,7 @@ public function __construct( protected readonly ?string $objectId, protected readonly ?int $previousPermissions, protected readonly ?array $previousMetadata, - ) - { + ) { } public function getUserType(): int diff --git a/src/Event/AclUpsertEvent.php b/src/Event/AclUpsertEvent.php index 6e78aa7..eb4523c 100644 --- a/src/Event/AclUpsertEvent.php +++ b/src/Event/AclUpsertEvent.php @@ -17,8 +17,7 @@ public function __construct( private readonly array $metadata, ?int $previousPermissions, ?array $previousMetadata, - ) - { + ) { parent::__construct($userType, $userId, $objectType, $objectId, $previousPermissions, $previousMetadata); } From af4dbaf9e0b7094de38d60335cbeae386a6efe8b Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Mon, 11 May 2026 15:48:50 +0200 Subject: [PATCH 4/4] fix composer.json to correct version constraint for symfony/yaml --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 684643e..ba69a04 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "symfony/framework-bundle": "^6.4|^7.4", "symfony/security-bundle": "^6.4|^7.4", "symfony/validator": "^6.4|^7.4", - "symfony/yaml": "6.4|^7.4" + "symfony/yaml": "^6.4|^7.4" }, "config": { "sort-packages": true