diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 3ac7fbe25..ad3a46f23 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -19,7 +19,7 @@ jobs: runs-on: [ubuntu-latest] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Lint markdown files uses: nosborn/github-action-markdown-cli@v3 diff --git a/.github/workflows/interoperability.yml b/.github/workflows/interoperability.yml index ba60ecf55..d2fc90837 100644 --- a/.github/workflows/interoperability.yml +++ b/.github/workflows/interoperability.yml @@ -47,10 +47,10 @@ jobs: git config --global core.autocrlf false git config --global core.eol lf - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Cache composer dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: $(composer config cache-files-dir) key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} @@ -69,7 +69,7 @@ jobs: - name: Cache metadata id: cache-metadata - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: /tmp/metadata key: ${{ runner.os }}-metadata-${{ env.date }} diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index af6bb216e..b1d8f2381 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -71,7 +71,7 @@ jobs: git config --global core.autocrlf false git config --global core.eol lf - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Get composer cache directory run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" @@ -86,7 +86,7 @@ jobs: echo "COMPOSER_ROOT_VERSION=$ROOT_VERSION" >> "$GITHUB_ENV" - name: Cache composer dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{ env.COMPOSER_CACHE }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -143,7 +143,7 @@ jobs: git config --global core.autocrlf false git config --global core.eol lf - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Get composer cache directory run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$env:GITHUB_ENV" @@ -158,7 +158,7 @@ jobs: echo "COMPOSER_ROOT_VERSION=$ROOT_VERSION" >> "$GITHUB_ENV" - name: Cache composer dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{ env.COMPOSER_CACHE }} key: ${{ runner.os }}-composer-${{ hashFiles('**\composer.json') }} @@ -190,7 +190,7 @@ jobs: - name: Setup problem matchers for PHP run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Get composer cache directory run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" @@ -205,7 +205,7 @@ jobs: echo "COMPOSER_ROOT_VERSION=$ROOT_VERSION" >> "$GITHUB_ENV" - name: Cache composer dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{ env.COMPOSER_CACHE }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -253,7 +253,7 @@ jobs: - name: Setup problem matchers for PHP run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Get composer cache directory run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" @@ -268,7 +268,7 @@ jobs: echo "COMPOSER_ROOT_VERSION=$ROOT_VERSION" >> "$GITHUB_ENV" - name: Cache composer dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{ env.COMPOSER_CACHE }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -291,7 +291,7 @@ jobs: runs-on: [ubuntu-latest] needs: [unit-tests-linux] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: actions/download-artifact@v8 with: @@ -299,7 +299,7 @@ jobs: path: ${{ github.workspace }}/build - name: Codecov - uses: codecov/codecov-action@v6 + uses: codecov/codecov-action@v7 with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true diff --git a/composer.json b/composer.json index a85f76545..2b9f44c97 100644 --- a/composer.json +++ b/composer.json @@ -33,8 +33,7 @@ "simplesamlphp/assert": "~2.0", "simplesamlphp/xml-common": "~2.8", "simplesamlphp/xml-security": "~2.3", - "simplesamlphp/xml-soap": "~2.3", - "robrichards/xmlseclibs": "^3.1" + "simplesamlphp/xml-soap": "~2.3" }, "require-dev": { "ext-intl": "*", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e8006de5f..5ab4b007f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,15 +1,5 @@ parameters: ignoreErrors: - - - message: '#^Call to an undefined method SimpleSAML\\SAML2\\XML\\samlp\\AbstractMessage\:\:addValidator\(\)\.$#' - identifier: method.notFound - path: src/Binding/HTTPArtifact.php - - - - message: '#^Call to an undefined method SimpleSAML\\SAML2\\XML\\samlp\\ArtifactResponse\:\:validate\(\)\.$#' - identifier: method.notFound - path: src/Binding/HTTPArtifact.php - - message: '#^Call to an undefined method SimpleSAML\\SAML2\\XML\\samlp\\AbstractMessage\:\:addValidator\(\)\.$#' identifier: method.notFound diff --git a/src/Binding/HTTPArtifact.php b/src/Binding/HTTPArtifact.php index 930ffa58a..9fd84dedd 100644 --- a/src/Binding/HTTPArtifact.php +++ b/src/Binding/HTTPArtifact.php @@ -9,12 +9,12 @@ use Nyholm\Psr7\Response; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use RobRichards\XMLSecLibs\XMLSecurityKey; use SimpleSAML\Configuration; use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Module\saml\Message as MSG; use SimpleSAML\SAML2\Assert\Assert; use SimpleSAML\SAML2\Binding; +use SimpleSAML\SAML2\Compat\ContainerSingleton; use SimpleSAML\SAML2\SOAPClient; use SimpleSAML\SAML2\Utils; use SimpleSAML\SAML2\XML\saml\Issuer; @@ -24,6 +24,8 @@ use SimpleSAML\SAML2\XML\samlp\ArtifactResponse; use SimpleSAML\Store\StoreFactory; use SimpleSAML\Utils\HTTP; +use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory; +use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; use function array_key_exists; use function base64_decode; @@ -173,8 +175,10 @@ public function receive(ServerRequestInterface $request): AbstractMessage $soap = new SOAPClient(); // Send message through SoapClient - /** @var \SimpleSAML\SAML2\XML\samlp\ArtifactResponse $artifactResponse */ $artifactResponse = $soap->send($ar, $this->spMetadata, $idpMetadata); + if (!($artifactResponse instanceof ArtifactResponse)) { + throw new Exception('Invalid message received in response to our ArtifactResolve.'); + } if (!$artifactResponse->isSuccess()) { throw new Exception('Received error from ArtifactResolutionService.'); @@ -183,18 +187,27 @@ public function receive(ServerRequestInterface $request): AbstractMessage $samlResponse = $artifactResponse->getMessage(); if ($samlResponse === null) { /* Empty ArtifactResponse - possibly because of Artifact replay? */ - throw new Exception('Empty ArtifactResponse received, maybe a replay?'); } - $samlResponse->addValidator([get_class($this), 'validateSignature'], $artifactResponse); - $query = $request->getQueryParams(); if (isset($query['RelayState'])) { $this->setRelayState($query['RelayState']); } - return $samlResponse; + if (!$samlResponse->isSigned()) { + return $samlResponse; + } + + $container = ContainerSingleton::getInstance(); + $blacklist = $container->getBlacklistedEncryptionAlgorithms(); + $verifier = (new SignatureAlgorithmFactory($blacklist))->getAlgorithm( + $samlResponse->getSignature()->getSignedInfo()->getSignatureMethod()->getAlgorithm(), + // TODO: Need to use the key from the metadata + PEMCertificatesMock::getPublicKey(PEMCertificatesMock::SELFSIGNED_PUBLIC_KEY), + ); + + return $samlResponse->verify($verifier); } @@ -205,17 +218,4 @@ public function setSPMetadata(Configuration $sp): void { $this->spMetadata = $sp; } - - - /** - * A validator which returns true if the ArtifactResponse was signed with the given key - * - * @param \SimpleSAML\SAML2\XML\samlp\ArtifactResponse $message - * @param \RobRichards\XMLSecLibs\XMLSecurityKey $key - */ - public static function validateSignature(ArtifactResponse $message, XMLSecurityKey $key): bool - { - // @todo verify if this works and/or needs to do anything more. Ref. HTTPRedirect binding - return $message->validate($key); - } } diff --git a/src/Configuration/IdentityProvider.php b/src/Configuration/IdentityProvider.php index 7c8dd4a3d..367de3149 100644 --- a/src/Configuration/IdentityProvider.php +++ b/src/Configuration/IdentityProvider.php @@ -8,7 +8,7 @@ use SimpleSAML\XMLSecurity\Constants as C; use function array_filter; -use function array_pop; +use function array_last; use function count; use function sprintf; @@ -94,7 +94,7 @@ public function getPrivateKey(string $name, ?bool $required = null) return null; } - return array_pop($key); + return array_last($key); } diff --git a/src/Configuration/ServiceProvider.php b/src/Configuration/ServiceProvider.php index ab4e2e255..4cfd1235a 100644 --- a/src/Configuration/ServiceProvider.php +++ b/src/Configuration/ServiceProvider.php @@ -8,7 +8,7 @@ use SimpleSAML\XMLSecurity\Constants as C; use function array_filter; -use function array_pop; +use function array_last; use function count; use function sprintf; @@ -102,7 +102,7 @@ public function getPrivateKey(string $name, ?bool $required = null) return null; } - return array_pop($key); + return array_last($key); } diff --git a/src/XML/IdentifierTrait.php b/src/XML/IdentifierTrait.php index 2ad1f2917..40a0a28ab 100644 --- a/src/XML/IdentifierTrait.php +++ b/src/XML/IdentifierTrait.php @@ -12,7 +12,7 @@ use SimpleSAML\SAML2\XML\saml\NameID; use SimpleSAML\XMLSchema\Exception\TooManyElementsException; -use function array_pop; +use function array_last; /** * Trait grouping common functionality for elements that can hold identifiers. @@ -94,7 +94,7 @@ protected static function getIdentifierFromXML(DOMElement $xml): ?IdentifierInte TooManyElementsException::class, ); - $identifier = array_pop($identifiers); + $identifier = array_last($identifiers); return $identifier; } diff --git a/src/XML/SignedElementTrait.php b/src/XML/SignedElementTrait.php index 641fd77cf..57bfd7a66 100644 --- a/src/XML/SignedElementTrait.php +++ b/src/XML/SignedElementTrait.php @@ -11,6 +11,8 @@ use SimpleSAML\XMLSecurity\XML\ds\Signature; use SimpleSAML\XMLSecurity\XML\SignedElementTrait as BaseSignedElementTrait; +use function array_last; + /** * Helper trait for processing signed elements. * @@ -37,7 +39,7 @@ protected function setSignature(Signature $signature): void $references = $signature->getSignedInfo()->getReferences(); Assert::count($references, 1, "A signature needs to have exactly one Reference, %d found."); - $reference = array_pop($references); + $reference = array_last($references); Assert::notNull($reference->getURI(), "URI attribute not found.", ReferenceValidationFailedException::class); Assert::startsWith( $reference->getURI()->getValue(), diff --git a/src/XML/ecp/Request.php b/src/XML/ecp/Request.php index 4f5f3b6ed..5bb4daea6 100644 --- a/src/XML/ecp/Request.php +++ b/src/XML/ecp/Request.php @@ -19,6 +19,7 @@ use SimpleSAML\XMLSchema\Exception\TooManyElementsException; use SimpleSAML\XMLSchema\Type\BooleanValue; +use function array_last; use function intval; use function strval; @@ -140,8 +141,8 @@ public static function fromXML(DOMElement $xml): static $idpList = IDPList::getChildrenOfClass($xml); return new static( - array_pop($issuer), - array_pop($idpList), + array_last($issuer), + array_last($idpList), self::getOptionalAttribute($xml, 'ProviderName', SAMLStringValue::class, null), self::getOptionalAttribute($xml, 'IsPassive', BooleanValue::class, null), ); diff --git a/src/XML/ecp/SubjectConfirmation.php b/src/XML/ecp/SubjectConfirmation.php index a5d6c3d9c..c13a11861 100644 --- a/src/XML/ecp/SubjectConfirmation.php +++ b/src/XML/ecp/SubjectConfirmation.php @@ -17,6 +17,8 @@ use SimpleSAML\XMLSchema\Exception\MissingAttributeException; use SimpleSAML\XMLSchema\Exception\TooManyElementsException; +use function array_last; + /** * Class representing the ECP SubjectConfirmation element. * @@ -113,7 +115,7 @@ public static function fromXML(DOMElement $xml): static return new static( self::getAttribute($xml, 'Method', SAMLAnyURIValue::class), - array_pop($subjectConfirmationData), + array_last($subjectConfirmationData), ); } diff --git a/src/XML/emd/RepublishRequest.php b/src/XML/emd/RepublishRequest.php index d11fb87f1..ff260b873 100644 --- a/src/XML/emd/RepublishRequest.php +++ b/src/XML/emd/RepublishRequest.php @@ -14,7 +14,7 @@ use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException; use SimpleSAML\XMLSchema\Exception\SchemaViolationException; -use function array_pop; +use function array_last; /** * Class implementing RepublishRequest. @@ -71,7 +71,7 @@ public static function fromXML(DOMElement $xml): static SchemaViolationException::class, ); - return new static(array_pop($republishTarget)); + return new static(array_last($republishTarget)); } diff --git a/src/XML/md/AbstractRoleDescriptor.php b/src/XML/md/AbstractRoleDescriptor.php index 231ee1bb8..1c3c0a602 100644 --- a/src/XML/md/AbstractRoleDescriptor.php +++ b/src/XML/md/AbstractRoleDescriptor.php @@ -24,7 +24,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSchema\Type\QNameValue; -use function array_pop; +use function array_last; /** * Class representing a SAML2 RoleDescriptor element. @@ -148,10 +148,10 @@ public static function fromXML(DOMElement $xml): static self::getOptionalAttribute($xml, 'ID', IDValue::class, null), self::getOptionalAttribute($xml, 'validUntil', SAMLDateTimeValue::class, null), self::getOptionalAttribute($xml, 'cacheDuration', DurationValue::class, null), - array_pop($extensions), + array_last($extensions), self::getOptionalAttribute($xml, 'errorURL', SAMLAnyURIValue::class, null), KeyDescriptor::getChildrenOfClass($xml), - array_pop($orgs), + array_last($orgs), ContactPerson::getChildrenOfClass($xml), self::getAttributesNSFromXML($xml), ); diff --git a/src/XML/md/ContactPerson.php b/src/XML/md/ContactPerson.php index 7a9f7c8cd..0a0742ae6 100644 --- a/src/XML/md/ContactPerson.php +++ b/src/XML/md/ContactPerson.php @@ -23,8 +23,8 @@ use function array_filter; use function array_key_exists; use function array_keys; +use function array_last; use function array_map; -use function array_pop; use function count; /** @@ -191,9 +191,9 @@ public static function fromXML(DOMElement $xml): static return new static( $contactType, - array_pop($company), - array_pop($givenName), - array_pop($surName), + array_last($company), + array_last($givenName), + array_last($surName), (count($extensions) === 1) ? $extensions[0] : null, $email, $telephone, diff --git a/src/XML/md/KeyDescriptor.php b/src/XML/md/KeyDescriptor.php index 4404d7b72..4f2910ae3 100644 --- a/src/XML/md/KeyDescriptor.php +++ b/src/XML/md/KeyDescriptor.php @@ -15,7 +15,7 @@ use SimpleSAML\XMLSchema\Exception\TooManyElementsException; use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use function array_pop; +use function array_last; /** * Class representing a KeyDescriptor element. @@ -97,7 +97,7 @@ public static function fromXML(DOMElement $xml): static Assert::maxCount($keyInfo, 1, 'Too many ds:KeyInfo in the KeyDescriptor.', TooManyElementsException::class); return new static( - array_pop($keyInfo), + array_last($keyInfo), self::getOptionalAttribute($xml, 'use', KeyTypesValue::class, null), EncryptionMethod::getChildrenOfClass($xml), ); diff --git a/src/XML/saml/Assertion.php b/src/XML/saml/Assertion.php index 65fe81b98..0d9224936 100644 --- a/src/XML/saml/Assertion.php +++ b/src/XML/saml/Assertion.php @@ -31,8 +31,8 @@ use SimpleSAML\XMLSecurity\XML\SignedElementInterface; use function array_filter; +use function array_last; use function array_merge; -use function array_pop; use function array_values; use function count; use function strval; @@ -315,11 +315,11 @@ public static function fromXML(DOMElement $xml): static $statements = AbstractStatement::getChildrenOfClass($xml); $assertion = new static( - array_pop($issuer), + array_last($issuer), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), self::getAttribute($xml, 'ID', IDValue::class), - array_pop($subject), - array_pop($conditions), + array_last($subject), + array_last($conditions), array_merge($authnStatement, $attrStatement, $statements), ); @@ -382,7 +382,7 @@ public function toXML(?DOMElement $parent = null): DOMElement // Test for an Issuer $messageElements = XPath::xpQuery($signedXML, './saml_assertion:Issuer', XPath::getXPath($signedXML)); - $issuer = array_pop($messageElements); + $issuer = array_last($messageElements); $signedXML->insertBefore($this->signature?->toXML($signedXML), $issuer->nextSibling); return $signedXML; diff --git a/src/XML/saml/AuthnContext.php b/src/XML/saml/AuthnContext.php index 53dd34ad3..adf30750e 100644 --- a/src/XML/saml/AuthnContext.php +++ b/src/XML/saml/AuthnContext.php @@ -15,7 +15,7 @@ use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException; use SimpleSAML\XMLSchema\Exception\TooManyElementsException; -use function array_pop; +use function array_last; use function is_null; /** @@ -142,9 +142,9 @@ public static function fromXML(DOMElement $xml): static $authorities = AuthenticatingAuthority::getChildrenOfClass($xml); return new static( - array_pop($authnContextClassRef), - array_pop($authnContextDecl), - array_pop($authnContextDeclRef), + array_last($authnContextClassRef), + array_last($authnContextDecl), + array_last($authnContextDeclRef), $authorities, ); } diff --git a/src/XML/saml/AuthnStatement.php b/src/XML/saml/AuthnStatement.php index ec11e19b1..bcb56e567 100644 --- a/src/XML/saml/AuthnStatement.php +++ b/src/XML/saml/AuthnStatement.php @@ -14,7 +14,7 @@ use SimpleSAML\XMLSchema\Exception\MissingElementException; use SimpleSAML\XMLSchema\Exception\TooManyElementsException; -use function array_pop; +use function array_last; /** * Class representing a SAML2 AuthnStatement @@ -131,11 +131,11 @@ public static function fromXML(DOMElement $xml): static $subjectLocality = SubjectLocality::getChildrenOfClass($xml); return new static( - array_pop($authnContext), + array_last($authnContext), self::getAttribute($xml, 'AuthnInstant', SAMLDateTimeValue::class), self::getOptionalAttribute($xml, 'SessionNotOnOrAfter', SAMLDateTimeValue::class, null), self::getOptionalAttribute($xml, 'SessionIndex', SAMLStringValue::class, null), - array_pop($subjectLocality), + array_last($subjectLocality), ); } diff --git a/src/XML/saml/AuthzDecisionStatement.php b/src/XML/saml/AuthzDecisionStatement.php index 2bf2b9409..deb866ed9 100644 --- a/src/XML/saml/AuthzDecisionStatement.php +++ b/src/XML/saml/AuthzDecisionStatement.php @@ -16,7 +16,7 @@ use SimpleSAML\XMLSchema\Exception\TooManyElementsException; use SimpleSAML\XMLSchema\Type\AnyURIValue; -use function array_pop; +use function array_last; use function strval; /** @@ -128,7 +128,7 @@ public static function fromXML(DOMElement $xml): static self::getAttribute($xml, 'Resource', AnyURIValue::class), self::getAttribute($xml, 'Decision', DecisionTypeValue::class), $action, - array_pop($evidence), + array_last($evidence), ); } diff --git a/src/XML/saml/Conditions.php b/src/XML/saml/Conditions.php index bdfdf9cc6..fc6926253 100644 --- a/src/XML/saml/Conditions.php +++ b/src/XML/saml/Conditions.php @@ -13,7 +13,7 @@ use SimpleSAML\XML\SchemaValidatableElementTrait; use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException; -use function array_pop; +use function array_last; /** * Class representing SAML 2 Conditions element. @@ -173,8 +173,8 @@ public static function fromXML(DOMElement $xml): static self::getOptionalAttribute($xml, 'NotOnOrAfter', SAMLDateTimeValue::class, null), $condition, $audienceRestriction, - array_pop($oneTimeUse), - array_pop($proxyRestriction), + array_last($oneTimeUse), + array_last($proxyRestriction), ); } diff --git a/src/XML/saml/SubjectConfirmation.php b/src/XML/saml/SubjectConfirmation.php index 67849f790..4f283cbf9 100644 --- a/src/XML/saml/SubjectConfirmation.php +++ b/src/XML/saml/SubjectConfirmation.php @@ -13,7 +13,7 @@ use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException; use SimpleSAML\XMLSchema\Exception\TooManyElementsException; -use function array_pop; +use function array_last; /** * Class representing SAML 2 SubjectConfirmation element. @@ -90,7 +90,7 @@ public static function fromXML(DOMElement $xml): static return new static( self::getAttribute($xml, 'Method', SAMLAnyURIValue::class), self::getIdentifierFromXML($xml), - array_pop($subjectConfirmationData), + array_last($subjectConfirmationData), ); } diff --git a/src/XML/samlp/AbstractMessage.php b/src/XML/samlp/AbstractMessage.php index 2fdfa1606..a7a20920f 100644 --- a/src/XML/samlp/AbstractMessage.php +++ b/src/XML/samlp/AbstractMessage.php @@ -18,7 +18,7 @@ use SimpleSAML\XMLSecurity\XML\SignableElementInterface; use SimpleSAML\XMLSecurity\XML\SignedElementInterface; -use function array_pop; +use function array_last; /** * Base class for all SAML 2 messages. @@ -220,7 +220,7 @@ public function toXML(?DOMElement $parent = null): DOMElement // Test for an Issuer $messageElements = XPath::xpQuery($signedXML, './saml_assertion:Issuer', XPath::getXPath($signedXML)); - $issuer = array_pop($messageElements); + $issuer = array_last($messageElements); $signedXML->insertBefore($this->signature?->toXML($signedXML), $issuer->nextSibling); return $signedXML; diff --git a/src/XML/samlp/ArtifactResolve.php b/src/XML/samlp/ArtifactResolve.php index bd2a4115b..a8d8f1152 100644 --- a/src/XML/samlp/ArtifactResolve.php +++ b/src/XML/samlp/ArtifactResolve.php @@ -20,7 +20,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; /** * The Artifact is part of the SAML 2.0 IdP code, and it builds an artifact object. @@ -110,10 +110,10 @@ public static function fromXML(DOMElement $xml): static self::getAttribute($xml, 'ID', IDValue::class), $artifact[0], self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/ArtifactResponse.php b/src/XML/samlp/ArtifactResponse.php index 25ea261d2..3f3a03f8a 100644 --- a/src/XML/samlp/ArtifactResponse.php +++ b/src/XML/samlp/ArtifactResponse.php @@ -21,7 +21,7 @@ use SimpleSAML\XMLSchema\Type\NCNameValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function version_compare; /** @@ -137,13 +137,13 @@ public static function fromXML(DOMElement $xml): static $response = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($status), + array_last($status), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - empty($issuer) ? null : array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - empty($extensions) ? null : array_pop($extensions), + array_last($extensions), $message, ); diff --git a/src/XML/samlp/AssertionIDRequest.php b/src/XML/samlp/AssertionIDRequest.php index 3cfa5ca62..0dd0843af 100644 --- a/src/XML/samlp/AssertionIDRequest.php +++ b/src/XML/samlp/AssertionIDRequest.php @@ -21,7 +21,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function version_compare; /** @@ -122,11 +122,11 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getAttribute($xml, 'ID', IDValue::class), $assertionIDRef, - array_pop($issuer), + array_last($issuer), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/AttributeQuery.php b/src/XML/samlp/AttributeQuery.php index 0b223457c..2eb3dd900 100644 --- a/src/XML/samlp/AttributeQuery.php +++ b/src/XML/samlp/AttributeQuery.php @@ -24,7 +24,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function in_array; /** @@ -149,13 +149,13 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($subject), + array_last($subject), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), Attribute::getChildrenOfClass($xml), - array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/AuthnQuery.php b/src/XML/samlp/AuthnQuery.php index 90e2a643a..3943c0bdc 100644 --- a/src/XML/samlp/AuthnQuery.php +++ b/src/XML/samlp/AuthnQuery.php @@ -22,7 +22,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function version_compare; /** @@ -133,14 +133,14 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($subject), + array_last($subject), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - array_pop($requestedAuthnContext), + array_last($requestedAuthnContext), self::getOptionalAttribute($xml, 'SessionIndex', SAMLStringValue::class, null), - array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/AuthnRequest.php b/src/XML/samlp/AuthnRequest.php index 5a10d71d4..2093bf747 100644 --- a/src/XML/samlp/AuthnRequest.php +++ b/src/XML/samlp/AuthnRequest.php @@ -24,7 +24,7 @@ use SimpleSAML\XMLSchema\Type\UnsignedShortValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function strval; /** @@ -297,10 +297,10 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getAttribute($xml, 'ID', IDValue::class), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - array_pop($requestedAuthnContext), - array_pop($subject), - array_pop($nameIdPolicy), - array_pop($conditions), + array_last($requestedAuthnContext), + array_last($subject), + array_last($nameIdPolicy), + array_last($conditions), self::getOptionalAttribute($xml, 'ForceAuthn', BooleanValue::class, null), self::getOptionalAttribute($xml, 'IsPassive', BooleanValue::class, null), self::getOptionalAttribute($xml, 'AssertionConsumerServiceURL', SAMLAnyURIValue::class, null), @@ -308,11 +308,11 @@ public static function fromXML(DOMElement $xml): static self::getOptionalAttribute($xml, 'ProtocolBinding', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'AttributeConsumingServiceIndex', UnsignedShortValue::class, null), self::getOptionalAttribute($xml, 'ProviderName', SAMLStringValue::class, null), - array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), - array_pop($scoping), + array_last($extensions), + array_last($scoping), ); if (!empty($signature)) { diff --git a/src/XML/samlp/AuthzDecisionQuery.php b/src/XML/samlp/AuthzDecisionQuery.php index 048771cc5..12703317a 100644 --- a/src/XML/samlp/AuthzDecisionQuery.php +++ b/src/XML/samlp/AuthzDecisionQuery.php @@ -162,15 +162,15 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($subject), + array_last($subject), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), self::getAttribute($xml, 'Resource', SAMLAnyURIValue::class), $action, - array_pop($evidence), - array_pop($issuer), + array_last($evidence), + array_last($issuer), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/IDPList.php b/src/XML/samlp/IDPList.php index 2ca484b4f..eea4d1147 100644 --- a/src/XML/samlp/IDPList.php +++ b/src/XML/samlp/IDPList.php @@ -18,7 +18,7 @@ use function array_filter; use function array_key_exists; use function array_keys; -use function array_pop; +use function array_last; /** * Class for handling SAML2 IDPList. @@ -97,7 +97,7 @@ public static function fromXML(DOMElement $xml): static return new static( $idpEntry, - empty($getComplete) ? null : array_pop($getComplete), + array_last($getComplete), ); } diff --git a/src/XML/samlp/LogoutRequest.php b/src/XML/samlp/LogoutRequest.php index 55cddd2c3..21e801126 100644 --- a/src/XML/samlp/LogoutRequest.php +++ b/src/XML/samlp/LogoutRequest.php @@ -26,7 +26,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; /** * Class for SAML 2 logout request messages. @@ -167,10 +167,10 @@ public static function fromXML(DOMElement $xml): static $notOnOrAfter, self::getOptionalAttribute($xml, 'Reason', SAMLStringValue::class, null), $sessionIndex, - array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/LogoutResponse.php b/src/XML/samlp/LogoutResponse.php index 0c1e39a3b..054838a65 100644 --- a/src/XML/samlp/LogoutResponse.php +++ b/src/XML/samlp/LogoutResponse.php @@ -19,7 +19,7 @@ use SimpleSAML\XMLSchema\Type\NCNameValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function strval; /** @@ -100,13 +100,13 @@ public static function fromXML(DOMElement $xml): static $response = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($status), + array_last($status), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - empty($extensions) ? null : array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/ManageNameIDRequest.php b/src/XML/samlp/ManageNameIDRequest.php index 9abc26f6d..0e68b72b4 100644 --- a/src/XML/samlp/ManageNameIDRequest.php +++ b/src/XML/samlp/ManageNameIDRequest.php @@ -23,8 +23,8 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; +use function array_last; use function array_merge; -use function array_pop; use function version_compare; /** @@ -87,13 +87,13 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getIdentifierFromXML($xml), - array_pop($newIdentifier), + array_last($newIdentifier), self::getAttribute($xml, 'ID', IDValue::class), - array_pop($issuer), + array_last($issuer), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/ManageNameIDResponse.php b/src/XML/samlp/ManageNameIDResponse.php index 742678a0b..5aeb65f2e 100644 --- a/src/XML/samlp/ManageNameIDResponse.php +++ b/src/XML/samlp/ManageNameIDResponse.php @@ -21,7 +21,7 @@ use SimpleSAML\XMLSchema\Type\NCNameValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function strval; /** @@ -108,13 +108,13 @@ public static function fromXML(DOMElement $xml): static $response = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($status), + array_last($status), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - empty($issuer) ? null : array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - empty($extensions) ? null : array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/NameIDMappingRequest.php b/src/XML/samlp/NameIDMappingRequest.php index e00bcb9f0..774fc6d29 100644 --- a/src/XML/samlp/NameIDMappingRequest.php +++ b/src/XML/samlp/NameIDMappingRequest.php @@ -20,7 +20,7 @@ use SimpleSAML\XMLSchema\Type\IDValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function version_compare; /** @@ -74,13 +74,13 @@ public static function fromXML(DOMElement $xml): static $request = new static( self::getIdentifierFromXML($xml), - array_pop($nameIdPolicy), + array_last($nameIdPolicy), self::getAttribute($xml, 'ID', IDValue::class), - array_pop($issuer), + array_last($issuer), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/NameIDMappingResponse.php b/src/XML/samlp/NameIDMappingResponse.php index 68509e03d..c6bef7fde 100644 --- a/src/XML/samlp/NameIDMappingResponse.php +++ b/src/XML/samlp/NameIDMappingResponse.php @@ -24,7 +24,7 @@ use SimpleSAML\XMLSchema\Type\NCNameValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use function array_pop; +use function array_last; use function strval; /** @@ -117,13 +117,13 @@ public static function fromXML(DOMElement $xml): static $response = new static( self::getIdentifierFromXML($xml), self::getAttribute($xml, 'ID', IDValue::class), - array_pop($status), + array_last($status), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - empty($issuer) ? null : array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - empty($extensions) ? null : array_pop($extensions), + array_last($extensions), ); if (!empty($signature)) { diff --git a/src/XML/samlp/Response.php b/src/XML/samlp/Response.php index e101b709d..5c702919a 100644 --- a/src/XML/samlp/Response.php +++ b/src/XML/samlp/Response.php @@ -24,8 +24,8 @@ use SimpleSAML\XMLSchema\Type\NCNameValue; use SimpleSAML\XMLSecurity\XML\ds\Signature; +use function array_last; use function array_merge; -use function array_pop; use function strval; /** @@ -131,13 +131,13 @@ public static function fromXML(DOMElement $xml): static $response = new static( self::getAttribute($xml, 'ID', IDValue::class), - array_pop($status), + array_last($status), self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class), - empty($issuer) ? null : array_pop($issuer), + array_last($issuer), self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null), self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null), self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null), - empty($extensions) ? null : array_pop($extensions), + array_last($extensions), array_merge(Assertion::getChildrenOfClass($xml), EncryptedAssertion::getChildrenOfClass($xml)), ); diff --git a/src/XML/samlp/Scoping.php b/src/XML/samlp/Scoping.php index 261128f34..020314197 100644 --- a/src/XML/samlp/Scoping.php +++ b/src/XML/samlp/Scoping.php @@ -12,7 +12,7 @@ use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException; use SimpleSAML\XMLSchema\Type\NonNegativeIntegerValue; -use function array_pop; +use function array_last; use function strval; /** @@ -96,7 +96,7 @@ public static function fromXML(DOMElement $xml): static return new static( self::getOptionalAttribute($xml, 'ProxyCount', NonNegativeIntegerValue::class, null), - array_pop($idpList), + array_last($idpList), $requesterId, ); } diff --git a/src/XML/samlp/Status.php b/src/XML/samlp/Status.php index 1adc2dcad..5a6615c76 100644 --- a/src/XML/samlp/Status.php +++ b/src/XML/samlp/Status.php @@ -14,7 +14,7 @@ use SimpleSAML\XMLSchema\Exception\MissingElementException; use SimpleSAML\XMLSchema\Exception\TooManyElementsException; -use function array_pop; +use function array_last; use function strval; /** @@ -113,8 +113,8 @@ public static function fromXML(DOMElement $xml): static $statusDetails = StatusDetail::getChildrenOfClass($xml); return new static( - array_pop($statusCode), - array_pop($statusMessage), + array_last($statusCode), + array_last($statusMessage), $statusDetails, ); } diff --git a/tests/SAML2/Constants.php b/tests/SAML2/Constants.php index 2271eb66d..b42e0871a 100644 --- a/tests/SAML2/Constants.php +++ b/tests/SAML2/Constants.php @@ -11,7 +11,7 @@ */ class Constants extends \SimpleSAML\SAML2\Constants { - public const string ENTITY_IDP = 'https://simplesamlphp.org/idp/metadata'; + public const string ENTITY_IDP = 'https://simplesamlphp.org/idp/metadata'; public const string ENTITY_SP = 'https://simplesamlphp.org/sp/metadata'; diff --git a/tests/SAML2/XML/md/EntityDescriptorTest.php b/tests/SAML2/XML/md/EntityDescriptorTest.php index 3f5041820..b988a0371 100644 --- a/tests/SAML2/XML/md/EntityDescriptorTest.php +++ b/tests/SAML2/XML/md/EntityDescriptorTest.php @@ -53,6 +53,7 @@ use SimpleSAML\XMLSchema\Type\StringValue; use SimpleSAML\XMLSecurity\TestUtils\SignedElementTestTrait; +use function array_last; use function dirname; use function strval; @@ -430,7 +431,7 @@ public function testUnmarshalling(): void $attributes = $entityDescriptor->getAttributesNS(); $this->assertCount(1, $attributes); - $attribute = array_pop($attributes); + $attribute = array_last($attributes); $this->assertEquals( [ 'namespaceURI' => 'urn:test:something',