Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Controller/PermissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ public function setAce(Request $request, AceSerializer $aceSerializer): Response
$userType = $data['userType'] ?? null;
$userId = $data['userId'] ?? null;
$mask = (int) ($data['mask'] ?? 0);
$metadata = (array) ($data['metadata'] ?? []);

$objectId = !empty($objectId) ? $objectId : null;

$userType = AccessControlEntry::getUserTypeFromString($userType);

$ace = $this->permissionManager->updateOrCreateAce($userType, $userId, $objectType, $objectId, $mask);
$ace = $this->permissionManager->updateOrCreateAce($userType, $userId, $objectType, $objectId, $mask, $metadata);
Comment thread
4rthem marked this conversation as resolved.

return new JsonResponse($aceSerializer->serialize($ace));
}
Expand Down
40 changes: 28 additions & 12 deletions src/Entity/AccessControlEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
namespace Alchemy\AclBundle\Entity;

use Alchemy\AclBundle\Model\AccessControlEntryInterface;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Doctrine\UuidGenerator;
use Ramsey\Uuid\Doctrine\UuidType;
use Ramsey\Uuid\Uuid;
use Symfony\Component\Validator\Constraints as Assert;

Expand All @@ -23,43 +26,46 @@ class AccessControlEntry implements AccessControlEntryInterface
* @var Uuid
*/
#[ORM\Id]
#[ORM\Column(type: 'uuid', unique: true)]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)]
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
protected $id;

#[ORM\Column(type: 'smallint')]
#[ORM\Column(type: Types::SMALLINT)]
protected int $userType = self::TYPE_USER_VALUE;

#[ORM\Column(type: 'string', length: 36, nullable: true)]
#[ORM\Column(type: Types::STRING, length: 36, nullable: true)]
protected ?string $userId = null;

/**
* The object type name (i.e. publication).
*/
#[Assert\NotNull]
#[ORM\Column(type: 'string', length: 20)]
#[ORM\Column(type: Types::STRING, length: 20)]
protected ?string $objectType = null;

#[ORM\Column(type: 'uuid', nullable: true)]
#[ORM\Column(type: UuidType::NAME, nullable: true)]
protected ?string $objectId = null;

#[ORM\Column(type: 'integer')]
#[ORM\Column(type: Types::INTEGER)]
protected int $mask = 0;

#[ORM\Column(type: Types::JSON, nullable: true)]
protected ?array $metadata = null;

/**
* i.e. "p:b9ccf60e-9f08-4388-b703-2953c40cb0a7".
*/
#[ORM\Column(type: 'string', length: 39, nullable: true)]
#[ORM\Column(type: Types::STRING, length: 39, nullable: true)]
protected ?string $parentId = null;

#[ORM\Column(type: 'datetime')]
private readonly \DateTime $createdAt;
#[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
private readonly \DateTimeImmutable $createdAt;

public function __construct()
{
$this->id = Uuid::uuid4();
$this->createdAt = new \DateTime();
$this->createdAt = new \DateTimeImmutable();
}

public static function getUserTypeFromString(string $type): int
Expand Down Expand Up @@ -169,7 +175,7 @@ public function resetPermissions(): void
$this->mask = 0;
}

public function getCreatedAt(): \DateTime
public function getCreatedAt(): \DateTimeImmutable
{
return $this->createdAt;
}
Expand All @@ -193,4 +199,14 @@ public function setParentId(?string $parentId): void
{
$this->parentId = $parentId;
}

public function getMetadata(): array
{
return $this->metadata ?? [];
}

public function setMetadata(array $metadata): void
{
$this->metadata = $metadata;
}
}
4 changes: 4 additions & 0 deletions src/Model/AccessControlEntryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public function removePermission(int $permission): void;

public function resetPermissions(): void;

public function getMetadata(): array;

public function setMetadata(array $metadata): void;

public function getParentId(): ?string;

public function setParentId(?string $parentId): void;
Expand Down
2 changes: 2 additions & 0 deletions src/Repository/DoctrinePermissionRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public function updateOrCreateAce(
string $objectType,
?string $objectId,
int $mask,
array $metadata = [],
?string $parentId = null,
bool $append = false,
): AccessControlEntryInterface {
Expand All @@ -134,6 +135,7 @@ public function updateOrCreateAce(
} else {
$ace->setMask($mask);
}
$ace->setMetadata($metadata);

$this->em->persist($ace);
$this->em->flush();
Expand Down
1 change: 1 addition & 0 deletions src/Repository/PermissionRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public function updateOrCreateAce(
string $objectType,
?string $objectId,
int $mask,
array $metadata = [],
Comment thread
4rthem marked this conversation as resolved.
?string $parentId = null,
bool $append = false,
): AccessControlEntryInterface;
Expand Down
18 changes: 10 additions & 8 deletions src/Security/PermissionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ interface PermissionInterface
public const int MASTER = 64;
public const int OWNER = 128;
public const int SHARE = 256;
public const int CHILD_CREATE = 512;
public const int CHILD_EDIT = 1024;
public const int CHILD_DELETE = 2048;
public const int CHILD_UNDELETE = 4096;
public const int CHILD_OPERATOR = 8192;
public const int CHILD_MASTER = 16384;
public const int CHILD_OWNER = 32768;
public const int CHILD_SHARE = 65536;
public const int CHILD_VIEW = 512;
public const int CHILD_CREATE = 1024;
public const int CHILD_EDIT = 2048;
public const int CHILD_DELETE = 4096;
public const int CHILD_UNDELETE = 8192;
public const int CHILD_OPERATOR = 16384;
public const int CHILD_MASTER = 32768;
public const int CHILD_OWNER = 65536;
public const int CHILD_SHARE = 131072;
Comment thread
4rthem marked this conversation as resolved.

public const array PERMISSIONS = [
'VIEW' => self::VIEW,
Expand All @@ -34,6 +35,7 @@ interface PermissionInterface
'MASTER' => self::MASTER,
'OWNER' => self::OWNER,
'SHARE' => self::SHARE,
'CHILD_VIEW' => self::CHILD_VIEW,
'CHILD_CREATE' => self::CHILD_CREATE,
'CHILD_EDIT' => self::CHILD_EDIT,
'CHILD_DELETE' => self::CHILD_DELETE,
Expand Down
20 changes: 15 additions & 5 deletions src/Security/PermissionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ public function __construct(
) {
}

public function isGranted(AclUserInterface $user, AclObjectInterface $object, array|int $permission): bool
public function resetCache(): void
{
if ($object->getAclOwnerId() === $user->getId()) {
$this->cache = [];
}

public function isGranted(AclUserInterface $user, AclObjectInterface $object, array|int $permission, bool $ownershipGrants = true): bool
{
if ($ownershipGrants && $object->getAclOwnerId() === $user->getId()) {
return true;
}
Comment thread
4rthem marked this conversation as resolved.

Expand All @@ -46,7 +51,10 @@ public function isGranted(AclUserInterface $user, AclObjectInterface $object, ar
return false;
}

private function getAces(AclUserInterface $user, AclObjectInterface $object): array
/**
* @return AccessControlEntryInterface[]
*/
public function getAces(AclUserInterface $user, AclObjectInterface $object): array
{
$objectKey = $this->objectMapper->getObjectKey($object);
$key = $this->getCacheKey(AccessControlEntryInterface::TYPE_USER_VALUE, $user->getId(), $objectKey, $object->getId());
Expand Down Expand Up @@ -124,7 +132,7 @@ public function grantUserOnObject(
$objectKey,
$object->getId(),
$permissions,
$parentId
parentId: $parentId
);
}

Expand All @@ -142,7 +150,7 @@ public function grantGroupOnObject(
$objectKey,
$object->getId(),
$permissions,
$parentId
parentId: $parentId
);
}

Expand Down Expand Up @@ -174,6 +182,7 @@ public function updateOrCreateAce(
string $objectType,
?string $objectId,
int $permissions,
array $metadata = [],
?string $parentId = null,
bool $append = false,
): ?AccessControlEntryInterface {
Expand All @@ -183,6 +192,7 @@ public function updateOrCreateAce(
$objectType,
$objectId,
$permissions,
$metadata,
$parentId,
$append
);
Expand Down
4 changes: 2 additions & 2 deletions src/Security/Voter/SetPermissionVoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#[AutoconfigureTag(name: 'security.voter')]
class SetPermissionVoter extends Voter
{
public const ACL_READ = 'ACL_READ';
public const ACL_WRITE = 'ACL_WRITE';
public const string ACL_READ = 'ACL_READ';
public const string ACL_WRITE = 'ACL_WRITE';

public function __construct(private readonly Security $security)
{
Expand Down
1 change: 1 addition & 0 deletions src/Serializer/AceSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function serialize(AccessControlEntryInterface $ace): array
'objectId' => $ace->getObjectId(),
'mask' => $ace->getMask(),
'parentId' => $ace->getParentId(),
'metadata' => $ace->getMetadata(),
];

if (null !== $userId) {
Expand Down
Loading