diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 1ac5d33..f413ebb 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/.gitignore b/.gitignore index 1ced127..66220cd 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/CHANGELOG.md b/CHANGELOG.md index 58ca176..e22b8e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 7.0.0 +- 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/docheader b/ci/qa/docheader new file mode 100755 index 0000000..55ed85d --- /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 0000000..90cda86 --- /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/phpcbf b/ci/qa/phpcbf index ff3fa20..138015b 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/phpcpd b/ci/qa/phpcpd index e9fec13..bb16ac4 100755 --- a/ci/qa/phpcpd +++ b/ci/qa/phpcpd @@ -3,5 +3,4 @@ cd $(dirname $0)/../../ # https://github.com/sebastianbergmann/phpcpd -./vendor/bin/phpcpd \ - ./src $1 +vendor/bin/phpcpd ./src \ No newline at end of file diff --git a/ci/qa/phpcs b/ci/qa/phpcs index 3a522b9..32dbcb2 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 7a6955e..5a3f19a 100644 --- a/ci/qa/phpcs.xml +++ b/ci/qa/phpcs.xml @@ -15,5 +15,18 @@ + src/Tests/* + + + src/Tests/* + + + + + + + + + diff --git a/ci/qa/phplint.yaml b/ci/qa/phplint.yaml index f07ad6c..0ce9205 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/phpstan-baseline.neon b/ci/qa/phpstan-baseline.neon index 1ac13fe..475dc6a 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/phpunit.xml b/ci/qa/phpunit.xml index 0f6f9a5..78f770d 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/ci/qa/rector.php b/ci/qa/rector.php new file mode 100644 index 0000000..116314c --- /dev/null +++ b/ci/qa/rector.php @@ -0,0 +1,15 @@ +withPaths([ + __DIR__ . '/../../src', + ]) + ->withAttributesSets(all: true) + ->withComposerBased(phpunit: true, symfony: true) + ->withTypeCoverageLevel(10) + ->withDeadCodeLevel(10) + ->withCodeQualityLevel(10); diff --git a/ci/qa/rector.sh b/ci/qa/rector.sh new file mode 100755 index 0000000..b2b5857 --- /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 02b28b5..29b8223 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", @@ -9,38 +9,47 @@ "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", - "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": "*", - "mbhsoft/phpunit-xsdvalidation": "^3.0", + "irstea/phpcpd-shim": "^6.0", + "malukenho/docheader": "^1.1", "mockery/mockery": "^1.5", "overtrue/phplint": "*", "phpmd/phpmd": "^2.6", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5", - "psr/log": "~1.0", - "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" + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "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": "^7.3.4" }, "scripts": { "check": [ - "@composer-validate", - "@phplint", - "@phpcpd", - "@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,7 +59,10 @@ "phpstan": "./ci/qa/phpstan", "phpstan-baseline": "./ci/qa/phpstan-update-baseline", "test": "./ci/qa/phpunit", - "phpcbf": "./ci/qa/phpcbf" + "license-headers": "./ci/qa/docheader", + "phpcbf": "./ci/qa/phpcbf", + "rector": "./ci/qa/rector.sh --dry-run", + "rector-fix": "./ci/qa/rector.sh" }, "autoload": { "psr-4": { @@ -67,7 +79,9 @@ "config": { "sort-packages": true, "allow-plugins": { - "phpstan/extension-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true, + "simplesamlphp/composer-xmlprovider-installer": true } } } diff --git a/src/DependencyInjection/SurfnetSamlExtension.php b/src/DependencyInjection/SurfnetSamlExtension.php index f858c5e..8763b4e 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 @@ -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/Exception/InvalidRequestException.php b/src/Http/Exception/InvalidRequestException.php index ebcc767..da90df9 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/PostBinding.php b/src/Http/PostBinding.php index a1e2d8e..d9ef75c 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 1156c00..b44af4d 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 4354f52..b97de3e 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 c15c4a2..f83d3cc 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 52e508a..b872b7f 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 { @@ -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 3e13edd..2c8dc13 100644 --- a/src/Monolog/SamlAuthenticationLogger.php +++ b/src/Monolog/SamlAuthenticationLogger.php @@ -20,12 +20,12 @@ namespace Surfnet\SamlBundle\Monolog; use Psr\Log\LoggerInterface; -use Surfnet\SamlBundle\Exception\RuntimeException; +use Stringable; /** * 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 +46,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 ff053aa..a393179 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 9202384..6b4bcc6 100644 --- a/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php +++ b/src/SAML2/Attribute/ConfigurableAttributeSetFactory.php @@ -25,16 +25,13 @@ 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); } - 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/AuthnRequestFactory.php b/src/SAML2/AuthnRequestFactory.php index be449c0..c2c08f7 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; @@ -34,7 +33,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") */ class AuthnRequestFactory { @@ -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/BridgeContainer.php b/src/SAML2/BridgeContainer.php index ca63d7f..e0aeeed 100644 --- a/src/SAML2/BridgeContainer.php +++ b/src/SAML2/BridgeContainer.php @@ -22,6 +22,7 @@ use DOMElement; use Psr\Log\LoggerInterface; use SAML2\Compat\AbstractContainer; +use Surfnet\SamlBundle\Exception\InvalidArgumentException; /** * Container that is required so that we can make the SAML2 lib work. @@ -55,6 +56,10 @@ public function debugMessage($message, $type): void $message = $message->ownerDocument->saveXML($message); } + if (!is_string($message)) { + throw new InvalidArgumentException("Debug message error: could not convert message to string."); + } + $this->logger->debug($message, ['type' => $type]); } @@ -75,7 +80,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/Chunk.php b/src/SAML2/Extensions/Chunk.php index ecdca7b..ccd6dc2 100644 --- a/src/SAML2/Extensions/Chunk.php +++ b/src/SAML2/Extensions/Chunk.php @@ -1,7 +1,7 @@ createElementNS('urn:mace:surf.nl:stepup:gssp-extensions', 'gssp:UserAttributes'); @@ -33,7 +32,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/SAML2/ReceivedAuthnRequest.php b/src/SAML2/ReceivedAuthnRequest.php index 07a6bee..c154cdb 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/SamlAuthenticator.php b/src/Security/Authentication/SamlAuthenticator.php index 5bc8b00..5855302 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; @@ -48,12 +45,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, @@ -73,7 +70,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, diff --git a/src/Signing/SignatureVerifier.php b/src/Signing/SignatureVerifier.php index 409c2d9..081b65a 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 87af4fb..561f44e 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 d86a164..93dabdf 100644 --- a/src/Tests/Component/Extensions/AuthnRequestExtensionsTest.php +++ b/src/Tests/Component/Extensions/AuthnRequestExtensionsTest.php @@ -1,7 +1,7 @@ twig = new Environment($loader); $this->router = m::mock(RouterInterface::class); $this->router->shouldReceive('generate')->andReturn('https://foobar.example.com'); + $this->xsdValidator = new XsdValidator(); + } + + 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 +129,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 +147,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 0000000..99a3d78 --- /dev/null +++ b/src/Tests/Component/Metadata/XsdValidator.php @@ -0,0 +1,56 @@ +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 []; + } + + 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 0000000..6be4caf --- /dev/null +++ b/src/Tests/Component/Metadata/XsdValidatorTest.php @@ -0,0 +1,126 @@ +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 b7708ac..1fd6a0a 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,11 +48,9 @@ class AuthnRequestSigningTest extends TestCase private ?string $publicKey = null; - /** - * @test - * @group Signing - * @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( @@ -72,11 +72,9 @@ public function deprecated_authn_request_signatures_are_verified_if_the_sender_u ); } - /** - * @test - * @group Signing - * @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( @@ -98,11 +96,9 @@ public function deprecated_authn_request_signatures_are_verified_if_the_sender_u ); } - /** - * @test - * @group Signing - * @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( @@ -123,11 +119,9 @@ public function deprecated_authn_request_signatures_are_not_verified_if_the_data ); } - /** - * @test - * @group Signing - * @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( @@ -147,10 +141,8 @@ public function deprecated_authn_request_signatures_are_not_verified_if_the_para ); } - /** - * @test - * @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); @@ -203,10 +195,8 @@ public function a_received_authn_requests_signature_is_verified_regardless_of_it ); } - /** - * @test - * @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 ac9d2a2..75436ca 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 25086aa..56d1838 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,10 +42,8 @@ public function setUp(): void $this->factory = new HttpBindingFactory($redirectBinding, $postBinding); } - /** - * @test - * @group http - */ + #[Test] + #[Group('http')] public function a_redirect_binding_can_be_built(): void { $request = new Request( @@ -60,10 +59,8 @@ public function a_redirect_binding_can_be_built(): void $this->assertInstanceOf(RedirectBinding::class, $binding); } - /** - * @test - * @group http - */ + #[Test] + #[Group('http')] public function a_post_binding_can_be_built(): void { $request = new Request( @@ -79,10 +76,8 @@ public function a_post_binding_can_be_built(): void $this->assertInstanceOf(PostBinding::class, $binding); } - /** - * @test - * @group http - */ + #[Test] + #[Group('http')] public function a_put_binding_can_not_be_built(): void { $this->expectExceptionMessage("Request type of \"PUT\" is not supported."); @@ -99,10 +94,8 @@ public function a_put_binding_can_not_be_built(): void $this->factory->build($request); } - /** - * @test - * @group http - */ + #[Test] + #[Group('http')] public function an_invalid_post_authn_request_is_rejected(): void { $this->expectExceptionMessage("POST-binding is supported for SAMLRequest."); @@ -119,10 +112,8 @@ public function an_invalid_post_authn_request_is_rejected(): void $this->factory->build($request); } - /** - * @test - * @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/PostBindingAuthnRequestTest.php b/src/Tests/Unit/Http/PostBindingAuthnRequestTest.php index 486cf3f..374eb44 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 9bbb592..86d6166 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/Http/RedirectBindingTest.php b/src/Tests/Unit/Http/RedirectBindingTest.php index 4e3dc71..32f54fe 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,12 +68,9 @@ public function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - /** - * @test - * @group http - * - * @dataProvider nonGetMethodProvider - */ + #[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); @@ -87,10 +87,8 @@ public function a_signed_authn_request_cannot_be_received_from_a_request_that_is $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @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); @@ -107,10 +105,8 @@ public function a_signed_authn_request_cannot_be_received_from_a_request_that_ha $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @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); @@ -142,9 +138,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 */ + #[Test] + #[Group('http')] public function a_signed_authn_requests_destination_must_match_request_uri(): void { $this->expectException(BadRequestHttpException::class); @@ -171,9 +167,9 @@ public function a_signed_authn_requests_destination_must_match_request_uri(): vo /** * Signed AuthNRequests destination have a destination - * @test - * @group http */ + #[Test] + #[Group('http')] public function a_signed_authn_requests_must_carry_a_destination(): void { $this->expectException(BadRequestHttpException::class); @@ -198,10 +194,8 @@ public function a_signed_authn_requests_must_carry_a_destination(): void $redirectBinding->receiveSignedAuthnRequestFrom($request); } - /** - * @test - * @group http - */ + #[Test] + #[Group('http')] public function a_signed_authn_request_cannot_be_received_if_the_signature_is_invalid(): void { $this->expectException(SignatureValidationFailedException::class); @@ -239,12 +233,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 - */ + #[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); @@ -260,10 +251,8 @@ public function a_unsigned_authn_request_cannot_be_received_from_a_request_that_ $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - /** - * @test - * @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); @@ -290,10 +279,8 @@ public function a_unsigned_authn_request_cannot_be_received_if_the_service_provi $redirectBinding->receiveUnsignedAuthnRequestFrom($request); } - /** - * @test - * @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); @@ -320,7 +307,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/Metadata/MetadataFactoryTest.php b/src/Tests/Unit/Metadata/MetadataFactoryTest.php index 2330526..7db81f2 100644 --- a/src/Tests/Unit/Metadata/MetadataFactoryTest.php +++ b/src/Tests/Unit/Metadata/MetadataFactoryTest.php @@ -1,10 +1,26 @@ 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 fb881c4..6e17b09 100644 --- a/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php +++ b/src/Tests/Unit/Monolog/SamlAuthenticationLoggerTest.php @@ -20,18 +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; - /** - * @test - */ + #[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 - */ + #[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 01533cc..dd2d48c 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,10 +27,8 @@ class AttributeDictionaryTest extends TestCase { - /** - * @test - * @group AttributeDictionary - */ + #[Test] + #[Group('AttributeDictionary')] public function finds_no_definition_when_no_definition_given(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -43,10 +43,8 @@ public function finds_no_definition_when_no_definition_given(): void ); } - /** - * @test - * @group AttributeDictionary - */ + #[Test] + #[Group('AttributeDictionary')] public function finds_no_definition_when_urn_matches_no_mace_urn(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -69,10 +67,8 @@ public function finds_no_definition_when_urn_matches_no_mace_urn(): void ); } - /** - * @test - * @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'; @@ -95,10 +91,8 @@ public function finds_no_definition_when_urn_matches_no_oid_urn(): void ); } - /** - * @test - * @group AttributeDictionary - */ + #[Test] + #[Group('AttributeDictionary')] public function finds_definition_when_urn_matches_urn_mace(): void { $maceAttributeUrn = 'urn:mace:some:attribute'; @@ -120,10 +114,8 @@ public function finds_definition_when_urn_matches_urn_mace(): void ); } - /** - * @test - * @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'; @@ -145,11 +137,8 @@ public function finds_definition_when_urn_matches_urn_oid(): void ); } - /** - * @test - * @group AttributeDictionary - * - */ + #[Test] + #[Group('AttributeDictionary')] public function shouldThrowExceptionForUnknownAttrib(): void { $this->expectException(UnknownUrnException::class); @@ -165,20 +154,16 @@ public function shouldThrowExceptionForUnknownAttrib(): void $attributeDictionary->getAttributeDefinitionByUrn('unknown:0.0.0.0.0'); } - /** - * @test - * @group AttributeDictionary - */ + #[Test] + #[Group('AttributeDictionary')] public function shouldIgnoreUnknownAttributes(): void { $attributeDictionary = new AttributeDictionary(true); $this->assertTrue($attributeDictionary->ignoreUnknownAttributes()); } - /** - * @test - * @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 2505157..a773a4f 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,11 +40,9 @@ protected function setUp(): void ContainerSingleton::setContainer(new MockContainer()); } - /** - * @test - * @group AssertionAdapter - * @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); @@ -51,11 +52,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 - */ + #[Test] + #[Group('AssertionAdapter')] + #[Group('AttributeSet')] public function which_attribute_set_is_created_from_attributes_is_configurable(): void { ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate(self::DUMMY_ATTRIBUTE_SET_CLASS); @@ -65,13 +64,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() - */ + #[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); @@ -80,11 +76,9 @@ public function the_attribute_set_to_use_can_only_be_represented_as_a_non_empty_ ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate($nonOrEmptyString); } - /** - * @test - * @group AssertionAdapter - * @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); @@ -93,7 +87,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 6ae310e..31a2a76 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,10 +35,8 @@ class AuthnRequestFactoryTest extends TestCase { use MockeryPHPUnitIntegration; - /** - * @test - * @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"); @@ -51,10 +51,8 @@ public function an_exception_is_thrown_when_a_request_is_not_properly_base64_enc AuthnRequestFactory::createFromHttpRequest($request); } - /** - * @test - * @group saml2 - */ + #[Test] + #[Group('saml2')] public function an_exception_is_thrown_when_a_request_cannot_be_inflated(): void { $this->expectExceptionMessage("Failed inflating the request;"); @@ -69,10 +67,8 @@ public function an_exception_is_thrown_when_a_request_cannot_be_inflated(): void AuthnRequestFactory::createFromHttpRequest($request); } - /** - * @test - * @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 8d446e4..dbccb67 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; @@ -55,7 +58,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 = <<authRequestNoSubject); @@ -114,10 +115,8 @@ public function setting_the_subject_generates_valid_xml(string $nameId, ?string $this->assertXmlStringEqualsXmlString($this->authRequestWithSubject, $authnRequest->getUnsignedXML()); } - /** - * @test - * @group saml2 - */ + #[Test] + #[Group('saml2')] public function the_nameid_and_format_can_be_retrieved_from_the_authnrequest(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestWithSubject); @@ -133,10 +132,8 @@ public function the_nameid_and_format_can_be_retrieved_from_the_authnrequest(): $this->assertEquals($nameId->getFormat(), $authnRequest->getNameIdFormat()); } - /** - * @test - * @group saml2 - */ + #[Test] + #[Group('saml2')] public function the_acs_url_can_be_retrieved_from_the_authnrequest(): void { $domDocument = DOMDocumentFactory::fromString($this->authRequestWithSubject); @@ -147,11 +144,9 @@ public function the_acs_url_can_be_retrieved_from_the_authnrequest(): void $this->assertEquals($this->acsUrl, $authnRequest->getAssertionConsumerServiceURL()); } - /** - * @test - * @group saml2 - * @dataProvider provideIsPassiveAndForceAuthnCombinations - */ + #[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); @@ -162,16 +157,16 @@ public function is_passive_and_force_authn_can_be_retrieved_from_the_authnreques $this->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] ]; } - 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 de7ef35..c9ca562 100644 --- a/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php +++ b/src/Tests/Unit/SAML2/ReceivedAuthnRequestPostTest.php @@ -18,15 +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 { - /** - * @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')); @@ -38,9 +37,7 @@ public function it_can_decode_a_signed_saml_request(): void $this->assertEquals('/index.php', $authnRequest->getRelayState()); } - /** - * @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')); @@ -52,9 +49,7 @@ public function it_can_decode_a_signed_saml_request_from_adfs_origin(): void $this->assertInstanceOf(ReceivedAuthnRequestPost::class, $parsed); } - /** - * @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')); @@ -66,9 +61,7 @@ public function it_can_decode_an_usigned_saml_request(): void $this->assertEquals('/index.php', $authnRequest->getRelayState()); } - /** - * @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 2146a8a..5c48ca4 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; @@ -42,12 +45,12 @@ class ReceivedAuthnRequestQueryStringTest extends TestCase AUTHNREQUEST_NO_SUBJECT; /** - * @test - * @group AuthnRequest * - * @dataProvider emptyStringProvider * @param $nonOrEmptyString */ + #[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,10 +59,8 @@ public function a_received_authn_request_query_string_cannot_be_parsed_from_empt ReceivedAuthnRequestQueryString::parse($nonOrEmptyString); } - /** - * @test - * @group AuthnRequest - */ + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_valid_key_value_pairs(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -68,10 +69,8 @@ public function a_received_authn_request_query_string_must_contain_valid_key_val ReceivedAuthnRequestQueryString::parse('a-key-without-a-value'); } - /** - * @test - * @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); @@ -85,13 +84,12 @@ public function a_received_authn_request_query_string_must_contain_a_base64_enco } /** - * @test - * @group AuthnRequest - * - * @dataProvider queryStringWithRepeatedSamlParametersProvider * @param $doubleParameterName * @param $queryStringWithDoubleParameter */ + #[Test] + #[DataProvider('queryStringWithRepeatedSamlParametersProvider')] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_cannot_contain_a_saml_parameter_twice( string $doubleParameterName, string $queryStringWithDoubleParameter @@ -102,10 +100,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_saml_para ReceivedAuthnRequestQueryString::parse($queryStringWithDoubleParameter); } - /** - * @test - * @group AuthnRequest - */ + #[Test] + #[Group('AuthnRequest')] public function a_received_authn_request_query_string_must_contain_a_saml_request(): void { $this->expectException('\\' . InvalidReceivedAuthnRequestQueryStringException::class); @@ -118,10 +114,8 @@ public function a_received_authn_request_query_string_must_contain_a_saml_reques ReceivedAuthnRequestQueryString::parse($queryStringWithoutSamlRequest); } - /** - * @test - * @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); @@ -134,10 +128,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureAlgorithmWithoutSignature); } - /** - * @test - * @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); @@ -150,10 +142,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureWithoutSignatureAlgorithm); } - /** - * @test - * @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); @@ -167,10 +157,8 @@ public function a_received_authn_request_query_string_cannot_contain_a_signature ReceivedAuthnRequestQueryString::parse($queryStringWithSignatureWithoutSignatureAlgorithm); } - /** - * @test - * @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')) @@ -186,10 +174,8 @@ public function a_signed_query_string_can_be_acquired_from_a_received_authn_requ $this->assertEquals($expectedSignedQueryString, $actualQueryString); } - /** - * @test - * @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'; @@ -211,10 +197,8 @@ public function query_parameters_that_are_not_used_for_a_saml_message_are_ignore ); } - /** - * @test - * @group AuthnRequest - */ + #[Test] + #[Group('AuthnRequest')] public function a_decoded_signature_can_be_acquired_from_a_received_authn_request_query_string(): void { $signature = 'signature'; @@ -235,10 +219,8 @@ public function a_decoded_signature_can_be_acquired_from_a_received_authn_reques ); } - /** - * @test - * @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); @@ -259,10 +241,8 @@ public function a_decoded_saml_request_can_be_acquired_from_a_received_authn_req ); } - /** - * @test - * @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); @@ -276,10 +256,8 @@ public function a_saml_request_cannot_be_decoded_from_a_received_authn_request_q $query->getDecodedSamlRequest(); } - /** - * @test - * @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')); @@ -317,7 +295,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 +313,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 3e4524a..e6d7f4f 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,10 +34,8 @@ class AssertionAdapterTest extends TestCase { use MockeryPHPUnitIntegration; - /** - * @test - * @group AssertionAdapter - */ + #[Test] + #[Group('AssertionAdapter')] public function presence_of_attribute_can_be_confirmed_based_on_mace_urn_attribute_definition(): void { @@ -62,10 +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'); } - /** - * @test - * @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'; @@ -91,10 +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'); } - /** - * @test - * @group AssertionAdapter - */ + #[Test] + #[Group('AssertionAdapter')] public function no_presence_of_attribute_can_be_confirmed_if_no_attribute_definition_found(): void { $this->expectException(UnknownUrnException::class); @@ -119,10 +115,8 @@ public function no_presence_of_attribute_can_be_confirmed_if_no_attribute_defini $attributeSet->contains($attributeExpectedNotToBeContained); } - /** - * @test - * @group AssertionAdapter - */ + #[Test] + #[Group('AssertionAdapter')] public function attribute_set_is_empty_if_no_attributes_found(): void { $assertion = m::mock(Assertion::class); @@ -136,10 +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'); } - /** - * @test - * @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'; @@ -162,10 +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'); } - /** - * @test - * @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 2bfc67c..705fb05 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,23 +32,19 @@ class InResponseToTest extends TestCase { - /** - * @test - * @group saml2-response - * @group saml2 - * @dataProvider provideAssertionsWithoutInResponseTo - */ + #[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')); } - /** - * @test - * @group saml2-response - * @group saml2 - */ + #[Test] + #[Group('saml2-response')] + #[Group('saml2')] public function in_reponse_to_equality_is_strictly_checked(): void { $assertion = new Assertion(); @@ -59,7 +58,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 87c9824..7f23ed3 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,9 +120,7 @@ public function test_start(): void $this->assertInstanceOf(RedirectResponse::class, $response); } - /** - * @dataProvider provideSupportsParameters - */ + #[DataProvider('provideSupportsParameters')] public function test_supports(bool $expectedResult, array $post, array $server, string $routeName): void { $request = new Request([], $post, [], [], [], $server); @@ -130,9 +129,7 @@ public function test_supports(bool $expectedResult, array $post, array $server, $this->assertEquals($expectedResult, $this->authenticator->supports($request)); } - /** - * @dataProvider provideSupportsRelayStateParameters - */ + #[DataProvider('provideSupportsRelayStateParameters')] public function test_supports_also_rejects(bool $expectation, array $post): void { $request = new Request( @@ -151,7 +148,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 +157,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']]; diff --git a/src/Value/DateTime.php b/src/Value/DateTime.php index b595d86..982f0a6 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); } /**