From 81c5c0c6683feb14663f3d26dc987346befeca71 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 29 Nov 2022 09:12:04 +0100 Subject: [PATCH] [Validator] Add `Uuid::TIME_BASED_VERSIONS` to match that a UUID being validated embeds a timestamp --- src/Symfony/Component/Validator/CHANGELOG.md | 5 +++ .../Component/Validator/Constraints/Uuid.php | 7 ++++ .../Validator/Constraints/UuidValidator.php | 4 ++- .../Tests/Constraints/UuidValidatorTest.php | 33 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 5d55f9cde0b31..88b152ed8dc31 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.3 +--- + + * Add `Uuid::TIME_BASED_VERSIONS` to match that a UUID being validated embeds a timestamp + 6.2 --- diff --git a/src/Symfony/Component/Validator/Constraints/Uuid.php b/src/Symfony/Component/Validator/Constraints/Uuid.php index 4c9dedd8fe94a..4c385d5322ca6 100644 --- a/src/Symfony/Component/Validator/Constraints/Uuid.php +++ b/src/Symfony/Component/Validator/Constraints/Uuid.php @@ -28,6 +28,7 @@ class Uuid extends Constraint public const INVALID_CHARACTERS_ERROR = '51120b12-a2bc-41bf-aa53-cd73daf330d0'; public const INVALID_HYPHEN_PLACEMENT_ERROR = '98469c83-0309-4f5d-bf95-a496dcaa869c'; public const INVALID_VERSION_ERROR = '21ba13b4-b185-4882-ac6f-d147355987eb'; + public const INVALID_TIME_BASED_VERSION_ERROR = '484081ca-6fbd-11ed-ade8-a3bdfd0fcf2f'; public const INVALID_VARIANT_ERROR = '164ef693-2b9d-46de-ad7f-836201f0c2db'; protected const ERROR_NAMES = [ @@ -65,6 +66,12 @@ class Uuid extends Constraint self::V8_CUSTOM, ]; + public const TIME_BASED_VERSIONS = [ + self::V1_MAC, + self::V6_SORTABLE, + self::V7_MONOTONIC, + ]; + /** * Message to display when validation fails. * diff --git a/src/Symfony/Component/Validator/Constraints/UuidValidator.php b/src/Symfony/Component/Validator/Constraints/UuidValidator.php index c4ccfb27dee9d..88f9e9674ad11 100644 --- a/src/Symfony/Component/Validator/Constraints/UuidValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UuidValidator.php @@ -235,9 +235,11 @@ private function validateStrict(string $value, Uuid $constraint) // Check version if (!\in_array($value[self::STRICT_VERSION_POSITION], $constraint->versions)) { + $code = Uuid::TIME_BASED_VERSIONS === $constraint->versions ? Uuid::INVALID_TIME_BASED_VERSION_ERROR : Uuid::INVALID_VERSION_ERROR; + $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_VERSION_ERROR) + ->setCode($code) ->addViolation(); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php index 2df1b276206cc..f003afa6e2461 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php @@ -263,4 +263,37 @@ public function testInvalidNonStrictUuidNamed() ->setCode(Uuid::INVALID_CHARACTERS_ERROR) ->assertRaised(); } + + /** + * @dataProvider getUuidForTimeBasedAssertions + */ + public function testTimeBasedUuid(string $uid, bool $expectedTimeBased) + { + $constraint = new Uuid([ + 'versions' => Uuid::TIME_BASED_VERSIONS, + ]); + + $this->validator->validate($uid, $constraint); + + if ($expectedTimeBased) { + $this->assertNoViolation(); + } else { + $this->buildViolation('This is not a valid UUID.') + ->setParameter('{{ value }}', '"'.$uid.'"') + ->setCode(Uuid::INVALID_TIME_BASED_VERSION_ERROR) + ->assertRaised(); + } + } + + public static function getUuidForTimeBasedAssertions(): \Generator + { + yield Uuid::V1_MAC => ['95ab107e-6fc2-11ed-9d6b-01bfd6e71dbd', true]; + yield Uuid::V2_DCE => ['216fff40-98d9-21e3-a5e2-0800200c9a66', false]; + yield Uuid::V3_MD5 => ['5d5b5ae1-5857-3531-9431-e8ac73c3e61d', false]; + yield Uuid::V4_RANDOM => ['ba6479dd-a5ea-403c-96ae-5964d0582e81', false]; + yield Uuid::V5_SHA1 => ['fc1cc19d-cb3c-5f6a-a0f6-706424f68e3a', false]; + yield Uuid::V6_SORTABLE => ['1ed6fc29-5ab1-6b6e-8aad-cfa821180d14', true]; + yield Uuid::V7_MONOTONIC => ['0184c292-b133-7e10-a3b4-d49c1ab49b2a', true]; + yield Uuid::V8_CUSTOM => ['00112233-4455-8677-8899-aabbccddeeff', false]; + } }