Skip to content

Commit 8f05eb1

Browse files
committed
Check related
1 parent 536ae7f commit 8f05eb1

File tree

2 files changed

+53
-50
lines changed

2 files changed

+53
-50
lines changed

src/Domain/Common/Model/Ability.php

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/Domain/Identity/Service/PermissionChecker.php

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,86 @@
44

55
namespace PhpList\Core\Domain\Identity\Service;
66

7-
use PhpList\Core\Domain\Common\Model\Ability;
7+
use PhpList\Core\Domain\Common\Model\Interfaces\DomainModel;
88
use PhpList\Core\Domain\Common\Model\Interfaces\OwnableInterface;
99
use PhpList\Core\Domain\Identity\Model\Administrator;
10+
use PhpList\Core\Domain\Identity\Model\PrivilegeFlag;
11+
use PhpList\Core\Domain\Messaging\Model\Message;
12+
use PhpList\Core\Domain\Subscription\Model\Subscriber;
13+
use PhpList\Core\Domain\Subscription\Model\SubscriberList;
1014

1115
class PermissionChecker
1216
{
13-
public function isGranted(
14-
Ability $ability,
15-
Administrator $actor,
16-
?OwnableInterface $resource = null,
17-
): bool {
18-
if ($this->isSuperAdmin($actor)) {
19-
return true;
20-
}
17+
private const REQUIRED_PRIVILEGE_MAP = [
18+
Subscriber::class => PrivilegeFlag::Subscribers,
19+
SubscriberList::class => PrivilegeFlag::Subscribers,
20+
Message::class => PrivilegeFlag::Campaigns,
21+
];
2122

22-
return match ($ability) {
23-
Ability::VIEW => $resource && $this->isOwner($actor, $resource),
24-
Ability::EDIT => $resource && $this->isOwner($actor, $resource),
25-
Ability::CREATE => $this->canCreate($actor),
26-
};
27-
}
23+
private const OWNERSHIP_MAP = [
24+
Subscriber::class => SubscriberList::class,
25+
Message::class => SubscriberList::class
26+
];
2827

29-
public function canView(Administrator $actor, OwnableInterface $resource): bool
28+
public function canManage(Administrator $actor, DomainModel $resource): bool
3029
{
31-
if ($this->isSuperAdmin($actor)) {
30+
if ($actor->isSuperUser()) {
3231
return true;
3332
}
3433

35-
return $this->isOwner($actor, $resource);
36-
}
34+
$required = $this->resolveRequiredPrivilege($resource);
35+
if ($required !== null && !$actor->getPrivileges()->has($required)) {
36+
return false;
37+
}
3738

38-
public function canEdit(Administrator $actor, OwnableInterface $resource): bool
39-
{
40-
if ($this->isSuperAdmin($actor)) {
41-
return true;
39+
if ($resource instanceof OwnableInterface) {
40+
return $actor->owns($resource);
41+
}
42+
43+
$notRestricted = true;
44+
foreach (self::OWNERSHIP_MAP as $resourceClass => $relatedClass) {
45+
if ($resource instanceof $resourceClass) {
46+
$related = $this->resolveRelatedEntity($resource, $relatedClass);
47+
$notRestricted = $this->checkRelatedResources($related, $actor);
48+
}
4249
}
4350

44-
return $this->isOwner($actor, $resource);
51+
return $notRestricted;
4552
}
4653

47-
public function canCreate(Administrator $actor): bool
54+
private function resolveRequiredPrivilege(DomainModel $resource): ?PrivilegeFlag
4855
{
49-
if ($this->isSuperAdmin($actor)) {
50-
return true;
56+
foreach (self::REQUIRED_PRIVILEGE_MAP as $class => $flag) {
57+
if ($resource instanceof $class) {
58+
return $flag;
59+
}
5160
}
5261

53-
return $actor->getId() !== null;
62+
return null;
5463
}
5564

56-
private function isSuperAdmin(Administrator $actor): bool
65+
/** @return OwnableInterface[] */
66+
private function resolveRelatedEntity(DomainModel $resource, string $relatedClass): array
5767
{
58-
if ($actor->isSuperUser()) {
59-
return true;
68+
if ($resource instanceof Subscriber && $relatedClass === SubscriberList::class) {
69+
return $resource->getSubscribedLists()->toArray();
6070
}
6171

62-
return false;
72+
if ($resource instanceof Message && $relatedClass === SubscriberList::class) {
73+
return $resource->getListMessages()->map(fn($lm) => $lm->getSubscriberList())->toArray();
74+
}
75+
76+
return [];
6377
}
6478

65-
private function isOwner(Administrator $actor, OwnableInterface $resource): bool
79+
private function checkRelatedResources(array $related, Administrator $actor): bool
6680
{
67-
$owner = $resource->getOwner();
68-
$myId = $actor->getId();
81+
foreach ($related as $relatedResource) {
82+
if ($actor->owns($relatedResource)) {
83+
return true;
84+
}
85+
}
6986

70-
return $owner !== null
71-
&& $myId !== null
72-
&& $owner->getId() === $myId;
87+
return false;
7388
}
7489
}

0 commit comments

Comments
 (0)