mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-24 13:49:03 +03:00
Implemented mechanism to add/remove roles from API keys
This commit is contained in:
parent
01b3c504f8
commit
041f231ff2
4 changed files with 82 additions and 5 deletions
|
@ -38,5 +38,8 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
|
|||
|
||||
$builder->createOneToMany('roles', ApiKeyRole::class)
|
||||
->mappedBy('apiKey')
|
||||
->setIndexBy('roleName')
|
||||
->cascadePersist()
|
||||
->orphanRemoval()
|
||||
->build();
|
||||
};
|
||||
|
|
39
module/Rest/src/ApiKey/Model/RoleDefinition.php
Normal file
39
module/Rest/src/ApiKey/Model/RoleDefinition.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\ApiKey\Model;
|
||||
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||
|
||||
final class RoleDefinition
|
||||
{
|
||||
private string $roleName;
|
||||
private array $meta;
|
||||
|
||||
private function __construct(string $roleName, array $meta)
|
||||
{
|
||||
$this->roleName = $roleName;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public static function forAuthoredShortUrls(): self
|
||||
{
|
||||
return new self(Role::AUTHORED_SHORT_URLS, []);
|
||||
}
|
||||
|
||||
public static function forDomain(string $domainId): self
|
||||
{
|
||||
return new self(Role::DOMAIN_SPECIFIC, ['domain_id' => $domainId]);
|
||||
}
|
||||
|
||||
public function roleName(): string
|
||||
{
|
||||
return $this->roleName;
|
||||
}
|
||||
|
||||
public function meta(): array
|
||||
{
|
||||
return $this->meta;
|
||||
}
|
||||
}
|
|
@ -7,10 +7,12 @@ namespace Shlinkio\Shlink\Rest\Entity;
|
|||
use Cake\Chronos\Chronos;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Exception;
|
||||
use Happyr\DoctrineSpecification\Spec;
|
||||
use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||
|
||||
class ApiKey extends AbstractEntity
|
||||
|
@ -21,12 +23,20 @@ class ApiKey extends AbstractEntity
|
|||
/** @var Collection|ApiKeyRole[] */
|
||||
private Collection $roles;
|
||||
|
||||
public function __construct(?Chronos $expirationDate = null)
|
||||
/**
|
||||
* @param RoleDefinition[] $roleDefinitions
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(?Chronos $expirationDate = null, array $roleDefinitions = [])
|
||||
{
|
||||
$this->key = Uuid::uuid4()->toString();
|
||||
$this->expirationDate = $expirationDate;
|
||||
$this->enabled = true;
|
||||
$this->roles = new ArrayCollection();
|
||||
|
||||
foreach ($roleDefinitions as $roleDefinition) {
|
||||
$this->registerRole($roleDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
public function getExpirationDate(): ?Chronos
|
||||
|
@ -81,13 +91,33 @@ class ApiKey extends AbstractEntity
|
|||
|
||||
public function hasRole(string $roleName): bool
|
||||
{
|
||||
return $this->roles->exists(fn ($key, ApiKeyRole $role) => $role->name() === $roleName);
|
||||
return $this->roles->containsKey($roleName);
|
||||
}
|
||||
|
||||
public function getRoleMeta(string $roleName): array
|
||||
{
|
||||
/** @var ApiKeyRole|false $role */
|
||||
$role = $this->roles->filter(fn (ApiKeyRole $role) => $role->name() === $roleName)->first();
|
||||
return ! $role ? [] : $role->meta();
|
||||
/** @var ApiKeyRole|null $role */
|
||||
$role = $this->roles->get($roleName);
|
||||
return $role === null ? [] : $role->meta();
|
||||
}
|
||||
|
||||
public function registerRole(RoleDefinition $roleDefinition): void
|
||||
{
|
||||
$roleName = $roleDefinition->roleName();
|
||||
$meta = $roleDefinition->meta();
|
||||
|
||||
if ($this->hasRole($roleName)) {
|
||||
/** @var ApiKeyRole $role */
|
||||
$role = $this->roles->get($roleName);
|
||||
$role->updateMeta($meta);
|
||||
} else {
|
||||
$role = new ApiKeyRole($roleDefinition->roleName(), $roleDefinition->meta(), $this);
|
||||
$this->roles[$roleName] = $role;
|
||||
}
|
||||
}
|
||||
|
||||
public function removeRole(string $roleName): void
|
||||
{
|
||||
$this->roles->remove($roleName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ class ApiKeyRole extends AbstractEntity
|
|||
return $this->meta;
|
||||
}
|
||||
|
||||
public function updateMeta(array $newMeta): void
|
||||
{
|
||||
$this->meta = $newMeta;
|
||||
}
|
||||
|
||||
public function apiKey(): ApiKey
|
||||
{
|
||||
return $this->apiKey;
|
||||
|
|
Loading…
Reference in a new issue