Add ApiKey check to tell if it has any role that is short-url restrictive

This commit is contained in:
Alejandro Celaya 2023-05-30 09:32:44 +02:00
parent 8b03532ddb
commit 12da04ef37
4 changed files with 20 additions and 5 deletions

View file

@ -59,8 +59,8 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito
default => $qb, default => $qb,
}); });
// For admins and when no API key is present, we'll return tags which are not linked to any short URL // For non-restricted API keys, we'll return tags which are not linked to any short URL
$joiningMethod = ApiKey::isAdmin($apiKey) ? 'leftJoin' : 'join'; $joiningMethod = ! ApiKey::isShortUrlRestricted($apiKey) ? 'leftJoin' : 'join';
$tagsSubQb = $conn->createQueryBuilder(); $tagsSubQb = $conn->createQueryBuilder();
$tagsSubQb $tagsSubQb
->select('t.id AS tag_id', 't.name AS tag', 'COUNT(DISTINCT s.id) AS short_urls_count') ->select('t.id AS tag_id', 't.name AS tag', 'COUNT(DISTINCT s.id) AS short_urls_count')

View file

@ -59,7 +59,7 @@ class TagService implements TagServiceInterface
*/ */
public function deleteTags(array $tagNames, ?ApiKey $apiKey = null): void public function deleteTags(array $tagNames, ?ApiKey $apiKey = null): void
{ {
if (! ApiKey::isAdmin($apiKey)) { if (ApiKey::isShortUrlRestricted($apiKey)) {
throw ForbiddenTagOperationException::forDeletion(); throw ForbiddenTagOperationException::forDeletion();
} }
@ -75,7 +75,7 @@ class TagService implements TagServiceInterface
*/ */
public function renameTag(TagRenaming $renaming, ?ApiKey $apiKey = null): Tag public function renameTag(TagRenaming $renaming, ?ApiKey $apiKey = null): Tag
{ {
if (! ApiKey::isAdmin($apiKey)) { if (ApiKey::isShortUrlRestricted($apiKey)) {
throw ForbiddenTagOperationException::forRenaming(); throw ForbiddenTagOperationException::forRenaming();
} }

View file

@ -18,7 +18,7 @@ class WithApiKeySpecsEnsuringJoin extends BaseSpecification
protected function getSpec(): Specification protected function getSpec(): Specification
{ {
return $this->apiKey === null || ApiKey::isAdmin($this->apiKey) ? Spec::andX() : Spec::andX( return $this->apiKey === null || ! ApiKey::isShortUrlRestricted($this->apiKey) ? Spec::andX() : Spec::andX(
Spec::join($this->fieldToJoin, 's'), Spec::join($this->fieldToJoin, 's'),
$this->apiKey->spec($this->fieldToJoin), $this->apiKey->spec($this->fieldToJoin),
); );

View file

@ -122,6 +122,21 @@ class ApiKey extends AbstractEntity
return $apiKey === null || $apiKey->roles->isEmpty(); return $apiKey === null || $apiKey->roles->isEmpty();
} }
/**
* Tells if provided API key has any of the roles restricting at the short URL level
*/
public static function isShortUrlRestricted(?ApiKey $apiKey): bool
{
if ($apiKey === null) {
return false;
}
return (
$apiKey->roles->containsKey(Role::AUTHORED_SHORT_URLS->value)
|| $apiKey->roles->containsKey(Role::DOMAIN_SPECIFIC->value)
);
}
public function hasRole(Role $role): bool public function hasRole(Role $role): bool
{ {
return $this->roles->containsKey($role->value); return $this->roles->containsKey($role->value);