Skip to content

Commit 97e1183

Browse files
committed
Add ManageNameIDRequest-element
1 parent 78e48b6 commit 97e1183

File tree

5 files changed

+288
-4
lines changed

5 files changed

+288
-4
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\SAML2\XML\samlp;
6+
7+
use DOMElement;
8+
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
9+
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
10+
use SimpleSAML\SAML2\XML\IdentifierTrait;
11+
use SimpleSAML\SAML2\XML\saml\EncryptedID;
12+
use SimpleSAML\SAML2\XML\saml\Issuer;
13+
use SimpleSAML\SAML2\XML\saml\NameID;
14+
use SimpleSAML\SAML2\XML\samlp\NewEncryptedID;
15+
use SimpleSAML\SAML2\XML\samlp\NewID;
16+
use SimpleSAML\SAML2\XML\samlp\Terminate;
17+
use SimpleSAML\XMLSchema\Type\IDValue;
18+
19+
/**
20+
* Class representing the samlp:ManageNameIDRequestType.
21+
*
22+
* @package simplesamlphp/saml2
23+
*/
24+
abstract class AbstractManageNameIDRequest extends AbstractRequest
25+
{
26+
use IdentifierTrait;
27+
28+
29+
/**
30+
* Initialize a ManageNameIDRequest.
31+
*
32+
* @param \SimpleSAML\SAML2\XML\saml\NameID|\SimpleSAML\SAML2\XML\saml\EncryptedID $identifier
33+
* @param (
34+
* \SimpleSAML\SAML2\XML\samlp\NewID|
35+
* \SimpleSAML\SAML2\XML\samlp\NewEncryptedID|
36+
* \SimpleSAML\SAML2\XML\samlp\Terminate
37+
* ) $newIdentifier
38+
* @param \SimpleSAML\XMLSchema\Type\IDValue $id
39+
* @param \SimpleSAML\SAML2\XML\saml\Issuer|null $issuer
40+
* @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $issueInstant
41+
* @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $destination
42+
* @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $consent
43+
* @param \SimpleSAML\SAML2\XML\samlp\Extensions $extensions
44+
*/
45+
final public function __construct(
46+
NameID|EncryptedID $identifier,
47+
protected NewID|NewEncryptedID|Terminate $newIdentifier,
48+
IDValue $id,
49+
?Issuer $issuer = null,
50+
?SAMLDateTimeValue $issueInstant = null,
51+
?SAMLAnyURIValue $destination = null,
52+
?SAMLAnyURIValue $consent = null,
53+
?Extensions $extensions = null,
54+
) {
55+
$this->setIdentifier($identifier);
56+
57+
parent::__construct($id, $issuer, $issueInstant, $destination, $consent, $extensions);
58+
}
59+
60+
61+
/**
62+
* Retrieve the new identifier.
63+
*
64+
* @return (
65+
* \SimpleSAML\SAML2\XML\samlp\NewID|
66+
* \SimpleSAML\SAML2\XML\samlp\NewEncryptedID|
67+
* \SimpleSAML\SAML2\XML\samlp\Terminate
68+
* )
69+
*/
70+
public function getNewIdentifier(): NewID|NewEncryptedID|Terminate
71+
{
72+
return $this->newIdentifier;
73+
}
74+
75+
76+
/**
77+
* Convert this ManageNameIDRequest to XML
78+
*/
79+
public function toUnsignedXML(?DOMElement $parent = null): DOMElement
80+
{
81+
$e = parent::toUnsignedXML($parent);
82+
83+
$this->getIdentifier()->toXML($e);
84+
$this->getNewIdentifier()->toXML($e);
85+
86+
return $e;
87+
}
88+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\SAML2\XML\samlp;
6+
7+
use DOMElement;
8+
use SimpleSAML\SAML2\Assert\Assert;
9+
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooHighException;
10+
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooLowException;
11+
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
12+
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
13+
use SimpleSAML\SAML2\Type\SAMLStringValue;
14+
use SimpleSAML\SAML2\XML\saml\Issuer;
15+
use SimpleSAML\SAML2\XML\samlp\NewEncryptedID;
16+
use SimpleSAML\SAML2\XML\samlp\NewID;
17+
use SimpleSAML\SAML2\XML\samlp\Terminate;
18+
use SimpleSAML\XML\SchemaValidatableElementInterface;
19+
use SimpleSAML\XML\SchemaValidatableElementTrait;
20+
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
21+
use SimpleSAML\XMLSchema\Exception\MissingElementException;
22+
use SimpleSAML\XMLSchema\Exception\TooManyElementsException;
23+
use SimpleSAML\XMLSchema\Type\IDValue;
24+
use SimpleSAML\XMLSecurity\XML\ds\Signature;
25+
26+
use function array_merge;
27+
use function array_pop;
28+
use function version_compare;
29+
30+
/**
31+
* Class for handling SAML2 ManageNameIDRequest.
32+
*
33+
* @package simplesamlphp/saml2
34+
*/
35+
final class ManageNameIDRequest extends AbstractManageNameIDRequest implements
36+
SchemaValidatableElementInterface
37+
{
38+
use SchemaValidatableElementTrait;
39+
40+
41+
/**
42+
* Convert XML into a ManageNameIDRequest
43+
*
44+
* @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
45+
* if the qualified name of the supplied element is wrong
46+
*/
47+
public static function fromXML(DOMElement $xml): static
48+
{
49+
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
50+
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
51+
52+
$version = self::getAttribute($xml, 'Version', SAMLStringValue::class);
53+
Assert::true(version_compare('2.0', strval($version), '<='), RequestVersionTooLowException::class);
54+
Assert::true(version_compare('2.0', strval($version), '>='), RequestVersionTooHighException::class);
55+
56+
$issuer = Issuer::getChildrenOfClass($xml);
57+
Assert::maxCount($issuer, 1, 'Only one <saml:Issuer> element is allowed.', TooManyElementsException::class);
58+
59+
$extensions = Extensions::getChildrenOfClass($xml);
60+
Assert::maxCount(
61+
$extensions,
62+
1,
63+
'Only one <samlp:Extensions> element is allowed.',
64+
TooManyElementsException::class,
65+
);
66+
67+
$signature = Signature::getChildrenOfClass($xml);
68+
Assert::maxCount(
69+
$signature,
70+
1,
71+
'Only one <ds:Signature> element is allowed.',
72+
TooManyElementsException::class,
73+
);
74+
75+
$newId = NewID::getChildrenOfClass($xml);
76+
Assert::maxCount($newId, 1, TooManyElementsException::class);
77+
78+
$newEncryptedId = NewEncryptedID::getChildrenOfClass($xml);
79+
Assert::maxCount($newEncryptedId, 1, TooManyElementsException::class);
80+
81+
$terminate = Terminate::getChildrenOfClass($xml);
82+
Assert::maxCount($terminate, 1, TooManyElementsException::class);
83+
84+
$newIdentifier = array_merge($newId, $newEncryptedId, $terminate);
85+
Assert::minCount($newIdentifier, 1, MissingElementException::class);
86+
Assert::maxCount($newIdentifier, 1, TooManyElementsException::class);
87+
88+
$request = new static(
89+
self::getIdentifierFromXML($xml),
90+
array_pop($newIdentifier),
91+
self::getAttribute($xml, 'ID', IDValue::class),
92+
array_pop($issuer),
93+
self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class),
94+
self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null),
95+
self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null),
96+
array_pop($extensions),
97+
);
98+
99+
if (!empty($signature)) {
100+
$request->setSignature($signature[0]);
101+
$request->messageContainedSignatureUponConstruction = true;
102+
$request->setXML($xml);
103+
}
104+
105+
return $request;
106+
}
107+
}

src/XML/samlp/NewEncryptedID.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use SimpleSAML\SAML2\Constants as C;
99
use SimpleSAML\SAML2\XML\saml\AbstractBaseID;
1010
use SimpleSAML\SAML2\XML\saml\AbstractEncryptedElement;
11-
use SimpleSAML\SAML2\XML\saml\IdentifierInterface;
1211
use SimpleSAML\SAML2\XML\saml\NameID;
1312
use SimpleSAML\XML\DOMDocumentFactory;
1413
use SimpleSAML\XML\SchemaValidatableElementInterface;
@@ -23,9 +22,7 @@
2322
*
2423
* @package simplesamlphp/saml2
2524
*/
26-
final class NewEncryptedID extends AbstractEncryptedElement implements
27-
IdentifierInterface,
28-
SchemaValidatableElementInterface
25+
final class NewEncryptedID extends AbstractEncryptedElement implements SchemaValidatableElementInterface
2926
{
3027
use SchemaValidatableElementTrait;
3128

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\SAML2\XML\samlp;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\Group;
9+
use PHPUnit\Framework\TestCase;
10+
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
11+
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
12+
use SimpleSAML\SAML2\Type\SAMLStringValue;
13+
use SimpleSAML\SAML2\XML\saml\Issuer;
14+
use SimpleSAML\SAML2\XML\saml\NameID;
15+
use SimpleSAML\SAML2\XML\samlp\AbstractMessage;
16+
use SimpleSAML\SAML2\XML\samlp\AbstractRequest;
17+
use SimpleSAML\SAML2\XML\samlp\AbstractSamlpElement;
18+
use SimpleSAML\SAML2\XML\samlp\ManageNameIDRequest;
19+
use SimpleSAML\SAML2\XML\samlp\Terminate;
20+
use SimpleSAML\XML\DOMDocumentFactory;
21+
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
22+
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;
23+
use SimpleSAML\XMLSchema\Type\IDValue;
24+
25+
use function dirname;
26+
use function strval;
27+
28+
/**
29+
* Class \SimpleSAML\SAML2\XML\samlp\ManageNameIDRequestTest
30+
*
31+
* @package simplesamlphp/saml2
32+
*/
33+
#[Group('saml')]
34+
#[CoversClass(ManageNameIDRequest::class)]
35+
#[CoversClass(AbstractRequest::class)]
36+
#[CoversClass(AbstractMessage::class)]
37+
#[CoversClass(AbstractSamlpElement::class)]
38+
final class ManageNameIDRequestTest extends TestCase
39+
{
40+
use SchemaValidationTestTrait;
41+
use SerializableElementTestTrait;
42+
43+
44+
/**
45+
*/
46+
public static function setUpBeforeClass(): void
47+
{
48+
self::$testedClass = ManageNameIDRequest::class;
49+
50+
self::$xmlRepresentation = DOMDocumentFactory::fromFile(
51+
dirname(__FILE__, 4) . '/resources/xml/samlp_ManageNameIDRequest.xml',
52+
);
53+
}
54+
55+
56+
// marshalling
57+
58+
59+
/**
60+
*/
61+
public function testMarshalling(): void
62+
{
63+
$nameId = new NameID(
64+
SAMLStringValue::fromString('TheNameIDValue'),
65+
SAMLStringValue::fromString('urn:x-simplesamlphp:namequalifier'),
66+
SAMLStringValue::fromString('urn:x-simplesamlphp:spnamequalifier'),
67+
SAMLAnyURIValue::fromString('urn:the:format'),
68+
SAMLStringValue::fromString('TheSPProvidedID'),
69+
);
70+
71+
$manageNameIdRequest = new ManageNameIDRequest(
72+
identifier: $nameId,
73+
newIdentifier: new Terminate(),
74+
issuer: new Issuer(
75+
SAMLStringValue::fromString('https://gateway.stepup.org/saml20/sp/metadata'),
76+
),
77+
id: IDValue::fromString('_2b0226190ca1c22de6f66e85f5c95158'),
78+
issueInstant: SAMLDateTimeValue::fromString('2014-09-22T13:42:00Z'),
79+
destination: SAMLAnyURIValue::fromString('https://tiqr.stepup.org/idp/profile/saml2/Redirect/SSO'),
80+
);
81+
82+
$this->assertEquals(
83+
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
84+
strval($manageNameIdRequest),
85+
);
86+
}
87+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<samlp:ManageNameIDRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_2b0226190ca1c22de6f66e85f5c95158" IssueInstant="2014-09-22T13:42:00Z" Destination="https://tiqr.stepup.org/idp/profile/saml2/Redirect/SSO">
2+
<saml:Issuer>https://gateway.stepup.org/saml20/sp/metadata</saml:Issuer>
3+
<saml:NameID NameQualifier="urn:x-simplesamlphp:namequalifier" SPNameQualifier="urn:x-simplesamlphp:spnamequalifier" Format="urn:the:format" SPProvidedID="TheSPProvidedID">TheNameIDValue</saml:NameID>
4+
<samlp:Terminate />
5+
</samlp:ManageNameIDRequest>

0 commit comments

Comments
 (0)