Skip to content

Commit

Permalink
Add support for IDP Discovery endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Feb 26, 2023
1 parent 9dc468f commit 20e88b7
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 0 deletions.
22 changes: 22 additions & 0 deletions schemas/sstc-saml-idp-discovery.xsd
@@ -0,0 +1,22 @@
<schema
targetNamespace="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
attributeFormDefault="unqualified"
blockDefault="substitution"
version="2.0">
<annotation>
<documentation>
Document identifier: sstc-saml-idp-discovery
Location: http://www.oasis-open.org/committees/documents.php?wg_abbrev=security
Revision history:
V1.0 (January 2007):
Initial version.
</documentation>
</annotation>
<import namespace="urn:oasis:names:tc:SAML:2.0:metadata"
schemaLocation="saml-schema-metadata-2.0.xsd"/>
<element name="DiscoveryResponse" type="md:IndexedEndpointType"/>
</schema>
5 changes: 5 additions & 0 deletions src/SAML2/Constants.php
Expand Up @@ -267,6 +267,11 @@ class Constants extends \SimpleSAML\XMLSecurity\Constants
*/
public const NS_SOAP = 'http://schemas.xmlsoap.org/soap/envelope/';

/**
* The namespace for the IDP Discovery protocol
*/
public const NS_IDPDISC = 'urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol';

/**
* The responding provider was unable to successfully authenticate the principal.
*
Expand Down
24 changes: 24 additions & 0 deletions src/SAML2/XML/idpdisc/DiscoveryResponse.php
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\SAML2\XML\idpdisc;

use SimpleSAML\SAML2\Constants as C;
use SimpleSAML\SAML2\XML\md\AbstractIndexedEndpointType;

/**
* Abstract class to be implemented by all the classes in this namespace
*
* @package simplesamlphp/saml2
*
* @see http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-idp-discovery.html
*/
final class DiscoveryResponse extends AbstractIndexedEndpointType
{
/** @var string */
public const NS = C::NS_IDPDISC;

/** @var string */
public const NS_PREFIX = 'idpdisc';
}
96 changes: 96 additions & 0 deletions tests/SAML2/XML/idpdisc/DiscoveryResponseTest.php
@@ -0,0 +1,96 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\SAML2\XML\idpdisc;

use DOMDocument;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Assert\AssertionFailedException;
use SimpleSAML\SAML2\XML\idpdisc\DiscoveryResponse;
use SimpleSAML\Test\SAML2\Constants as C;
use SimpleSAML\Test\XML\SchemaValidationTestTrait;
use SimpleSAML\Test\XML\SerializableElementTestTrait;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingAttributeException;

use function dirname;
use function strval;

/**
* Class \SAML2\XML\idpdisc\DiscoveryResponseTest
*
* @covers \SimpleSAML\SAML2\XML\idpdisc\DiscoveryResponse
* @covers \SimpleSAML\SAML2\XML\md\AbstractIndexedEndpointType
* @covers \SimpleSAML\SAML2\XML\md\AbstractMdElement
* @package simplesamlphp/saml2
*/
final class DiscoveryEndpointTest extends TestCase
{
use SchemaValidationTestTrait;
use SerializableElementTestTrait;


/**
*/
protected function setUp(): void
{
$this->schema = dirname(__FILE__, 5) . '/schemas/sstc-saml-idp-discovery.xsd';

$this->testedClass = DiscoveryResponse::class;

$this->xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 4) . '/resources/xml/idpdisc_DiscoveryResponse.xml',
);
}


// test marshalling


/**
* Test creating a DiscoveryResponse from scratch.
*/
public function testMarshalling(): void
{
$discoResponse = new DiscoveryResponse(43, C::BINDING_HTTP_POST, C::LOCATION_A, false);

$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
strval($discoResponse),
);
}


/**
* Test that creating a DiscoveryResponse from scratch without specifying isDefault works.
*/
public function testMarshallingWithoutIsDefault(): void
{
$discoResponse = new DiscoveryResponse(43, C::BINDING_HTTP_POST, C::LOCATION_A);
$this->xmlRepresentation->documentElement->removeAttribute('isDefault');
$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
strval($discoResponse),
);
$this->assertNull($discoResponse->getIsDefault());
}


// test unmarshalling


/**
* Test creating a DiscoveryResponse from XML.
*/
public function testUnmarshalling(): void
{
$discoResponse = DiscoveryResponse::fromXML($this->xmlRepresentation->documentElement);

$this->assertEquals(
$this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement),
strval($discoResponse),
);
}
}
1 change: 1 addition & 0 deletions tests/resources/xml/idpdisc_DiscoveryResponse.xml
@@ -0,0 +1 @@
<idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://simplesamlphp.org/some/endpoint" index="43" isDefault="false" />

0 comments on commit 20e88b7

Please sign in to comment.