From 7d8c998250364dd69171c0b185f14ac02ecb2d5e Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Wed, 15 Nov 2023 20:51:20 +0100 Subject: [PATCH 1/4] Deprecate PK Loader in favor of the symfony/serializer --- .../Controller/AssertionControllerFactory.php | 11 ++- .../AssertionResponseController.php | 16 +++- .../AttestationControllerFactory.php | 11 ++- .../AttestationResponseController.php | 15 +++- src/symfony/src/Resources/config/security.php | 3 +- src/symfony/src/Resources/config/services.php | 24 +++--- .../Authenticator/WebauthnAuthenticator.php | 27 ++++++- .../AttestationObjectDenormalizer.php | 27 +++---- .../AttestationStatementDenormalizer.php | 2 +- .../AuthenticationExtensionsDenormalizer.php | 18 +---- ...enticatorAssertionResponseDenormalizer.php | 25 +++--- ...ticatorAttestationResponseDenormalizer.php | 29 ++++--- .../AuthenticatorDataDenormalizer.php | 43 +++++----- .../AuthenticatorResponseDenormalizer.php | 41 ++++------ .../CollectedClientDataDenormalizer.php | 15 +--- .../PublicKeyCredentialDenormalizer.php | 18 ++--- ...PublicKeyCredentialOptionsDenormalizer.php | 78 ++++++++++++++++--- ...licKeyCredentialParametersDenormalizer.php | 37 +++++++++ .../PublicKeyCredentialSourceDenormalizer.php | 32 +++++--- ...licKeyCredentialUserEntityDenormalizer.php | 16 ++-- .../Denormalizer/TrustPathDenormalizer.php | 22 +----- .../src/PublicKeyCredentialLoader.php | 3 + tests/symfony/config/config.yml | 3 +- .../functional/Assertion/AssertionTest.php | 2 +- .../AdditionalAuthenticatorTest.php | 17 +++- .../Attestation/AttestationTest.php | 10 +-- .../PackedAttestationStatementTest.php | 2 +- .../MetadataService/ConformanceTest.php | 2 +- 28 files changed, 341 insertions(+), 208 deletions(-) create mode 100644 src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php diff --git a/src/symfony/src/Controller/AssertionControllerFactory.php b/src/symfony/src/Controller/AssertionControllerFactory.php index 2a2c9a918..fcfdf24c6 100644 --- a/src/symfony/src/Controller/AssertionControllerFactory.php +++ b/src/symfony/src/Controller/AssertionControllerFactory.php @@ -31,11 +31,18 @@ public function __construct( private readonly SerializerInterface $serializer, private readonly ValidatorInterface $validator, private readonly PublicKeyCredentialRequestOptionsFactory $publicKeyCredentialRequestOptionsFactory, - private readonly PublicKeyCredentialLoader $publicKeyCredentialLoader, + private readonly null|PublicKeyCredentialLoader $publicKeyCredentialLoader, private readonly AuthenticatorAssertionResponseValidator $authenticatorAssertionResponseValidator, private readonly PublicKeyCredentialUserEntityRepositoryInterface $publicKeyCredentialUserEntityRepository, private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository ) { + if ($this->publicKeyCredentialLoader !== null) { + trigger_deprecation( + 'web-auth/webauthn-bundle', + '4.8.0', + 'The argument "$publicKeyCredentialLoader" is deprecated since 4.5.0 and will be removed in 5.0.0. Please set null instead; the serializer will be used instead.' + ); + } $this->logger = new NullLogger(); } @@ -111,7 +118,7 @@ public function createResponseController( null|AuthenticatorAssertionResponseValidator $authenticatorAssertionResponseValidator = null, ): AssertionResponseController { return new AssertionResponseController( - $this->publicKeyCredentialLoader, + $this->publicKeyCredentialLoader ?? $this->serializer, $authenticatorAssertionResponseValidator ?? $this->authenticatorAssertionResponseValidator, $this->logger, $optionStorage, diff --git a/src/symfony/src/Controller/AssertionResponseController.php b/src/symfony/src/Controller/AssertionResponseController.php index 62d93bf6b..6e1b155a5 100644 --- a/src/symfony/src/Controller/AssertionResponseController.php +++ b/src/symfony/src/Controller/AssertionResponseController.php @@ -10,6 +10,7 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; +use Symfony\Component\Serializer\SerializerInterface; use Throwable; use Webauthn\AuthenticatorAssertionResponse; use Webauthn\AuthenticatorAssertionResponseValidator; @@ -18,6 +19,7 @@ use Webauthn\Bundle\Security\Handler\SuccessHandler; use Webauthn\Bundle\Security\Storage\OptionsStorage; use Webauthn\Exception\AuthenticatorResponseVerificationException; +use Webauthn\PublicKeyCredential; use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialRequestOptions; @@ -27,7 +29,7 @@ final class AssertionResponseController * @param null|string[] $securedRelyingPartyIds */ public function __construct( - private readonly PublicKeyCredentialLoader $publicKeyCredentialLoader, + private readonly SerializerInterface|PublicKeyCredentialLoader $publicKeyCredentialLoader, private readonly AuthenticatorAssertionResponseValidator $assertionResponseValidator, private readonly LoggerInterface $logger, private readonly OptionsStorage $optionsStorage, @@ -36,6 +38,13 @@ public function __construct( private readonly null|array $securedRelyingPartyIds = null, private readonly ?PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository = null ) { + if ($this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader) { + trigger_deprecation( + 'web-auth/webauthn-bundle', + '4.8.0', + 'The argument "$publicKeyCredentialLoader" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a Symfony Serializer instead.' + ); + } } public function __invoke(Request $request): Response @@ -47,7 +56,10 @@ public function __invoke(Request $request): Response ) ? $request->getContentTypeFormat() : $request->getContentType(); $format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader->load($content); + + $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( + $content + ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAssertionResponse || throw new BadRequestHttpException( 'Invalid response' diff --git a/src/symfony/src/Controller/AttestationControllerFactory.php b/src/symfony/src/Controller/AttestationControllerFactory.php index 77ebf7095..286a067e0 100644 --- a/src/symfony/src/Controller/AttestationControllerFactory.php +++ b/src/symfony/src/Controller/AttestationControllerFactory.php @@ -26,10 +26,17 @@ public function __construct( private readonly SerializerInterface $serializer, private readonly ValidatorInterface $validator, private readonly PublicKeyCredentialCreationOptionsFactory $publicKeyCredentialCreationOptionsFactory, - private readonly PublicKeyCredentialLoader $publicKeyCredentialLoader, + private readonly null|PublicKeyCredentialLoader $publicKeyCredentialLoader, private readonly AuthenticatorAttestationResponseValidator $attestationResponseValidator, private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository ) { + if ($this->publicKeyCredentialLoader !== null) { + trigger_deprecation( + 'web-auth/webauthn-bundle', + '4.8.0', + 'The argument "$publicKeyCredentialLoader" is deprecated since 4.5.0 and will be removed in 5.0.0. Please set null instead; the serializer will be used instead.' + ); + } } /** @@ -98,7 +105,7 @@ public function createResponseController( null|AuthenticatorAttestationResponseValidator $attestationResponseValidator = null, ): AttestationResponseController { return new AttestationResponseController( - $this->publicKeyCredentialLoader, + $this->publicKeyCredentialLoader ?? $this->serializer, $attestationResponseValidator ?? $this->attestationResponseValidator, $this->publicKeyCredentialSourceRepository, $optionStorage, diff --git a/src/symfony/src/Controller/AttestationResponseController.php b/src/symfony/src/Controller/AttestationResponseController.php index 785faa49c..8877af0d9 100644 --- a/src/symfony/src/Controller/AttestationResponseController.php +++ b/src/symfony/src/Controller/AttestationResponseController.php @@ -9,6 +9,7 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; +use Symfony\Component\Serializer\SerializerInterface; use Throwable; use Webauthn\AuthenticatorAttestationResponse; use Webauthn\AuthenticatorAttestationResponseValidator; @@ -19,6 +20,7 @@ use Webauthn\Bundle\Security\Handler\FailureHandler; use Webauthn\Bundle\Security\Handler\SuccessHandler; use Webauthn\Bundle\Security\Storage\OptionsStorage; +use Webauthn\PublicKeyCredential; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialSourceRepository; @@ -30,7 +32,7 @@ final class AttestationResponseController * @param null|string[] $securedRelyingPartyIds */ public function __construct( - private readonly PublicKeyCredentialLoader $publicKeyCredentialLoader, + private readonly SerializerInterface|PublicKeyCredentialLoader $publicKeyCredentialLoader, private readonly AuthenticatorAttestationResponseValidator $attestationResponseValidator, private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, private readonly OptionsStorage $optionStorage, @@ -49,6 +51,13 @@ public function __construct( ) ); } + if ($this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader) { + trigger_deprecation( + 'web-auth/webauthn-bundle', + '4.8.0', + 'The argument "$publicKeyCredentialLoader" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a Symfony Serializer instead.' + ); + } } public function __invoke(Request $request): Response @@ -63,7 +72,9 @@ public function __invoke(Request $request): Response ) ? $request->getContentTypeFormat() : $request->getContentType(); $format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader->load($content); + $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( + $content + ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAttestationResponse || throw new BadRequestHttpException( 'Invalid response' diff --git a/src/symfony/src/Resources/config/security.php b/src/symfony/src/Resources/config/security.php index 3272d3afc..41395a083 100644 --- a/src/symfony/src/Resources/config/security.php +++ b/src/symfony/src/Resources/config/security.php @@ -22,7 +22,6 @@ use Webauthn\Bundle\Security\Storage\CacheStorage; use Webauthn\Bundle\Security\Storage\SessionStorage; use Webauthn\Bundle\Security\WebauthnFirewallConfig; -use Webauthn\PublicKeyCredentialLoader; use function Symfony\Component\DependencyInjection\Loader\Configurator\abstract_arg; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; @@ -50,7 +49,7 @@ abstract_arg('Options Storage'), service(PublicKeyCredentialSourceRepositoryInterface::class), service(PublicKeyCredentialUserEntityRepositoryInterface::class), - service(PublicKeyCredentialLoader::class), + service(SerializerInterface::class), abstract_arg('Authenticator Assertion Response Validator'), abstract_arg( 'Authenticator Attestation Response Validator' diff --git a/src/symfony/src/Resources/config/services.php b/src/symfony/src/Resources/config/services.php index b4b389229..4422ea1fb 100644 --- a/src/symfony/src/Resources/config/services.php +++ b/src/symfony/src/Resources/config/services.php @@ -29,6 +29,7 @@ use Webauthn\CeremonyStep\CeremonyStepManager; use Webauthn\CeremonyStep\CeremonyStepManagerFactory; use Webauthn\Counter\ThrowExceptionIfInvalid; +use Webauthn\Denormalizer\AttestationObjectDenormalizer; use Webauthn\Denormalizer\AttestationStatementDenormalizer; use Webauthn\Denormalizer\AuthenticationExtensionsDenormalizer; use Webauthn\Denormalizer\AuthenticatorAssertionResponseDenormalizer; @@ -97,7 +98,12 @@ ->public(); $container ->set(PublicKeyCredentialLoader::class) - ->args([null, service('webauthn-serializer')]) + ->deprecate( + 'web-auth/webauthn-symfony-bundle', + '4.8.0', + '%service_id% is deprecated since 4.8.0 and will be removed in 5.0.0', + ) + ->args([null, service(SerializerInterface::class)]) ->public(); $container ->set(PublicKeyCredentialCreationOptionsFactory::class) @@ -142,7 +148,7 @@ service(SerializerInterface::class), service(ValidatorInterface::class), service(PublicKeyCredentialCreationOptionsFactory::class), - service(PublicKeyCredentialLoader::class), + null, service(AuthenticatorAttestationResponseValidator::class), service(PublicKeyCredentialSourceRepository::class)->nullOnInvalid(), ]); @@ -152,7 +158,7 @@ service(SerializerInterface::class), service(ValidatorInterface::class), service(PublicKeyCredentialRequestOptionsFactory::class), - service(PublicKeyCredentialLoader::class), + null, service(AuthenticatorAssertionResponseValidator::class), service(PublicKeyCredentialUserEntityRepositoryInterface::class), service(PublicKeyCredentialSourceRepository::class)->nullOnInvalid(), @@ -179,6 +185,7 @@ ->alias('webauthn.request_factory.default', RequestFactoryInterface::class); $container->set(ExtensionDescriptorDenormalizer::class); + $container->set(AttestationObjectDenormalizer::class); $container->set(AttestationStatementDenormalizer::class) ->args([service(AttestationStatementSupportManager::class)]) ; @@ -196,17 +203,6 @@ ->args([service(AttestationStatementSupportManager::class)]) ; $container->set(MetadataStatementSerializerFactory::class); - $container->set('webauthn-serializer') - ->class(SerializerInterface::class) - ->factory([service(WebauthnSerializerFactory::class), 'create']) - ->public() - ; - $container->set('mds-serializer') - ->class(SerializerInterface::class) - ->factory([service(MetadataStatementSerializerFactory::class), 'create']) - ->public() - ; - $container->set(DefaultFailureHandler::class); $container->set(DefaultSuccessHandler::class); }; diff --git a/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php b/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php index db7b89224..ced0ecef9 100644 --- a/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php +++ b/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php @@ -18,6 +18,7 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; +use Symfony\Component\Serializer\SerializerInterface; use Throwable; use Webauthn\AuthenticatorAssertionResponse; use Webauthn\AuthenticatorAssertionResponseValidator; @@ -37,6 +38,7 @@ use Webauthn\Exception\AuthenticatorResponseVerificationException; use Webauthn\Exception\InvalidDataException; use Webauthn\MetadataService\CanLogData; +use Webauthn\PublicKeyCredential; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialRequestOptions; @@ -55,7 +57,7 @@ public function __construct( private readonly OptionsStorage $optionsStorage, private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository, private readonly PublicKeyCredentialUserEntityRepositoryInterface $credentialUserEntityRepository, - private readonly PublicKeyCredentialLoader $publicKeyCredentialLoader, + private readonly PublicKeyCredentialLoader|SerializerInterface $publicKeyCredentialLoader, private readonly AuthenticatorAssertionResponseValidator $assertionResponseValidator, private readonly AuthenticatorAttestationResponseValidator $attestationResponseValidator ) { @@ -70,6 +72,13 @@ public function __construct( ) ); } + if ($this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader) { + trigger_deprecation( + 'web-auth/webauthn-bundle', + '4.8.0', + 'The argument "$publicKeyCredentialLoader" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a Symfony Serializer instead.' + ); + } $this->logger = new NullLogger(); } @@ -177,7 +186,13 @@ private function processWithAssertion(Request $request): Passport ) ? $request->getContentTypeFormat() : $request->getContentType(); $format === 'json' || throw InvalidDataException::create($format, 'Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader->load($content); + $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( + $content + ) : $this->publicKeyCredentialLoader->deserialize( + $content, + PublicKeyCredential::class, + 'json' + ); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAssertionResponse || throw InvalidDataException::create( $response, @@ -243,7 +258,13 @@ private function processWithAttestation(Request $request): Passport ) ? $request->getContentTypeFormat() : $request->getContentType(); $format === 'json' || throw InvalidDataException::create($format, 'Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader->load($content); + $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( + $content + ) : $this->publicKeyCredentialLoader->deserialize( + $content, + PublicKeyCredential::class, + 'json' + ); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAttestationResponse || throw InvalidDataException::create( $response, diff --git a/src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php b/src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php index 80f7e1ac1..d3452c294 100644 --- a/src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php @@ -11,6 +11,8 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Webauthn\AttestationStatement\AttestationObject; +use Webauthn\AttestationStatement\AttestationStatement; +use Webauthn\AuthenticatorData; use Webauthn\Exception\InvalidDataException; use Webauthn\StringStream; @@ -18,8 +20,6 @@ final class AttestationObjectDenormalizer implements DenormalizerInterface, Deno { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'ATTESTATION_OBJECT_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -38,23 +38,20 @@ public function denormalize(mixed $data, string $type, string $format = null, ar 'Invalid attestation object. Presence of extra bytes.' ); $stream->close(); + $authData = $attestationObject['authData'] ?? throw InvalidDataException::create( + $attestationObject, + 'Invalid attestation object. Missing "authData" field.' + ); - $data = [ - 'rawAttestationObject' => $data, - 'attStmt' => $attestationObject, - 'authData' => $attestationObject['authData'], - ]; - $context[self::ALREADY_CALLED] = true; - - return $this->denormalizer->denormalize($data, $type, $format, $context); + return AttestationObject::create( + $data, + $this->denormalizer->denormalize($attestationObject, AttestationStatement::class, $format, $context), + $this->denormalizer->denormalize($authData, AuthenticatorData::class, $format, $context), + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === AttestationObject::class; } @@ -64,7 +61,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AttestationObject::class => false, + AttestationObject::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/AttestationStatementDenormalizer.php b/src/webauthn/src/Denormalizer/AttestationStatementDenormalizer.php index 15aaabae5..b1623f2aa 100644 --- a/src/webauthn/src/Denormalizer/AttestationStatementDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AttestationStatementDenormalizer.php @@ -33,7 +33,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AttestationStatement::class => false, + AttestationStatement::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php index 311077802..1c1677805 100644 --- a/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php @@ -19,8 +19,6 @@ final class AuthenticationExtensionsDenormalizer implements DenormalizerInterfac { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'AUTHENTICATION_EXTENSIONS_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -33,19 +31,11 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $data[$key] = AuthenticationExtension::create($key, $value); } - $context[self::ALREADY_CALLED] = true; - - return $this->denormalizer->denormalize([ - 'extensions' => $data, - ], $type, $format, $context); + return AuthenticationExtensions::create($data); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return in_array( $type, [ @@ -63,9 +53,9 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AuthenticationExtensions::class => false, - AuthenticationExtensionsClientInputs::class => false, - AuthenticationExtensionsClientOutputs::class => false, + AuthenticationExtensions::class => true, + AuthenticationExtensionsClientInputs::class => true, + AuthenticationExtensionsClientOutputs::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php index 027d2a073..23fc6cf9f 100644 --- a/src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php @@ -9,15 +9,16 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Webauthn\AttestationStatement\AttestationObject; use Webauthn\AuthenticatorAssertionResponse; +use Webauthn\AuthenticatorData; +use Webauthn\CollectedClientData; use Webauthn\Util\Base64; final class AuthenticatorAssertionResponseDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'AUTHENTICATOR_ASSERTION_RESPONSE_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -32,16 +33,22 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $data['userHandle'] = Base64::decode($userHandle); } - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize($data, $type, $format, $context); + return AuthenticatorAssertionResponse::create( + $this->denormalizer->denormalize($data['clientDataJSON'], CollectedClientData::class, $format, $context), + $this->denormalizer->denormalize($data['authenticatorData'], AuthenticatorData::class, $format, $context), + $data['signature'], + $data['userHandle'] ?? null, + ! isset($data['attestationObject']) ? null : $this->denormalizer->denormalize( + $data['attestationObject'], + AttestationObject::class, + $format, + $context + ), + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === AuthenticatorAssertionResponse::class; } @@ -51,7 +58,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AuthenticatorAssertionResponse::class => false, + AuthenticatorAssertionResponse::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php index fb82fca06..e76029d19 100644 --- a/src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php @@ -9,15 +9,15 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Webauthn\AttestationStatement\AttestationObject; use Webauthn\AuthenticatorAttestationResponse; +use Webauthn\CollectedClientData; use Webauthn\Util\Base64; final class AuthenticatorAttestationResponseDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'AUTHENTICATOR_ATTESTATIONN_RESPONSE_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -27,17 +27,28 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $data['clientDataJSON'] = Base64UrlSafe::decodeNoPadding($data['clientDataJSON']); $data['attestationObject'] = Base64::decode($data['attestationObject']); - $context[self::ALREADY_CALLED] = true; + $clientDataJSON = $this->denormalizer->denormalize( + $data['clientDataJSON'], + CollectedClientData::class, + $format, + $context + ); + $attestationObject = $this->denormalizer->denormalize( + $data['attestationObject'], + AttestationObject::class, + $format, + $context + ); - return $this->denormalizer->denormalize($data, $type, $format, $context); + return AuthenticatorAttestationResponse::create( + $clientDataJSON, + $attestationObject, + $data['transports'] ?? [], + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === AuthenticatorAttestationResponse::class; } @@ -47,7 +58,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AuthenticatorAttestationResponse::class => false, + AuthenticatorAttestationResponse::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php index ab2cf1760..d057d4d6e 100644 --- a/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php @@ -16,6 +16,8 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Uid\Uuid; +use Webauthn\AttestedCredentialData; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputsLoader; use Webauthn\AuthenticatorData; use Webauthn\Exception\InvalidDataException; @@ -27,8 +29,6 @@ final class AuthenticatorDataDenormalizer implements DenormalizerInterface, Deno { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'AUTHENTICATOR_DATA_PREPROCESS_ALREADY_CALLED'; - private readonly Decoder $decoder; public function __construct() @@ -60,11 +60,11 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $authData, 'The data does not contain a valid credential public key.' ); - $attestedCredentialData = [ - 'aaguid' => $aaguid, - 'credentialId' => $credentialId, - 'credentialPublicKey' => (string) $credentialPublicKey, - ]; + $attestedCredentialData = AttestedCredentialData::create( + $aaguid, + $credentialId, + (string) $credentialPublicKey, + ); } $extension = null; if (0 !== (ord($flags) & AuthenticatorData::FLAG_ED)) { @@ -76,25 +76,24 @@ public function denormalize(mixed $data, string $type, string $format = null, ar 'Invalid authentication data. Presence of extra bytes.' ); $authDataStream->close(); - $data = [ - 'authData' => $authData, - 'rpIdHash' => $rp_id_hash, - 'flags' => $flags, - 'signCount' => $signCount[1], - 'attestedCredentialData' => $attestedCredentialData, - 'extensions' => $extension, - ]; - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize($data, $type, $format, $context); + return AuthenticatorData::create( + $authData, + $rp_id_hash, + $flags, + $signCount[1], + $attestedCredentialData, + $extension === null ? null : $this->denormalizer->denormalize( + $extension, + AuthenticationExtensions::class, + $format, + $context + ), + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === AuthenticatorData::class; } @@ -104,7 +103,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AuthenticatorData::class => false, + AuthenticatorData::class => true, ]; } diff --git a/src/webauthn/src/Denormalizer/AuthenticatorResponseDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticatorResponseDenormalizer.php index 77ca9b264..28fdfb76a 100644 --- a/src/webauthn/src/Denormalizer/AuthenticatorResponseDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticatorResponseDenormalizer.php @@ -18,42 +18,29 @@ final class AuthenticatorResponseDenormalizer implements DenormalizerInterface, { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'AUTHENTICATOR_RESPONSE_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { throw new BadMethodCallException('Please set a denormalizer before calling denormalize()!'); } - switch (true) { - case ! array_key_exists('authenticatorData', $data) && ! array_key_exists('signature', $data): - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize( - $data, - AuthenticatorAttestationResponse::class, - $format, - $context - ); - case array_key_exists('authenticatorData', $data) && array_key_exists('signature', $data): - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize( - $data, - AuthenticatorAssertionResponse::class, - $format, - $context - ); - default: - throw InvalidDataException::create($data, 'Unable to create the response object'); - } + $realType = match (true) { + ! array_key_exists('authenticatorData', $data) && ! array_key_exists( + 'signature', + $data + ) => AuthenticatorAttestationResponse::class, + array_key_exists('authenticatorData', $data) && array_key_exists( + 'signature', + $data + ) => AuthenticatorAssertionResponse::class, + default => throw InvalidDataException::create($data, 'Unable to create the response object'), + }; + + return $this->denormalizer->denormalize($data, $realType, $format, $context); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === AuthenticatorResponse::class; } @@ -63,7 +50,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - AuthenticatorResponse::class => false, + AuthenticatorResponse::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php b/src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php index 84b8dee1c..5dffbbe03 100644 --- a/src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php +++ b/src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php @@ -15,28 +15,17 @@ final class CollectedClientDataDenormalizer implements DenormalizerInterface, De { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'COLLECTED_CLIENT_DATA_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { throw new BadMethodCallException('Please set a denormalizer before calling denormalize()!'); } - $data = [ - 'data' => json_decode($data, true, flags: JSON_THROW_ON_ERROR), - 'rawData' => $data, - ]; - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize($data, $type, $format, $context); + return CollectedClientData::create($data, json_decode($data, true, flags: JSON_THROW_ON_ERROR)); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === CollectedClientData::class; } @@ -46,7 +35,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - CollectedClientData::class => false, + CollectedClientData::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php index b3f206a98..4da3d6b9a 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php @@ -9,6 +9,7 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Webauthn\AuthenticatorResponse; use Webauthn\Exception\InvalidDataException; use Webauthn\PublicKeyCredential; use Webauthn\Util\Base64; @@ -18,8 +19,6 @@ final class PublicKeyCredentialDenormalizer implements DenormalizerInterface, De { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'PUBLIC_KEY_CREDENTIAL_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -33,17 +32,16 @@ public function denormalize(mixed $data, string $type, string $format = null, ar hash_equals($id, $rawId) || throw InvalidDataException::create($data, 'Invalid ID'); $data['rawId'] = $rawId; - $context[self::ALREADY_CALLED] = true; - - return $this->denormalizer->denormalize($data, $type, $format, $context); + return PublicKeyCredential::create( + $data['id'], + $data['type'], + $data['rawId'], + $this->denormalizer->denormalize($data['response'], AuthenticatorResponse::class, $format, $context), + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === PublicKeyCredential::class; } @@ -53,7 +51,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - PublicKeyCredential::class => false, + PublicKeyCredential::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php index 078fc4c58..f24c229d5 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php @@ -9,8 +9,14 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; +use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\PublicKeyCredentialCreationOptions; +use Webauthn\PublicKeyCredentialDescriptor; +use Webauthn\PublicKeyCredentialParameters; use Webauthn\PublicKeyCredentialRequestOptions; +use Webauthn\PublicKeyCredentialRpEntity; +use Webauthn\PublicKeyCredentialUserEntity; use function array_key_exists; use function in_array; @@ -18,8 +24,6 @@ final class PublicKeyCredentialOptionsDenormalizer implements DenormalizerInterf { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'PUBLIC_KEY_CREDENTIAL_OPTIONS_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -36,17 +40,69 @@ public function denormalize(mixed $data, string $type, string $format = null, ar } } } - $context[self::ALREADY_CALLED] = true; - - return $this->denormalizer->denormalize($data, $type, $format, $context); + if ($type === PublicKeyCredentialCreationOptions::class) { + return PublicKeyCredentialCreationOptions::create( + $this->denormalizer->denormalize($data['rp'], PublicKeyCredentialRpEntity::class, $format, $context), + $this->denormalizer->denormalize( + $data['user'], + PublicKeyCredentialUserEntity::class, + $format, + $context + ), + $data['challenge'], + ! isset($data['pubKeyCredParams']) ? [] : $this->denormalizer->denormalize( + $data['pubKeyCredParams'], + PublicKeyCredentialParameters::class . '[]', + $format, + $context + ), + ! isset($data['authenticatorSelection']) ? null : $this->denormalizer->denormalize( + $data['authenticatorSelection'], + AuthenticatorSelectionCriteria::class, + $format, + $context + ), + $data['attestation'] ?? null, + ! isset($data['excludeCredentials']) ? [] : $this->denormalizer->denormalize( + $data['excludeCredentials'], + PublicKeyCredentialDescriptor::class . '[]', + $format, + $context + ), + $data['timeout'] ?? null, + ! isset($data['extensions']) ? null : $this->denormalizer->denormalize( + $data['extensions'], + AuthenticationExtensions::class, + $format, + $context + ), + ); + } + if ($type === PublicKeyCredentialRequestOptions::class) { + return PublicKeyCredentialRequestOptions::create( + $data['challenge'], + $data['rpId'] ?? null, + ! isset($data['allowCredentials']) ? [] : $this->denormalizer->denormalize( + $data['allowCredentials'], + PublicKeyCredentialDescriptor::class . '[]', + $format, + $context + ), + $data['userVerification'] ?? null, + $data['timeout'] ?? null, + ! isset($data['extensions']) ? null : $this->denormalizer->denormalize( + $data['extensions'], + AuthenticationExtensions::class, + $format, + $context + ), + ); + } + throw new BadMethodCallException('Unsupported type'); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return in_array( $type, [PublicKeyCredentialCreationOptions::class, PublicKeyCredentialRequestOptions::class], @@ -60,8 +116,8 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - PublicKeyCredentialCreationOptions::class => false, - PublicKeyCredentialRequestOptions::class => false, + PublicKeyCredentialCreationOptions::class => true, + PublicKeyCredentialRequestOptions::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php new file mode 100644 index 000000000..b5d640688 --- /dev/null +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php @@ -0,0 +1,37 @@ + + */ + public function getSupportedTypes(?string $format): array + { + return [ + PublicKeyCredentialParameters::class => true, + ]; + } +} diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php index 3a643bfbe..0d9517ab0 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php @@ -4,11 +4,14 @@ namespace Webauthn\Denormalizer; +use InvalidDataException; use Symfony\Component\Serializer\Exception\BadMethodCallException; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Symfony\Component\Uid\Uuid; use Webauthn\PublicKeyCredentialSource; +use Webauthn\TrustPath\TrustPath; use Webauthn\Util\Base64; use function array_key_exists; @@ -16,8 +19,6 @@ final class PublicKeyCredentialSourceDenormalizer implements DenormalizerInterfa { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'PUBLIC_KEY_CREDENTIAL_SOURCE_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -25,22 +26,29 @@ public function denormalize(mixed $data, string $type, string $format = null, ar } $keys = ['publicKeyCredentialId', 'credentialPublicKey', 'userHandle']; foreach ($keys as $key) { - if (! array_key_exists($key, $data)) { - return $data; - } + array_key_exists($key, $data) || throw InvalidDataException::create($data, 'Missing ' . $key); $data[$key] = Base64::decode($data[$key]); } - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize($data, $type, $format, $context); + return PublicKeyCredentialSource::create( + $data['publicKeyCredentialId'], + $data['type'], + $data['transports'], + $data['attestationType'], + $this->denormalizer->denormalize($data['trustPath'], TrustPath::class, $format, $context), + Uuid::fromString($data['aaguid']), + $data['credentialPublicKey'], + $data['userHandle'], + $data['counter'], + $data['otherUI'] ?? null, + $data['backupEligible'] ?? null, + $data['backupStatus'] ?? null, + $data['uvInitialized'] ?? null, + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === PublicKeyCredentialSource::class; } @@ -50,7 +58,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - PublicKeyCredentialSource::class => false, + PublicKeyCredentialSource::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php index f6f3e4771..8f376c0fc 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php @@ -16,8 +16,6 @@ final class PublicKeyCredentialUserEntityDenormalizer implements DenormalizerInt { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'PUBLIC_KEY_CREDENTIAL_USER_ENTITY_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { if ($this->denormalizer === null) { @@ -27,17 +25,17 @@ public function denormalize(mixed $data, string $type, string $format = null, ar return $data; } $data['id'] = Base64::decode($data['id']); - $context[self::ALREADY_CALLED] = true; - return $this->denormalizer->denormalize($data, $type, $format, $context); + return PublicKeyCredentialUserEntity::create( + $data['name'], + $data['id'], + $data['displayName'], + $data['icon'] ?? null + ); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === PublicKeyCredentialUserEntity::class; } @@ -47,7 +45,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - PublicKeyCredentialUserEntity::class => false, + PublicKeyCredentialUserEntity::class => true, ]; } } diff --git a/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php b/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php index 5cb76c205..0f53e33bc 100644 --- a/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php +++ b/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php @@ -4,26 +4,16 @@ namespace Webauthn\Denormalizer; -use Symfony\Component\Serializer\Exception\BadMethodCallException; -use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; -use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Webauthn\Exception\InvalidTrustPathException; use Webauthn\TrustPath\TrustPath; use function array_key_exists; use function in_array; -final class TrustPathDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface +final class TrustPathDenormalizer implements DenormalizerInterface { - use DenormalizerAwareTrait; - - private const ALREADY_CALLED = 'TRUST_PATH_PREPROCESS_ALREADY_CALLED'; - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) { - if ($this->denormalizer === null) { - throw new BadMethodCallException('Please set a denormalizer before calling denormalize()!'); - } array_key_exists('type', $data) || throw InvalidTrustPathException::create('The trust path type is missing'); $className = $data['type']; if (class_exists($className) !== true) { @@ -39,17 +29,11 @@ public function denormalize(mixed $data, string $type, string $format = null, ar ); } - $context[self::ALREADY_CALLED] = true; - - return $this->denormalizer->denormalize($data, $className, $format, $context); + return $className::createFromArray($data); } public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - if ($context[self::ALREADY_CALLED] ?? false) { - return false; - } - return $type === TrustPath::class; } @@ -59,7 +43,7 @@ public function supportsDenormalization(mixed $data, string $type, string $forma public function getSupportedTypes(?string $format): array { return [ - TrustPath::class => false, + TrustPath::class => true, ]; } } diff --git a/src/webauthn/src/PublicKeyCredentialLoader.php b/src/webauthn/src/PublicKeyCredentialLoader.php index 2122ec8e1..ea1837b29 100644 --- a/src/webauthn/src/PublicKeyCredentialLoader.php +++ b/src/webauthn/src/PublicKeyCredentialLoader.php @@ -19,6 +19,9 @@ use function is_string; use const JSON_THROW_ON_ERROR; +/** + * @deprecated since 4.8.0 and will be removed in 5.0.0. Please use the Symfony serializer instead + */ class PublicKeyCredentialLoader implements CanLogData { private LoggerInterface $logger; diff --git a/tests/symfony/config/config.yml b/tests/symfony/config/config.yml index df44027bc..c44230693 100644 --- a/tests/symfony/config/config.yml +++ b/tests/symfony/config/config.yml @@ -55,7 +55,7 @@ services: - 'webauthn.mds_service' arguments: - '%kernel.project_dir%/tests/metadataStatements' - - '@mds-serializer' + - '@serializer' # fido_alliance_official: # class: Webauthn\MetadataService\Service\FidoAllianceCompliantMetadataService @@ -97,6 +97,7 @@ doctrine: url: '%env(resolve:DATABASE_URL)%' orm: + enable_lazy_ghost_objects: true auto_generate_proxy_classes: true naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware auto_mapping: true diff --git a/tests/symfony/functional/Assertion/AssertionTest.php b/tests/symfony/functional/Assertion/AssertionTest.php index 5bdbf9ae7..45f6b394b 100644 --- a/tests/symfony/functional/Assertion/AssertionTest.php +++ b/tests/symfony/functional/Assertion/AssertionTest.php @@ -48,7 +48,7 @@ public function anAssertionResponseCanBeLoadedAndVerified(): void ), ]; /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); $publicKeyCredential = $serializer->deserialize( '{"id":"eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w","type":"public-key","rawId":"eHouz/Zi7+BmByHjJ/tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp/B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB+w==","response":{"authenticatorData":"SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAAAew","clientDataJSON":"eyJjaGFsbGVuZ2UiOiJHMEpiTExuZGVmM2EwSXkzUzJzU1FBOHVPNFNPX3plNkZaTUF1UEk2LXhJIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0MyIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ","signature":"MEUCIEY/vcNkbo/LdMTfLa24ZYLlMMVMRd8zXguHBvqud9AJAiEAwCwpZpvcMaqCrwv85w/8RGiZzE+gOM61ffxmgEDeyhM=","userHandle":null}}', PublicKeyCredential::class, diff --git a/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php b/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php index bf7112057..488a041a8 100644 --- a/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php +++ b/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php @@ -6,6 +6,7 @@ use Cose\Algorithms; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Depends; use PHPUnit\Framework\Attributes\Test; use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; @@ -15,6 +16,7 @@ use Webauthn\Bundle\Security\Authentication\Token\WebauthnToken; use Webauthn\Bundle\Security\Storage\Item; use Webauthn\Bundle\Security\Storage\OptionsStorage; +use Webauthn\PublicKeyCredential; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialParameters; @@ -23,6 +25,7 @@ use Webauthn\Tests\Bundle\Functional\CustomSessionStorage; use Webauthn\Tests\Bundle\Functional\PublicKeyCredentialSourceRepository; use Webauthn\Tests\Bundle\Functional\User; +use function assert; use function base64_decode; use function count; use const JSON_THROW_ON_ERROR; @@ -75,6 +78,18 @@ public function anExistingUserCanAskForOptionsUsingTheDedicatedController(): voi } #[Test] + public function thePublicKeyCredentialDataCanBeLoaded(): void + { + $data = '{"id":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK","type":"public-key","rawId":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB/MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1+RIuTF9DUtEJZEEK","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiI5V3FncFJJWXZHTUNVWWlGVDIwbzFVN2hTRDE5M2sxMXp1NHRLUDd3UmNyRTI2enMxemM0TEh5UGludlBHUzg2d3U2YkR2cHdidDhYcDJiUTNWQlJTUSIsImNsaWVudEV4dGVuc2lvbnMiOnt9LCJoYXNoQWxnb3JpdGhtIjoiU0hBLTI1NiIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjkSZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAAAAAAAAAAAAAAAAAAAAAAAAAYJjIobiMfS7pLMMQTjIzBw3+hADjTsu6nVoWkEO3TrVYkdnFQfzDW2cVEYtnL4ErykiC295iEnvZTzRvbGIKI7mOYjYp2DoOoUVcZptFbLLjRtqZtfkSLkxfQ1LRCWRBCqUBAgMmIAEhWCAcPxwKyHADVjTgTsat4R/Jax6PWte50A8ZasMm4w6RxCJYILt0FCiGwC6rBrh3ySNy0yiUjZpNGAhW+aM9YYyYnUTJ"}}'; + $serializer = static::getContainer()->get(SerializerInterface::class); + assert($serializer instanceof SerializerInterface); + $publicKeyCredential = $serializer->deserialize($data, PublicKeyCredential::class, 'json'); + + static::assertInstanceOf(PublicKeyCredential::class, $publicKeyCredential); + } + + #[Test] + #[Depends('thePublicKeyCredentialDataCanBeLoaded')] public function withTheOptionAnExistingUserCanRegisterNewAnotherAuthenticator(): void { /** @var PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository */ @@ -160,7 +175,7 @@ public function anExistingUserCanGetOptionsTestItsAuthenticators(): void private function logIn(): void { /** @var SerializerInterface $serializer */ - $serializer = static::getContainer()->get('webauthn-serializer'); + $serializer = static::getContainer()->get(SerializerInterface::class); $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"EhNVt3T8V12FJvSAc50nhKnZ-MEc-kf84xepDcGyN1g","attestation":"direct","user":{"name":"XY5nn3p_6olTLjoB2Jbb","id":"OTI5ZmJhMmYtMjM2MS00YmM2LWE5MTctYmI3NmFhMTRjN2Y5","displayName":"Bennie Moneypenny"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( $options, diff --git a/tests/symfony/functional/Attestation/AttestationTest.php b/tests/symfony/functional/Attestation/AttestationTest.php index 24d83f88f..2c1587326 100644 --- a/tests/symfony/functional/Attestation/AttestationTest.php +++ b/tests/symfony/functional/Attestation/AttestationTest.php @@ -47,7 +47,7 @@ public function foo(): void ), ); /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); $publicKeyCredential = $serializer->deserialize( '{"id":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK","type":"public-key","rawId":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB/MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1+RIuTF9DUtEJZEEK","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiI5V3FncFJJWXZHTUNVWWlGVDIwbzFVN2hTRDE5M2sxMXp1NHRLUDd3UmNyRTI2enMxemM0TEh5UGludlBHUzg2d3U2YkR2cHdidDhYcDJiUTNWQlJTUSIsImNsaWVudEV4dGVuc2lvbnMiOnt9LCJoYXNoQWxnb3JpdGhtIjoiU0hBLTI1NiIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjkSZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAAAAAAAAAAAAAAAAAAAAAAAAAYJjIobiMfS7pLMMQTjIzBw3+hADjTsu6nVoWkEO3TrVYkdnFQfzDW2cVEYtnL4ErykiC295iEnvZTzRvbGIKI7mOYjYp2DoOoUVcZptFbLLjRtqZtfkSLkxfQ1LRCWRBCqUBAgMmIAEhWCAcPxwKyHADVjTgTsat4R/Jax6PWte50A8ZasMm4w6RxCJYILt0FCiGwC6rBrh3ySNy0yiUjZpNGAhW+aM9YYyYnUTJ"}}', PublicKeyCredential::class, @@ -92,7 +92,7 @@ public function anAttestationResponseCanBeLoadedAndVerified(): void ), ); /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); $publicKeyCredential = $serializer->deserialize( '{"id":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK","type":"public-key","rawId":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB/MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1+RIuTF9DUtEJZEEK","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiI5V3FncFJJWXZHTUNVWWlGVDIwbzFVN2hTRDE5M2sxMXp1NHRLUDd3UmNyRTI2enMxemM0TEh5UGludlBHUzg2d3U2YkR2cHdidDhYcDJiUTNWQlJTUSIsImNsaWVudEV4dGVuc2lvbnMiOnt9LCJoYXNoQWxnb3JpdGhtIjoiU0hBLTI1NiIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjkSZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAAAAAAAAAAAAAAAAAAAAAAAAAYJjIobiMfS7pLMMQTjIzBw3+hADjTsu6nVoWkEO3TrVYkdnFQfzDW2cVEYtnL4ErykiC295iEnvZTzRvbGIKI7mOYjYp2DoOoUVcZptFbLLjRtqZtfkSLkxfQ1LRCWRBCqUBAgMmIAEhWCAcPxwKyHADVjTgTsat4R/Jax6PWte50A8ZasMm4w6RxCJYILt0FCiGwC6rBrh3ySNy0yiUjZpNGAhW+aM9YYyYnUTJ"}}', PublicKeyCredential::class, @@ -124,7 +124,7 @@ public function aFullCertificateChainShouldNotBeUsedForThisSelfAttestation(): vo { // Given /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"h8lQZpu-S0rTLOOeAr7BeWoPPTkhtqcEzlHizEyzVeQ","attestation":"direct","user":{"name":"fwOcfew16ujF_p7Hl5eh","id":"ZTc4N2YzZmItMDgwZS00ZDNjLTlhZDItYmE3OTAwYTVlNTg1","displayName":"Gretchen Mo"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( @@ -164,7 +164,7 @@ public function eddsa(): void { // Given /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); self::bootKernel(); self::$kernel->getContainer()->get(PublicKeyCredentialSourceRepository::class)->clearCredentials(); @@ -201,7 +201,7 @@ public function certificateExpired(): void { // Given /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); //Then $this->expectException(CertificateChainException::class); diff --git a/tests/symfony/functional/Attestation/PackedAttestationStatementTest.php b/tests/symfony/functional/Attestation/PackedAttestationStatementTest.php index dbf26ed66..f99f1219a 100644 --- a/tests/symfony/functional/Attestation/PackedAttestationStatementTest.php +++ b/tests/symfony/functional/Attestation/PackedAttestationStatementTest.php @@ -40,7 +40,7 @@ public function aPackedAttestationWithSelfStatementCanBeVerified(): void attestation: PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT ); /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); $publicKeyCredential = $serializer->deserialize( '{"id":"AFkzwaxVuCUz4qFPaNAgnYgoZKKTtvGIAaIASAbnlHGy8UktdI_jN0CetpIkiw9--R0AF9a6OJnHD-G4aIWur-Pxj-sI9xDE-AVeQKve","type":"public-key","rawId":"AFkzwaxVuCUz4qFPaNAgnYgoZKKTtvGIAaIASAbnlHGy8UktdI/jN0CetpIkiw9++R0AF9a6OJnHD+G4aIWur+Pxj+sI9xDE+AVeQKve","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJvRlVHaFVldlFIWDdKNm80T0ZhdTVQYm5jQ0FUYUh3akhETEx6Q1RwaXl3Iiwib3JpZ2luIjoiaHR0cHM6Ly9zcG9ta3ktd2ViYXV0aG4uaGVyb2t1YXBwLmNvbSIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ","attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIgAMCQZYRl2cA+ab2MB3OGBCbq3j62rSubwhaCVSHJvKMCIQD0mMLs/5jjwd0KxYzb9/iM15T1gJ3L1Uv5BnMtQtVYBmhhdXRoRGF0YVjStIXbbgSILsWHHbR0Fjkl96X4ROZYLvVtOopBWCQoAqpFXE8bBwAAAAAAAAAAAAAAAAAAAAAATgBZM8GsVbglM+KhT2jQIJ2IKGSik7bxiAGiAEgG55RxsvFJLXSP4zdAnraSJIsPfvkdABfWujiZxw/huGiFrq/j8Y/rCPcQxPgFXkCr3qUBAgMmIAEhWCBOSwRVQxXPb76nvmQ2HQ8i5Bin8M4zfZCqIlKXrcxxmyJYIOFCAZ9+rRhklvn1nk2TahaCvpH96emEuKoGxpEObvQg"}}', PublicKeyCredential::class, diff --git a/tests/symfony/functional/MetadataService/ConformanceTest.php b/tests/symfony/functional/MetadataService/ConformanceTest.php index d2fabd481..e5ccd4ad2 100644 --- a/tests/symfony/functional/MetadataService/ConformanceTest.php +++ b/tests/symfony/functional/MetadataService/ConformanceTest.php @@ -27,7 +27,7 @@ public function theMetadataStatementIsMissing(): void { // Given /** @var SerializerInterface $serializer */ - $serializer = self::getContainer()->get('webauthn-serializer'); + $serializer = self::getContainer()->get(SerializerInterface::class); $callback = self::getContainer()->get(MockClientCallback::class); $callback->addResponses([ From abd3fc8b1b0b0cced4fb5c4f929d7058c0161beb Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Wed, 15 Nov 2023 20:53:18 +0100 Subject: [PATCH 2/4] Deprecate PK Loader in favor of the symfony/serializer --- phpstan-baseline.neon | 441 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 428 insertions(+), 13 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 7d07aff61..87372b78b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -623,6 +623,14 @@ parameters: count: 1 path: src/symfony/src/Controller/AssertionControllerFactory.php + - + message: """ + #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AssertionControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: + since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# + """ + count: 1 + path: src/symfony/src/Controller/AssertionControllerFactory.php + - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\Bundle\\\\Controller\\\\AssertionControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" count: 1 @@ -646,6 +654,22 @@ parameters: count: 1 path: src/symfony/src/Controller/AssertionResponseController.php + - + message: """ + #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AssertionResponseController\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: + since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# + """ + count: 1 + path: src/symfony/src/Controller/AssertionResponseController.php + + - + message: """ + #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: + since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# + """ + count: 1 + path: src/symfony/src/Controller/AttestationControllerFactory.php + - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" count: 1 @@ -684,6 +708,14 @@ parameters: count: 1 path: src/symfony/src/Controller/AttestationResponseController.php + - + message: """ + #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationResponseController\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: + since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# + """ + count: 1 + path: src/symfony/src/Controller/AttestationResponseController.php + - message: """ #^Access to deprecated property \\$authenticatorSelection of class Webauthn\\\\Bundle\\\\Dto\\\\PublicKeyCredentialCreationOptionsRequest\\: @@ -1143,6 +1175,14 @@ parameters: count: 1 path: src/symfony/src/Repository/PublicKeyCredentialSourceRepository.php + - + message: """ + #^Fetching class constant class of deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: + since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# + """ + count: 1 + path: src/symfony/src/Resources/config/services.php + - message: "#^Fetching class constant class of deprecated class Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" count: 2 @@ -1299,6 +1339,14 @@ parameters: count: 2 path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php + - + message: """ + #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Security\\\\Http\\\\Authenticator\\\\WebauthnAuthenticator\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: + since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# + """ + count: 1 + path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php + - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\Bundle\\\\Security\\\\Http\\\\Authenticator\\\\WebauthnAuthenticator\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" count: 1 @@ -2178,6 +2226,21 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php + - + message: "#^Parameter \\#1 \\$rawAttestationObject of static method Webauthn\\\\AttestationStatement\\\\AttestationObject\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php + + - + message: "#^Parameter \\#2 \\$attStmt of static method Webauthn\\\\AttestationStatement\\\\AttestationObject\\:\\:create\\(\\) expects Webauthn\\\\AttestationStatement\\\\AttestationStatement, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php + + - + message: "#^Parameter \\#3 \\$authData of static method Webauthn\\\\AttestationStatement\\\\AttestationObject\\:\\:create\\(\\) expects Webauthn\\\\AuthenticatorData, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AttestationObjectDenormalizer.php + - message: "#^Cannot access offset 'fmt' on mixed\\.$#" count: 1 @@ -2239,24 +2302,34 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php + - + message: "#^Parameter \\#1 \\$extensions of static method Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\:\\:create\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php + + - + message: "#^Cannot access offset 'attestationObject' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + - message: "#^Cannot access offset 'authenticatorData' on mixed\\.$#" - count: 2 + count: 3 path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php - message: "#^Cannot access offset 'clientDataJSON' on mixed\\.$#" - count: 2 + count: 3 path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php - message: "#^Cannot access offset 'signature' on mixed\\.$#" - count: 2 + count: 3 path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php - message: "#^Cannot access offset 'userHandle' on mixed\\.$#" - count: 2 + count: 3 path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php - @@ -2269,6 +2342,11 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + - + message: "#^Parameter \\#1 \\$clientDataJSON of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects Webauthn\\\\CollectedClientData, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\Util\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" count: 3 @@ -2279,6 +2357,26 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + - + message: "#^Parameter \\#2 \\$authenticatorData of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects Webauthn\\\\AuthenticatorData, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + + - + message: "#^Parameter \\#3 \\$signature of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + + - + message: "#^Parameter \\#4 \\$userHandle of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + + - + message: "#^Parameter \\#5 \\$attestationObject of static method Webauthn\\\\AuthenticatorAssertionResponse\\:\\:create\\(\\) expects Webauthn\\\\AttestationStatement\\\\AttestationObject\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAssertionResponseDenormalizer.php + - message: "#^Cannot access offset 'attestationObject' on mixed\\.$#" count: 2 @@ -2286,7 +2384,12 @@ parameters: - message: "#^Cannot access offset 'clientDataJSON' on mixed\\.$#" - count: 2 + count: 3 + path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php + + - + message: "#^Cannot access offset 'transports' on mixed\\.$#" + count: 1 path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php - @@ -2299,6 +2402,11 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php + - + message: "#^Parameter \\#1 \\$clientDataJSON of static method Webauthn\\\\AuthenticatorAttestationResponse\\:\\:create\\(\\) expects Webauthn\\\\CollectedClientData, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php + - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\Util\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" count: 1 @@ -2309,6 +2417,16 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php + - + message: "#^Parameter \\#2 \\$attestationObject of static method Webauthn\\\\AuthenticatorAttestationResponse\\:\\:create\\(\\) expects Webauthn\\\\AttestationStatement\\\\AttestationObject, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php + + - + message: "#^Parameter \\#3 \\$transports of static method Webauthn\\\\AuthenticatorAttestationResponse\\:\\:create\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorAttestationResponseDenormalizer.php + - message: "#^Cannot access offset 1 on array\\|false\\.$#" count: 2 @@ -2349,6 +2467,11 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php + - + message: "#^Parameter \\#6 \\$extensions of static method Webauthn\\\\AuthenticatorData\\:\\:create\\(\\) expects Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php + - message: "#^Method Webauthn\\\\Denormalizer\\\\AuthenticatorResponseDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 @@ -2379,6 +2502,16 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php + - + message: "#^Parameter \\#1 \\$rawData of static method Webauthn\\\\CollectedClientData\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php + + - + message: "#^Parameter \\#2 \\$data of static method Webauthn\\\\CollectedClientData\\:\\:create\\(\\) expects array, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/CollectedClientDataDenormalizer.php + - message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 @@ -2394,21 +2527,86 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php + - + message: "#^Parameter \\#4 \\$response of static method Webauthn\\\\PublicKeyCredential\\:\\:create\\(\\) expects Webauthn\\\\AuthenticatorResponse, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php + - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - + message: "#^Cannot access offset 'allowCredentials' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - message: "#^Cannot access offset 'allowCredentials'\\|'excludeCredentials' on mixed\\.$#" count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - + message: "#^Cannot access offset 'attestation' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'authenticatorSelect…' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'challenge' on mixed\\.$#" + count: 2 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'excludeCredentials' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'extensions' on mixed\\.$#" + count: 2 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - message: "#^Cannot access offset 'id' on mixed\\.$#" count: 2 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - + message: "#^Cannot access offset 'pubKeyCredParams' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'rp' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'rpId' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'timeout' on mixed\\.$#" + count: 2 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'user' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Cannot access offset 'userVerification' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - message: "#^Cannot access offset mixed on mixed\\.$#" count: 1 @@ -2424,16 +2622,176 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - + message: "#^Parameter \\#1 \\$challenge of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decodeNoPadding\\(\\) expects string, mixed given\\.$#" count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - + message: "#^Parameter \\#1 \\$rp of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects Webauthn\\\\PublicKeyCredentialRpEntity, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" count: 2 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + - + message: "#^Parameter \\#2 \\$rpId of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#2 \\$user of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects Webauthn\\\\PublicKeyCredentialUserEntity, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#3 \\$allowCredentials of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#3 \\$challenge of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#4 \\$pubKeyCredParams of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#4 \\$userVerification of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#5 \\$authenticatorSelection of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects Webauthn\\\\AuthenticatorSelectionCriteria\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#5 \\$timeout of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects int\\<1, max\\>\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#6 \\$attestation of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#6 \\$extensions of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects array\\\\|Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#7 \\$excludeCredentials of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#8 \\$timeout of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects int\\<1, max\\>\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Parameter \\#9 \\$extensions of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:create\\(\\) expects Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php + + - + message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialParametersDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php + + - + message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialParametersDenormalizer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php + + - + message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialParametersDenormalizer.php + + - + message: "#^Call to static method create\\(\\) on an unknown class InvalidDataException\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'aaguid' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'attestationType' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'backupEligible' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'backupStatus' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'counter' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'credentialPublicKey' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'otherUI' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'publicKeyCredential…' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'transports' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'trustPath' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'type' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'userHandle' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Cannot access offset 'uvInitialized' on mixed\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + - message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialSourceDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 @@ -2449,11 +2807,76 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + - + message: "#^Parameter \\#1 \\$publicKeyCredentialId of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#1 \\$uuid of static method Symfony\\\\Component\\\\Uid\\\\Uuid\\:\\:fromString\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#10 \\$otherUI of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects array\\\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#11 \\$backupEligible of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#12 \\$backupStatus of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#13 \\$uvInitialized of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + - + message: "#^Parameter \\#2 \\$type of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#3 \\$transports of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#4 \\$attestationType of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#5 \\$trustPath of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects Webauthn\\\\TrustPath\\\\TrustPath, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#7 \\$credentialPublicKey of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#8 \\$userHandle of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + + - + message: "#^Parameter \\#9 \\$counter of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects int, mixed given\\.$#" + count: 1 + path: src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php + - message: "#^Method Webauthn\\\\Denormalizer\\\\PublicKeyCredentialUserEntityDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 @@ -2519,14 +2942,6 @@ parameters: count: 1 path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - message: """ - #^Call to deprecated method loadArray\\(\\) of class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use \\{self\\:\\:load\\} instead$# - """ - count: 1 - path: src/webauthn/src/PublicKeyCredentialLoader.php - - message: "#^Cannot call method load\\(\\) on Webauthn\\\\AttestationStatement\\\\AttestationObjectLoader\\|null\\.$#" count: 1 From 0636d8b8d13cec297faa719ab53322748516405b Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Wed, 15 Nov 2023 21:06:26 +0100 Subject: [PATCH 3/4] Deprecate PK Loader in favor of the symfony/serializer --- .../Http/Authenticator/WebauthnAuthenticator.php | 12 ++---------- tests/symfony/config/config.yml | 1 - 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php b/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php index ced0ecef9..53862aad8 100644 --- a/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php +++ b/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php @@ -188,11 +188,7 @@ private function processWithAssertion(Request $request): Passport $content = $request->getContent(); $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( $content - ) : $this->publicKeyCredentialLoader->deserialize( - $content, - PublicKeyCredential::class, - 'json' - ); + ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAssertionResponse || throw InvalidDataException::create( $response, @@ -260,11 +256,7 @@ private function processWithAttestation(Request $request): Passport $content = $request->getContent(); $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( $content - ) : $this->publicKeyCredentialLoader->deserialize( - $content, - PublicKeyCredential::class, - 'json' - ); + ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAttestationResponse || throw InvalidDataException::create( $response, diff --git a/tests/symfony/config/config.yml b/tests/symfony/config/config.yml index c44230693..10c12e23e 100644 --- a/tests/symfony/config/config.yml +++ b/tests/symfony/config/config.yml @@ -97,7 +97,6 @@ doctrine: url: '%env(resolve:DATABASE_URL)%' orm: - enable_lazy_ghost_objects: true auto_generate_proxy_classes: true naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware auto_mapping: true From 96fbaec2bceb28b8018094dd55a9f44a7e11d51e Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Wed, 15 Nov 2023 21:17:08 +0100 Subject: [PATCH 4/4] Deprecate PK Loader in favor of the symfony/serializer --- .../src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php index 0d9517ab0..8022d8432 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialSourceDenormalizer.php @@ -4,12 +4,12 @@ namespace Webauthn\Denormalizer; -use InvalidDataException; use Symfony\Component\Serializer\Exception\BadMethodCallException; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Uid\Uuid; +use Webauthn\Exception\InvalidDataException; use Webauthn\PublicKeyCredentialSource; use Webauthn\TrustPath\TrustPath; use Webauthn\Util\Base64;