mirror of
https://github.com/shlinkio/shlink.git
synced 2025-01-22 14:33:16 -06:00
Converted Role constants to enum
This commit is contained in:
parent
404455928e
commit
e8f7daac6f
@ -73,13 +73,16 @@ class GenerateKeyCommand extends Command
|
|||||||
$authorOnly,
|
$authorOnly,
|
||||||
'a',
|
'a',
|
||||||
InputOption::VALUE_NONE,
|
InputOption::VALUE_NONE,
|
||||||
sprintf('Adds the "%s" role to the new API key.', Role::AUTHORED_SHORT_URLS),
|
sprintf('Adds the "%s" role to the new API key.', Role::AUTHORED_SHORT_URLS->value),
|
||||||
)
|
)
|
||||||
->addOption(
|
->addOption(
|
||||||
$domainOnly,
|
$domainOnly,
|
||||||
'd',
|
'd',
|
||||||
InputOption::VALUE_REQUIRED,
|
InputOption::VALUE_REQUIRED,
|
||||||
sprintf('Adds the "%s" role to the new API key, with the domain provided.', Role::DOMAIN_SPECIFIC),
|
sprintf(
|
||||||
|
'Adds the "%s" role to the new API key, with the domain provided.',
|
||||||
|
Role::DOMAIN_SPECIFIC->value,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
->setHelp($help);
|
->setHelp($help);
|
||||||
}
|
}
|
||||||
@ -99,7 +102,7 @@ class GenerateKeyCommand extends Command
|
|||||||
if (! $apiKey->isAdmin()) {
|
if (! $apiKey->isAdmin()) {
|
||||||
ShlinkTable::default($io)->render(
|
ShlinkTable::default($io)->render(
|
||||||
['Role name', 'Role metadata'],
|
['Role name', 'Role metadata'],
|
||||||
$apiKey->mapRoles(fn (string $name, array $meta) => [$name, arrayToString($meta, 0)]),
|
$apiKey->mapRoles(fn (Role $role, array $meta) => [$role->value, arrayToString($meta, 0)]),
|
||||||
null,
|
null,
|
||||||
'Roles',
|
'Roles',
|
||||||
);
|
);
|
||||||
|
@ -60,10 +60,10 @@ class ListKeysCommand extends Command
|
|||||||
}
|
}
|
||||||
$rowData[] = $expiration?->toAtomString() ?? '-';
|
$rowData[] = $expiration?->toAtomString() ?? '-';
|
||||||
$rowData[] = $apiKey->isAdmin() ? 'Admin' : implode("\n", $apiKey->mapRoles(
|
$rowData[] = $apiKey->isAdmin() ? 'Admin' : implode("\n", $apiKey->mapRoles(
|
||||||
fn (string $roleName, array $meta) =>
|
fn (Role $role, array $meta) =>
|
||||||
empty($meta)
|
empty($meta)
|
||||||
? Role::toFriendlyName($roleName)
|
? Role::toFriendlyName($role)
|
||||||
: sprintf('%s: %s', Role::toFriendlyName($roleName), Role::domainAuthorityFromMeta($meta)),
|
: sprintf('%s: %s', Role::toFriendlyName($role), Role::domainAuthorityFromMeta($meta)),
|
||||||
));
|
));
|
||||||
|
|
||||||
return $rowData;
|
return $rowData;
|
||||||
|
@ -16,7 +16,7 @@ class InvalidRoleConfigException extends InvalidArgumentException implements Exc
|
|||||||
return new self(sprintf(
|
return new self(sprintf(
|
||||||
'You cannot create an API key with the "%s" role attached to the default domain. '
|
'You cannot create an API key with the "%s" role attached to the default domain. '
|
||||||
. 'The role is currently limited to non-default domains.',
|
. 'The role is currently limited to non-default domains.',
|
||||||
Role::DOMAIN_SPECIFIC,
|
Role::DOMAIN_SPECIFIC->value,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class InvalidRoleConfigExceptionTest extends TestCase
|
|||||||
self::assertEquals(sprintf(
|
self::assertEquals(sprintf(
|
||||||
'You cannot create an API key with the "%s" role attached to the default domain. '
|
'You cannot create an API key with the "%s" role attached to the default domain. '
|
||||||
. 'The role is currently limited to non-default domains.',
|
. 'The role is currently limited to non-default domains.',
|
||||||
Role::DOMAIN_SPECIFIC,
|
Role::DOMAIN_SPECIFIC->value,
|
||||||
), $e->getMessage());
|
), $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ namespace Shlinkio\Shlink\Core\Domain\Repository;
|
|||||||
use Doctrine\ORM\Query\Expr\Join;
|
use Doctrine\ORM\Query\Expr\Join;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
|
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
|
||||||
use Happyr\DoctrineSpecification\Spec;
|
|
||||||
use Shlinkio\Shlink\Core\Domain\Spec\IsDomain;
|
use Shlinkio\Shlink\Core\Domain\Spec\IsDomain;
|
||||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||||
@ -77,10 +76,9 @@ class DomainRepository extends EntitySpecificationRepository implements DomainRe
|
|||||||
// FIXME The $apiKey->spec() method cannot be used here, as it returns a single spec which assumes the
|
// FIXME The $apiKey->spec() method cannot be used here, as it returns a single spec which assumes the
|
||||||
// ShortUrl is the root entity. Here, the Domain is the root entity.
|
// ShortUrl is the root entity. Here, the Domain is the root entity.
|
||||||
// Think on a way to centralize the conditional behavior and make $apiKey->spec() more flexible.
|
// Think on a way to centralize the conditional behavior and make $apiKey->spec() more flexible.
|
||||||
yield from $apiKey?->mapRoles(fn (string $roleName, array $meta) => match ($roleName) {
|
yield from $apiKey?->mapRoles(fn (Role $role, array $meta) => match ($role) {
|
||||||
Role::DOMAIN_SPECIFIC => ['d', new IsDomain(Role::domainIdFromMeta($meta))],
|
Role::DOMAIN_SPECIFIC => ['d', new IsDomain(Role::domainIdFromMeta($meta))],
|
||||||
Role::AUTHORED_SHORT_URLS => ['s', new BelongsToApiKey($apiKey)],
|
Role::AUTHORED_SHORT_URLS => ['s', new BelongsToApiKey($apiKey)],
|
||||||
default => [null, Spec::andX()],
|
|
||||||
}) ?? [];
|
}) ?? [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,14 +81,13 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito
|
|||||||
->groupBy('t.id_0', 't.name_1');
|
->groupBy('t.id_0', 't.name_1');
|
||||||
|
|
||||||
// Apply API key role conditions to the native query too, as they will affect the amounts on the aggregates
|
// Apply API key role conditions to the native query too, as they will affect the amounts on the aggregates
|
||||||
$apiKey?->mapRoles(static fn (string $roleName, array $meta) => match ($roleName) {
|
$apiKey?->mapRoles(static fn (Role $role, array $meta) => match ($role) {
|
||||||
Role::DOMAIN_SPECIFIC => $nativeQb->andWhere(
|
Role::DOMAIN_SPECIFIC => $nativeQb->andWhere(
|
||||||
$nativeQb->expr()->eq('s.domain_id', $conn->quote(Role::domainIdFromMeta($meta))),
|
$nativeQb->expr()->eq('s.domain_id', $conn->quote(Role::domainIdFromMeta($meta))),
|
||||||
),
|
),
|
||||||
Role::AUTHORED_SHORT_URLS => $nativeQb->andWhere(
|
Role::AUTHORED_SHORT_URLS => $nativeQb->andWhere(
|
||||||
$nativeQb->expr()->eq('s.author_api_key_id', $conn->quote($apiKey->getId())),
|
$nativeQb->expr()->eq('s.author_api_key_id', $conn->quote($apiKey->getId())),
|
||||||
),
|
),
|
||||||
default => $nativeQb,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($orderMainQuery) {
|
if ($orderMainQuery) {
|
||||||
|
@ -6,7 +6,9 @@ namespace Shlinkio\Shlink\Rest;
|
|||||||
|
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
|
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
|
||||||
|
use Doctrine\ORM\Mapping\Builder\FieldBuilder;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
|
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||||
|
|
||||||
use function Shlinkio\Shlink\Core\determineTableName;
|
use function Shlinkio\Shlink\Core\determineTableName;
|
||||||
@ -22,11 +24,14 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
|
|||||||
->option('unsigned', true)
|
->option('unsigned', true)
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$builder->createField('roleName', Types::STRING)
|
(new FieldBuilder($builder, [
|
||||||
->columnName('role_name')
|
'fieldName' => 'roleName',
|
||||||
->length(255)
|
'type' => Types::STRING,
|
||||||
->nullable(false)
|
'enumType' => Role::class,
|
||||||
->build();
|
]))->columnName('role_name')
|
||||||
|
->length(255)
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
$builder->createField('meta', Types::JSON)
|
$builder->createField('meta', Types::JSON)
|
||||||
->columnName('meta')
|
->columnName('meta')
|
||||||
|
@ -9,7 +9,7 @@ use Shlinkio\Shlink\Rest\ApiKey\Role;
|
|||||||
|
|
||||||
final class RoleDefinition
|
final class RoleDefinition
|
||||||
{
|
{
|
||||||
private function __construct(public readonly string $roleName, public readonly array $meta)
|
private function __construct(public readonly Role $role, public readonly array $meta)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
// phpcs:disable
|
||||||
|
// TODO Enable coding style checks again once code sniffer 3.7 is released https://github.com/squizlabs/PHP_CodeSniffer/issues/3474
|
||||||
namespace Shlinkio\Shlink\Rest\ApiKey;
|
namespace Shlinkio\Shlink\Rest\ApiKey;
|
||||||
|
|
||||||
use Happyr\DoctrineSpecification\Spec;
|
use Happyr\DoctrineSpecification\Spec;
|
||||||
@ -12,31 +14,24 @@ use Shlinkio\Shlink\Core\ShortUrl\Spec\BelongsToDomain;
|
|||||||
use Shlinkio\Shlink\Core\ShortUrl\Spec\BelongsToDomainInlined;
|
use Shlinkio\Shlink\Core\ShortUrl\Spec\BelongsToDomainInlined;
|
||||||
use Shlinkio\Shlink\Rest\Entity\ApiKeyRole;
|
use Shlinkio\Shlink\Rest\Entity\ApiKeyRole;
|
||||||
|
|
||||||
// TODO Convert to enum
|
enum Role: string
|
||||||
class Role
|
|
||||||
{
|
{
|
||||||
public const AUTHORED_SHORT_URLS = 'AUTHORED_SHORT_URLS';
|
case AUTHORED_SHORT_URLS = 'AUTHORED_SHORT_URLS';
|
||||||
public const DOMAIN_SPECIFIC = 'DOMAIN_SPECIFIC';
|
case DOMAIN_SPECIFIC = 'DOMAIN_SPECIFIC';
|
||||||
private const ROLE_FRIENDLY_NAMES = [
|
|
||||||
self::AUTHORED_SHORT_URLS => 'Author only',
|
|
||||||
self::DOMAIN_SPECIFIC => 'Domain only',
|
|
||||||
];
|
|
||||||
|
|
||||||
public static function toSpec(ApiKeyRole $role, ?string $context = null): Specification
|
public static function toSpec(ApiKeyRole $role, ?string $context = null): Specification
|
||||||
{
|
{
|
||||||
return match ($role->name()) {
|
return match ($role->role()) {
|
||||||
self::AUTHORED_SHORT_URLS => new BelongsToApiKey($role->apiKey(), $context),
|
self::AUTHORED_SHORT_URLS => new BelongsToApiKey($role->apiKey(), $context),
|
||||||
self::DOMAIN_SPECIFIC => new BelongsToDomain(self::domainIdFromMeta($role->meta()), $context),
|
self::DOMAIN_SPECIFIC => new BelongsToDomain(self::domainIdFromMeta($role->meta()), $context),
|
||||||
default => Spec::andX(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function toInlinedSpec(ApiKeyRole $role): Specification
|
public static function toInlinedSpec(ApiKeyRole $role): Specification
|
||||||
{
|
{
|
||||||
return match ($role->name()) {
|
return match ($role->role()) {
|
||||||
self::AUTHORED_SHORT_URLS => Spec::andX(new BelongsToApiKeyInlined($role->apiKey())),
|
self::AUTHORED_SHORT_URLS => Spec::andX(new BelongsToApiKeyInlined($role->apiKey())),
|
||||||
self::DOMAIN_SPECIFIC => Spec::andX(new BelongsToDomainInlined(self::domainIdFromMeta($role->meta()))),
|
self::DOMAIN_SPECIFIC => Spec::andX(new BelongsToDomainInlined(self::domainIdFromMeta($role->meta()))),
|
||||||
default => Spec::andX(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +45,11 @@ class Role
|
|||||||
return $meta['authority'] ?? '';
|
return $meta['authority'] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function toFriendlyName(string $roleName): string
|
public static function toFriendlyName(Role $role): string
|
||||||
{
|
{
|
||||||
return self::ROLE_FRIENDLY_NAMES[$roleName] ?? '';
|
return match ($role) {
|
||||||
|
self::AUTHORED_SHORT_URLS => 'Author only',
|
||||||
|
self::DOMAIN_SPECIFIC => 'Domain only',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,40 +113,40 @@ class ApiKey extends AbstractEntity
|
|||||||
return $this->roles->isEmpty();
|
return $this->roles->isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasRole(string $roleName): bool
|
public function hasRole(Role $role): bool
|
||||||
{
|
{
|
||||||
return $this->roles->containsKey($roleName);
|
return $this->roles->containsKey($role->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRoleMeta(string $roleName): array
|
public function getRoleMeta(Role $role): array
|
||||||
{
|
{
|
||||||
/** @var ApiKeyRole|null $role */
|
/** @var ApiKeyRole|null $apiKeyRole */
|
||||||
$role = $this->roles->get($roleName);
|
$apiKeyRole = $this->roles->get($role->value);
|
||||||
return $role?->meta() ?? [];
|
return $apiKeyRole?->meta() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @template T
|
* @template T
|
||||||
* @param callable(string $roleName, array $meta): T $fun
|
* @param callable(Role $role, array $meta): T $fun
|
||||||
* @return T[]
|
* @return T[]
|
||||||
*/
|
*/
|
||||||
public function mapRoles(callable $fun): array
|
public function mapRoles(callable $fun): array
|
||||||
{
|
{
|
||||||
return $this->roles->map(fn (ApiKeyRole $role) => $fun($role->name(), $role->meta()))->getValues();
|
return $this->roles->map(fn (ApiKeyRole $role) => $fun($role->role(), $role->meta()))->getValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function registerRole(RoleDefinition $roleDefinition): void
|
public function registerRole(RoleDefinition $roleDefinition): void
|
||||||
{
|
{
|
||||||
$roleName = $roleDefinition->roleName;
|
$role = $roleDefinition->role;
|
||||||
$meta = $roleDefinition->meta;
|
$meta = $roleDefinition->meta;
|
||||||
|
|
||||||
if ($this->hasRole($roleName)) {
|
if ($this->hasRole($role)) {
|
||||||
/** @var ApiKeyRole $role */
|
/** @var ApiKeyRole $apiKeyRole */
|
||||||
$role = $this->roles->get($roleName);
|
$apiKeyRole = $this->roles->get($role);
|
||||||
$role->updateMeta($meta);
|
$apiKeyRole->updateMeta($meta);
|
||||||
} else {
|
} else {
|
||||||
$role = new ApiKeyRole($roleDefinition->roleName, $roleDefinition->meta, $this);
|
$apiKeyRole = new ApiKeyRole($roleDefinition->role, $roleDefinition->meta, $this);
|
||||||
$this->roles[$roleName] = $role;
|
$this->roles[$role->value] = $apiKeyRole;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,25 @@ declare(strict_types=1);
|
|||||||
namespace Shlinkio\Shlink\Rest\Entity;
|
namespace Shlinkio\Shlink\Rest\Entity;
|
||||||
|
|
||||||
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
||||||
|
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||||
|
|
||||||
class ApiKeyRole extends AbstractEntity
|
class ApiKeyRole extends AbstractEntity
|
||||||
{
|
{
|
||||||
public function __construct(private string $roleName, private array $meta, private ApiKey $apiKey)
|
public function __construct(private Role $roleName, private array $meta, private ApiKey $apiKey)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function name(): string
|
public function role(): Role
|
||||||
{
|
{
|
||||||
return $this->roleName;
|
return $this->roleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated Use role() instead */
|
||||||
|
public function name(): Role
|
||||||
|
{
|
||||||
|
return $this->role();
|
||||||
|
}
|
||||||
|
|
||||||
public function meta(): array
|
public function meta(): array
|
||||||
{
|
{
|
||||||
return $this->meta;
|
return $this->meta;
|
||||||
|
@ -16,7 +16,7 @@ class RoleDefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$definition = RoleDefinition::forAuthoredShortUrls();
|
$definition = RoleDefinition::forAuthoredShortUrls();
|
||||||
|
|
||||||
self::assertEquals(Role::AUTHORED_SHORT_URLS, $definition->roleName);
|
self::assertEquals(Role::AUTHORED_SHORT_URLS, $definition->role);
|
||||||
self::assertEquals([], $definition->meta);
|
self::assertEquals([], $definition->meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ class RoleDefinitionTest extends TestCase
|
|||||||
$domain = Domain::withAuthority('foo.com')->setId('123');
|
$domain = Domain::withAuthority('foo.com')->setId('123');
|
||||||
$definition = RoleDefinition::forDomain($domain);
|
$definition = RoleDefinition::forDomain($domain);
|
||||||
|
|
||||||
self::assertEquals(Role::DOMAIN_SPECIFIC, $definition->roleName);
|
self::assertEquals(Role::DOMAIN_SPECIFIC, $definition->role);
|
||||||
self::assertEquals(['domain_id' => '123', 'authority' => 'foo.com'], $definition->meta);
|
self::assertEquals(['domain_id' => '123', 'authority' => 'foo.com'], $definition->meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ class RoleTest extends TestCase
|
|||||||
{
|
{
|
||||||
$apiKey = ApiKey::create();
|
$apiKey = ApiKey::create();
|
||||||
|
|
||||||
yield 'invalid role' => [new ApiKeyRole('invalid', [], $apiKey), Spec::andX()];
|
|
||||||
yield 'author role' => [
|
yield 'author role' => [
|
||||||
new ApiKeyRole(Role::AUTHORED_SHORT_URLS, [], $apiKey),
|
new ApiKeyRole(Role::AUTHORED_SHORT_URLS, [], $apiKey),
|
||||||
new BelongsToApiKey($apiKey),
|
new BelongsToApiKey($apiKey),
|
||||||
@ -54,7 +53,6 @@ class RoleTest extends TestCase
|
|||||||
{
|
{
|
||||||
$apiKey = ApiKey::create();
|
$apiKey = ApiKey::create();
|
||||||
|
|
||||||
yield 'invalid role' => [new ApiKeyRole('invalid', [], $apiKey), Spec::andX()];
|
|
||||||
yield 'author role' => [
|
yield 'author role' => [
|
||||||
new ApiKeyRole(Role::AUTHORED_SHORT_URLS, [], $apiKey),
|
new ApiKeyRole(Role::AUTHORED_SHORT_URLS, [], $apiKey),
|
||||||
Spec::andX(new BelongsToApiKeyInlined($apiKey)),
|
Spec::andX(new BelongsToApiKeyInlined($apiKey)),
|
||||||
@ -101,15 +99,14 @@ class RoleTest extends TestCase
|
|||||||
* @test
|
* @test
|
||||||
* @dataProvider provideRoleNames
|
* @dataProvider provideRoleNames
|
||||||
*/
|
*/
|
||||||
public function getsExpectedRoleFriendlyName(string $roleName, string $expectedFriendlyName): void
|
public function getsExpectedRoleFriendlyName(Role $roleName, string $expectedFriendlyName): void
|
||||||
{
|
{
|
||||||
self::assertEquals($expectedFriendlyName, Role::toFriendlyName($roleName));
|
self::assertEquals($expectedFriendlyName, Role::toFriendlyName($roleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideRoleNames(): iterable
|
public function provideRoleNames(): iterable
|
||||||
{
|
{
|
||||||
yield 'unknown' => ['unknown', ''];
|
yield Role::AUTHORED_SHORT_URLS->value => [Role::AUTHORED_SHORT_URLS, 'Author only'];
|
||||||
yield Role::AUTHORED_SHORT_URLS => [Role::AUTHORED_SHORT_URLS, 'Author only'];
|
yield Role::DOMAIN_SPECIFIC->value => [Role::DOMAIN_SPECIFIC, 'Domain only'];
|
||||||
yield Role::DOMAIN_SPECIFIC => [Role::DOMAIN_SPECIFIC, 'Domain only'];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class ApiKeyServiceTest extends TestCase
|
|||||||
self::assertEquals($date, $key->getExpirationDate());
|
self::assertEquals($date, $key->getExpirationDate());
|
||||||
self::assertEquals($name, $key->name());
|
self::assertEquals($name, $key->name());
|
||||||
foreach ($roles as $roleDefinition) {
|
foreach ($roles as $roleDefinition) {
|
||||||
self::assertTrue($key->hasRole($roleDefinition->roleName));
|
self::assertTrue($key->hasRole($roleDefinition->role));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user