From 44ad3585a9ac72fc09a99b5dbe76cf754c83c002 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Fri, 17 Feb 2023 19:23:39 +0100 Subject: [PATCH] add more context to events --- Controller/PermissionController.php | 5 ++ Event/AclDeleteEvent.php | 32 +----------- Event/AclEvent.php | 53 ++++++++++++++++++++ Event/AclUpsertEvent.php | 31 +++--------- Model/AccessControlEntryInterface.php | 2 + Repository/DoctrinePermissionRepository.php | 34 ++++++++++--- Repository/PermissionRepositoryInterface.php | 18 ++++++- Security/PermissionManager.php | 25 ++++++--- 8 files changed, 129 insertions(+), 71 deletions(-) create mode 100644 Event/AclEvent.php diff --git a/Controller/PermissionController.php b/Controller/PermissionController.php index 919eb49..7cfedd7 100644 --- a/Controller/PermissionController.php +++ b/Controller/PermissionController.php @@ -4,6 +4,7 @@ namespace Alchemy\AclBundle\Controller; +use Alchemy\AclBundle\Entity\AccessControlEntry; use Alchemy\AclBundle\Mapping\ObjectMapping; use Alchemy\AclBundle\Model\AccessControlEntryInterface; use Alchemy\AclBundle\Repository\PermissionRepositoryInterface; @@ -65,6 +66,8 @@ public function setAce(Request $request): Response $objectId = !empty($objectId) ? $objectId : null; + $userType = AccessControlEntry::getUserTypeFromString($userType); + $this->permissionManager->updateOrCreateAce($userType, $userId, $objectType, $objectId, $mask); return new JsonResponse(true); @@ -122,6 +125,8 @@ public function deleteAce(Request $request): Response $objectId = !empty($objectId) ? $objectId : null; + $userType = AccessControlEntry::getUserTypeFromString($userType); + $this->permissionManager->deleteAce($userType, $userId, $objectType, $objectId); return new JsonResponse(true); diff --git a/Event/AclDeleteEvent.php b/Event/AclDeleteEvent.php index dac832a..bf2135a 100644 --- a/Event/AclDeleteEvent.php +++ b/Event/AclDeleteEvent.php @@ -4,37 +4,7 @@ namespace Alchemy\AclBundle\Event; -use Symfony\Contracts\EventDispatcher\Event; - -class AclDeleteEvent extends Event +class AclDeleteEvent extends AclEvent { public const NAME = 'acl.delete'; - private string $objectType; - private ?string $objectId; - - public function __construct(string $objectType, ?string $objectId) - { - $this->objectType = $objectType; - $this->objectId = $objectId; - } - - public function getObjectType(): string - { - return $this->objectType; - } - - public function setObjectType(string $objectType): void - { - $this->objectType = $objectType; - } - - public function getObjectId(): ?string - { - return $this->objectId; - } - - public function setObjectId(?string $objectId): void - { - $this->objectId = $objectId; - } } diff --git a/Event/AclEvent.php b/Event/AclEvent.php new file mode 100644 index 0000000..c72c5e5 --- /dev/null +++ b/Event/AclEvent.php @@ -0,0 +1,53 @@ +userType = $userType; + $this->userId = $userId; + $this->objectType = $objectType; + $this->objectId = $objectId; + } + + public function getUserType(): int + { + return $this->userType; + } + + public function getUserId(): ?string + { + return $this->userId; + } + + public function getObjectType(): string + { + return $this->objectType; + } + + public function setObjectType(string $objectType): void + { + $this->objectType = $objectType; + } + + public function getObjectId(): ?string + { + return $this->objectId; + } + + public function setObjectId(?string $objectId): void + { + $this->objectId = $objectId; + } +} diff --git a/Event/AclUpsertEvent.php b/Event/AclUpsertEvent.php index 728beda..fe9396d 100644 --- a/Event/AclUpsertEvent.php +++ b/Event/AclUpsertEvent.php @@ -4,37 +4,20 @@ namespace Alchemy\AclBundle\Event; -use Symfony\Contracts\EventDispatcher\Event; - -class AclUpsertEvent extends Event +class AclUpsertEvent extends AclEvent { public const NAME = 'acl.upsert'; - private string $objectType; - private ?string $objectId; - public function __construct(string $objectType, ?string $objectId) - { - $this->objectType = $objectType; - $this->objectId = $objectId; - } - - public function getObjectType(): string - { - return $this->objectType; - } - - public function setObjectType(string $objectType): void - { - $this->objectType = $objectType; - } + private int $permissions; - public function getObjectId(): ?string + public function __construct(int $userType, ?string $userId, string $objectType, ?string $objectId, int $permissions) { - return $this->objectId; + $this->permissions = $permissions; + parent::__construct($userType, $userId, $objectType, $objectId); } - public function setObjectId(?string $objectId): void + public function getPermissions(): int { - $this->objectId = $objectId; + return $this->permissions; } } diff --git a/Model/AccessControlEntryInterface.php b/Model/AccessControlEntryInterface.php index 90a5b63..923307a 100644 --- a/Model/AccessControlEntryInterface.php +++ b/Model/AccessControlEntryInterface.php @@ -40,6 +40,8 @@ public function getMask(): int; public function setMask(int $mask): void; + public function hasPermission(int $permission): bool; + public function setPermissions(array $permissions): void; public function getPermissions(): array; diff --git a/Repository/DoctrinePermissionRepository.php b/Repository/DoctrinePermissionRepository.php index 2206e97..4ac065c 100644 --- a/Repository/DoctrinePermissionRepository.php +++ b/Repository/DoctrinePermissionRepository.php @@ -57,16 +57,20 @@ public function getAllowedGroupIds(string $objectType, string $objectId, int $pe ->getAllowedGroupIds($objectType, $objectId, $permission); } - public function updateOrCreateAce(string $userType, ?string $userId, string $objectType, ?string $objectId, int $mask): ?AccessControlEntryInterface + public function findAce( + int $userType, + ?string $userId, + string $objectType, + string $objectId + ): ?AccessControlEntryInterface { if (null !== $objectId && empty($objectId)) { throw new InvalidArgumentException('Empty objectId'); } $userId = AccessControlEntry::USER_WILDCARD === $userId ? null : $userId; - $userType = AccessControlEntry::getUserTypeFromString($userType); - $ace = $this->em->getRepository(AccessControlEntry::class) + return $this->em->getRepository(AccessControlEntry::class) ->findOneBy([ 'objectType' => $objectType, 'objectId' => $objectId, @@ -74,6 +78,19 @@ public function updateOrCreateAce(string $userType, ?string $userId, string $obj 'userId' => $userId, ]); + } + + public function updateOrCreateAce( + int $userType, + ?string $userId, + string $objectType, + ?string $objectId, + int $mask, + bool $append = false + ): AccessControlEntryInterface + { + $ace = $this->findAce($userType, $userId, $objectType, $objectId); + if (!$ace instanceof AccessControlEntry) { $ace = new AccessControlEntry(); $ace->setUserType($userType); @@ -82,7 +99,11 @@ public function updateOrCreateAce(string $userType, ?string $userId, string $obj $ace->setObjectId($objectId); } - $ace->setMask($mask); + if ($append) { + $ace->addPermission($mask); + } else { + $ace->setMask($mask); + } $this->em->persist($ace); $this->em->flush(); @@ -90,10 +111,9 @@ public function updateOrCreateAce(string $userType, ?string $userId, string $obj return $ace; } - public function deleteAce(string $userType, ?string $userId, string $objectType, ?string $objectId): bool + public function deleteAce(int $userType, ?string $userId, string $objectType, ?string $objectId): bool { - $userId = AccessControlEntry::USER_WILDCARD === $userId ? null : $userId; - $userType = AccessControlEntry::getUserTypeFromString($userType); + $userId = AccessControlEntryInterface::USER_WILDCARD === $userId ? null : $userId; $ace = $this->em->getRepository(AccessControlEntry::class) ->findOneBy([ diff --git a/Repository/PermissionRepositoryInterface.php b/Repository/PermissionRepositoryInterface.php index 048b52d..db79bf6 100644 --- a/Repository/PermissionRepositoryInterface.php +++ b/Repository/PermissionRepositoryInterface.php @@ -24,10 +24,24 @@ public function getAllowedGroupIds(string $objectType, string $objectId, int $pe */ public function getObjectAces(string $objectType, ?string $objectId): array; - public function updateOrCreateAce(string $userType, string $userId, string $objectType, ?string $objectId, int $permissions): ?AccessControlEntryInterface; + public function findAce( + int $userType, + ?string $userId, + string $objectType, + string $objectId + ): ?AccessControlEntryInterface; + + public function updateOrCreateAce( + int $userType, + string $userId, + string $objectType, + ?string $objectId, + int $mask, + bool $append = false + ): AccessControlEntryInterface; /** * @return bool Whether the ACE has been deleted */ - public function deleteAce(string $userType, string $userId, string $objectType, ?string $objectId): bool; + public function deleteAce(int $userType, string $userId, string $objectType, ?string $objectId): bool; } diff --git a/Security/PermissionManager.php b/Security/PermissionManager.php index ef8c9c7..8abafd7 100644 --- a/Security/PermissionManager.php +++ b/Security/PermissionManager.php @@ -102,7 +102,7 @@ public function grantUserOnObject(string $userId, AclObjectInterface $object, in $objectKey = $this->objectMapper->getObjectKey($object); $this->updateOrCreateAce( - AccessControlEntryInterface::TYPE_USER, + AccessControlEntryInterface::TYPE_USER_VALUE, $userId, $objectKey, $object->getId(), @@ -115,7 +115,7 @@ public function grantGroupOnObject(string $userId, AclObjectInterface $object, i $objectKey = $this->objectMapper->getObjectKey($object); $this->updateOrCreateAce( - AccessControlEntryInterface::TYPE_GROUP, + AccessControlEntryInterface::TYPE_GROUP_VALUE, $userId, $objectKey, $object->getId(), @@ -123,22 +123,33 @@ public function grantGroupOnObject(string $userId, AclObjectInterface $object, i ); } - public function updateOrCreateAce(string $userType, string $userId, string $objectType, ?string $objectId, int $permissions): ?AccessControlEntryInterface + public function findAce( + int $userType, + ?string $userId, + string $objectType, + string $objectId + ): ?AccessControlEntryInterface + { + return $this->repository->findAce($userType, $userId, $objectType, $objectId); + } + + public function updateOrCreateAce(int $userType, string $userId, string $objectType, ?string $objectId, int $permissions, bool $append = false): ?AccessControlEntryInterface { $ace = $this->repository->updateOrCreateAce( $userType, $userId, $objectType, $objectId, - $permissions + $permissions, + $append ); - $this->eventDispatcher->dispatch(new AclUpsertEvent($objectType, $objectId), AclUpsertEvent::NAME); + $this->eventDispatcher->dispatch(new AclUpsertEvent($userType, $userId, $objectType, $objectId, $permissions), AclUpsertEvent::NAME); return $ace; } - public function deleteAce(string $userType, string $userId, string $objectType, ?string $objectId): void + public function deleteAce(int $userType, string $userId, string $objectType, ?string $objectId): void { if ($this->repository->deleteAce( $userType, @@ -146,7 +157,7 @@ public function deleteAce(string $userType, string $userId, string $objectType, $objectType, $objectId )) { - $this->eventDispatcher->dispatch(new AclDeleteEvent($objectType, $objectId), AclDeleteEvent::NAME); + $this->eventDispatcher->dispatch(new AclDeleteEvent($userType, $userId, $objectType, $objectId), AclDeleteEvent::NAME); } } }