Ensure auto-generated name API keys do not throw duplicated name

This commit is contained in:
Alejandro Celaya
2024-11-09 12:07:07 +01:00
parent d228b88e51
commit 3c6f12aec6
5 changed files with 53 additions and 12 deletions

View File

@@ -19,17 +19,13 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
{
}
/**
* @inheritDoc
*/
public function create(ApiKeyMeta $apiKeyMeta): ApiKey
{
return $this->em->wrapInTransaction(function () use ($apiKeyMeta) {
$apiKey = ApiKey::fromMeta($apiKeyMeta);
// TODO If name is auto-generated, do not throw. Instead, re-generate a new key
if ($this->repo->nameExists($apiKey->name)) {
throw new InvalidArgumentException(
sprintf('Another API key with name "%s" already exists', $apiKeyMeta->name),
);
}
$apiKey = ApiKey::fromMeta($this->ensureUniqueName($apiKeyMeta));
$this->em->persist($apiKey);
$this->em->flush();
@@ -37,6 +33,29 @@ readonly class ApiKeyService implements ApiKeyServiceInterface
});
}
/**
* Given an ApiKeyMeta object, it returns another instance ensuring the name is unique.
* - If the name was auto-generated, it continues re-trying until a unique name is resolved.
* - If the name was explicitly provided, it throws in case of name conflict.
*/
private function ensureUniqueName(ApiKeyMeta $apiKeyMeta): ApiKeyMeta
{
if (! $this->repo->nameExists($apiKeyMeta->name)) {
return $apiKeyMeta;
}
if (! $apiKeyMeta->isNameAutoGenerated) {
throw new InvalidArgumentException(
sprintf('Another API key with name "%s" already exists', $apiKeyMeta->name),
);
}
return $this->ensureUniqueName(ApiKeyMeta::fromParams(
expirationDate: $apiKeyMeta->expirationDate,
roleDefinitions: $apiKeyMeta->roleDefinitions,
));
}
public function createInitial(string $key): ApiKey|null
{
return $this->repo->createInitialApiKey($key);