From 383612783ff2d908600eb5bf95b70862e89c10d8 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 6 Nov 2025 11:56:04 +0100 Subject: [PATCH 1/6] Basic fixes, updates, and add rector --- .gitignore | 1 + ci/qa/phpcpd | 7 ------- ci/qa/phplint.yaml | 4 ++-- ci/qa/rector.php | 16 ++++++++++++++++ ci/qa/rector.sh | 5 +++++ composer.json | 13 +++++++------ src/SAML2/BridgeContainer.php | 2 +- src/SAML2/Extensions/GsspUserAttributesChunk.php | 2 +- .../Authentication/SamlAuthenticator.php | 2 +- 9 files changed, 34 insertions(+), 18 deletions(-) delete mode 100755 ci/qa/phpcpd create mode 100644 ci/qa/rector.php create mode 100755 ci/qa/rector.sh diff --git a/.gitignore b/.gitignore index 1ced127c..66220cde 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .idea composer.lock .phpunit.result.cache +var \ No newline at end of file diff --git a/ci/qa/phpcpd b/ci/qa/phpcpd deleted file mode 100755 index e9fec13e..00000000 --- a/ci/qa/phpcpd +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -cd $(dirname $0)/../../ - -# https://github.com/sebastianbergmann/phpcpd -./vendor/bin/phpcpd \ - ./src $1 diff --git a/ci/qa/phplint.yaml b/ci/qa/phplint.yaml index f07ad6c9..0ce92053 100644 --- a/ci/qa/phplint.yaml +++ b/ci/qa/phplint.yaml @@ -1,6 +1,6 @@ -path: [./src, ./tests] +path: [./src] jobs: 10 -cache: /var/qa/phplint.cache +cache-dir: var/qa/phplint.cache extensions: - php exclude: diff --git a/ci/qa/rector.php b/ci/qa/rector.php new file mode 100644 index 00000000..e73f4b26 --- /dev/null +++ b/ci/qa/rector.php @@ -0,0 +1,16 @@ +withPaths([ + __DIR__ . '/../../src', + ]) + ->withPhpSets() + ->withAttributesSets(all: true) + ->withComposerBased(phpunit: true, symfony: true) + ->withTypeCoverageLevel(0) + ->withDeadCodeLevel(0) + ->withCodeQualityLevel(0); diff --git a/ci/qa/rector.sh b/ci/qa/rector.sh new file mode 100755 index 00000000..b2b58571 --- /dev/null +++ b/ci/qa/rector.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# Ensure we run from project root +cd "$(dirname "$0")/../../" || exit 1 +./vendor/bin/rector --config=ci/qa/rector.php "$@" diff --git a/composer.json b/composer.json index 02b28b5f..2aff72f3 100644 --- a/composer.json +++ b/composer.json @@ -23,20 +23,19 @@ "mockery/mockery": "^1.5", "overtrue/phplint": "*", "phpmd/phpmd": "^2.6", - "phpstan/phpstan": "^1.10", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^9.5", "psr/log": "~1.0", + "rector/rector": "^2.2", "sebastian/exporter": "^4.0.5", - "sebastian/phpcpd": "^6.0", "squizlabs/php_codesniffer": "^3.7.1", - "symfony/phpunit-bridge": "^6.3", - "phpstan/extension-installer": "^1.3" + "symfony/phpunit-bridge": "^6.3" }, "scripts": { "check": [ "@composer-validate", "@phplint", - "@phpcpd", "@phpcs", "@phpmd", "@phpstan", @@ -50,7 +49,9 @@ "phpstan": "./ci/qa/phpstan", "phpstan-baseline": "./ci/qa/phpstan-update-baseline", "test": "./ci/qa/phpunit", - "phpcbf": "./ci/qa/phpcbf" + "phpcbf": "./ci/qa/phpcbf", + "rector": "./ci/qa/rector.sh --dry-run", + "rector-fix": "./ci/qa/rector.sh" }, "autoload": { "psr-4": { diff --git a/src/SAML2/BridgeContainer.php b/src/SAML2/BridgeContainer.php index ca63d7fb..f4b9148b 100644 --- a/src/SAML2/BridgeContainer.php +++ b/src/SAML2/BridgeContainer.php @@ -75,7 +75,7 @@ public function getTempDir(): string return ''; } - public function writeFile(string $filename, string $data, int $mode = null): void + public function writeFile(string $filename, string $data, ?int $mode = null): void { $this->notSupported(__METHOD__); } diff --git a/src/SAML2/Extensions/GsspUserAttributesChunk.php b/src/SAML2/Extensions/GsspUserAttributesChunk.php index dab8d555..e8eb759f 100644 --- a/src/SAML2/Extensions/GsspUserAttributesChunk.php +++ b/src/SAML2/Extensions/GsspUserAttributesChunk.php @@ -24,7 +24,7 @@ class GsspUserAttributesChunk extends Chunk { - public function __construct(DOMElement $value = null) + public function __construct(?DOMElement $value = null) { $doc = new DOMDocument("1.0", "UTF-8"); $root = $doc->createElementNS('urn:mace:surf.nl:stepup:gssp-extensions', 'gssp:UserAttributes'); diff --git a/src/Security/Authentication/SamlAuthenticator.php b/src/Security/Authentication/SamlAuthenticator.php index 5bc8b00c..00332861 100644 --- a/src/Security/Authentication/SamlAuthenticator.php +++ b/src/Security/Authentication/SamlAuthenticator.php @@ -73,7 +73,7 @@ public function __construct( ) { } - public function start(Request $request, AuthenticationException $authException = null): Response + public function start(Request $request, ?AuthenticationException $authException = null): Response { $authnRequest = AuthnRequestFactory::createNewRequest( $this->serviceProvider, From bd5f6a0a1477a5d5b84dbe77f0065d553b1a9dce Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 6 Nov 2025 13:06:02 +0100 Subject: [PATCH 2/6] Replace EOL mbhsoft/phpunit-xsdvalidation lib Upgrade PHPUnit and apply attributes --- composer.json | 6 +- .../Metadata/MetadataFactoryTest.php | 27 +++- src/Tests/Component/Metadata/XsdValidator.php | 74 ++++++++++ .../Component/Metadata/XsdValidatorTest.php | 127 ++++++++++++++++++ .../Signing/AuthnRequestSigningTest.php | 44 +++--- .../Unit/Http/HttpBindingFactoryTest.php | 30 ++--- src/Tests/Unit/Http/RedirectBindingTest.php | 58 +++----- .../Monolog/SamlAuthenticationLoggerTest.php | 8 +- .../Attribute/AttributeDictionaryTest.php | 49 +++---- .../ConfigurableAttributeSetFactoryTest.php | 37 ++--- .../Unit/SAML2/AuthnRequestFactoryTest.php | 18 +-- src/Tests/Unit/SAML2/AuthnRequestTest.php | 30 ++--- .../SAML2/ReceivedAuthnRequestPostTest.php | 16 +-- .../ReceivedAuthnRequestQueryStringTest.php | 89 +++++------- .../Assertion/AssertionAdapterTest.php | 36 ++--- .../Response/Assertion/InResponseToTest.php | 20 ++- .../Unit/Security/SamlAuthenticatorTest.php | 12 +- 17 files changed, 382 insertions(+), 299 deletions(-) create mode 100644 src/Tests/Component/Metadata/XsdValidator.php create mode 100644 src/Tests/Component/Metadata/XsdValidatorTest.php diff --git a/composer.json b/composer.json index 2aff72f3..9baa4154 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,17 @@ "twig/twig": "^3" }, "require-dev": { + "ext-libxml": "*", "ext-zlib": "*", - "mbhsoft/phpunit-xsdvalidation": "^3.0", "mockery/mockery": "^1.5", "overtrue/phplint": "*", "phpmd/phpmd": "^2.6", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^10.0.0", "psr/log": "~1.0", "rector/rector": "^2.2", - "sebastian/exporter": "^4.0.5", + "sebastian/exporter": "^5.0.0", "squizlabs/php_codesniffer": "^3.7.1", "symfony/phpunit-bridge": "^6.3" }, diff --git a/src/Tests/Component/Metadata/MetadataFactoryTest.php b/src/Tests/Component/Metadata/MetadataFactoryTest.php index b6ce62f1..29e6f015 100644 --- a/src/Tests/Component/Metadata/MetadataFactoryTest.php +++ b/src/Tests/Component/Metadata/MetadataFactoryTest.php @@ -18,7 +18,6 @@ namespace Surfnet\SamlBundle\Tests\Component\Metadata; -use Jasny\PHPUnit\Constraint\XSDValidation; use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use PHPUnit\Framework\TestCase; @@ -43,6 +42,8 @@ class MetadataFactoryTest extends TestCase public m\Mock|RouterInterface $router; + private XsdValidator $xsdValidator; + public function setUp(): void { // Load the XML template from filesystem as the FilesystemLoader does not honour the bundle prefix @@ -54,6 +55,24 @@ public function setUp(): void $this->twig = new Environment($loader); $this->router = m::mock(RouterInterface::class); $this->router->shouldReceive('generate')->andReturn('https://foobar.example.com'); + $this->xsdValidator = new XsdValidator(); + } + + /** + * Helper method to assert XML document is valid against XSD schema + */ + private function assertXmlIsValidAgainstXsd(\DOMDocument $document, string $xsdPath): void + { + $errors = $this->xsdValidator->validate($document, $xsdPath); + + if (!empty($errors)) { + self::fail( + "XML document does not validate against XSD schema.\n" . + "Validation errors:\n" . implode("\n", $errors) + ); + } + + self::assertTrue(true, "XML document is valid against XSD schema"); } public function test_valid_metadata_xml(): void @@ -112,9 +131,8 @@ public function test_builds_idp_metadata(): void $metadataConfiguration->ssoRoute = 'https://foobar.example.com'; $this->buildFactory($metadataConfiguration); $metadata = $this->factory->generate(); - $constraint = new XSDValidation(__DIR__ . '/xsd/metadata.xsd'); self::assertEquals($expectedResult, $metadata->__toString()); - self::assertThat($metadata->document, $constraint); + $this->assertXmlIsValidAgainstXsd($metadata->document, __DIR__ . '/xsd/metadata.xsd'); } public function test_builds_idp_metadata_signed(): void @@ -131,8 +149,7 @@ public function test_builds_idp_metadata_signed(): void $signingService = new SigningService($keyLoader, $privateKeyLoader); $this->buildFactory($metadataConfiguration, $signingService); $metadata = $this->factory->generate(); - $constraint = new XSDValidation(__DIR__ . '/xsd/metadata.xsd'); - self::assertThat($metadata->document, $constraint); + $this->assertXmlIsValidAgainstXsd($metadata->document, __DIR__ . '/xsd/metadata.xsd'); } private function buildFactory(MetadataConfiguration $metadata, SigningService $signingService = null): void diff --git a/src/Tests/Component/Metadata/XsdValidator.php b/src/Tests/Component/Metadata/XsdValidator.php new file mode 100644 index 00000000..95efe8d5 --- /dev/null +++ b/src/Tests/Component/Metadata/XsdValidator.php @@ -0,0 +1,74 @@ +schemaValidate($xsdPath); + + if (!$isValid) { + $errors = libxml_get_errors(); + $errorMessages = array_map(function ($error) { + return sprintf( + "Line %d: %s", + $error->line, + trim($error->message) + ); + }, $errors); + libxml_clear_errors(); + + return $errorMessages; + } + + libxml_clear_errors(); + return []; + } + + /** + * Check if an XML document is valid against an XSD schema + * + * @param DOMDocument $document The XML document to validate + * @param string $xsdPath Path to the XSD schema file + * @return bool True if valid, false otherwise + */ + public function isValid(DOMDocument $document, string $xsdPath): bool + { + return empty($this->validate($document, $xsdPath)); + } +} + diff --git a/src/Tests/Component/Metadata/XsdValidatorTest.php b/src/Tests/Component/Metadata/XsdValidatorTest.php new file mode 100644 index 00000000..cc9141c7 --- /dev/null +++ b/src/Tests/Component/Metadata/XsdValidatorTest.php @@ -0,0 +1,127 @@ +validator = new XsdValidator(); + } + + public function test_validates_valid_xml_document(): void + { + $xml = << + + + + + +XML; + + $document = new DOMDocument(); + $document->loadXML($xml); + + $errors = $this->validator->validate($document, __DIR__ . '/xsd/metadata.xsd'); + + self::assertEmpty($errors); + } + + public function test_is_valid_returns_true_for_valid_xml(): void + { + $xml = << + + + + + +XML; + + $document = new DOMDocument(); + $document->loadXML($xml); + + $isValid = $this->validator->isValid($document, __DIR__ . '/xsd/metadata.xsd'); + + self::assertTrue($isValid); + } + + public function test_detects_invalid_xml_document(): void + { + $xml = << + + + + + +XML; + + $document = new DOMDocument(); + $document->loadXML($xml); + + $errors = $this->validator->validate($document, __DIR__ . '/xsd/metadata.xsd'); + + self::assertNotEmpty($errors); + self::assertIsArray($errors); + } + + public function test_is_valid_returns_false_for_invalid_xml(): void + { + $xml = << + + + + + +XML; + + $document = new DOMDocument(); + $document->loadXML($xml); + + $isValid = $this->validator->isValid($document, __DIR__ . '/xsd/metadata.xsd'); + + self::assertFalse($isValid); + } + + public function test_returns_error_for_missing_xsd_file(): void + { + $xml = << + + +XML; + + $document = new DOMDocument(); + $document->loadXML($xml); + + $errors = $this->validator->validate($document, __DIR__ . '/xsd/non-existent.xsd'); + + self::assertNotEmpty($errors); + self::assertStringContainsString('not found', $errors[0]); + } +} + diff --git a/src/Tests/Component/Signing/AuthnRequestSigningTest.php b/src/Tests/Component/Signing/AuthnRequestSigningTest.php index b7708acb..02e37a63 100644 --- a/src/Tests/Component/Signing/AuthnRequestSigningTest.php +++ b/src/Tests/Component/Signing/AuthnRequestSigningTest.php @@ -46,11 +46,9 @@ class AuthnRequestSigningTest extends TestCase private ?string $publicKey = null; - /** - * @test - * @group Signing - * @group Deprecated - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('Signing')] + #[\PHPUnit\Framework\Attributes\Group('Deprecated')] public function deprecated_authn_request_signatures_are_verified_if_the_sender_uses_rfc1738_encoding(): void { $authnRequestWithDefaultEncoding = $this->createSignedAuthnRequest( @@ -72,11 +70,9 @@ public function deprecated_authn_request_signatures_are_verified_if_the_sender_u ); } - /** - * @test - * @group Signing - * @group Deprecated - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('Signing')] + #[\PHPUnit\Framework\Attributes\Group('Deprecated')] public function deprecated_authn_request_signatures_are_verified_if_the_sender_uses_something_other_than_rfc1738_encoding(): void { $authnRequestWithCustomEncoding = $this->createSignedAuthnRequest( @@ -98,11 +94,9 @@ public function deprecated_authn_request_signatures_are_verified_if_the_sender_u ); } - /** - * @test - * @group Signing - * @group Deprecated - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('Signing')] + #[\PHPUnit\Framework\Attributes\Group('Deprecated')] public function deprecated_authn_request_signatures_are_not_verified_if_the_data_to_sign_does_not_correspond_with_the_signature_sent(): void { $authnRequestWithModifiedDataToSign = $this->createSignedAuthnRequest( @@ -123,11 +117,9 @@ public function deprecated_authn_request_signatures_are_not_verified_if_the_data ); } - /** - * @test - * @group Signing - * @group Deprecated - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('Signing')] + #[\PHPUnit\Framework\Attributes\Group('Deprecated')] public function deprecated_authn_request_signatures_are_not_verified_if_the_parameter_order_of_the_sent_query_is_not_correct(): void { $authnRequestWithModifiedDataToSign = $this->createSignedAuthnRequest( @@ -147,10 +139,8 @@ public function deprecated_authn_request_signatures_are_not_verified_if_the_para ); } - /** - * @test - * @group Signing - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('Signing')] public function a_received_authn_requests_signature_is_verified_regardless_of_its_encoding(): void { $signatureVerifier = new SignatureVerifier(new KeyLoader, new NullLogger); @@ -203,10 +193,8 @@ public function a_received_authn_requests_signature_is_verified_regardless_of_it ); } - /** - * @test - * @group Signing - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('Signing')] public function a_received_authn_requests_signature_is_not_verified_if_the_data_to_sign_does_not_correspond_with_the_signature_sent(): void { $signatureVerifier = new SignatureVerifier(new KeyLoader, new NullLogger); diff --git a/src/Tests/Unit/Http/HttpBindingFactoryTest.php b/src/Tests/Unit/Http/HttpBindingFactoryTest.php index 25086aa9..80316e60 100644 --- a/src/Tests/Unit/Http/HttpBindingFactoryTest.php +++ b/src/Tests/Unit/Http/HttpBindingFactoryTest.php @@ -41,10 +41,8 @@ public function setUp(): void $this->factory = new HttpBindingFactory($redirectBinding, $postBinding); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_redirect_binding_can_be_built(): void { $request = new Request( @@ -60,10 +58,8 @@ public function a_redirect_binding_can_be_built(): void $this->assertInstanceOf(RedirectBinding::class, $binding); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_post_binding_can_be_built(): void { $request = new Request( @@ -79,10 +75,8 @@ public function a_post_binding_can_be_built(): void $this->assertInstanceOf(PostBinding::class, $binding); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_put_binding_can_not_be_built(): void { $this->expectExceptionMessage("Request type of \"PUT\" is not supported."); @@ -99,10 +93,8 @@ public function a_put_binding_can_not_be_built(): void $this->factory->build($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function an_invalid_post_authn_request_is_rejected(): void { $this->expectExceptionMessage("POST-binding is supported for SAMLRequest."); @@ -119,10 +111,8 @@ public function an_invalid_post_authn_request_is_rejected(): void $this->factory->build($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function an_invalid_get_authn_request_is_rejected(): void { $this->expectExceptionMessage("Redirect binding is supported for SAMLRequest and Response."); diff --git a/src/Tests/Unit/Http/RedirectBindingTest.php b/src/Tests/Unit/Http/RedirectBindingTest.php index 4e3dc718..d4b5728a 100644 --- a/src/Tests/Unit/Http/RedirectBindingTest.php +++ b/src/Tests/Unit/Http/RedirectBindingTest.php @@ -65,12 +65,9 @@ public function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - /** - * @test - * @group http - * - * @dataProvider nonGetMethodProvider - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('nonGetMethodProvider')] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_signed_authn_request_cannot_be_received_from_a_request_that_is_not_a_get_request(string $nonGetMethod): void { $this->expectException(BadRequestHttpException::class); @@ -87,10 +84,8 @@ public function a_signed_authn_request_cannot_be_received_from_a_request_that_is $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_signed_authn_request_cannot_be_received_from_a_request_that_has_no_signed_saml_request(): void { $this->expectException(UnsignedRequestException::class); @@ -107,10 +102,8 @@ public function a_signed_authn_request_cannot_be_received_from_a_request_that_ha $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_signed_authn_request_cannot_be_received_if_the_service_provider_in_the_authn_request_is_unknown(): void { $this->expectException(UnknownServiceProviderException::class); @@ -142,9 +135,9 @@ public function a_signed_authn_request_cannot_be_received_if_the_service_provide /** * Signed AuthNRequests destination MUST match the request URI - * @test - * @group http */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_signed_authn_requests_destination_must_match_request_uri(): void { $this->expectException(BadRequestHttpException::class); @@ -171,9 +164,9 @@ public function a_signed_authn_requests_destination_must_match_request_uri(): vo /** * Signed AuthNRequests destination have a destination - * @test - * @group http */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_signed_authn_requests_must_carry_a_destination(): void { $this->expectException(BadRequestHttpException::class); @@ -198,10 +191,8 @@ public function a_signed_authn_requests_must_carry_a_destination(): void $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_signed_authn_request_cannot_be_received_if_the_signature_is_invalid(): void { $this->expectException(SignatureValidationFailedException::class); @@ -239,12 +230,9 @@ public function a_signed_authn_request_cannot_be_received_if_the_signature_is_in $redirectBinding = new RedirectBinding($mockSignatureVerifier, $mockEntityRepository); $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @group http - * - * @dataProvider nonGetMethodProvider - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('nonGetMethodProvider')] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_unsigned_authn_request_cannot_be_received_from_a_request_that_is_not_a_get_request(string $nonGetMethod): void { $this->expectException(BadRequestHttpException::class); @@ -260,10 +248,8 @@ public function a_unsigned_authn_request_cannot_be_received_from_a_request_that_ $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_unsigned_authn_request_cannot_be_received_if_the_service_provider_in_the_authn_request_is_unknown(): void { $this->expectException(UnknownServiceProviderException::class); @@ -290,10 +276,8 @@ public function a_unsigned_authn_request_cannot_be_received_if_the_service_provi $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - /** - * @test - * @group http - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('http')] public function a_unsigned_authn_request_cannot_be_received_if_the_service_provider_in_the_authn_request_is_unknown_with_destination(): void { $this->expectException(UnknownServiceProviderException::class); @@ -320,7 +304,7 @@ public function a_unsigned_authn_request_cannot_be_received_if_the_service_provi $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - public function nonGetMethodProvider(): array + public static function nonGetMethodProvider(): array { return [ [Request::METHOD_POST], diff --git a/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php b/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php index fb881c46..da6fbbfa 100644 --- a/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php +++ b/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php @@ -29,9 +29,7 @@ final class SamlAuthenticationLoggerTest extends TestCase { use MockeryPHPUnitIntegration; - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function it_returns_a_logger_for_an_authentication(): void { $requestId = md5('boesboes'); @@ -44,9 +42,7 @@ public function it_returns_a_logger_for_an_authentication(): void $logger->emergency('message2'); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function it_does_not_throw_when_no_authentication(): void { $innerLogger = m::mock(LoggerInterface::class); diff --git a/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php b/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php index 01533ccf..af15b9e4 100644 --- a/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php +++ b/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php @@ -25,10 +25,8 @@ class AttributeDictionaryTest extends TestCase { - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function finds_no_definition_when_no_definition_given(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -43,10 +41,8 @@ public function finds_no_definition_when_no_definition_given(): void ); } - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function finds_no_definition_when_urn_matches_no_mace_urn(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -69,10 +65,8 @@ public function finds_no_definition_when_urn_matches_no_mace_urn(): void ); } - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function finds_no_definition_when_urn_matches_no_oid_urn(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -95,10 +89,8 @@ public function finds_no_definition_when_urn_matches_no_oid_urn(): void ); } - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function finds_definition_when_urn_matches_urn_mace(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -120,10 +112,8 @@ public function finds_definition_when_urn_matches_urn_mace(): void ); } - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function finds_definition_when_urn_matches_urn_oid(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -145,11 +135,8 @@ public function finds_definition_when_urn_matches_urn_oid(): void ); } - /** - * @test - * @group AttributeDictionary - * - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function shouldThrowExceptionForUnknownAttrib(): void { $this->expectException(UnknownUrnException::class); @@ -165,20 +152,16 @@ public function shouldThrowExceptionForUnknownAttrib(): void $attributeDictionary->getAttributeDefinitionByUrn('unknown:0.0.0.0.0'); } - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function shouldIgnoreUnknownAttributes(): void { $attributeDictionary = new AttributeDictionary(true); $this->assertTrue($attributeDictionary->ignoreUnknownAttributes()); } - /** - * @test - * @group AttributeDictionary - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] public function shouldNotIgnoreUnknownAttributes(): void { $attributeDictionary = new AttributeDictionary(); diff --git a/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php b/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php index 2505157a..6a6a3522 100644 --- a/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php +++ b/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php @@ -37,11 +37,9 @@ protected function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - /** - * @test - * @group AssertionAdapter - * @group AttributeSet - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] public function which_attribute_set_is_created_from_a_saml_assertion_is_configurable(): void { ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate(self::DUMMY_ATTRIBUTE_SET_CLASS); @@ -51,11 +49,9 @@ public function which_attribute_set_is_created_from_a_saml_assertion_is_configur $this->assertInstanceOf(self::DUMMY_ATTRIBUTE_SET_CLASS, $attributeSet); } - /** - * @test - * @group AssertionAdapter - * @group AttributeSet - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] public function which_attribute_set_is_created_from_attributes_is_configurable(): void { ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate(self::DUMMY_ATTRIBUTE_SET_CLASS); @@ -65,13 +61,10 @@ public function which_attribute_set_is_created_from_attributes_is_configurable() $this->assertInstanceOf(self::DUMMY_ATTRIBUTE_SET_CLASS, $attributeSet); } - /** - * @test - * @group AssertionAdapter - * @group AttributeSet - * - * @dataProvider nonOrEmptyStringProvider() - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('nonOrEmptyStringProvider')] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] public function the_attribute_set_to_use_can_only_be_represented_as_a_non_empty_string(int|float|bool|array|stdClass|string $nonOrEmptyString): void { $this->expectException(InvalidArgumentException::class); @@ -80,11 +73,9 @@ public function the_attribute_set_to_use_can_only_be_represented_as_a_non_empty_ ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate($nonOrEmptyString); } - /** - * @test - * @group AssertionAdapter - * @group AttributeSet - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] public function the_attribute_set_to_use_has_to_implement_attribute_set_factory(): void { $this->expectException(InvalidArgumentException::class); @@ -93,7 +84,7 @@ public function the_attribute_set_to_use_has_to_implement_attribute_set_factory( ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate('Non\Existent\Class'); } - public function nonOrEmptyStringProvider(): array + public static function nonOrEmptyStringProvider(): array { return [ 'integer' => [1], diff --git a/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php b/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php index 6ae310ef..c93bf1ea 100644 --- a/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php +++ b/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php @@ -33,10 +33,8 @@ class AuthnRequestFactoryTest extends TestCase { use MockeryPHPUnitIntegration; - /** - * @test - * @group saml2 - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function an_exception_is_thrown_when_a_request_is_not_properly_base64_encoded(): void { $this->expectExceptionMessage("Failed decoding the request, did not receive a valid base64 string"); @@ -51,10 +49,8 @@ public function an_exception_is_thrown_when_a_request_is_not_properly_base64_enc AuthnRequestFactory::createFromHttpRequest($request); } - /** - * @test - * @group saml2 - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function an_exception_is_thrown_when_a_request_cannot_be_inflated(): void { $this->expectExceptionMessage("Failed inflating the request;"); @@ -69,10 +65,8 @@ public function an_exception_is_thrown_when_a_request_cannot_be_inflated(): void AuthnRequestFactory::createFromHttpRequest($request); } - /** - * @test - * @group saml2 - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function verify_force_authn_works_as_intended(): void { $sp = m::mock(ServiceProvider::class); diff --git a/src/Tests/Unit/SAML2/AuthnRequestTest.php b/src/Tests/Unit/SAML2/AuthnRequestTest.php index 8d446e4f..75b946da 100644 --- a/src/Tests/Unit/SAML2/AuthnRequestTest.php +++ b/src/Tests/Unit/SAML2/AuthnRequestTest.php @@ -98,11 +98,9 @@ class AuthnRequestTest extends TestCase private string $acsUrl = 'https://example.org'; - /** - * @test - * @group saml2 - * @dataProvider provideNameIDAndFormatCombinations - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('provideNameIDAndFormatCombinations')] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function setting_the_subject_generates_valid_xml(string $nameId, ?string $format): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestNoSubject); @@ -114,10 +112,8 @@ public function setting_the_subject_generates_valid_xml(string $nameId, ?string $this->assertXmlStringEqualsXmlString($this->authRequestWithSubject, $authnRequest->getUnsignedXML()); } - /** - * @test - * @group saml2 - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function the_nameid_and_format_can_be_retrieved_from_the_authnrequest(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestWithSubject); @@ -133,10 +129,8 @@ public function the_nameid_and_format_can_be_retrieved_from_the_authnrequest(): $this->assertEquals($nameId->getFormat(), $authnRequest->getNameIdFormat()); } - /** - * @test - * @group saml2 - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function the_acs_url_can_be_retrieved_from_the_authnrequest(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestWithSubject); @@ -147,11 +141,9 @@ public function the_acs_url_can_be_retrieved_from_the_authnrequest(): void $this->assertEquals($this->acsUrl, $authnRequest->getAssertionConsumerServiceURL()); } - /** - * @test - * @group saml2 - * @dataProvider provideIsPassiveAndForceAuthnCombinations - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('provideIsPassiveAndForceAuthnCombinations')] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function is_passive_and_force_authn_can_be_retrieved_from_the_authnrequest(string $xml, bool $isPassive, bool $forceAuthn): void { $domDocument = DOMDocumentFactory::fromString($xml); @@ -171,7 +163,7 @@ public function provideIsPassiveAndForceAuthnCombinations(): array ]; } - public function provideNameIDAndFormatCombinations(): array + public static function provideNameIDAndFormatCombinations(): array { $nameId = new NameID(); $nameId->setValue('user@example.org'); diff --git a/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php b/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php index de7ef350..c23c3830 100644 --- a/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php +++ b/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php @@ -24,9 +24,7 @@ class ReceivedAuthnRequestPostTest extends TestCase { - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function it_can_decode_a_signed_saml_request(): void { $samlRequest = str_replace(PHP_EOL, '', file_get_contents(__DIR__ . '/Resources/valid-signed.xml')); @@ -38,9 +36,7 @@ public function it_can_decode_a_signed_saml_request(): void $this->assertEquals('/index.php', $authnRequest->getRelayState()); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function it_can_decode_a_signed_saml_request_from_adfs_origin(): void { $samlRequest = str_replace(PHP_EOL, '', file_get_contents(__DIR__ . '/Resources/valid-signed-adfs.xml')); @@ -52,9 +48,7 @@ public function it_can_decode_a_signed_saml_request_from_adfs_origin(): void $this->assertInstanceOf(ReceivedAuthnRequestPost::class, $parsed); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function it_can_decode_an_usigned_saml_request(): void { $samlRequest = str_replace(PHP_EOL, '', file_get_contents(__DIR__ . '/Resources/valid-unsigned.xml')); @@ -66,9 +60,7 @@ public function it_can_decode_an_usigned_saml_request(): void $this->assertEquals('/index.php', $authnRequest->getRelayState()); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function it_rejects_malformed_saml_request(): void { $this->expectExceptionMessage("Failed decoding SAML request, did not receive a valid base64 string"); diff --git a/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php b/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php index 2146a8ab..c753ac6c 100644 --- a/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php +++ b/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php @@ -42,12 +42,12 @@ class ReceivedAuthnRequestQueryStringTest extends TestCase AUTHNREQUEST_NO_SUBJECT; /** - * @test - * @group AuthnRequest * - * @dataProvider emptyStringProvider * @param $nonOrEmptyString */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('emptyStringProvider')] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_be_parsed_from_empty_strings(string $nonOrEmptyString): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -56,10 +56,8 @@ public function a_received_authn_request_query_string_cannot_be_parsed_from_empt ReceivedAuthnRequestQueryString::parse($nonOrEmptyString); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_valid_key_value_pairs(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -68,10 +66,8 @@ public function a_received_authn_request_query_string_must_contain_valid_key_val ReceivedAuthnRequestQueryString::parse('a-key-without-a-value'); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_a_base64_encoded_saml_request(): void { $this->expectException('\\' . InvalidRequestException::class); @@ -85,13 +81,12 @@ public function a_received_authn_request_query_string_must_contain_a_base64_enco } /** - * @test - * @group AuthnRequest - * - * @dataProvider queryStringWithRepeatedSamlParametersProvider * @param $doubleParameterName * @param $queryStringWithDoubleParameter */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('queryStringWithRepeatedSamlParametersProvider')] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_saml_parameter_twice( string $doubleParameterName, string $queryStringWithDoubleParameter @@ -102,10 +97,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_saml_para ReceivedAuthnRequestQueryString::parse($queryStringWithDoubleParameter); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_a_saml_request(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -118,10 +111,8 @@ public function a_received_authn_request_query_string_must_contain_a_saml_reques ReceivedAuthnRequestQueryString::parse($queryStringWithoutSamlRequest); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_signature_algorithm_without_a_signature(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -134,10 +125,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureAlgorithmWithoutSignature); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_signature_without_a_signature_algorithm(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -150,10 +139,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureWithoutSignatureAlgorithm); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_signature_that_is_not_properly_base64_encoded(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -167,10 +154,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureWithoutSignatureAlgorithm); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_signed_query_string_can_be_acquired_from_a_received_authn_request_query_string(): void { $expectedSignedQueryString = ReceivedAuthnRequestQueryString::PARAMETER_REQUEST . '=' . urlencode(base64_encode('saml-request')) @@ -186,10 +171,8 @@ public function a_signed_query_string_can_be_acquired_from_a_received_authn_requ $this->assertEquals($expectedSignedQueryString, $actualQueryString); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function query_parameters_that_are_not_used_for_a_saml_message_are_ignored_when_creating_a_signed_query_string(): void { $arbitraryParameterToIgnore = 'arbitraryParameter=this-should-be-ignored'; @@ -211,10 +194,8 @@ public function query_parameters_that_are_not_used_for_a_saml_message_are_ignore ); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_decoded_signature_can_be_acquired_from_a_received_authn_request_query_string(): void { $signature = 'signature'; @@ -235,10 +216,8 @@ public function a_decoded_signature_can_be_acquired_from_a_received_authn_reques ); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_decoded_saml_request_can_be_acquired_from_a_received_authn_request_query_string(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestNoSubject); @@ -259,10 +238,8 @@ public function a_decoded_saml_request_can_be_acquired_from_a_received_authn_req ); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function a_saml_request_cannot_be_decoded_from_a_received_authn_request_query_string_if_it_was_not_properly_gzipped(): void { $this->expectException('\\' . InvalidRequestException::class); @@ -276,10 +253,8 @@ public function a_saml_request_cannot_be_decoded_from_a_received_authn_request_q $query->getDecodedSamlRequest(); } - /** - * @test - * @group AuthnRequest - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] public function parameters_can_be_queried_from_the_received_authn_request_query(): void { $samlRequest = urlencode(base64_encode('encoded-saml-request')); @@ -317,7 +292,7 @@ public function parameters_can_be_queried_from_the_received_authn_request_query( ); } - public function emptyStringProvider(): array + public static function emptyStringProvider(): array { return [ 'empty string' => [''], @@ -335,7 +310,7 @@ public function nonStringProvider(): array ]; } - public function queryStringWithRepeatedSamlParametersProvider(): array + public static function queryStringWithRepeatedSamlParametersProvider(): array { $queryString = ReceivedAuthnRequestQueryString::PARAMETER_REQUEST . '=' . urlencode(base64_encode('saml-request')) . '&' . ReceivedAuthnRequestQueryString::PARAMETER_RELAY_STATE . '=relay-state' diff --git a/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php b/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php index 3e4524a7..dcf96f33 100644 --- a/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php +++ b/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php @@ -32,10 +32,8 @@ class AssertionAdapterTest extends TestCase { use MockeryPHPUnitIntegration; - /** - * @test - * @group AssertionAdapter - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] public function presence_of_attribute_can_be_confirmed_based_on_mace_urn_attribute_definition(): void { @@ -62,10 +60,8 @@ public function presence_of_attribute_can_be_confirmed_based_on_mace_urn_attribu $this->assertTrue($attributeIsInSet, 'Expected attribute to be part of AttributeSet, but it is not'); } - /** - * @test - * @group AssertionAdapter - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] public function presence_of_attribute_can_be_confirmed_based_on_oid_urn_attribute_definition(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -91,10 +87,8 @@ public function presence_of_attribute_can_be_confirmed_based_on_oid_urn_attribut $this->assertTrue($attributeIsInSet, 'Expected attribute to be part of AttributeSet, but it is not'); } - /** - * @test - * @group AssertionAdapter - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] public function no_presence_of_attribute_can_be_confirmed_if_no_attribute_definition_found(): void { $this->expectException(UnknownUrnException::class); @@ -119,10 +113,8 @@ public function no_presence_of_attribute_can_be_confirmed_if_no_attribute_defini $attributeSet->contains($attributeExpectedNotToBeContained); } - /** - * @test - * @group AssertionAdapter - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] public function attribute_set_is_empty_if_no_attributes_found(): void { $assertion = m::mock(Assertion::class); @@ -136,10 +128,8 @@ public function attribute_set_is_empty_if_no_attributes_found(): void $this->assertCount(0, $attributeSet, 'Expected attribute set to be empty, but it is not'); } - /** - * @test - * @group AssertionAdapter - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] public function attribute_set_has_content_when_attributes_found(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -162,10 +152,8 @@ public function attribute_set_has_content_when_attributes_found(): void $this->assertCount(1, $attributeSet, 'Expected attribute AttributeSet to have content, but it does not'); } - /** - * @test - * @group AssertionAdapter - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] public function attribute_set_has_no_duplicate_attribute_definitions_when_same_attributes_found(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; diff --git a/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php b/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php index 2bfc67cd..d4e6b45f 100644 --- a/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php +++ b/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php @@ -29,23 +29,19 @@ class InResponseToTest extends TestCase { - /** - * @test - * @group saml2-response - * @group saml2 - * @dataProvider provideAssertionsWithoutInResponseTo - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\DataProvider('provideAssertionsWithoutInResponseTo')] + #[\PHPUnit\Framework\Attributes\Group('saml2-response')] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function assertions_without_in_response_to_are_tested_as_if_in_response_to_is_null(Assertion $assertion): void { $this->assertTrue(InResponseTo::assertEquals($assertion, null)); $this->assertFalse(InResponseTo::assertEquals($assertion, 'some not-null-value')); } - /** - * @test - * @group saml2-response - * @group saml2 - */ + #[\PHPUnit\Framework\Attributes\Test] + #[\PHPUnit\Framework\Attributes\Group('saml2-response')] + #[\PHPUnit\Framework\Attributes\Group('saml2')] public function in_reponse_to_equality_is_strictly_checked(): void { $assertion = new Assertion(); @@ -59,7 +55,7 @@ public function in_reponse_to_equality_is_strictly_checked(): void $this->assertFalse(InResponseTo::assertEquals($assertion, 1)); } - public function provideAssertionsWithoutInResponseTo(): array + public static function provideAssertionsWithoutInResponseTo(): array { ContainerSingleton::setContainer(new MockContainer()); $assertionWithoutSubjectConfirmation = new Assertion(); diff --git a/src/Tests/Unit/Security/SamlAuthenticatorTest.php b/src/Tests/Unit/Security/SamlAuthenticatorTest.php index 87c9824e..cd762ff4 100644 --- a/src/Tests/Unit/Security/SamlAuthenticatorTest.php +++ b/src/Tests/Unit/Security/SamlAuthenticatorTest.php @@ -119,9 +119,7 @@ public function test_start(): void $this->assertInstanceOf(RedirectResponse::class, $response); } - /** - * @dataProvider provideSupportsParameters - */ + #[\PHPUnit\Framework\Attributes\DataProvider('provideSupportsParameters')] public function test_supports(bool $expectedResult, array $post, array $server, string $routeName): void { $request = new Request([], $post, [], [], [], $server); @@ -130,9 +128,7 @@ public function test_supports(bool $expectedResult, array $post, array $server, $this->assertEquals($expectedResult, $this->authenticator->supports($request)); } - /** - * @dataProvider provideSupportsRelayStateParameters - */ + #[\PHPUnit\Framework\Attributes\DataProvider('provideSupportsRelayStateParameters')] public function test_supports_also_rejects(bool $expectation, array $post): void { $request = new Request( @@ -151,7 +147,7 @@ public function test_supports_also_rejects(bool $expectation, array $post): void $this->assertEquals($expectation, $this->authenticator->supports($request)); } - public function provideSupportsParameters(): Generator + public static function provideSupportsParameters(): Generator { yield [true, ['SAMLResponse' => 'foobar'], ['REQUEST_URI' => '/route-name', 'REQUEST_METHOD' => 'POST'], '/route-name']; yield [false, ['SAMLRespons' => 'foobar'], ['REQUEST_URI' => '/route-name', 'REQUEST_METHOD' => 'POST'], '/route-name']; @@ -160,7 +156,7 @@ public function provideSupportsParameters(): Generator yield [false, ['SAMLResponse' => 'foobar'], ['REQUEST_URI' => '/route-name', 'REQUEST_METHOD' => 'POST'], '/route']; } - public function provideSupportsRelayStateParameters(): Generator + public static function provideSupportsRelayStateParameters(): Generator { yield [false, ['SAMLResponse' => 'rejection', 'RelayState' => 'rejection']]; yield [false, ['SAMLResponse' => 'hurts', 'RelayState' => 'rejection']]; From 19d6c0c7b9e9d0c23f6e03e0c284c4aedd1eedd3 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 6 Nov 2025 13:57:04 +0100 Subject: [PATCH 3/6] Fix phpstan issues Update codensniffer, phpunit, psr/log and fix issues. --- ci/qa/phpstan-baseline.neon | 439 ++++++++++++------ ci/qa/rector.php | 7 +- composer.json | 8 +- .../SurfnetSamlExtension.php | 8 +- src/Http/PostBinding.php | 2 +- src/Http/ReceivedAuthnRequestPost.php | 9 +- src/Http/ReceivedAuthnRequestQueryString.php | 6 +- src/Http/RedirectBinding.php | 4 +- src/Metadata/MetadataFactory.php | 10 +- src/Monolog/SamlAuthenticationLogger.php | 21 +- src/SAML2/Attribute/AttributeDictionary.php | 2 +- .../ConfigurableAttributeSetFactory.php | 5 +- src/SAML2/AuthnRequestFactory.php | 2 +- src/SAML2/BridgeContainer.php | 5 + .../Extensions/GsspUserAttributesChunk.php | 1 - .../Authentication/SamlAuthenticator.php | 4 +- .../Unit/Http/PostBindingAuthnRequestTest.php | 14 +- .../Unit/Http/PostBindingSamlResponseTest.php | 10 +- src/Tests/Unit/SAML2/AuthnRequestTest.php | 14 +- src/Value/DateTime.php | 9 +- 20 files changed, 353 insertions(+), 227 deletions(-) diff --git a/ci/qa/phpstan-baseline.neon b/ci/qa/phpstan-baseline.neon index 1ac13feb..475dc6a8 100644 --- a/ci/qa/phpstan-baseline.neon +++ b/ci/qa/phpstan-baseline.neon @@ -1,686 +1,823 @@ parameters: ignoreErrors: - - message: "#^Parameter \\#1 \\$id of method Symfony\\\\Component\\\\DependencyInjection\\\\ContainerBuilder\\:\\:hasDefinition\\(\\) expects string, array\\|bool\\|float\\|int\\|string\\|UnitEnum\\|null given\\.$#" + message: '#^Parameter \#1 \$id of method Symfony\\Component\\DependencyInjection\\ContainerBuilder\:\:hasDefinition\(\) expects string, array\|bool\|float\|int\|string\|UnitEnum\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/DependencyInjection/Compiler/SpRepositoryAliasCompilerPass.php - - message: "#^Parameter \\#2 \\$id of method Symfony\\\\Component\\\\DependencyInjection\\\\ContainerBuilder\\:\\:setAlias\\(\\) expects string\\|Symfony\\\\Component\\\\DependencyInjection\\\\Alias, array\\|bool\\|float\\|int\\|string\\|UnitEnum\\|null given\\.$#" + message: '#^Parameter \#2 \$id of method Symfony\\Component\\DependencyInjection\\ContainerBuilder\:\:setAlias\(\) expects string\|Symfony\\Component\\DependencyInjection\\Alias, array\|bool\|float\|int\|string\|UnitEnum\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/DependencyInjection/Compiler/SpRepositoryAliasCompilerPass.php - - message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, array\\|bool\\|float\\|int\\|string\\|UnitEnum\\|null given\\.$#" + message: '#^Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, array\|bool\|float\|int\|string\|UnitEnum\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/DependencyInjection/Compiler/SpRepositoryAliasCompilerPass.php - - message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + message: '#^Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition\:\:children\(\)\.$#' + identifier: method.notFound count: 6 path: ../../src/DependencyInjection/Configuration.php - - message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:scalarNode\\(\\)\\.$#" + message: '#^Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface\:\:scalarNode\(\)\.$#' + identifier: method.notFound count: 1 path: ../../src/DependencyInjection/Configuration.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseCertificateData\\(\\) has parameter \\$provider with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseCertificateData\(\) has parameter \$provider with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseCertificateData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseCertificateData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseHostedConfiguration\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseHostedConfiguration\(\) has parameter \$configuration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseHostedIdpConfiguration\\(\\) has parameter \\$identityProvider with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseHostedIdpConfiguration\(\) has parameter \$identityProvider with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseHostedSpConfiguration\\(\\) has parameter \\$serviceProvider with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseHostedSpConfiguration\(\) has parameter \$serviceProvider with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseMetadataConfiguration\\(\\) has parameter \\$configuration with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseMetadataConfiguration\(\) has parameter \$configuration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseRemoteConfiguration\\(\\) has parameter \\$remoteConfiguration with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseRemoteConfiguration\(\) has parameter \$remoteConfiguration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseRemoteIdentityProviderConfiguration\\(\\) has parameter \\$identityProvider with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseRemoteIdentityProviderConfiguration\(\) has parameter \$identityProvider with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseRemoteIdentityProviderConfigurations\\(\\) has parameter \\$identityProviders with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseRemoteIdentityProviderConfigurations\(\) has parameter \$identityProviders with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseRemoteServiceProviderConfiguration\\(\\) has parameter \\$serviceProvider with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseRemoteServiceProviderConfiguration\(\) has parameter \$serviceProvider with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\DependencyInjection\\\\SurfnetSamlExtension\\:\\:parseRemoteServiceProviderConfigurations\\(\\) has parameter \\$serviceProviders with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\DependencyInjection\\SurfnetSamlExtension\:\:parseRemoteServiceProviderConfigurations\(\) has parameter \$serviceProviders with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/DependencyInjection/SurfnetSamlExtension.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\HostedEntities\\:\\:__construct\\(\\) has parameter \\$identityProviderConfiguration with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\HostedEntities\:\:__construct\(\) has parameter \$identityProviderConfiguration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/HostedEntities.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\HostedEntities\\:\\:__construct\\(\\) has parameter \\$serviceProviderConfiguration with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\HostedEntities\:\:__construct\(\) has parameter \$serviceProviderConfiguration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/HostedEntities.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\HostedEntities\\:\\:createStandardEntityConfiguration\\(\\) has parameter \\$entityConfiguration with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\HostedEntities\:\:createStandardEntityConfiguration\(\) has parameter \$entityConfiguration with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/HostedEntities.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\HostedEntities\\:\\:createStandardEntityConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\HostedEntities\:\:createStandardEntityConfiguration\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/HostedEntities.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\HostedEntities\\:\\:generateUrl\\(\\) has parameter \\$routeDefinition with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\HostedEntities\:\:generateUrl\(\) has parameter \$routeDefinition with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/HostedEntities.php - - message: "#^Parameter \\#1 \\$request of method Symfony\\\\Component\\\\Routing\\\\RequestContext\\:\\:fromRequest\\(\\) expects Symfony\\\\Component\\\\HttpFoundation\\\\Request, Symfony\\\\Component\\\\HttpFoundation\\\\Request\\|null given\\.$#" + message: '#^Parameter \#1 \$request of method Symfony\\Component\\Routing\\RequestContext\:\:fromRequest\(\) expects Symfony\\Component\\HttpFoundation\\Request, Symfony\\Component\\HttpFoundation\\Request\|null given\.$#' + identifier: argument.type count: 2 path: ../../src/Entity/HostedEntities.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\IdentityProvider\\:\\:getSsoUrl\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\IdentityProvider\:\:getSsoUrl\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Entity/IdentityProvider.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\IdentityProviders\\:\\:find\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\IdentityProviders\:\:find\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Entity/ImmutableCollection/IdentityProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\IdentityProviders\\:\\:findByEntityId\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\IdentityProviders\:\:findByEntityId\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Entity/ImmutableCollection/IdentityProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\IdentityProviders\\:\\:findByEntityId\\(\\) has parameter \\$entityId with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\IdentityProviders\:\:findByEntityId\(\) has parameter \$entityId with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Entity/ImmutableCollection/IdentityProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\IdentityProviders\\:\\:hasByEntityId\\(\\) has parameter \\$entityId with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\IdentityProviders\:\:hasByEntityId\(\) has parameter \$entityId with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Entity/ImmutableCollection/IdentityProviders.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\IdentityProviders\\:\\:\\$identityProviders type has no value type specified in iterable type array\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\IdentityProviders\:\:\$identityProviders type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/ImmutableCollection/IdentityProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\ServiceProviders\\:\\:find\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\ServiceProviders\:\:find\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Entity/ImmutableCollection/ServiceProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\ServiceProviders\\:\\:findByEntityId\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\ServiceProviders\:\:findByEntityId\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Entity/ImmutableCollection/ServiceProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\ServiceProviders\\:\\:findByEntityId\\(\\) has parameter \\$entityId with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\ServiceProviders\:\:findByEntityId\(\) has parameter \$entityId with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Entity/ImmutableCollection/ServiceProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\ServiceProviders\\:\\:hasByEntityId\\(\\) has parameter \\$entityId with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\ServiceProviders\:\:hasByEntityId\(\) has parameter \$entityId with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Entity/ImmutableCollection/ServiceProviders.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Entity\\\\ImmutableCollection\\\\ServiceProviders\\:\\:\\$serviceProviders type has no value type specified in iterable type array\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Entity\\ImmutableCollection\\ServiceProviders\:\:\$serviceProviders type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Entity/ImmutableCollection/ServiceProviders.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\ServiceProvider\\:\\:getAssertionConsumerUrl\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\ServiceProvider\:\:getAssertionConsumerUrl\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Entity/ServiceProvider.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Entity\\\\StaticServiceProviderRepository\\:\\:getServiceProvider\\(\\) has parameter \\$entityId with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Entity\\StaticServiceProviderRepository\:\:getServiceProvider\(\) has parameter \$entityId with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Entity/StaticServiceProviderRepository.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Exception\\\\InvalidArgumentException\\:\\:invalidType\\(\\) has parameter \\$expectedType with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Exception\\InvalidArgumentException\:\:invalidType\(\) has parameter \$expectedType with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Exception/InvalidArgumentException.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Exception\\\\InvalidArgumentException\\:\\:invalidType\\(\\) has parameter \\$parameter with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Exception\\InvalidArgumentException\:\:invalidType\(\) has parameter \$parameter with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Exception/InvalidArgumentException.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Exception\\\\InvalidArgumentException\\:\\:invalidType\\(\\) has parameter \\$value with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Exception\\InvalidArgumentException\:\:invalidType\(\) has parameter \$value with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Exception/InvalidArgumentException.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Exception\\\\NotFound\\:\\:identityProvider\\(\\) has parameter \\$entityId with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Exception\\NotFound\:\:identityProvider\(\) has parameter \$entityId with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Exception/NotFound.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Exception\\\\SamlInvalidConfigurationException\\:\\:missingCertificate\\(\\) has parameter \\$path with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Exception\\SamlInvalidConfigurationException\:\:missingCertificate\(\) has parameter \$path with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Exception/SamlInvalidConfigurationException.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Exception\\\\UnknownUrnException\\:\\:__construct\\(\\) has parameter \\$urn with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Exception\\UnknownUrnException\:\:__construct\(\) has parameter \$urn with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Exception/UnknownUrnException.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Http\\\\PostBinding\\:\\:getFullRequestUri\\(\\) should return string but returns mixed\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Http\\PostBinding\:\:getFullRequestUri\(\) should return string but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/Http/PostBinding.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Http\\\\PostBinding\\:\\:processResponse\\(\\) should return SAML2\\\\Assertion but returns mixed\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Http\\PostBinding\:\:processResponse\(\) should return SAML2\\Assertion but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/Http/PostBinding.php - - message: "#^Parameter \\#1 \\$decodedSamlRequest of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:from\\(\\) expects string, bool\\|string given\\.$#" + message: '#^Parameter \#1 \$entityId of class Surfnet\\SamlBundle\\Http\\Exception\\UnknownServiceProviderException constructor expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/Http/PostBinding.php - - message: "#^Parameter \\#1 \\$entityId of class Surfnet\\\\SamlBundle\\\\Http\\\\Exception\\\\UnknownServiceProviderException constructor expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$entityId of method Surfnet\\SamlBundle\\Entity\\ServiceProviderRepository\:\:getServiceProvider\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/Http/PostBinding.php - - message: "#^Parameter \\#1 \\$entityId of method Surfnet\\\\SamlBundle\\\\Entity\\\\ServiceProviderRepository\\:\\:getServiceProvider\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$entityId of method Surfnet\\SamlBundle\\Entity\\ServiceProviderRepository\:\:hasServiceProvider\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/Http/PostBinding.php - - message: "#^Parameter \\#1 \\$entityId of method Surfnet\\\\SamlBundle\\\\Entity\\\\ServiceProviderRepository\\:\\:hasServiceProvider\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$string of function base64_decode expects string, float\|int\\|int\<1, max\>\|string\|true given\.$#' + identifier: argument.type count: 1 path: ../../src/Http/PostBinding.php - - message: "#^Parameter \\#1 \\$string of function base64_decode expects string, float\\|int\\\\|int\\<1, max\\>\\|string\\|true given\\.$#" - count: 1 - path: ../../src/Http/PostBinding.php - - - - message: "#^Cannot call method verify\\(\\) on Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\|null\\.$#" - count: 1 - path: ../../src/Http/ReceivedAuthnRequestPost.php - - - - message: "#^Method Surfnet\\\\SamlBundle\\\\Http\\\\ReceivedAuthnRequestPost\\:\\:parse\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#" + message: '#^Cannot call method verify\(\) on Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Http/ReceivedAuthnRequestPost.php - - message: "#^Parameter \\#1 \\$decodedSamlRequest of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:from\\(\\) expects string, bool\\|string given\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Http\\ReceivedAuthnRequestPost\:\:parse\(\) has parameter \$parameters with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Http/ReceivedAuthnRequestPost.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Http\\\\ReceivedAuthnRequestQueryString\\:\\:getDecodedSignature\\(\\) should return string but returns string\\|false\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Http\\ReceivedAuthnRequestQueryString\:\:getDecodedSignature\(\) should return string but returns string\|false\.$#' + identifier: return.type count: 1 path: ../../src/Http/ReceivedAuthnRequestQueryString.php - - message: "#^Parameter \\#1 \\$data of function gzinflate expects string, string\\|false given\\.$#" + message: '#^Parameter \#1 \$data of function gzinflate expects string, string\|false given\.$#' + identifier: argument.type count: 1 path: ../../src/Http/ReceivedAuthnRequestQueryString.php - - message: "#^Parameter \\#1 \\$string of function urldecode expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$string of function urldecode expects string, string\|null given\.$#' + identifier: argument.type count: 2 path: ../../src/Http/ReceivedAuthnRequestQueryString.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Http\\\\ReceivedAuthnRequestQueryString\\:\\:\\$samlParameters type has no value type specified in iterable type array\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Http\\ReceivedAuthnRequestQueryString\:\:\$samlParameters type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Http/ReceivedAuthnRequestQueryString.php - - message: "#^Cannot call method getServiceProvider\\(\\) on Surfnet\\\\SamlBundle\\\\Entity\\\\ServiceProviderRepository\\|null\\.$#" + message: '#^Cannot call method getServiceProvider\(\) on Surfnet\\SamlBundle\\Entity\\ServiceProviderRepository\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Http/RedirectBinding.php - - message: "#^Cannot call method hasServiceProvider\\(\\) on Surfnet\\\\SamlBundle\\\\Entity\\\\ServiceProviderRepository\\|null\\.$#" + message: '#^Cannot call method hasServiceProvider\(\) on Surfnet\\SamlBundle\\Entity\\ServiceProviderRepository\|null\.$#' + identifier: method.nonObject count: 2 path: ../../src/Http/RedirectBinding.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Http\\\\RedirectBinding\\:\\:getFullRequestUri\\(\\) should return string but returns mixed\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Http\\RedirectBinding\:\:getFullRequestUri\(\) should return string but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/Http/RedirectBinding.php - - message: "#^Parameter \\#1 \\$entityId of class Surfnet\\\\SamlBundle\\\\Http\\\\Exception\\\\UnknownServiceProviderException constructor expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$entityId of class Surfnet\\SamlBundle\\Http\\Exception\\UnknownServiceProviderException constructor expects string, string\|null given\.$#' + identifier: argument.type count: 2 path: ../../src/Http/RedirectBinding.php - - message: "#^Parameter \\#1 \\$signatureAlgorithm of class Surfnet\\\\SamlBundle\\\\Http\\\\Exception\\\\UnsupportedSignatureException constructor expects string, string\\|null given\\.$#" - count: 1 - path: ../../src/Http/RedirectBinding.php - - - - message: "#^Method Surfnet\\\\SamlBundle\\\\Http\\\\XMLResponse\\:\\:__construct\\(\\) has parameter \\$headers with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Http\\XMLResponse\:\:__construct\(\) has parameter \$headers with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Http/XMLResponse.php - - message: "#^Cannot access property \\$childNodes on DOMElement\\|null\\.$#" + message: '#^Cannot access property \$childNodes on DOMElement\|null\.$#' + identifier: property.nonObject count: 1 path: ../../src/Metadata/Metadata.php - - message: "#^Cannot call method saveXML\\(\\) on DOMDocument\\|null\\.$#" + message: '#^Cannot call method saveXML\(\) on DOMDocument\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Metadata/Metadata.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Metadata\\\\Metadata\\:\\:getRootDomElement\\(\\) should return DOMElement but returns DOMElement\\|null\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Metadata\\Metadata\:\:getRootDomElement\(\) should return DOMElement but returns DOMElement\|null\.$#' + identifier: return.type count: 1 path: ../../src/Metadata/Metadata.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Metadata\\\\MetadataConfiguration\\:\\:\\$assertionConsumerRoute type has no value type specified in iterable type array\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Metadata\\MetadataConfiguration\:\:\$assertionConsumerRoute type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Metadata/MetadataConfiguration.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Metadata\\\\MetadataConfiguration\\:\\:\\$entityIdRoute type has no value type specified in iterable type array\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Metadata\\MetadataConfiguration\:\:\$entityIdRoute type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Metadata/MetadataConfiguration.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Metadata\\\\MetadataConfiguration\\:\\:\\$ssoRoute type has no value type specified in iterable type array\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Metadata\\MetadataConfiguration\:\:\$ssoRoute type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Metadata/MetadataConfiguration.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Metadata\\\\MetadataFactory\\:\\:getUrl\\(\\) has parameter \\$routeDefinition with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Metadata\\MetadataFactory\:\:getUrl\(\) has parameter \$routeDefinition with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Metadata/MetadataFactory.php - - message: "#^Parameter \\#1 \\$publicKeyFile of method Surfnet\\\\SamlBundle\\\\Metadata\\\\MetadataFactory\\:\\:getCertificateData\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$publicKeyFile of method Surfnet\\SamlBundle\\Metadata\\MetadataFactory\:\:getCertificateData\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/Metadata/MetadataFactory.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Signing\\\\KeyPair\\:\\:\\$privateKeyFile \\(string\\) does not accept string\\|null\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Signing\\KeyPair\:\:\$privateKeyFile \(string\) does not accept string\|null\.$#' + identifier: assign.propertyType count: 1 path: ../../src/Metadata/MetadataFactory.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\Signing\\\\KeyPair\\:\\:\\$publicKeyFile \\(string\\) does not accept string\\|null\\.$#" + message: '#^Property Surfnet\\SamlBundle\\Signing\\KeyPair\:\:\$publicKeyFile \(string\) does not accept string\|null\.$#' + identifier: assign.propertyType count: 1 path: ../../src/Metadata/MetadataFactory.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Monolog\\\\SamlAuthenticationLogger\\:\\:modifyContext\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Monolog\\SamlAuthenticationLogger\:\:modifyContext\(\) has parameter \$context with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Monolog/SamlAuthenticationLogger.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Monolog\\\\SamlAuthenticationLogger\\:\\:modifyContext\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Monolog\\SamlAuthenticationLogger\:\:modifyContext\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Monolog/SamlAuthenticationLogger.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\Attribute\\\\Attribute\\:\\:getValue\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\Attribute\\Attribute\:\:getValue\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/Attribute/Attribute.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\Attribute\\\\AttributeSet\\:\\:create\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\Attribute\\AttributeSet\:\:create\(\) has parameter \$attributes with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/Attribute/AttributeSet.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\Attribute\\\\AttributeSetFactory\\:\\:create\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\Attribute\\AttributeSetFactory\:\:create\(\) has parameter \$attributes with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/Attribute/AttributeSetFactory.php - - message: "#^Interface Surfnet\\\\SamlBundle\\\\SAML2\\\\Attribute\\\\AttributeSetInterface extends generic interface IteratorAggregate but does not specify its types\\: TKey, TValue$#" + message: '#^Interface Surfnet\\SamlBundle\\SAML2\\Attribute\\AttributeSetInterface extends generic interface IteratorAggregate but does not specify its types\: TKey, TValue$#' + identifier: missingType.generics count: 1 path: ../../src/SAML2/Attribute/AttributeSetInterface.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\Attribute\\\\ConfigurableAttributeSetFactory\\:\\:create\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\Attribute\\ConfigurableAttributeSetFactory\:\:create\(\) has parameter \$attributes with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/Attribute/ConfigurableAttributeSetFactory.php - - message: "#^Cannot access property \\$type on RobRichards\\\\XMLSecLibs\\\\XMLSecurityKey\\|null\\.$#" + message: '#^Cannot access property \$type on RobRichards\\XMLSecLibs\\XMLSecurityKey\|null\.$#' + identifier: property.nonObject count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot call method getFormat\\(\\) on SAML2\\\\XML\\\\saml\\\\NameID\\|null\\.$#" + message: '#^Cannot call method getFormat\(\) on SAML2\\XML\\saml\\NameID\|null\.$#' + identifier: method.nonObject count: 2 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot call method getValue\\(\\) on SAML2\\\\XML\\\\saml\\\\Issuer\\|null\\.$#" + message: '#^Cannot call method getValue\(\) on SAML2\\XML\\saml\\Issuer\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot call method getValue\\(\\) on SAML2\\\\XML\\\\saml\\\\NameID\\|null\\.$#" + message: '#^Cannot call method getValue\(\) on SAML2\\XML\\saml\\NameID\|null\.$#' + identifier: method.nonObject count: 3 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot call method saveXML\\(\\) on DOMDocument\\|null\\.$#" + message: '#^Cannot call method saveXML\(\) on DOMDocument\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot call method signData\\(\\) on RobRichards\\\\XMLSecLibs\\\\XMLSecurityKey\\|null\\.$#" + message: '#^Cannot call method signData\(\) on RobRichards\\XMLSecLibs\\XMLSecurityKey\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot cast mixed to string\\.$#" + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:getDestination\\(\\) should return string but returns string\\|null\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:getAuthenticationContextClassRef\(\) should return string\|null but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:getSignatureAlgorithm\\(\\) should return string but returns string\\|null\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:getDestination\(\) should return string but returns string\|null\.$#' + identifier: return.type count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:getUnsignedXML\\(\\) should return string but returns string\\|false\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:getSignatureAlgorithm\(\) should return string but returns string\|null\.$#' + identifier: return.type count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:setAuthenticationContextClassRef\\(\\) has parameter \\$authnClassRef with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:getUnsignedXML\(\) should return string but returns string\|false\.$#' + identifier: return.type count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:setScoping\\(\\) has parameter \\$requesterIds with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:setAuthenticationContextClassRef\(\) has parameter \$authnClassRef with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:signRequestQuery\\(\\) has parameter \\$queryParams with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:setScoping\(\) has parameter \$requesterIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Parameter \\#1 \\$string of function base64_encode expects string, string\\|false given\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:signRequestQuery\(\) has parameter \$queryParams with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Parameter \\#2 \\$namespace of class Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\Chunk constructor expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$array of function reset expects array\|object, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:\\$signature \\(string\\|null\\) does not accept string\\|false\\.$#" + message: '#^Parameter \#1 \$string of function base64_encode expects string, string\|false given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequest.php - - message: "#^Cannot cast mixed to string\\.$#" + message: '#^Parameter \#2 \$namespace of class Surfnet\\SamlBundle\\SAML2\\Extensions\\Chunk constructor expects string, string\|null given\.$#' + identifier: argument.type count: 1 - path: ../../src/SAML2/AuthnRequestFactory.php + path: ../../src/SAML2/AuthnRequest.php - - message: "#^Parameter \\#1 \\$key of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequestFactory\\:\\:loadPrivateKey\\(\\) expects SAML2\\\\Configuration\\\\PrivateKey, mixed given\\.$#" + message: '#^Property Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:\$signature \(string\|null\) does not accept string\|false\.$#' + identifier: assign.propertyType + count: 1 + path: ../../src/SAML2/AuthnRequest.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#1 \\$value of method SAML2\\\\XML\\\\saml\\\\NameIDType\\:\\:setValue\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$key of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequestFactory\:\:loadPrivateKey\(\) expects SAML2\\Configuration\\PrivateKey, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#1 \\$xml of static method SAML2\\\\Message\\:\\:fromXML\\(\\) expects DOMElement, DOMNode\\|null given\\.$#" + message: '#^Parameter \#1 \$value of method SAML2\\XML\\saml\\NameIDType\:\:setValue\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#2 \\$rawRequest of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:createSigned\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#1 \$xml of static method SAML2\\Message\:\:fromXML\(\) expects DOMElement, DOMNode\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#2 \\$rawRequest of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:createUnsigned\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#2 \$rawRequest of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:createSigned\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#3 \\$relayState of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:createSigned\\(\\) expects string\\|null, mixed given\\.$#" + message: '#^Parameter \#2 \$rawRequest of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:createUnsigned\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#3 \\$relayState of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:createUnsigned\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#3 \$relayState of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:createSigned\(\) expects string\|null, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#4 \\$signature of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:createSigned\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#3 \$relayState of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:createUnsigned\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Parameter \\#5 \\$signatureAlgorithm of static method Surfnet\\\\SamlBundle\\\\SAML2\\\\AuthnRequest\\:\\:createSigned\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#4 \$signature of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:createSigned\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Cannot call method saveXML\\(\\) on DOMDocument\\|null\\.$#" + message: '#^Parameter \#5 \$signatureAlgorithm of static method Surfnet\\SamlBundle\\SAML2\\AuthnRequest\:\:createSigned\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 - path: ../../src/SAML2/BridgeContainer.php + path: ../../src/SAML2/AuthnRequestFactory.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\BridgeContainer\\:\\:postRedirect\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Cannot call method saveXML\(\) on DOMDocument\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/SAML2/BridgeContainer.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\BridgeContainer\\:\\:redirect\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\BridgeContainer\:\:postRedirect\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/BridgeContainer.php - - message: "#^Parameter \\#1 \\$message of method Psr\\\\Log\\\\LoggerInterface\\:\\:debug\\(\\) expects string, string\\|false given\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\BridgeContainer\:\:redirect\(\) has parameter \$data with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/BridgeContainer.php - - message: "#^Property Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\Chunk\\:\\:\\$value \\(DOMElement\\) does not accept DOMElement\\|null\\.$#" + message: '#^Property Surfnet\\SamlBundle\\SAML2\\Extensions\\Chunk\:\:\$value \(DOMElement\) does not accept DOMElement\|null\.$#' + identifier: assign.propertyType count: 1 path: ../../src/SAML2/Extensions/Chunk.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\Extensions\\:\\:getChunks\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\Extensions\\Extensions\:\:getChunks\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/Extensions/Extensions.php - - message: "#^Cannot call method saveXML\\(\\) on DOMDocument\\|null\\.$#" + message: '#^Cannot call method saveXML\(\) on DOMDocument\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/SAML2/Extensions/GsspUserAttributesChunk.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\GsspUserAttributesChunk\\:\\:toXML\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\Extensions\\GsspUserAttributesChunk\:\:toXML\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/SAML2/Extensions/GsspUserAttributesChunk.php - - message: "#^Parameter \\#1 \\$element of method Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\Chunk\\:\\:append\\(\\) expects DOMElement, DOMElement\\|null given\\.$#" + message: '#^Parameter \#1 \$element of method Surfnet\\SamlBundle\\SAML2\\Extensions\\Chunk\:\:append\(\) expects DOMElement, DOMElement\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/Extensions/GsspUserAttributesChunk.php - - message: "#^Parameter \\#3 \\$value of method Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\Chunk\\:\\:__construct\\(\\) expects DOMElement, DOMElement\\|null given\\.$#" + message: '#^Parameter \#3 \$value of method Surfnet\\SamlBundle\\SAML2\\Extensions\\Chunk\:\:__construct\(\) expects DOMElement, DOMElement\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/Extensions/GsspUserAttributesChunk.php - - message: "#^Cannot call method saveXML\\(\\) on DOMDocument\\|null\\.$#" + message: '#^Cannot call method saveXML\(\) on DOMDocument\|null\.$#' + identifier: method.nonObject + count: 1 + path: ../../src/SAML2/ReceivedAuthnRequest.php + + - + message: '#^Method Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\:\:getAssertionConsumerServiceURL\(\) should return string but returns string\|null\.$#' + identifier: return.type + count: 1 + path: ../../src/SAML2/ReceivedAuthnRequest.php + + - + message: '#^Method Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\:\:getAuthenticationContextClassRef\(\) should return string\|null but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:getAssertionConsumerServiceURL\\(\\) should return string but returns string\\|null\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\:\:getScopingRequesterIds\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:getScopingRequesterIds\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\:\:getUnsignedXML\(\) should return string but returns string\|false\.$#' + identifier: return.type count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:getUnsignedXML\\(\\) should return string but returns string\\|false\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\:\:setAuthenticationContextClassRef\(\) has parameter \$authnClassRef with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:setAuthenticationContextClassRef\\(\\) has parameter \\$authnClassRef with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\SAML2\\ReceivedAuthnRequest\:\:setScoping\(\) has parameter \$requesterIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\SAML2\\\\ReceivedAuthnRequest\\:\\:setScoping\\(\\) has parameter \\$requesterIds with no value type specified in iterable type array\\.$#" + message: '#^Parameter \#1 \$array of function reset expects array\|object, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Parameter \\#1 \\$xml of static method SAML2\\\\Message\\:\\:fromXML\\(\\) expects DOMElement, DOMNode given\\.$#" + message: '#^Parameter \#1 \$xml of static method SAML2\\Message\:\:fromXML\(\) expects DOMElement, DOMNode given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Parameter \\#2 \\$namespace of class Surfnet\\\\SamlBundle\\\\SAML2\\\\Extensions\\\\Chunk constructor expects string, string\\|null given\\.$#" + message: '#^Parameter \#2 \$namespace of class Surfnet\\SamlBundle\\SAML2\\Extensions\\Chunk constructor expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/SAML2/ReceivedAuthnRequest.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\AuthenticatedSessionStateHandler\\:\\:setCurrentRequestUri\\(\\) has no return type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\AuthenticatedSessionStateHandler\:\:setCurrentRequestUri\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: ../../src/Security/Authentication/AuthenticatedSessionStateHandler.php - - message: "#^Cannot call method notice\\(\\) on Psr\\\\Log\\\\LoggerInterface\\|null\\.$#" + message: '#^Cannot call method notice\(\) on Psr\\Log\\LoggerInterface\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Security/Authentication/Handler/FailureHandler.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Passport\\\\Badge\\\\SamlAttributesBadge\\:\\:__construct\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\Passport\\Badge\\SamlAttributesBadge\:\:__construct\(\) has parameter \$attributes with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Security/Authentication/Passport/Badge/SamlAttributesBadge.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Passport\\\\Badge\\\\SamlAttributesBadge\\:\\:getAttributes\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\Passport\\Badge\\SamlAttributesBadge\:\:getAttributes\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Security/Authentication/Passport/Badge/SamlAttributesBadge.php - - message: "#^Cannot call method getAttributes\\(\\) on Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Passport\\\\Badge\\\\SamlAttributesBadge\\|null\\.$#" + message: '#^Cannot call method getAttributes\(\) on Surfnet\\SamlBundle\\Security\\Authentication\\Passport\\Badge\\SamlAttributesBadge\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Security/Authentication/SamlAuthenticator.php - - message: "#^Cannot call method getUserIdentifier\\(\\) on Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null\\.$#" + message: '#^Cannot call method getUserIdentifier\(\) on Symfony\\Component\\Security\\Core\\User\\UserInterface\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Security/Authentication/SamlAuthenticator.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Session\\\\SessionStorage\\:\\:getCurrentRequestUri\\(\\) should return string but returns mixed\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\Session\\SessionStorage\:\:getCurrentRequestUri\(\) should return string but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/Security/Authentication/Session/SessionStorage.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Session\\\\SessionStorage\\:\\:getRequestId\\(\\) should return string but returns mixed\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\Session\\SessionStorage\:\:getRequestId\(\) should return string but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/Security/Authentication/Session/SessionStorage.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Session\\\\SessionStorage\\:\\:setCurrentRequestUri\\(\\) has parameter \\$uri with no type specified\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\Session\\SessionStorage\:\:setCurrentRequestUri\(\) has parameter \$uri with no type specified\.$#' + identifier: missingType.parameter count: 1 path: ../../src/Security/Authentication/Session/SessionStorage.php - - message: "#^Parameter \\#1 \\$string of static method Surfnet\\\\SamlBundle\\\\Value\\\\DateTime\\:\\:fromString\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#1 \$string of static method Surfnet\\SamlBundle\\Value\\DateTime\:\:fromString\(\) expects string, mixed given\.$#' + identifier: argument.type count: 2 path: ../../src/Security/Authentication/Session/SessionStorage.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Security\\\\Authentication\\\\Token\\\\SamlToken\\:\\:__construct\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Security\\Authentication\\Token\\SamlToken\:\:__construct\(\) has parameter \$attributes with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Security/Authentication/Token/SamlToken.php - - message: "#^Method Surfnet\\\\SamlBundle\\\\Service\\\\SigningService\\:\\:loadPublicKeyFromFile\\(\\) should return SAML2\\\\Certificate\\\\X509 but returns mixed\\.$#" + message: '#^Method Surfnet\\SamlBundle\\Service\\SigningService\:\:loadPublicKeyFromFile\(\) should return SAML2\\Certificate\\X509 but returns mixed\.$#' + identifier: return.type count: 1 path: ../../src/Service/SigningService.php - - message: "#^Parameter \\#2 \\$publicKey of method Surfnet\\\\SamlBundle\\\\Signing\\\\SignatureVerifier\\:\\:isRequestSignedWith\\(\\) expects SAML2\\\\Certificate\\\\X509, mixed given\\.$#" + message: '#^Parameter \#2 \$publicKey of method Surfnet\\SamlBundle\\Signing\\SignatureVerifier\:\:isRequestSignedWith\(\) expects SAML2\\Certificate\\X509, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/Signing/SignatureVerifier.php - - message: "#^Parameter \\#2 \\$publicKey of method Surfnet\\\\SamlBundle\\\\Signing\\\\SignatureVerifier\\:\\:isSignedWith\\(\\) expects SAML2\\\\Certificate\\\\X509, mixed given\\.$#" + message: '#^Parameter \#2 \$publicKey of method Surfnet\\SamlBundle\\Signing\\SignatureVerifier\:\:isSignedWith\(\) expects SAML2\\Certificate\\X509, mixed given\.$#' + identifier: argument.type count: 1 path: ../../src/Signing/SignatureVerifier.php - - message: "#^Parameter \\#2 \\$signature of method RobRichards\\\\XMLSecLibs\\\\XMLSecurityKey\\:\\:verifySignature\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#2 \$signature of method RobRichards\\XMLSecLibs\\XMLSecurityKey\:\:verifySignature\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 1 path: ../../src/Signing/SignatureVerifier.php diff --git a/ci/qa/rector.php b/ci/qa/rector.php index e73f4b26..116314ce 100644 --- a/ci/qa/rector.php +++ b/ci/qa/rector.php @@ -8,9 +8,8 @@ ->withPaths([ __DIR__ . '/../../src', ]) - ->withPhpSets() ->withAttributesSets(all: true) ->withComposerBased(phpunit: true, symfony: true) - ->withTypeCoverageLevel(0) - ->withDeadCodeLevel(0) - ->withCodeQualityLevel(0); + ->withTypeCoverageLevel(10) + ->withDeadCodeLevel(10) + ->withCodeQualityLevel(10); diff --git a/composer.json b/composer.json index 9baa4154..f7e9d067 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "php": "^8.1", "ext-dom": "*", "ext-openssl": "*", + "psr/log": "^3.0", "robrichards/xmlseclibs": "^3.1.1", "simplesamlphp/saml2": "^4.6", "symfony/dependency-injection": "^6.3", @@ -25,11 +26,10 @@ "phpmd/phpmd": "^2.6", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^10.0.0", - "psr/log": "~1.0", + "phpunit/phpunit": "^11.0.0", "rector/rector": "^2.2", - "sebastian/exporter": "^5.0.0", - "squizlabs/php_codesniffer": "^3.7.1", + "sebastian/exporter": "^6.3", + "squizlabs/php_codesniffer": "^4.0", "symfony/phpunit-bridge": "^6.3" }, "scripts": { diff --git a/src/DependencyInjection/SurfnetSamlExtension.php b/src/DependencyInjection/SurfnetSamlExtension.php index f858c5ee..b5e30adc 100644 --- a/src/DependencyInjection/SurfnetSamlExtension.php +++ b/src/DependencyInjection/SurfnetSamlExtension.php @@ -158,9 +158,7 @@ private function parseRemoteConfiguration(array $remoteConfiguration, ContainerB if (!empty($remoteConfiguration['identity_provider']['enabled'])) { $definition = $this->parseRemoteIdentityProviderConfiguration($remoteConfiguration['identity_provider']); - if ($definition !== null) { - $container->setDefinition('surfnet_saml.remote.idp', $definition); - } + $container->setDefinition('surfnet_saml.remote.idp', $definition); } } @@ -169,7 +167,7 @@ private function parseRemoteConfiguration(array $remoteConfiguration, ContainerB */ private function parseRemoteIdentityProviderConfigurations(array $identityProviders, ContainerBuilder $container): void { - $definitions = array_map(fn($config) => $this->parseRemoteIdentityProviderConfiguration($config), $identityProviders); + $definitions = array_map(fn($config): Definition => $this->parseRemoteIdentityProviderConfiguration($config), $identityProviders); $definition = new Definition(StaticIdentityProviderRepository::class, [ $definitions @@ -202,7 +200,7 @@ private function parseRemoteIdentityProviderConfiguration(array $identityProvide */ private function parseRemoteServiceProviderConfigurations(array $serviceProviders, ContainerBuilder $container): void { - $definitions = array_map(fn($config) => $this->parseRemoteServiceProviderConfiguration($config), $serviceProviders); + $definitions = array_map(fn($config): Definition => $this->parseRemoteServiceProviderConfiguration($config), $serviceProviders); $definition = new Definition(StaticServiceProviderRepository::class, [ $definitions diff --git a/src/Http/PostBinding.php b/src/Http/PostBinding.php index a1e2d8eb..d9ef75c7 100644 --- a/src/Http/PostBinding.php +++ b/src/Http/PostBinding.php @@ -42,7 +42,7 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") */ class PostBinding implements HttpBinding { diff --git a/src/Http/ReceivedAuthnRequestPost.php b/src/Http/ReceivedAuthnRequestPost.php index 1156c000..b44af4d9 100644 --- a/src/Http/ReceivedAuthnRequestPost.php +++ b/src/Http/ReceivedAuthnRequestPost.php @@ -28,12 +28,15 @@ final class ReceivedAuthnRequestPost implements SignatureVerifiable public const PARAMETER_REQUEST = 'SAMLRequest'; public const PARAMETER_RELAY_STATE = 'RelayState'; - private ?string $relayState; + private ?string $relayState = null; private ?ReceivedAuthnRequest $receivedRequest = null; - private function __construct(private readonly string $samlRequest) + private readonly string $samlRequest; + + private function __construct(string $samlRequest) { + $this->samlRequest = $samlRequest; } public static function parse(array $parameters): self @@ -62,7 +65,7 @@ public function hasRelayState(): bool return $this->relayState !== null; } - public function getDecodedSamlRequest(): string|bool + public function getDecodedSamlRequest(): string { return base64_decode($this->samlRequest); } diff --git a/src/Http/ReceivedAuthnRequestQueryString.php b/src/Http/ReceivedAuthnRequestQueryString.php index 4354f525..b97de3ea 100644 --- a/src/Http/ReceivedAuthnRequestQueryString.php +++ b/src/Http/ReceivedAuthnRequestQueryString.php @@ -49,8 +49,8 @@ private function __construct(private readonly string $samlRequest) } /** - * @SuppressWarnings(PHPMD.CyclomaticComplexity) Extensive validation - * @SuppressWarnings(PHPMD.NPathComplexity) Extensive validation + * @SuppressWarnings("PHPMD.CyclomaticComplexity") Extensive validation + * @SuppressWarnings("PHPMD.NPathComplexity") Extensive validation */ public static function parse(string $query): ReceivedAuthnRequestQueryString { @@ -211,7 +211,7 @@ public function getSamlRequest(): string return $this->samlRequest; } - public function getSignatureAlgorithm(): ?string + public function getSignatureAlgorithm(): string { return urldecode($this->signatureAlgorithm); } diff --git a/src/Http/RedirectBinding.php b/src/Http/RedirectBinding.php index c15c4a27..f83d3cc8 100644 --- a/src/Http/RedirectBinding.php +++ b/src/Http/RedirectBinding.php @@ -32,7 +32,7 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - not much we can do about it + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") - not much we can do about it * @see https://www.pivotaltracker.com/story/show/83028366 */ class RedirectBinding implements HttpBinding @@ -71,7 +71,7 @@ public function receiveUnsignedAuthnRequestFrom(Request $request): ReceivedAuthn } /** - * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings("PHPMD.NPathComplexity") */ public function receiveSignedAuthnRequestFrom(Request $request): ReceivedAuthnRequest { diff --git a/src/Metadata/MetadataFactory.php b/src/Metadata/MetadataFactory.php index 52e508a7..d0c1aa09 100644 --- a/src/Metadata/MetadataFactory.php +++ b/src/Metadata/MetadataFactory.php @@ -72,10 +72,7 @@ private function buildMetadata(): Metadata $metadata->hasSpMetadata = true; $metadata->assertionConsumerUrl = $this->getUrl($metadataConfiguration->assertionConsumerRoute); - if ($metadataConfiguration->spCertificate && - $metadataConfiguration->spCertificate !== '' && - $metadataConfiguration->spCertificate !== '0' - ) { + if ($metadataConfiguration->spCertificate) { $metadata->spCertificate = $this->getCertificateData($metadataConfiguration->spCertificate); } } @@ -84,10 +81,7 @@ private function buildMetadata(): Metadata $metadata->hasIdPMetadata = true; $metadata->ssoUrl = $this->getUrl($metadataConfiguration->ssoRoute); - if ($metadataConfiguration->idpCertificate && - $metadataConfiguration->idpCertificate !== '' && - $metadataConfiguration->idpCertificate !== '0' - ) { + if ($metadataConfiguration->idpCertificate) { $certificate = $this->getCertificateData($metadataConfiguration->idpCertificate); } else { $certificate = $this->getCertificateData($metadataConfiguration->publicKey); diff --git a/src/Monolog/SamlAuthenticationLogger.php b/src/Monolog/SamlAuthenticationLogger.php index 3e13edd6..8d2e140a 100644 --- a/src/Monolog/SamlAuthenticationLogger.php +++ b/src/Monolog/SamlAuthenticationLogger.php @@ -20,12 +20,11 @@ namespace Surfnet\SamlBundle\Monolog; use Psr\Log\LoggerInterface; -use Surfnet\SamlBundle\Exception\RuntimeException; /** * Decorates a PSR logger and adds information pertaining to a SAML request procedure to each message's context. * - * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings("PHPMD.TooManyPublicMethods") */ final class SamlAuthenticationLogger implements LoggerInterface { @@ -46,47 +45,47 @@ public function forAuthentication(string $requestId): self return $logger; } - public function emergency($message, array $context = []): void + public function emergency(string|\Stringable $message, array $context = []): void { $this->logger->emergency($message, $this->modifyContext($context)); } - public function alert($message, array $context = []): void + public function alert(string|\Stringable $message, array $context = []): void { $this->logger->alert($message, $this->modifyContext($context)); } - public function critical($message, array $context = []): void + public function critical(string|\Stringable $message, array $context = []): void { $this->logger->critical($message, $this->modifyContext($context)); } - public function error($message, array $context = []): void + public function error(string|\Stringable $message, array $context = []): void { $this->logger->error($message, $this->modifyContext($context)); } - public function warning($message, array $context = []): void + public function warning(string|\Stringable $message, array $context = []): void { $this->logger->warning($message, $this->modifyContext($context)); } - public function notice($message, array $context = []): void + public function notice(string|\Stringable $message, array $context = []): void { $this->logger->notice($message, $this->modifyContext($context)); } - public function info($message, array $context = []): void + public function info(string|\Stringable $message, array $context = []): void { $this->logger->info($message, $this->modifyContext($context)); } - public function debug($message, array $context = []): void + public function debug(string|\Stringable $message, array $context = []): void { $this->logger->debug($message, $this->modifyContext($context)); } - public function log($level, $message, array $context = []): void + public function log($level, string|\Stringable $message, array $context = []): void { $this->logger->log($level, $message, $this->modifyContext($context)); } diff --git a/src/SAML2/Attribute/AttributeDictionary.php b/src/SAML2/Attribute/AttributeDictionary.php index ff053aad..a393179d 100644 --- a/src/SAML2/Attribute/AttributeDictionary.php +++ b/src/SAML2/Attribute/AttributeDictionary.php @@ -107,7 +107,7 @@ public function getAttributeDefinition(string $attributeName): AttributeDefiniti public function findAttributeDefinitionByUrn(string $urn): ?AttributeDefinition { - if (!is_string($urn) || $urn === '') { + if ($urn === '') { throw InvalidArgumentException::invalidType('non-empty string', $urn, 'urn'); } diff --git a/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php b/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php index 92023845..03bc0457 100644 --- a/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php +++ b/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php @@ -25,10 +25,7 @@ final class ConfigurableAttributeSetFactory implements AttributeSetFactory { private static string $attributeSetClassName = AttributeSet::class; - /** - * @param string $attributeSetClassName - */ - public static function configureWhichAttributeSetToCreate($attributeSetClassName): void + public static function configureWhichAttributeSetToCreate(mixed $attributeSetClassName): void { if (!is_string($attributeSetClassName) || $attributeSetClassName === '') { throw InvalidArgumentException::invalidType('non-empty string', 'attributeSetClassName', $attributeSetClassName); diff --git a/src/SAML2/AuthnRequestFactory.php b/src/SAML2/AuthnRequestFactory.php index be449c04..9b998a38 100644 --- a/src/SAML2/AuthnRequestFactory.php +++ b/src/SAML2/AuthnRequestFactory.php @@ -34,7 +34,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") */ class AuthnRequestFactory { diff --git a/src/SAML2/BridgeContainer.php b/src/SAML2/BridgeContainer.php index f4b9148b..97ca3035 100644 --- a/src/SAML2/BridgeContainer.php +++ b/src/SAML2/BridgeContainer.php @@ -21,6 +21,7 @@ use BadMethodCallException; use DOMElement; use Psr\Log\LoggerInterface; +use RuntimeException; use SAML2\Compat\AbstractContainer; /** @@ -55,6 +56,10 @@ public function debugMessage($message, $type): void $message = $message->ownerDocument->saveXML($message); } + if (!is_string($message)) { + throw new RuntimeException("Debug message error: could not convert message to string."); + } + $this->logger->debug($message, ['type' => $type]); } diff --git a/src/SAML2/Extensions/GsspUserAttributesChunk.php b/src/SAML2/Extensions/GsspUserAttributesChunk.php index e8eb759f..ae3b99b4 100644 --- a/src/SAML2/Extensions/GsspUserAttributesChunk.php +++ b/src/SAML2/Extensions/GsspUserAttributesChunk.php @@ -33,7 +33,6 @@ public function __construct(?DOMElement $value = null) if ($value && $value->hasChildNodes()) { foreach ($value->childNodes as $child) { - assert($child instanceof DOMNode); $root->appendChild($doc->importNode($child->cloneNode(true), true)); } } diff --git a/src/Security/Authentication/SamlAuthenticator.php b/src/Security/Authentication/SamlAuthenticator.php index 00332861..b2260e53 100644 --- a/src/Security/Authentication/SamlAuthenticator.php +++ b/src/Security/Authentication/SamlAuthenticator.php @@ -48,12 +48,12 @@ use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") */ class SamlAuthenticator extends AbstractAuthenticator implements InteractiveAuthenticatorInterface, AuthenticationEntryPointInterface { /** - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @SuppressWarnings("PHPMD.ExcessiveParameterList") */ public function __construct( private readonly IdentityProvider $identityProvider, diff --git a/src/Tests/Unit/Http/PostBindingAuthnRequestTest.php b/src/Tests/Unit/Http/PostBindingAuthnRequestTest.php index 486cf3f5..374eb44a 100644 --- a/src/Tests/Unit/Http/PostBindingAuthnRequestTest.php +++ b/src/Tests/Unit/Http/PostBindingAuthnRequestTest.php @@ -68,7 +68,7 @@ public function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - public function test_receive_signed_authn_request_happy_flow() + public function test_receive_signed_authn_request_happy_flow(): void { $requestUri = 'https://stepup.example.com/sso?with-some-addition=true'; $post = [ @@ -100,7 +100,7 @@ public function test_receive_signed_authn_request_happy_flow() self::assertEquals('https://stepup.example.com/sso', $authnRequest->getDestination()); } - public function test_receive_signed_authn_request_must_have_sp_repo() + public function test_receive_signed_authn_request_must_have_sp_repo(): void { $requestUri = 'https://stepup.example.com/sso?with-some-addition=true'; $post = [ @@ -118,7 +118,7 @@ public function test_receive_signed_authn_request_must_have_sp_repo() $postBinding->receiveSignedAuthnRequestFrom($request); } - public function test_receive_signed_authn_request_http_request_must_be_post() + public function test_receive_signed_authn_request_http_request_must_be_post(): void { $requestUri = 'https://stepup.example.com/sso?with-some-addition=true'; $post = [ @@ -132,7 +132,7 @@ public function test_receive_signed_authn_request_http_request_must_be_post() $this->postBinding->receiveSignedAuthnRequestFrom($request); } - public function test_receive_signed_authn_request_must_have_destination() + public function test_receive_signed_authn_request_must_have_destination(): void { $requestUri = 'https://stepup.example.com/sso?with-some-addition=true'; $post = [ @@ -147,7 +147,7 @@ public function test_receive_signed_authn_request_must_have_destination() $this->postBinding->receiveSignedAuthnRequestFrom($request); } - public function test_receive_signed_authn_request_request_uri_must_start_with_destination() + public function test_receive_signed_authn_request_request_uri_must_start_with_destination(): void { $requestUri = 'https://stepup.example.com/sso'; $post = [ @@ -163,7 +163,7 @@ public function test_receive_signed_authn_request_request_uri_must_start_with_de $this->postBinding->receiveSignedAuthnRequestFrom($request); } - public function test_receive_signed_authn_request_unknown_sp() + public function test_receive_signed_authn_request_unknown_sp(): void { $requestUri = 'https://stepup.example.com/sso'; $post = [ @@ -184,7 +184,7 @@ public function test_receive_signed_authn_request_unknown_sp() $this->postBinding->receiveSignedAuthnRequestFrom($request); } - public function test_receive_signed_authn_request_signature_validation_failed() + public function test_receive_signed_authn_request_signature_validation_failed(): void { $requestUri = 'https://stepup.example.com/sso'; $post = [ diff --git a/src/Tests/Unit/Http/PostBindingSamlResponseTest.php b/src/Tests/Unit/Http/PostBindingSamlResponseTest.php index 9bbb592c..86d6166c 100644 --- a/src/Tests/Unit/Http/PostBindingSamlResponseTest.php +++ b/src/Tests/Unit/Http/PostBindingSamlResponseTest.php @@ -79,7 +79,7 @@ private function buildRequest(): Request return new Request([], $post, [], [], [], ['REQUEST_URI' => $requestUri]); } - public function test_process_response_happy_flow() + public function test_process_response_happy_flow(): void { $request = $this->buildRequest(); $request->setMethod(Request::METHOD_POST); @@ -97,7 +97,7 @@ public function test_process_response_happy_flow() self::assertInstanceOf(Assertion::class, $samlResponse); } - public function test_process_response_must_have_saml_response() + public function test_process_response_must_have_saml_response(): void { $requestUri = 'https://stepup.example.com/'; $post = [ @@ -114,7 +114,7 @@ public function test_process_response_must_have_saml_response() $this->postBinding->processResponse($request, $idp, $sp); } - public function test_process_response_precondition_not_met() + public function test_process_response_precondition_not_met(): void { $request = $this->buildRequest(); @@ -131,7 +131,7 @@ public function test_process_response_precondition_not_met() self::expectException(NoAuthnContextSamlResponseException::class); $this->postBinding->processResponse($request, $idp, $sp); } - public function test_process_response_authn_failed() + public function test_process_response_authn_failed(): void { $request = $this->buildRequest(); @@ -148,7 +148,7 @@ public function test_process_response_authn_failed() self::expectException(AuthnFailedSamlResponseException::class); $this->postBinding->processResponse($request, $idp, $sp); } - public function test_process_response_other_precondition_not_met() + public function test_process_response_other_precondition_not_met(): void { $request = $this->buildRequest(); diff --git a/src/Tests/Unit/SAML2/AuthnRequestTest.php b/src/Tests/Unit/SAML2/AuthnRequestTest.php index 75b946da..b7c686bd 100644 --- a/src/Tests/Unit/SAML2/AuthnRequestTest.php +++ b/src/Tests/Unit/SAML2/AuthnRequestTest.php @@ -55,7 +55,7 @@ class AuthnRequestTest extends TestCase AUTHNREQUEST_NO_SUBJECT; - private string $authRequestIsPassiveFalseAndNoForceAuthnFalse = << AUTHNREQUEST_IS_PASSIVE_F_AND_FORCE_AUTH_F; - private string $authRequestIsPassiveAndForceAuthnFalse = << AUTHNREQUEST_IS_PASSIVE_AND_FORCE_AUTHN_F; - private string $authRequestIsPassiveFalseAndForceAuthn = <<assertEquals($forceAuthn, $authnRequest->isForceAuthn()); } - public function provideIsPassiveAndForceAuthnCombinations(): array + public static function provideIsPassiveAndForceAuthnCombinations(): array { return [ - 'isPassive false and ForceAuthn false' => [$this->authRequestIsPassiveFalseAndNoForceAuthnFalse, false, false], - 'isPassive and ForceAuthn false' => [$this->authRequestIsPassiveAndForceAuthnFalse, true, false], - 'isPassive false and ForceAuthn' => [$this->authRequestIsPassiveFalseAndForceAuthn, false, true] + 'isPassive false and ForceAuthn false' => [self::$authRequestIsPassiveFalseAndNoForceAuthnFalse, false, false], + 'isPassive and ForceAuthn false' => [self::$authRequestIsPassiveAndForceAuthnFalse, true, false], + 'isPassive false and ForceAuthn' => [self::$authRequestIsPassiveFalseAndForceAuthn, false, true] ]; } diff --git a/src/Value/DateTime.php b/src/Value/DateTime.php index b595d864..982f0a69 100644 --- a/src/Value/DateTime.php +++ b/src/Value/DateTime.php @@ -24,7 +24,7 @@ use Surfnet\SamlBundle\Exception\InvalidArgumentException; /** - * @SuppressWarnings(PHPMD.TooManyPublicMethods) due to comparison methods + * @SuppressWarnings("PHPMD.TooManyPublicMethods") due to comparison methods */ class DateTime implements Stringable { @@ -33,16 +33,11 @@ class DateTime implements Stringable */ final public const FORMAT = DATE_ATOM; - /** - * Allows for mocking of time. - */ - private static ?self $now = null; - private readonly CoreDateTime $dateTime; public static function now(): self { - return self::$now ?: new self(new CoreDateTime); + return new self(new CoreDateTime); } /** From e4691563c2228491c4062512618425ed97517868 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 6 Nov 2025 14:47:06 +0100 Subject: [PATCH 4/6] Coding standards: auto remove unused imports and require `use`. Coding standards: Add AlphabeticallySortedUses --- ci/qa/phpcbf | 2 +- ci/qa/phpcs | 2 +- ci/qa/phpcs.xml | 9 +++ composer.json | 2 + .../SurfnetSamlExtension.php | 4 +- .../Exception/InvalidRequestException.php | 3 +- src/Http/ReceivedAuthnRequestPost.php | 3 +- src/Metadata/MetadataFactory.php | 2 +- src/Monolog/SamlAuthenticationLogger.php | 19 +++--- src/SAML2/AuthnRequestFactory.php | 3 +- .../Extensions/GsspUserAttributesChunk.php | 1 - src/SAML2/ReceivedAuthnRequest.php | 3 +- .../AuthenticatedSessionStateHandler.php | 5 +- .../Authentication/SamlAuthenticator.php | 3 - src/Signing/SignatureVerifier.php | 3 +- src/Tests/Bootstrap.php | 3 +- .../Extensions/AuthnRequestExtensionsTest.php | 1 - .../Metadata/MetadataFactoryTest.php | 5 +- src/Tests/Component/Metadata/XsdValidator.php | 1 - .../Component/Metadata/XsdValidatorTest.php | 1 - .../Signing/AuthnRequestSigningTest.php | 34 +++++----- src/Tests/TestSaml2Container.php | 2 +- .../Unit/Http/HttpBindingFactoryTest.php | 23 +++---- src/Tests/Unit/Http/RedirectBindingTest.php | 43 +++++++------ .../Unit/Metadata/MetadataFactoryTest.php | 5 +- .../Monolog/SamlAuthenticationLoggerTest.php | 6 +- .../Attribute/AttributeDictionaryTest.php | 34 +++++----- .../ConfigurableAttributeSetFactoryTest.php | 29 +++++---- .../Unit/SAML2/AuthnRequestFactoryTest.php | 14 +++-- src/Tests/Unit/SAML2/AuthnRequestTest.php | 23 ++++--- .../SAML2/ReceivedAuthnRequestPostTest.php | 9 +-- .../ReceivedAuthnRequestQueryStringTest.php | 63 ++++++++++--------- .../Assertion/AssertionAdapterTest.php | 26 ++++---- .../Response/Assertion/InResponseToTest.php | 17 ++--- .../Unit/Security/SamlAuthenticatorTest.php | 17 ++--- 35 files changed, 224 insertions(+), 196 deletions(-) diff --git a/ci/qa/phpcbf b/ci/qa/phpcbf index ff3fa206..138015bd 100755 --- a/ci/qa/phpcbf +++ b/ci/qa/phpcbf @@ -3,4 +3,4 @@ cd $(dirname $0)/../../ # https://github.com/squizlabs/PHP_CodeSniffer/wiki/Fixing-Errors-Automatically -./vendor/bin/phpcbf --standard=ci/qa/phpcs.xml $1 +./vendor/bin/phpcbf --standard=ci/qa/phpcs.xml --extensions=php src $1 diff --git a/ci/qa/phpcs b/ci/qa/phpcs index 3a522b9b..32dbcb22 100755 --- a/ci/qa/phpcs +++ b/ci/qa/phpcs @@ -3,4 +3,4 @@ cd $(dirname $0)/../../ # https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage -./vendor/bin/phpcs --report=full --standard=ci/qa/phpcs.xml --ignore=*/Tests/* --warning-severity=0 --extensions=php src +./vendor/bin/phpcs --report=full --standard=ci/qa/phpcs.xml --warning-severity=0 --extensions=php src diff --git a/ci/qa/phpcs.xml b/ci/qa/phpcs.xml index 7a6955e7..b1a9c10b 100644 --- a/ci/qa/phpcs.xml +++ b/ci/qa/phpcs.xml @@ -15,5 +15,14 @@ + src/Tests/* + + + src/Tests/* + + + + + diff --git a/composer.json b/composer.json index f7e9d067..7c621d46 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ "phpunit/phpunit": "^11.0.0", "rector/rector": "^2.2", "sebastian/exporter": "^6.3", + "slevomat/coding-standard": "^8.24", "squizlabs/php_codesniffer": "^4.0", "symfony/phpunit-bridge": "^6.3" }, @@ -68,6 +69,7 @@ "config": { "sort-packages": true, "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, "phpstan/extension-installer": true } } diff --git a/src/DependencyInjection/SurfnetSamlExtension.php b/src/DependencyInjection/SurfnetSamlExtension.php index b5e30adc..8763b4e4 100644 --- a/src/DependencyInjection/SurfnetSamlExtension.php +++ b/src/DependencyInjection/SurfnetSamlExtension.php @@ -24,11 +24,11 @@ use Surfnet\SamlBundle\Entity\StaticServiceProviderRepository; use Surfnet\SamlBundle\Exception\SamlInvalidConfigurationException; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; use function array_key_exists; class SurfnetSamlExtension extends Extension diff --git a/src/Http/Exception/InvalidRequestException.php b/src/Http/Exception/InvalidRequestException.php index ebcc767a..da90df96 100644 --- a/src/Http/Exception/InvalidRequestException.php +++ b/src/Http/Exception/InvalidRequestException.php @@ -18,9 +18,8 @@ namespace Surfnet\SamlBundle\Http\Exception; -use Surfnet\SamlBundle\Exception\Exception; use Surfnet\SamlBundle\Exception\RuntimeException; -class InvalidRequestException extends RuntimeException implements Exception +class InvalidRequestException extends RuntimeException { } diff --git a/src/Http/ReceivedAuthnRequestPost.php b/src/Http/ReceivedAuthnRequestPost.php index b44af4d9..cebf09db 100644 --- a/src/Http/ReceivedAuthnRequestPost.php +++ b/src/Http/ReceivedAuthnRequestPost.php @@ -18,7 +18,6 @@ namespace Surfnet\SamlBundle\Http; -use Exception; use RobRichards\XMLSecLibs\XMLSecurityKey; use Surfnet\SamlBundle\Http\Exception\InvalidRequestException; use Surfnet\SamlBundle\SAML2\ReceivedAuthnRequest; @@ -81,7 +80,7 @@ public function getRelayState(): ?string } /** - * @throws Exception when signature is invalid (@see SAML2\Utils::validateSignature) + * @throws \Exception when signature is invalid (@see SAML2\Utils::validateSignature) */ public function verify(XMLSecurityKey $key): bool { diff --git a/src/Metadata/MetadataFactory.php b/src/Metadata/MetadataFactory.php index d0c1aa09..b872b7f3 100644 --- a/src/Metadata/MetadataFactory.php +++ b/src/Metadata/MetadataFactory.php @@ -21,11 +21,11 @@ use SAML2\DOMDocumentFactory; use SAML2\Utilities\Certificate; use SAML2\Utilities\File; +use Surfnet\SamlBundle\Exception\RuntimeException; use Surfnet\SamlBundle\Service\SigningService; use Surfnet\SamlBundle\Signing\KeyPair; use Symfony\Component\Routing\RouterInterface; use Twig\Environment; -use Surfnet\SamlBundle\Exception\RuntimeException; class MetadataFactory { diff --git a/src/Monolog/SamlAuthenticationLogger.php b/src/Monolog/SamlAuthenticationLogger.php index 8d2e140a..2c8dc131 100644 --- a/src/Monolog/SamlAuthenticationLogger.php +++ b/src/Monolog/SamlAuthenticationLogger.php @@ -20,6 +20,7 @@ namespace Surfnet\SamlBundle\Monolog; use Psr\Log\LoggerInterface; +use Stringable; /** * Decorates a PSR logger and adds information pertaining to a SAML request procedure to each message's context. @@ -45,47 +46,47 @@ public function forAuthentication(string $requestId): self return $logger; } - public function emergency(string|\Stringable $message, array $context = []): void + public function emergency(string|Stringable $message, array $context = []): void { $this->logger->emergency($message, $this->modifyContext($context)); } - public function alert(string|\Stringable $message, array $context = []): void + public function alert(string|Stringable $message, array $context = []): void { $this->logger->alert($message, $this->modifyContext($context)); } - public function critical(string|\Stringable $message, array $context = []): void + public function critical(string|Stringable $message, array $context = []): void { $this->logger->critical($message, $this->modifyContext($context)); } - public function error(string|\Stringable $message, array $context = []): void + public function error(string|Stringable $message, array $context = []): void { $this->logger->error($message, $this->modifyContext($context)); } - public function warning(string|\Stringable $message, array $context = []): void + public function warning(string|Stringable $message, array $context = []): void { $this->logger->warning($message, $this->modifyContext($context)); } - public function notice(string|\Stringable $message, array $context = []): void + public function notice(string|Stringable $message, array $context = []): void { $this->logger->notice($message, $this->modifyContext($context)); } - public function info(string|\Stringable $message, array $context = []): void + public function info(string|Stringable $message, array $context = []): void { $this->logger->info($message, $this->modifyContext($context)); } - public function debug(string|\Stringable $message, array $context = []): void + public function debug(string|Stringable $message, array $context = []): void { $this->logger->debug($message, $this->modifyContext($context)); } - public function log($level, string|\Stringable $message, array $context = []): void + public function log($level, string|Stringable $message, array $context = []): void { $this->logger->log($level, $message, $this->modifyContext($context)); } diff --git a/src/SAML2/AuthnRequestFactory.php b/src/SAML2/AuthnRequestFactory.php index 9b998a38..c2c08f7a 100644 --- a/src/SAML2/AuthnRequestFactory.php +++ b/src/SAML2/AuthnRequestFactory.php @@ -18,7 +18,6 @@ namespace Surfnet\SamlBundle\SAML2; -use Exception; use RobRichards\XMLSecLibs\XMLSecurityKey; use SAML2\AuthnRequest as SAML2AuthnRequest; use SAML2\Certificate\PrivateKeyLoader; @@ -70,7 +69,7 @@ public static function createFromHttpRequest(Request $httpRequest): AuthnRequest } /** - * @throws Exception + * @throws \Exception */ private static function createAuthnRequestFromHttpRequest( Request $httpRequest diff --git a/src/SAML2/Extensions/GsspUserAttributesChunk.php b/src/SAML2/Extensions/GsspUserAttributesChunk.php index ae3b99b4..f4d712f0 100644 --- a/src/SAML2/Extensions/GsspUserAttributesChunk.php +++ b/src/SAML2/Extensions/GsspUserAttributesChunk.php @@ -19,7 +19,6 @@ use DOMDocument; use DOMElement; -use DOMNode; use SAML2\Utils; class GsspUserAttributesChunk extends Chunk diff --git a/src/SAML2/ReceivedAuthnRequest.php b/src/SAML2/ReceivedAuthnRequest.php index 07a6bee4..c154cdbe 100644 --- a/src/SAML2/ReceivedAuthnRequest.php +++ b/src/SAML2/ReceivedAuthnRequest.php @@ -18,7 +18,6 @@ namespace Surfnet\SamlBundle\SAML2; -use Exception; use RobRichards\XMLSecLibs\XMLSecurityKey; use SAML2\AuthnRequest as SAML2AuthnRequest; use SAML2\Constants; @@ -166,7 +165,7 @@ public function getScopingRequesterIds(): array } /** - * @throws Exception when signature is invalid (@see SAML2\Utils::validateSignature) + * @throws \Exception when signature is invalid (@see SAML2\Utils::validateSignature) */ public function verify(XMLSecurityKey $key): bool { diff --git a/src/Security/Authentication/AuthenticatedSessionStateHandler.php b/src/Security/Authentication/AuthenticatedSessionStateHandler.php index c3dfa655..4fcc63f5 100644 --- a/src/Security/Authentication/AuthenticatedSessionStateHandler.php +++ b/src/Security/Authentication/AuthenticatedSessionStateHandler.php @@ -18,7 +18,6 @@ namespace Surfnet\SamlBundle\Security\Authentication; -use Surfnet\SamlBundle\Security\Exception\LogicException; use Surfnet\SamlBundle\Value\DateTime; interface AuthenticatedSessionStateHandler @@ -26,7 +25,7 @@ interface AuthenticatedSessionStateHandler /** * Sets the moment at which the user was authenticated * - * @throws LogicException when an authentication moment was already logged + * @throws \LogicException when an authentication moment was already logged */ public function logAuthenticationMoment(): void; @@ -35,7 +34,7 @@ public function isAuthenticationMomentLogged(): bool; /** * Gets the moment at which the user was authenticated * - * @throws LogicException when no authentication moment was logged + * @throws \LogicException when no authentication moment was logged */ public function getAuthenticationMoment(): DateTime; diff --git a/src/Security/Authentication/SamlAuthenticator.php b/src/Security/Authentication/SamlAuthenticator.php index b2260e53..5855302e 100644 --- a/src/Security/Authentication/SamlAuthenticator.php +++ b/src/Security/Authentication/SamlAuthenticator.php @@ -20,14 +20,11 @@ use Psr\Log\LoggerInterface; use SAML2\Assertion; -use SAML2\Compat\ContainerSingleton; use Surfnet\SamlBundle\Entity\IdentityProvider; use Surfnet\SamlBundle\Entity\ServiceProvider; use Surfnet\SamlBundle\Http\RedirectBinding; use Surfnet\SamlBundle\SAML2\AuthnRequestFactory; -use Surfnet\SamlBundle\SAML2\BridgeContainer; use Surfnet\SamlBundle\Security\Authentication\Handler\AuthenticationHandler; -use Surfnet\SamlBundle\Security\Authentication\Handler\ProcessSamlAuthenticationHandler; use Surfnet\SamlBundle\Security\Authentication\Passport\Badge\SamlAttributesBadge; use Surfnet\SamlBundle\Security\Authentication\Provider\SamlProviderInterface; use Surfnet\SamlBundle\Security\Authentication\Token\SamlToken; diff --git a/src/Signing/SignatureVerifier.php b/src/Signing/SignatureVerifier.php index 409c2d99..081b65a7 100644 --- a/src/Signing/SignatureVerifier.php +++ b/src/Signing/SignatureVerifier.php @@ -18,7 +18,6 @@ namespace Surfnet\SamlBundle\Signing; -use Exception; use Psr\Log\LoggerInterface; use RobRichards\XMLSecLibs\XMLSecurityKey; use SAML2\Certificate\Key; @@ -109,7 +108,7 @@ public function hasValidSignature(AuthnRequest $request, ServiceProvider $servic } /** - * @throws Exception + * @throws \Exception */ public function isSignedWith(AuthnRequest $request, X509 $publicKey): bool { diff --git a/src/Tests/Bootstrap.php b/src/Tests/Bootstrap.php index 87af4fbf..561f44e6 100644 --- a/src/Tests/Bootstrap.php +++ b/src/Tests/Bootstrap.php @@ -17,6 +17,7 @@ */ use Psr\Log\NullLogger; +use SAML2\Compat\ContainerSingleton; use Surfnet\SamlBundle\Tests\TestSaml2Container; require_once __DIR__ . '/../../vendor/autoload.php'; @@ -25,4 +26,4 @@ new NullLogger() ); -SAML2\Compat\ContainerSingleton::setContainer($container); +ContainerSingleton::setContainer($container); diff --git a/src/Tests/Component/Extensions/AuthnRequestExtensionsTest.php b/src/Tests/Component/Extensions/AuthnRequestExtensionsTest.php index d86a1647..1e166a0d 100644 --- a/src/Tests/Component/Extensions/AuthnRequestExtensionsTest.php +++ b/src/Tests/Component/Extensions/AuthnRequestExtensionsTest.php @@ -21,7 +21,6 @@ use DOMDocument; use DOMNode; use DOMXPath; -use Exception; use PHPUnit\Framework\TestCase; use RobRichards\XMLSecLibs\XMLSecEnc; use RobRichards\XMLSecLibs\XMLSecurityDSig; diff --git a/src/Tests/Component/Metadata/MetadataFactoryTest.php b/src/Tests/Component/Metadata/MetadataFactoryTest.php index 29e6f015..ce3d5c58 100644 --- a/src/Tests/Component/Metadata/MetadataFactoryTest.php +++ b/src/Tests/Component/Metadata/MetadataFactoryTest.php @@ -18,6 +18,7 @@ namespace Surfnet\SamlBundle\Tests\Component\Metadata; +use DOMDocument; use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use PHPUnit\Framework\TestCase; @@ -28,8 +29,8 @@ use Surfnet\SamlBundle\Service\SigningService; use Surfnet\SamlBundle\Signing\Signable; use Symfony\Component\Routing\RouterInterface; -use Twig\Loader\ArrayLoader; use Twig\Environment; +use Twig\Loader\ArrayLoader; use function dirname; class MetadataFactoryTest extends TestCase @@ -61,7 +62,7 @@ public function setUp(): void /** * Helper method to assert XML document is valid against XSD schema */ - private function assertXmlIsValidAgainstXsd(\DOMDocument $document, string $xsdPath): void + private function assertXmlIsValidAgainstXsd(DOMDocument $document, string $xsdPath): void { $errors = $this->xsdValidator->validate($document, $xsdPath); diff --git a/src/Tests/Component/Metadata/XsdValidator.php b/src/Tests/Component/Metadata/XsdValidator.php index 95efe8d5..576f16f6 100644 --- a/src/Tests/Component/Metadata/XsdValidator.php +++ b/src/Tests/Component/Metadata/XsdValidator.php @@ -71,4 +71,3 @@ public function isValid(DOMDocument $document, string $xsdPath): bool return empty($this->validate($document, $xsdPath)); } } - diff --git a/src/Tests/Component/Metadata/XsdValidatorTest.php b/src/Tests/Component/Metadata/XsdValidatorTest.php index cc9141c7..b4791f68 100644 --- a/src/Tests/Component/Metadata/XsdValidatorTest.php +++ b/src/Tests/Component/Metadata/XsdValidatorTest.php @@ -124,4 +124,3 @@ public function test_returns_error_for_missing_xsd_file(): void self::assertStringContainsString('not found', $errors[0]); } } - diff --git a/src/Tests/Component/Signing/AuthnRequestSigningTest.php b/src/Tests/Component/Signing/AuthnRequestSigningTest.php index 02e37a63..1fd6a0ae 100644 --- a/src/Tests/Component/Signing/AuthnRequestSigningTest.php +++ b/src/Tests/Component/Signing/AuthnRequestSigningTest.php @@ -18,6 +18,8 @@ namespace Surfnet\SamlBundle\Tests\Component\Signing; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use RobRichards\XMLSecLibs\XMLSecurityKey; @@ -46,9 +48,9 @@ class AuthnRequestSigningTest extends TestCase private ?string $publicKey = null; - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('Signing')] - #[\PHPUnit\Framework\Attributes\Group('Deprecated')] + #[Test] + #[Group('Signing')] + #[Group('Deprecated')] public function deprecated_authn_request_signatures_are_verified_if_the_sender_uses_rfc1738_encoding(): void { $authnRequestWithDefaultEncoding = $this->createSignedAuthnRequest( @@ -70,9 +72,9 @@ public function deprecated_authn_request_signatures_are_verified_if_the_sender_u ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('Signing')] - #[\PHPUnit\Framework\Attributes\Group('Deprecated')] + #[Test] + #[Group('Signing')] + #[Group('Deprecated')] public function deprecated_authn_request_signatures_are_verified_if_the_sender_uses_something_other_than_rfc1738_encoding(): void { $authnRequestWithCustomEncoding = $this->createSignedAuthnRequest( @@ -94,9 +96,9 @@ public function deprecated_authn_request_signatures_are_verified_if_the_sender_u ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('Signing')] - #[\PHPUnit\Framework\Attributes\Group('Deprecated')] + #[Test] + #[Group('Signing')] + #[Group('Deprecated')] public function deprecated_authn_request_signatures_are_not_verified_if_the_data_to_sign_does_not_correspond_with_the_signature_sent(): void { $authnRequestWithModifiedDataToSign = $this->createSignedAuthnRequest( @@ -117,9 +119,9 @@ public function deprecated_authn_request_signatures_are_not_verified_if_the_data ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('Signing')] - #[\PHPUnit\Framework\Attributes\Group('Deprecated')] + #[Test] + #[Group('Signing')] + #[Group('Deprecated')] public function deprecated_authn_request_signatures_are_not_verified_if_the_parameter_order_of_the_sent_query_is_not_correct(): void { $authnRequestWithModifiedDataToSign = $this->createSignedAuthnRequest( @@ -139,8 +141,8 @@ public function deprecated_authn_request_signatures_are_not_verified_if_the_para ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('Signing')] + #[Test] + #[Group('Signing')] public function a_received_authn_requests_signature_is_verified_regardless_of_its_encoding(): void { $signatureVerifier = new SignatureVerifier(new KeyLoader, new NullLogger); @@ -193,8 +195,8 @@ public function a_received_authn_requests_signature_is_verified_regardless_of_it ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('Signing')] + #[Test] + #[Group('Signing')] public function a_received_authn_requests_signature_is_not_verified_if_the_data_to_sign_does_not_correspond_with_the_signature_sent(): void { $signatureVerifier = new SignatureVerifier(new KeyLoader, new NullLogger); diff --git a/src/Tests/TestSaml2Container.php b/src/Tests/TestSaml2Container.php index ac9d2a26..75436ca9 100644 --- a/src/Tests/TestSaml2Container.php +++ b/src/Tests/TestSaml2Container.php @@ -19,8 +19,8 @@ namespace Surfnet\SamlBundle\Tests; use BadMethodCallException; -use SAML2\Compat\AbstractContainer; use Psr\Log\LoggerInterface; +use SAML2\Compat\AbstractContainer; class TestSaml2Container extends AbstractContainer { diff --git a/src/Tests/Unit/Http/HttpBindingFactoryTest.php b/src/Tests/Unit/Http/HttpBindingFactoryTest.php index 80316e60..56d18388 100644 --- a/src/Tests/Unit/Http/HttpBindingFactoryTest.php +++ b/src/Tests/Unit/Http/HttpBindingFactoryTest.php @@ -20,12 +20,13 @@ use Mockery; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Surfnet\SamlBundle\Exception\InvalidArgumentException; use Surfnet\SamlBundle\Http\HttpBindingFactory; use Surfnet\SamlBundle\Http\PostBinding; use Surfnet\SamlBundle\Http\RedirectBinding; -use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; class HttpBindingFactoryTest extends TestCase @@ -41,8 +42,8 @@ public function setUp(): void $this->factory = new HttpBindingFactory($redirectBinding, $postBinding); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_redirect_binding_can_be_built(): void { $request = new Request( @@ -58,8 +59,8 @@ public function a_redirect_binding_can_be_built(): void $this->assertInstanceOf(RedirectBinding::class, $binding); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_post_binding_can_be_built(): void { $request = new Request( @@ -75,8 +76,8 @@ public function a_post_binding_can_be_built(): void $this->assertInstanceOf(PostBinding::class, $binding); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_put_binding_can_not_be_built(): void { $this->expectExceptionMessage("Request type of \"PUT\" is not supported."); @@ -93,8 +94,8 @@ public function a_put_binding_can_not_be_built(): void $this->factory->build($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function an_invalid_post_authn_request_is_rejected(): void { $this->expectExceptionMessage("POST-binding is supported for SAMLRequest."); @@ -111,8 +112,8 @@ public function an_invalid_post_authn_request_is_rejected(): void $this->factory->build($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function an_invalid_get_authn_request_is_rejected(): void { $this->expectExceptionMessage("Redirect binding is supported for SAMLRequest and Response."); diff --git a/src/Tests/Unit/Http/RedirectBindingTest.php b/src/Tests/Unit/Http/RedirectBindingTest.php index d4b5728a..32f54fef 100644 --- a/src/Tests/Unit/Http/RedirectBindingTest.php +++ b/src/Tests/Unit/Http/RedirectBindingTest.php @@ -20,6 +20,9 @@ use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\Compat\ContainerSingleton; use SAML2\Compat\MockContainer; @@ -65,9 +68,9 @@ public function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('nonGetMethodProvider')] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[DataProvider('nonGetMethodProvider')] + #[Group('http')] public function a_signed_authn_request_cannot_be_received_from_a_request_that_is_not_a_get_request(string $nonGetMethod): void { $this->expectException(BadRequestHttpException::class); @@ -84,8 +87,8 @@ public function a_signed_authn_request_cannot_be_received_from_a_request_that_is $redirectBinding->receiveSignedAuthnRequestFrom($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_signed_authn_request_cannot_be_received_from_a_request_that_has_no_signed_saml_request(): void { $this->expectException(UnsignedRequestException::class); @@ -102,8 +105,8 @@ public function a_signed_authn_request_cannot_be_received_from_a_request_that_ha $redirectBinding->receiveSignedAuthnRequestFrom($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_signed_authn_request_cannot_be_received_if_the_service_provider_in_the_authn_request_is_unknown(): void { $this->expectException(UnknownServiceProviderException::class); @@ -136,8 +139,8 @@ public function a_signed_authn_request_cannot_be_received_if_the_service_provide /** * Signed AuthNRequests destination MUST match the request URI */ - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_signed_authn_requests_destination_must_match_request_uri(): void { $this->expectException(BadRequestHttpException::class); @@ -165,8 +168,8 @@ public function a_signed_authn_requests_destination_must_match_request_uri(): vo /** * Signed AuthNRequests destination have a destination */ - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_signed_authn_requests_must_carry_a_destination(): void { $this->expectException(BadRequestHttpException::class); @@ -191,8 +194,8 @@ public function a_signed_authn_requests_must_carry_a_destination(): void $redirectBinding->receiveSignedAuthnRequestFrom($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_signed_authn_request_cannot_be_received_if_the_signature_is_invalid(): void { $this->expectException(SignatureValidationFailedException::class); @@ -230,9 +233,9 @@ public function a_signed_authn_request_cannot_be_received_if_the_signature_is_in $redirectBinding = new RedirectBinding($mockSignatureVerifier, $mockEntityRepository); $redirectBinding->receiveSignedAuthnRequestFrom($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('nonGetMethodProvider')] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[DataProvider('nonGetMethodProvider')] + #[Group('http')] public function a_unsigned_authn_request_cannot_be_received_from_a_request_that_is_not_a_get_request(string $nonGetMethod): void { $this->expectException(BadRequestHttpException::class); @@ -248,8 +251,8 @@ public function a_unsigned_authn_request_cannot_be_received_from_a_request_that_ $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_unsigned_authn_request_cannot_be_received_if_the_service_provider_in_the_authn_request_is_unknown(): void { $this->expectException(UnknownServiceProviderException::class); @@ -276,8 +279,8 @@ public function a_unsigned_authn_request_cannot_be_received_if_the_service_provi $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('http')] + #[Test] + #[Group('http')] public function a_unsigned_authn_request_cannot_be_received_if_the_service_provider_in_the_authn_request_is_unknown_with_destination(): void { $this->expectException(UnknownServiceProviderException::class); diff --git a/src/Tests/Unit/Metadata/MetadataFactoryTest.php b/src/Tests/Unit/Metadata/MetadataFactoryTest.php index 23305269..7e4e65ba 100644 --- a/src/Tests/Unit/Metadata/MetadataFactoryTest.php +++ b/src/Tests/Unit/Metadata/MetadataFactoryTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use ReflectionMethod; +use RuntimeException; use Surfnet\SamlBundle\Metadata\MetadataFactory; class MetadataFactoryTest extends TestCase @@ -31,8 +32,8 @@ public function testGetCertificateData(): void // Test with an invalid certificate $invalidPublicKeyFile = __DIR__ . '/invalid_certificate.pem'; // File with invalid certificate - $this->expectException(\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Could not parse PEM certificate in ' . $invalidPublicKeyFile); $reflectionMethod->invoke($metadataFactoryMock, $invalidPublicKeyFile); } -} \ No newline at end of file +} diff --git a/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php b/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php index da6fbbfa..6e17b090 100644 --- a/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php +++ b/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php @@ -20,16 +20,16 @@ use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; -use Surfnet\SamlBundle\Exception\RuntimeException; use Surfnet\SamlBundle\Monolog\SamlAuthenticationLogger; final class SamlAuthenticationLoggerTest extends TestCase { use MockeryPHPUnitIntegration; - #[\PHPUnit\Framework\Attributes\Test] + #[Test] public function it_returns_a_logger_for_an_authentication(): void { $requestId = md5('boesboes'); @@ -42,7 +42,7 @@ public function it_returns_a_logger_for_an_authentication(): void $logger->emergency('message2'); } - #[\PHPUnit\Framework\Attributes\Test] + #[Test] public function it_does_not_throw_when_no_authentication(): void { $innerLogger = m::mock(LoggerInterface::class); diff --git a/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php b/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php index af15b9e4..dd2d48c9 100644 --- a/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php +++ b/src/Tests/Unit/SAML2/Attribute/AttributeDictionaryTest.php @@ -18,6 +18,8 @@ namespace Surfnet\SamlBundle\Tests\Unit\SAML2\Attribute; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Surfnet\SamlBundle\Exception\UnknownUrnException; use Surfnet\SamlBundle\SAML2\Attribute\AttributeDefinition; @@ -25,8 +27,8 @@ class AttributeDictionaryTest extends TestCase { - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function finds_no_definition_when_no_definition_given(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -41,8 +43,8 @@ public function finds_no_definition_when_no_definition_given(): void ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function finds_no_definition_when_urn_matches_no_mace_urn(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -65,8 +67,8 @@ public function finds_no_definition_when_urn_matches_no_mace_urn(): void ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function finds_no_definition_when_urn_matches_no_oid_urn(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -89,8 +91,8 @@ public function finds_no_definition_when_urn_matches_no_oid_urn(): void ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function finds_definition_when_urn_matches_urn_mace(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -112,8 +114,8 @@ public function finds_definition_when_urn_matches_urn_mace(): void ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function finds_definition_when_urn_matches_urn_oid(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -135,8 +137,8 @@ public function finds_definition_when_urn_matches_urn_oid(): void ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function shouldThrowExceptionForUnknownAttrib(): void { $this->expectException(UnknownUrnException::class); @@ -152,16 +154,16 @@ public function shouldThrowExceptionForUnknownAttrib(): void $attributeDictionary->getAttributeDefinitionByUrn('unknown:0.0.0.0.0'); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function shouldIgnoreUnknownAttributes(): void { $attributeDictionary = new AttributeDictionary(true); $this->assertTrue($attributeDictionary->ignoreUnknownAttributes()); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AttributeDictionary')] + #[Test] + #[Group('AttributeDictionary')] public function shouldNotIgnoreUnknownAttributes(): void { $attributeDictionary = new AttributeDictionary(); diff --git a/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php b/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php index 6a6a3522..a773a4f6 100644 --- a/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php +++ b/src/Tests/Unit/SAML2/Attribute/ConfigurableAttributeSetFactoryTest.php @@ -18,6 +18,9 @@ namespace Surfnet\SamlBundle\Tests\Unit\SAML2\Attribute; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\Assertion; use SAML2\Compat\ContainerSingleton; @@ -37,9 +40,9 @@ protected function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] - #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] + #[Test] + #[Group('AssertionAdapter')] + #[Group('AttributeSet')] public function which_attribute_set_is_created_from_a_saml_assertion_is_configurable(): void { ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate(self::DUMMY_ATTRIBUTE_SET_CLASS); @@ -49,9 +52,9 @@ public function which_attribute_set_is_created_from_a_saml_assertion_is_configur $this->assertInstanceOf(self::DUMMY_ATTRIBUTE_SET_CLASS, $attributeSet); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] - #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] + #[Test] + #[Group('AssertionAdapter')] + #[Group('AttributeSet')] public function which_attribute_set_is_created_from_attributes_is_configurable(): void { ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate(self::DUMMY_ATTRIBUTE_SET_CLASS); @@ -61,10 +64,10 @@ public function which_attribute_set_is_created_from_attributes_is_configurable() $this->assertInstanceOf(self::DUMMY_ATTRIBUTE_SET_CLASS, $attributeSet); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('nonOrEmptyStringProvider')] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] - #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] + #[Test] + #[DataProvider('nonOrEmptyStringProvider')] + #[Group('AssertionAdapter')] + #[Group('AttributeSet')] public function the_attribute_set_to_use_can_only_be_represented_as_a_non_empty_string(int|float|bool|array|stdClass|string $nonOrEmptyString): void { $this->expectException(InvalidArgumentException::class); @@ -73,9 +76,9 @@ public function the_attribute_set_to_use_can_only_be_represented_as_a_non_empty_ ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate($nonOrEmptyString); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] - #[\PHPUnit\Framework\Attributes\Group('AttributeSet')] + #[Test] + #[Group('AssertionAdapter')] + #[Group('AttributeSet')] public function the_attribute_set_to_use_has_to_implement_attribute_set_factory(): void { $this->expectException(InvalidArgumentException::class); diff --git a/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php b/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php index c93bf1ea..31a2a76e 100644 --- a/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php +++ b/src/Tests/Unit/SAML2/AuthnRequestFactoryTest.php @@ -20,6 +20,8 @@ use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\Configuration\PrivateKey; use Surfnet\SamlBundle\Entity\IdentityProvider; @@ -33,8 +35,8 @@ class AuthnRequestFactoryTest extends TestCase { use MockeryPHPUnitIntegration; - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[Group('saml2')] public function an_exception_is_thrown_when_a_request_is_not_properly_base64_encoded(): void { $this->expectExceptionMessage("Failed decoding the request, did not receive a valid base64 string"); @@ -49,8 +51,8 @@ public function an_exception_is_thrown_when_a_request_is_not_properly_base64_enc AuthnRequestFactory::createFromHttpRequest($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[Group('saml2')] public function an_exception_is_thrown_when_a_request_cannot_be_inflated(): void { $this->expectExceptionMessage("Failed inflating the request;"); @@ -65,8 +67,8 @@ public function an_exception_is_thrown_when_a_request_cannot_be_inflated(): void AuthnRequestFactory::createFromHttpRequest($request); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[Group('saml2')] public function verify_force_authn_works_as_intended(): void { $sp = m::mock(ServiceProvider::class); diff --git a/src/Tests/Unit/SAML2/AuthnRequestTest.php b/src/Tests/Unit/SAML2/AuthnRequestTest.php index b7c686bd..dbccb67c 100644 --- a/src/Tests/Unit/SAML2/AuthnRequestTest.php +++ b/src/Tests/Unit/SAML2/AuthnRequestTest.php @@ -18,6 +18,9 @@ namespace Surfnet\SamlBundle\Tests\Unit\SAML2; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\AuthnRequest as SAML2AuthnRequest; use SAML2\DOMDocumentFactory; @@ -98,9 +101,9 @@ class AuthnRequestTest extends TestCase private string $acsUrl = 'https://example.org'; - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('provideNameIDAndFormatCombinations')] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[DataProvider('provideNameIDAndFormatCombinations')] + #[Group('saml2')] public function setting_the_subject_generates_valid_xml(string $nameId, ?string $format): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestNoSubject); @@ -112,8 +115,8 @@ public function setting_the_subject_generates_valid_xml(string $nameId, ?string $this->assertXmlStringEqualsXmlString($this->authRequestWithSubject, $authnRequest->getUnsignedXML()); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[Group('saml2')] public function the_nameid_and_format_can_be_retrieved_from_the_authnrequest(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestWithSubject); @@ -129,8 +132,8 @@ public function the_nameid_and_format_can_be_retrieved_from_the_authnrequest(): $this->assertEquals($nameId->getFormat(), $authnRequest->getNameIdFormat()); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[Group('saml2')] public function the_acs_url_can_be_retrieved_from_the_authnrequest(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestWithSubject); @@ -141,9 +144,9 @@ public function the_acs_url_can_be_retrieved_from_the_authnrequest(): void $this->assertEquals($this->acsUrl, $authnRequest->getAssertionConsumerServiceURL()); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('provideIsPassiveAndForceAuthnCombinations')] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[DataProvider('provideIsPassiveAndForceAuthnCombinations')] + #[Group('saml2')] public function is_passive_and_force_authn_can_be_retrieved_from_the_authnrequest(string $xml, bool $isPassive, bool $forceAuthn): void { $domDocument = DOMDocumentFactory::fromString($xml); diff --git a/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php b/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php index c23c3830..c9ca562d 100644 --- a/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php +++ b/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php @@ -18,13 +18,14 @@ namespace Tests\Unit\SAML2; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Surfnet\SamlBundle\Http\Exception\InvalidRequestException; use Surfnet\SamlBundle\Http\ReceivedAuthnRequestPost; class ReceivedAuthnRequestPostTest extends TestCase { - #[\PHPUnit\Framework\Attributes\Test] + #[Test] public function it_can_decode_a_signed_saml_request(): void { $samlRequest = str_replace(PHP_EOL, '', file_get_contents(__DIR__ . '/Resources/valid-signed.xml')); @@ -36,7 +37,7 @@ public function it_can_decode_a_signed_saml_request(): void $this->assertEquals('/index.php', $authnRequest->getRelayState()); } - #[\PHPUnit\Framework\Attributes\Test] + #[Test] public function it_can_decode_a_signed_saml_request_from_adfs_origin(): void { $samlRequest = str_replace(PHP_EOL, '', file_get_contents(__DIR__ . '/Resources/valid-signed-adfs.xml')); @@ -48,7 +49,7 @@ public function it_can_decode_a_signed_saml_request_from_adfs_origin(): void $this->assertInstanceOf(ReceivedAuthnRequestPost::class, $parsed); } - #[\PHPUnit\Framework\Attributes\Test] + #[Test] public function it_can_decode_an_usigned_saml_request(): void { $samlRequest = str_replace(PHP_EOL, '', file_get_contents(__DIR__ . '/Resources/valid-unsigned.xml')); @@ -60,7 +61,7 @@ public function it_can_decode_an_usigned_saml_request(): void $this->assertEquals('/index.php', $authnRequest->getRelayState()); } - #[\PHPUnit\Framework\Attributes\Test] + #[Test] public function it_rejects_malformed_saml_request(): void { $this->expectExceptionMessage("Failed decoding SAML request, did not receive a valid base64 string"); diff --git a/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php b/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php index c753ac6c..5c48ca4e 100644 --- a/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php +++ b/src/Tests/Unit/SAML2/ReceivedAuthnRequestQueryStringTest.php @@ -18,6 +18,9 @@ namespace Tests\Unit\SAML2; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\AuthnRequest as SAML2AuthnRequest; use SAML2\DOMDocumentFactory; @@ -45,9 +48,9 @@ class ReceivedAuthnRequestQueryStringTest extends TestCase * * @param $nonOrEmptyString */ - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('emptyStringProvider')] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[DataProvider('emptyStringProvider')] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_be_parsed_from_empty_strings(string $nonOrEmptyString): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -56,8 +59,8 @@ public function a_received_authn_request_query_string_cannot_be_parsed_from_empt ReceivedAuthnRequestQueryString::parse($nonOrEmptyString); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_valid_key_value_pairs(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -66,8 +69,8 @@ public function a_received_authn_request_query_string_must_contain_valid_key_val ReceivedAuthnRequestQueryString::parse('a-key-without-a-value'); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_a_base64_encoded_saml_request(): void { $this->expectException('\\' . InvalidRequestException::class); @@ -84,9 +87,9 @@ public function a_received_authn_request_query_string_must_contain_a_base64_enco * @param $doubleParameterName * @param $queryStringWithDoubleParameter */ - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('queryStringWithRepeatedSamlParametersProvider')] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[DataProvider('queryStringWithRepeatedSamlParametersProvider')] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_saml_parameter_twice( string $doubleParameterName, string $queryStringWithDoubleParameter @@ -97,8 +100,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_saml_para ReceivedAuthnRequestQueryString::parse($queryStringWithDoubleParameter); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_a_saml_request(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -111,8 +114,8 @@ public function a_received_authn_request_query_string_must_contain_a_saml_reques ReceivedAuthnRequestQueryString::parse($queryStringWithoutSamlRequest); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_signature_algorithm_without_a_signature(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -125,8 +128,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureAlgorithmWithoutSignature); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_signature_without_a_signature_algorithm(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -139,8 +142,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureWithoutSignatureAlgorithm); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_signature_that_is_not_properly_base64_encoded(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -154,8 +157,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureWithoutSignatureAlgorithm); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_signed_query_string_can_be_acquired_from_a_received_authn_request_query_string(): void { $expectedSignedQueryString = ReceivedAuthnRequestQueryString::PARAMETER_REQUEST . '=' . urlencode(base64_encode('saml-request')) @@ -171,8 +174,8 @@ public function a_signed_query_string_can_be_acquired_from_a_received_authn_requ $this->assertEquals($expectedSignedQueryString, $actualQueryString); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function query_parameters_that_are_not_used_for_a_saml_message_are_ignored_when_creating_a_signed_query_string(): void { $arbitraryParameterToIgnore = 'arbitraryParameter=this-should-be-ignored'; @@ -194,8 +197,8 @@ public function query_parameters_that_are_not_used_for_a_saml_message_are_ignore ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_decoded_signature_can_be_acquired_from_a_received_authn_request_query_string(): void { $signature = 'signature'; @@ -216,8 +219,8 @@ public function a_decoded_signature_can_be_acquired_from_a_received_authn_reques ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_decoded_saml_request_can_be_acquired_from_a_received_authn_request_query_string(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestNoSubject); @@ -238,8 +241,8 @@ public function a_decoded_saml_request_can_be_acquired_from_a_received_authn_req ); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function a_saml_request_cannot_be_decoded_from_a_received_authn_request_query_string_if_it_was_not_properly_gzipped(): void { $this->expectException('\\' . InvalidRequestException::class); @@ -253,8 +256,8 @@ public function a_saml_request_cannot_be_decoded_from_a_received_authn_request_q $query->getDecodedSamlRequest(); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AuthnRequest')] + #[Test] + #[Group('AuthnRequest')] public function parameters_can_be_queried_from_the_received_authn_request_query(): void { $samlRequest = urlencode(base64_encode('encoded-saml-request')); diff --git a/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php b/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php index dcf96f33..e6d7f4f6 100644 --- a/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php +++ b/src/Tests/Unit/SAML2/Response/Assertion/AssertionAdapterTest.php @@ -20,6 +20,8 @@ use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\Assertion; use Surfnet\SamlBundle\Exception\UnknownUrnException; @@ -32,8 +34,8 @@ class AssertionAdapterTest extends TestCase { use MockeryPHPUnitIntegration; - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[Test] + #[Group('AssertionAdapter')] public function presence_of_attribute_can_be_confirmed_based_on_mace_urn_attribute_definition(): void { @@ -60,8 +62,8 @@ public function presence_of_attribute_can_be_confirmed_based_on_mace_urn_attribu $this->assertTrue($attributeIsInSet, 'Expected attribute to be part of AttributeSet, but it is not'); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[Test] + #[Group('AssertionAdapter')] public function presence_of_attribute_can_be_confirmed_based_on_oid_urn_attribute_definition(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -87,8 +89,8 @@ public function presence_of_attribute_can_be_confirmed_based_on_oid_urn_attribut $this->assertTrue($attributeIsInSet, 'Expected attribute to be part of AttributeSet, but it is not'); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[Test] + #[Group('AssertionAdapter')] public function no_presence_of_attribute_can_be_confirmed_if_no_attribute_definition_found(): void { $this->expectException(UnknownUrnException::class); @@ -113,8 +115,8 @@ public function no_presence_of_attribute_can_be_confirmed_if_no_attribute_defini $attributeSet->contains($attributeExpectedNotToBeContained); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[Test] + #[Group('AssertionAdapter')] public function attribute_set_is_empty_if_no_attributes_found(): void { $assertion = m::mock(Assertion::class); @@ -128,8 +130,8 @@ public function attribute_set_is_empty_if_no_attributes_found(): void $this->assertCount(0, $attributeSet, 'Expected attribute set to be empty, but it is not'); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[Test] + #[Group('AssertionAdapter')] public function attribute_set_has_content_when_attributes_found(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; @@ -152,8 +154,8 @@ public function attribute_set_has_content_when_attributes_found(): void $this->assertCount(1, $attributeSet, 'Expected attribute AttributeSet to have content, but it does not'); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('AssertionAdapter')] + #[Test] + #[Group('AssertionAdapter')] public function attribute_set_has_no_duplicate_attribute_definitions_when_same_attributes_found(): void { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; diff --git a/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php b/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php index d4e6b45f..705fb050 100644 --- a/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php +++ b/src/Tests/Unit/SAML2/Response/Assertion/InResponseToTest.php @@ -18,6 +18,9 @@ namespace Surfnet\SamlBundle\Tests\Unit\SAML2\Response\Assertion; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use SAML2\Assertion; use SAML2\Compat\ContainerSingleton; @@ -29,19 +32,19 @@ class InResponseToTest extends TestCase { - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\DataProvider('provideAssertionsWithoutInResponseTo')] - #[\PHPUnit\Framework\Attributes\Group('saml2-response')] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[DataProvider('provideAssertionsWithoutInResponseTo')] + #[Group('saml2-response')] + #[Group('saml2')] public function assertions_without_in_response_to_are_tested_as_if_in_response_to_is_null(Assertion $assertion): void { $this->assertTrue(InResponseTo::assertEquals($assertion, null)); $this->assertFalse(InResponseTo::assertEquals($assertion, 'some not-null-value')); } - #[\PHPUnit\Framework\Attributes\Test] - #[\PHPUnit\Framework\Attributes\Group('saml2-response')] - #[\PHPUnit\Framework\Attributes\Group('saml2')] + #[Test] + #[Group('saml2-response')] + #[Group('saml2')] public function in_reponse_to_equality_is_strictly_checked(): void { $assertion = new Assertion(); diff --git a/src/Tests/Unit/Security/SamlAuthenticatorTest.php b/src/Tests/Unit/Security/SamlAuthenticatorTest.php index cd762ff4..7f23ed33 100644 --- a/src/Tests/Unit/Security/SamlAuthenticatorTest.php +++ b/src/Tests/Unit/Security/SamlAuthenticatorTest.php @@ -21,20 +21,21 @@ use Generator; use Mockery; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; use SAML2\Assertion; use SAML2\Configuration\PrivateKey; -use Surfnet\SamlBundle\Security\Authentication\Handler\FailureHandler; -use Surfnet\SamlBundle\Security\Authentication\Handler\SuccessHandler; -use Surfnet\SamlBundle\Security\Authentication\Passport\Badge\SamlAttributesBadge; -use Surfnet\SamlBundle\Security\Authentication\SamlAuthenticationStateHandler; -use Surfnet\SamlBundle\Security\Authentication\SamlAuthenticator; -use Psr\Log\LoggerInterface; use Surfnet\SamlBundle\Entity\IdentityProvider; use Surfnet\SamlBundle\Entity\ServiceProvider; use Surfnet\SamlBundle\Http\RedirectBinding; +use Surfnet\SamlBundle\Security\Authentication\Handler\FailureHandler; use Surfnet\SamlBundle\Security\Authentication\Handler\ProcessSamlAuthenticationHandler; +use Surfnet\SamlBundle\Security\Authentication\Handler\SuccessHandler; +use Surfnet\SamlBundle\Security\Authentication\Passport\Badge\SamlAttributesBadge; use Surfnet\SamlBundle\Security\Authentication\Provider\SamlProviderInterface; +use Surfnet\SamlBundle\Security\Authentication\SamlAuthenticationStateHandler; +use Surfnet\SamlBundle\Security\Authentication\SamlAuthenticator; use Surfnet\SamlBundle\Security\Authentication\Token\SamlToken; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -119,7 +120,7 @@ public function test_start(): void $this->assertInstanceOf(RedirectResponse::class, $response); } - #[\PHPUnit\Framework\Attributes\DataProvider('provideSupportsParameters')] + #[DataProvider('provideSupportsParameters')] public function test_supports(bool $expectedResult, array $post, array $server, string $routeName): void { $request = new Request([], $post, [], [], [], $server); @@ -128,7 +129,7 @@ public function test_supports(bool $expectedResult, array $post, array $server, $this->assertEquals($expectedResult, $this->authenticator->supports($request)); } - #[\PHPUnit\Framework\Attributes\DataProvider('provideSupportsRelayStateParameters')] + #[DataProvider('provideSupportsRelayStateParameters')] public function test_supports_also_rejects(bool $expectation, array $post): void { $request = new Request( From 64925e053ba21e7cc8e77ce5e692142b6b650b1a Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 6 Nov 2025 14:57:16 +0100 Subject: [PATCH 5/6] Update symfony 6 > 7 --- .github/workflows/test-integration.yml | 13 ++----- CHANGELOG.md | 4 ++ ci/qa/docheader | 6 +++ ci/qa/docheader.template | 16 ++++++++ ci/qa/phpcpd | 6 +++ ci/qa/phpunit.xml | 15 +------- composer.json | 37 ++++++++++++------- .../ConfigurableAttributeSetFactory.php | 2 +- src/SAML2/Extensions/Chunk.php | 2 +- src/SAML2/Extensions/Extensions.php | 3 +- .../Extensions/GsspUserAttributesChunk.php | 2 +- .../Extensions/AuthnRequestExtensionsTest.php | 3 +- .../Extensions/ChunkSerializationTest.php | 2 +- .../Metadata/MetadataFactoryTest.php | 5 +-- src/Tests/Component/Metadata/XsdValidator.php | 19 +--------- .../Component/Metadata/XsdValidatorTest.php | 2 +- .../Unit/Metadata/MetadataFactoryTest.php | 15 ++++++++ 17 files changed, 87 insertions(+), 65 deletions(-) create mode 100755 ci/qa/docheader create mode 100644 ci/qa/docheader.template create mode 100755 ci/qa/phpcpd diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 1ac5d332..f413ebbe 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -6,16 +6,9 @@ jobs: continue-on-error: ${{ matrix.experimental }} strategy: matrix: - php-versions: [ '8.2'] + php-versions: [ '8.2', '8.4'] experimental: [false] - include: - - php-versions: '8.1' - experimental: true - - php-versions: '8.3' - experimental: true - - php-versions: '8.4' - experimental: true - timeout-minutes: 30 + timeout-minutes: 15 name: PHP ${{ matrix.php-versions }} on Ubuntu latest. Experimental == ${{ matrix.experimental }} steps: - name: Install PHP @@ -29,7 +22,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} - id: checks name: Run CI tests - run: composer check + run: composer check-ci continue-on-error: ${{ matrix.experimental }} - name: Output log files on failure if: failure() diff --git a/CHANGELOG.md b/CHANGELOG.md index 58ca1762..dfeb983a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 7.0.0 +- Add SF 7 support +- Upgrade dev & qa tooling + # 6.0.0 - Add SF 6 support - Require PHP 8.1 diff --git a/ci/qa/docheader b/ci/qa/docheader new file mode 100755 index 00000000..55ed85d5 --- /dev/null +++ b/ci/qa/docheader @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +cd $(dirname $0)/../../ + +./vendor/bin/docheader --no-ansi --docheader=ci/qa/docheader.template check src/ + diff --git a/ci/qa/docheader.template b/ci/qa/docheader.template new file mode 100644 index 00000000..90cda86b --- /dev/null +++ b/ci/qa/docheader.template @@ -0,0 +1,16 @@ +/** + * Copyright %regexp:\d{4}% SURFnet %regexp:(B.V.|bv)% + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/ci/qa/phpcpd b/ci/qa/phpcpd new file mode 100755 index 00000000..bb16ac4c --- /dev/null +++ b/ci/qa/phpcpd @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +cd $(dirname $0)/../../ + +# https://github.com/sebastianbergmann/phpcpd +vendor/bin/phpcpd ./src \ No newline at end of file diff --git a/ci/qa/phpunit.xml b/ci/qa/phpunit.xml index 0f6f9a54..78f770de 100644 --- a/ci/qa/phpunit.xml +++ b/ci/qa/phpunit.xml @@ -1,10 +1,11 @@ @@ -18,16 +19,4 @@ ../../src/Tests/Component - - - ../../src - - - ../../src/Tests - - - - - - diff --git a/composer.json b/composer.json index 7c621d46..29b82236 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "surfnet/stepup-saml-bundle", "type": "symfony-bundle", - "description": "A Symfony 6 bundle that integrates the simplesamlphp\\saml2 library with Symfony.", + "description": "A Symfony 7 bundle that integrates the simplesamlphp\\saml2 library with Symfony.", "keywords": ["surfnet", "StepUp", "simplesamlphp", "SAML", "SAML2"], "license": "Apache-2.0", "minimum-stability": "stable", @@ -12,15 +12,17 @@ "psr/log": "^3.0", "robrichards/xmlseclibs": "^3.1.1", "simplesamlphp/saml2": "^4.6", - "symfony/dependency-injection": "^6.3", - "symfony/framework-bundle": "^6.3", - "symfony/security-bundle": "^6.3", - "symfony/templating": "^6.3", + "symfony/dependency-injection": "^6.3|^7.0", + "symfony/framework-bundle": "^6.3|^7.0", + "symfony/security-bundle": "^6.3|^7.0", + "symfony/templating": "^6.3|7.0", "twig/twig": "^3" }, "require-dev": { "ext-libxml": "*", "ext-zlib": "*", + "irstea/phpcpd-shim": "^6.0", + "malukenho/docheader": "^1.1", "mockery/mockery": "^1.5", "overtrue/phplint": "*", "phpmd/phpmd": "^2.6", @@ -31,16 +33,23 @@ "sebastian/exporter": "^6.3", "slevomat/coding-standard": "^8.24", "squizlabs/php_codesniffer": "^4.0", - "symfony/phpunit-bridge": "^6.3" + "symfony/phpunit-bridge": "^7.3.4" }, "scripts": { "check": [ - "@composer-validate", - "@phplint", - "@phpcs", - "@phpmd", - "@phpstan", - "@test" + "@check-ci", + "@rector" + ], + "check-ci": [ + "@composer-validate", + "@license-headers", + "@phplint", + "@phpcpd", + "@phpcs", + "@phpmd", + "@test", + "@phpstan", + "@composer audit" ], "composer-validate": "./ci/qa/validate", "phplint": "./ci/qa/phplint", @@ -50,6 +59,7 @@ "phpstan": "./ci/qa/phpstan", "phpstan-baseline": "./ci/qa/phpstan-update-baseline", "test": "./ci/qa/phpunit", + "license-headers": "./ci/qa/docheader", "phpcbf": "./ci/qa/phpcbf", "rector": "./ci/qa/rector.sh --dry-run", "rector-fix": "./ci/qa/rector.sh" @@ -70,7 +80,8 @@ "sort-packages": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "simplesamlphp/composer-xmlprovider-installer": true } } } diff --git a/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php b/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php index 03bc0457..6b4bcc61 100644 --- a/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php +++ b/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php @@ -31,7 +31,7 @@ public static function configureWhichAttributeSetToCreate(mixed $attributeSetCla throw InvalidArgumentException::invalidType('non-empty string', 'attributeSetClassName', $attributeSetClassName); } - if (!is_a($attributeSetClassName, '\Surfnet\SamlBundle\SAML2\Attribute\AttributeSetFactory', true)) { + if (!is_a($attributeSetClassName, AttributeSetFactory::class, true)) { throw new InvalidArgumentException(sprintf( 'Cannot use class "%s": it must implement "%s"', $attributeSetClassName, diff --git a/src/SAML2/Extensions/Chunk.php b/src/SAML2/Extensions/Chunk.php index ecdca7b6..ccd6dc21 100644 --- a/src/SAML2/Extensions/Chunk.php +++ b/src/SAML2/Extensions/Chunk.php @@ -1,7 +1,7 @@ xsdValidator = new XsdValidator(); } - /** - * Helper method to assert XML document is valid against XSD schema - */ private function assertXmlIsValidAgainstXsd(DOMDocument $document, string $xsdPath): void { $errors = $this->xsdValidator->validate($document, $xsdPath); diff --git a/src/Tests/Component/Metadata/XsdValidator.php b/src/Tests/Component/Metadata/XsdValidator.php index 576f16f6..99a3d787 100644 --- a/src/Tests/Component/Metadata/XsdValidator.php +++ b/src/Tests/Component/Metadata/XsdValidator.php @@ -1,7 +1,7 @@ validate($document, $xsdPath)); diff --git a/src/Tests/Component/Metadata/XsdValidatorTest.php b/src/Tests/Component/Metadata/XsdValidatorTest.php index b4791f68..6be4cafa 100644 --- a/src/Tests/Component/Metadata/XsdValidatorTest.php +++ b/src/Tests/Component/Metadata/XsdValidatorTest.php @@ -1,7 +1,7 @@ Date: Mon, 17 Nov 2025 11:13:23 +0100 Subject: [PATCH 6/6] Changelog: mention bc break PHPCS: search comments for annotations Prior to this change, phpcs would not allow imports for classes referenced in annotations only. This change enables that. Also, fix a wrong reference to `\LogicException` where in reality `\Surfnet\SamlBundle\Security\Exception\LogicException` was thrown. Update to samlbundle exception. --- CHANGELOG.md | 3 +++ ci/qa/phpcs.xml | 6 +++++- src/Http/ReceivedAuthnRequestPost.php | 3 ++- src/SAML2/BridgeContainer.php | 4 ++-- .../Authentication/AuthenticatedSessionStateHandler.php | 5 +++-- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfeb983a..e22b8e0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ - Add SF 7 support - Upgrade dev & qa tooling +Backward compatibility breaks: + * Minor: `\Surfnet\SamlBundle\SAML2\BridgeContainer::debugMessage` Will now throw a `\Surfnet\SamlBundle\Exception\InvalidArgumentException` instead of 'Fatal error: Uncaught TypeError' if an invalid `$message` is debugged. + # 6.0.0 - Add SF 6 support - Require PHP 8.1 diff --git a/ci/qa/phpcs.xml b/ci/qa/phpcs.xml index b1a9c10b..5a3f19a1 100644 --- a/ci/qa/phpcs.xml +++ b/ci/qa/phpcs.xml @@ -23,6 +23,10 @@ - + + + + + diff --git a/src/Http/ReceivedAuthnRequestPost.php b/src/Http/ReceivedAuthnRequestPost.php index cebf09db..b44af4d9 100644 --- a/src/Http/ReceivedAuthnRequestPost.php +++ b/src/Http/ReceivedAuthnRequestPost.php @@ -18,6 +18,7 @@ namespace Surfnet\SamlBundle\Http; +use Exception; use RobRichards\XMLSecLibs\XMLSecurityKey; use Surfnet\SamlBundle\Http\Exception\InvalidRequestException; use Surfnet\SamlBundle\SAML2\ReceivedAuthnRequest; @@ -80,7 +81,7 @@ public function getRelayState(): ?string } /** - * @throws \Exception when signature is invalid (@see SAML2\Utils::validateSignature) + * @throws Exception when signature is invalid (@see SAML2\Utils::validateSignature) */ public function verify(XMLSecurityKey $key): bool { diff --git a/src/SAML2/BridgeContainer.php b/src/SAML2/BridgeContainer.php index 97ca3035..e0aeeedf 100644 --- a/src/SAML2/BridgeContainer.php +++ b/src/SAML2/BridgeContainer.php @@ -21,8 +21,8 @@ use BadMethodCallException; use DOMElement; use Psr\Log\LoggerInterface; -use RuntimeException; use SAML2\Compat\AbstractContainer; +use Surfnet\SamlBundle\Exception\InvalidArgumentException; /** * Container that is required so that we can make the SAML2 lib work. @@ -57,7 +57,7 @@ public function debugMessage($message, $type): void } if (!is_string($message)) { - throw new RuntimeException("Debug message error: could not convert message to string."); + throw new InvalidArgumentException("Debug message error: could not convert message to string."); } $this->logger->debug($message, ['type' => $type]); diff --git a/src/Security/Authentication/AuthenticatedSessionStateHandler.php b/src/Security/Authentication/AuthenticatedSessionStateHandler.php index 4fcc63f5..c3dfa655 100644 --- a/src/Security/Authentication/AuthenticatedSessionStateHandler.php +++ b/src/Security/Authentication/AuthenticatedSessionStateHandler.php @@ -18,6 +18,7 @@ namespace Surfnet\SamlBundle\Security\Authentication; +use Surfnet\SamlBundle\Security\Exception\LogicException; use Surfnet\SamlBundle\Value\DateTime; interface AuthenticatedSessionStateHandler @@ -25,7 +26,7 @@ interface AuthenticatedSessionStateHandler /** * Sets the moment at which the user was authenticated * - * @throws \LogicException when an authentication moment was already logged + * @throws LogicException when an authentication moment was already logged */ public function logAuthenticationMoment(): void; @@ -34,7 +35,7 @@ public function isAuthenticationMomentLogged(): bool; /** * Gets the moment at which the user was authenticated * - * @throws \LogicException when no authentication moment was logged + * @throws LogicException when no authentication moment was logged */ public function getAuthenticationMoment(): DateTime;