diff --git a/data/migrations/Version20210306165711.php b/data/migrations/Version20210306165711.php
new file mode 100644
index 00000000..5a7b9fe7
--- /dev/null
+++ b/data/migrations/Version20210306165711.php
@@ -0,0 +1,45 @@
+getTable(self::TABLE);
+ $this->skipIf($apiKeys->hasColumn(self::COLUMN));
+
+ $apiKeys->addColumn(
+ self::COLUMN,
+ Types::STRING,
+ [
+ 'notnull' => false,
+ ],
+ );
+ }
+
+ public function down(Schema $schema): void
+ {
+ $apiKeys = $schema->getTable(self::TABLE);
+ $this->skipIf(! $apiKeys->hasColumn(self::COLUMN));
+
+ $apiKeys->dropColumn(self::COLUMN);
+ }
+
+ /**
+ * @fixme Workaround for https://github.com/doctrine/migrations/issues/1104
+ */
+ public function isTransactional(): bool
+ {
+ return false;
+ }
+}
diff --git a/module/CLI/src/Command/Api/GenerateKeyCommand.php b/module/CLI/src/Command/Api/GenerateKeyCommand.php
index 119fa020..31df82a1 100644
--- a/module/CLI/src/Command/Api/GenerateKeyCommand.php
+++ b/module/CLI/src/Command/Api/GenerateKeyCommand.php
@@ -42,6 +42,10 @@ class GenerateKeyCommand extends BaseCommand
%command.full_name%
+ You can optionally set its name for tracking purposes with --name or -m:
+
+ %command.full_name% --name Alice
+
You can optionally set its expiration date with --expiration-date or -e:
%command.full_name% --expiration-date 2020-01-01
@@ -56,6 +60,12 @@ class GenerateKeyCommand extends BaseCommand
$this
->setName(self::NAME)
->setDescription('Generates a new valid API key.')
+ ->addOption(
+ 'name',
+ 'm',
+ InputOption::VALUE_REQUIRED,
+ 'The name by which this API key will be known.',
+ )
->addOptionWithDeprecatedFallback(
'expiration-date',
'e',
@@ -82,6 +92,7 @@ class GenerateKeyCommand extends BaseCommand
$expirationDate = $this->getOptionWithDeprecatedFallback($input, 'expiration-date');
$apiKey = $this->apiKeyService->create(
isset($expirationDate) ? Chronos::parse($expirationDate) : null,
+ $input->getOption('name'),
...$this->roleResolver->determineRoles($input),
);
diff --git a/module/CLI/src/Command/Api/ListKeysCommand.php b/module/CLI/src/Command/Api/ListKeysCommand.php
index 9243779b..ac5fc73d 100644
--- a/module/CLI/src/Command/Api/ListKeysCommand.php
+++ b/module/CLI/src/Command/Api/ListKeysCommand.php
@@ -58,6 +58,7 @@ class ListKeysCommand extends BaseCommand
// Set columns for this row
$rowData = [sprintf($messagePattern, $apiKey)];
+ $rowData[] = $apiKey->name() ?? '-';
if (! $enabledOnly) {
$rowData[] = sprintf($messagePattern, $this->getEnabledSymbol($apiKey));
}
@@ -74,10 +75,12 @@ class ListKeysCommand extends BaseCommand
ShlinkTable::fromOutput($output)->render(array_filter([
'Key',
+ 'Name',
! $enabledOnly ? 'Is enabled' : null,
'Expiration date',
'Roles',
]), $rows);
+
return ExitCodes::EXIT_SUCCESS;
}
diff --git a/module/CLI/test/Command/Api/GenerateKeyCommandTest.php b/module/CLI/test/Command/Api/GenerateKeyCommandTest.php
index 00548f17..ee822bee 100644
--- a/module/CLI/test/Command/Api/GenerateKeyCommandTest.php
+++ b/module/CLI/test/Command/Api/GenerateKeyCommandTest.php
@@ -40,22 +40,43 @@ class GenerateKeyCommandTest extends TestCase
/** @test */
public function noExpirationDateIsDefinedIfNotProvided(): void
{
- $create = $this->apiKeyService->create(null)->willReturn(new ApiKey());
+ $this->apiKeyService->create(
+ null, // Expiration date
+ null, // Name
+ )->shouldBeCalledOnce()
+ ->willReturn(new ApiKey());
$this->commandTester->execute([]);
$output = $this->commandTester->getDisplay();
self::assertStringContainsString('Generated API key: ', $output);
- $create->shouldHaveBeenCalledOnce();
}
/** @test */
public function expirationDateIsDefinedIfProvided(): void
{
- $this->apiKeyService->create(Argument::type(Chronos::class))->shouldBeCalledOnce()
- ->willReturn(new ApiKey());
+ $this->apiKeyService->create(
+ Argument::type(Chronos::class), // Expiration date
+ null, // Name
+ )->shouldBeCalledOnce()
+ ->willReturn(new ApiKey());
+
$this->commandTester->execute([
'--expiration-date' => '2016-01-01',
]);
}
+
+ /** @test */
+ public function nameIsDefinedIfProvided(): void
+ {
+ $this->apiKeyService->create(
+ null, // Expiration date
+ Argument::type('string'), // Name
+ )->shouldBeCalledOnce()
+ ->willReturn(new ApiKey());
+
+ $this->commandTester->execute([
+ '--name' => 'Alice',
+ ]);
+ }
}
diff --git a/module/CLI/test/Command/Api/ListKeysCommandTest.php b/module/CLI/test/Command/Api/ListKeysCommandTest.php
index e0cada5d..54ce19bc 100644
--- a/module/CLI/test/Command/Api/ListKeysCommandTest.php
+++ b/module/CLI/test/Command/Api/ListKeysCommandTest.php
@@ -52,13 +52,13 @@ class ListKeysCommandTest extends TestCase
[ApiKey::withKey('foo'), ApiKey::withKey('bar'), ApiKey::withKey('baz')],
false,
<<