Skip to content

Commit

Permalink
add more context to events
Browse files Browse the repository at this point in the history
  • Loading branch information
4rthem committed Feb 17, 2023
1 parent cc25535 commit 44ad358
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 71 deletions.
5 changes: 5 additions & 0 deletions Controller/PermissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
32 changes: 1 addition & 31 deletions Event/AclDeleteEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
53 changes: 53 additions & 0 deletions Event/AclEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Alchemy\AclBundle\Event;

use Symfony\Contracts\EventDispatcher\Event;

abstract class AclEvent extends Event
{
protected int $userType;
protected ?string $userId;
protected string $objectType;
protected ?string $objectId;

public function __construct(int $userType, ?string $userId, string $objectType, ?string $objectId)
{
$this->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;
}
}
31 changes: 7 additions & 24 deletions Event/AclUpsertEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
2 changes: 2 additions & 0 deletions Model/AccessControlEntryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
34 changes: 27 additions & 7 deletions Repository/DoctrinePermissionRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,40 @@ 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,
'userType' => $userType,
'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);
Expand All @@ -82,18 +99,21 @@ 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();

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([
Expand Down
18 changes: 16 additions & 2 deletions Repository/PermissionRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
25 changes: 18 additions & 7 deletions Security/PermissionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -115,38 +115,49 @@ 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(),
$permissions
);
}

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,
$userId,
$objectType,
$objectId
)) {
$this->eventDispatcher->dispatch(new AclDeleteEvent($objectType, $objectId), AclDeleteEvent::NAME);
$this->eventDispatcher->dispatch(new AclDeleteEvent($userType, $userId, $objectType, $objectId), AclDeleteEvent::NAME);
}
}
}

0 comments on commit 44ad358

Please sign in to comment.