From ede46ac13aa75c307768a73d933a6e1656ad11eb Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Sun, 21 Mar 2021 13:47:20 +0100 Subject: [PATCH] [Uid] Handle predefined namespaces keywords "dns", "url", "oid" and "x500" --- .../Uid/Command/GenerateUuidCommand.php | 4 ++-- .../Component/Uid/Factory/UuidFactory.php | 24 +++++++++++++++---- .../Tests/Command/GenerateUlidCommandTest.php | 2 +- .../Tests/Command/GenerateUuidCommandTest.php | 9 +++++++ .../Uid/Tests/Factory/UuidFactoryTest.php | 5 ++++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Uid/Command/GenerateUuidCommand.php b/src/Symfony/Component/Uid/Command/GenerateUuidCommand.php index aab44257be..b6992151ec 100644 --- a/src/Symfony/Component/Uid/Command/GenerateUuidCommand.php +++ b/src/Symfony/Component/Uid/Command/GenerateUuidCommand.php @@ -44,7 +44,7 @@ class GenerateUuidCommand extends Command new InputOption('time-based', null, InputOption::VALUE_REQUIRED, 'The timestamp, to generate a time-based UUID: a parsable date/time string'), new InputOption('node', null, InputOption::VALUE_REQUIRED, 'The UUID whose node part should be used as the node of the generated UUID'), new InputOption('name-based', null, InputOption::VALUE_REQUIRED, 'The name, to generate a name-based UUID'), - new InputOption('namespace', null, InputOption::VALUE_REQUIRED, 'The UUID to use at the namespace for named-based UUIDs'), + new InputOption('namespace', null, InputOption::VALUE_REQUIRED, 'The UUID to use at the namespace for named-based UUIDs, predefined namespaces keywords "dns", "url", "oid" and "x500" are accepted'), new InputOption('random-based', null, InputOption::VALUE_NONE, 'To generate a random-based UUID'), new InputOption('count', 'c', InputOption::VALUE_REQUIRED, 'The number of UUID to generate', 1), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'The UUID output format: rfc4122, base58 or base32', 'rfc4122'), @@ -144,7 +144,7 @@ EOF break; case null !== $name: - if ($namespace) { + if ($namespace && !\in_array($namespace, ['dns', 'url', 'oid', 'x500'], true)) { try { $namespace = Uuid::fromString($namespace); } catch (\InvalidArgumentException $e) { diff --git a/src/Symfony/Component/Uid/Factory/UuidFactory.php b/src/Symfony/Component/Uid/Factory/UuidFactory.php index edf64672da..ddcb0501d1 100644 --- a/src/Symfony/Component/Uid/Factory/UuidFactory.php +++ b/src/Symfony/Component/Uid/Factory/UuidFactory.php @@ -40,8 +40,8 @@ class UuidFactory $timeBasedNode = Uuid::fromString($timeBasedNode); } - if (null !== $nameBasedNamespace && !$nameBasedNamespace instanceof Uuid) { - $nameBasedNamespace = Uuid::fromString($nameBasedNamespace); + if (null !== $nameBasedNamespace) { + $nameBasedNamespace = $this->getNamespace($nameBasedNamespace); } $this->defaultClass = is_numeric($defaultClass) ? Uuid::class.'V'.$defaultClass : $defaultClass; @@ -95,10 +95,24 @@ class UuidFactory throw new \LogicException(sprintf('A namespace should be defined when using "%s()".', __METHOD__)); } - if (!$namespace instanceof Uuid) { - $namespace = Uuid::fromString($namespace); + return new NameBasedUuidFactory($this->nameBasedClass, $this->getNamespace($namespace)); + } + + /** + * @param Uuid|string $namespace + */ + private function getNamespace($namespace): Uuid + { + if ($namespace instanceof Uuid) { + return $namespace; } - return new NameBasedUuidFactory($this->nameBasedClass, $namespace); + switch ($namespace) { + case 'dns': return new UuidV1(Uuid::NAMESPACE_DNS); + case 'url': return new UuidV1(Uuid::NAMESPACE_URL); + case 'oid': return new UuidV1(Uuid::NAMESPACE_OID); + case 'x500': return new UuidV1(Uuid::NAMESPACE_X500); + default: return Uuid::fromString($namespace); + } } } diff --git a/src/Symfony/Component/Uid/Tests/Command/GenerateUlidCommandTest.php b/src/Symfony/Component/Uid/Tests/Command/GenerateUlidCommandTest.php index 95e221fb1d..789a557107 100644 --- a/src/Symfony/Component/Uid/Tests/Command/GenerateUlidCommandTest.php +++ b/src/Symfony/Component/Uid/Tests/Command/GenerateUlidCommandTest.php @@ -90,7 +90,7 @@ final class GenerateUlidCommandTest extends TestCase Ulid::fromRfc4122(trim($commandTester->getDisplay())); } - public function testTimestampIncrementWhenGeneratingSeveralUlids() + public function testUlidsAreDifferentWhenGeneratingSeveralNow() { $commandTester = new CommandTester(new GenerateUlidCommand()); diff --git a/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php b/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php index ac69a5a6d4..408fd47d31 100644 --- a/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php +++ b/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php @@ -220,4 +220,13 @@ final class GenerateUuidCommandTest extends TestCase $this->assertNotSame($uuids[0], $uuids[1]); } + + public function testNamespacePredefinedKeyword() + { + $commandTester = new CommandTester(new GenerateUuidCommand()); + + $this->assertSame(0, $commandTester->execute(['--name-based' => 'https://symfony.com', '--namespace' => 'url'])); + + $this->assertSame('9c7d0eda-982d-5708-b4bd-79b3b179725d', (string) Uuid::fromRfc4122(trim($commandTester->getDisplay()))); + } } diff --git a/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php b/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php index a6a05fade2..e808f38098 100644 --- a/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php +++ b/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php @@ -90,4 +90,9 @@ final class UuidFactoryTest extends TestCase { $this->assertInstanceOf(UuidV4::class, (new UuidFactory())->randomBased()->create()); } + + public function testCreateNamedWithNamespacePredefinedKeyword() + { + $this->assertSame('1002657d-3019-59b1-96dc-afc2a3e57c61', (string) (new UuidFactory())->nameBased('dns')->create('symfony.com')); + } }