summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaime Perez Crespo <jaime.perez@uninett.no>2015-08-04 12:19:36 +0200
committerJaime Perez Crespo <jaime.perez@uninett.no>2015-08-04 12:19:36 +0200
commit701009c27cbdf1835e1b6e8948a90ae08de2c1fa (patch)
treee136384947f4322487d46aa59a13ac3128365185
parentd66068e8be08efe59385a27e6089af3dbef0b03d (diff)
downloadsimplesamlphp-701009c27cbdf1835e1b6e8948a90ae08de2c1fa.zip
simplesamlphp-701009c27cbdf1835e1b6e8948a90ae08de2c1fa.tar.gz
simplesamlphp-701009c27cbdf1835e1b6e8948a90ae08de2c1fa.tar.bz2
Reformat SimpleSAML_Metadata_SAMLBuilder.
-rw-r--r--lib/SimpleSAML/Metadata/SAMLBuilder.php1414
1 files changed, 720 insertions, 694 deletions
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index c2c377e..d2f8d18 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -1,5 +1,6 @@
<?php
+
/**
* Class for generating SAML 2.0 metadata from simpleSAMLphp metadata arrays.
*
@@ -7,736 +8,761 @@
*
* @package simpleSAMLphp
*/
-class SimpleSAML_Metadata_SAMLBuilder {
-
-
-
- /**
- * The EntityDescriptor we are building.
- *
- * @var string
- */
- private $entityDescriptor;
-
-
- /**
- * The maximum time in seconds the metadata should be cached.
- *
- * @var int|null
- */
- private $maxCache = NULL;
-
-
- /**
- * The maximum time in seconds since the current time that this metadata should be considered valid.
- *
- * @var int|null
- */
- private $maxDuration = NULL;
-
- /**
- * Initialize the SAML builder.
- *
- * @param string $entityId The entity id of the entity.
- * @param int|null $maxCache The maximum time in seconds the metadata should be cached. Defaults to null
- * @param int|null $maxDuration The maximum time in seconds this metadata should be considered valid. Defaults
- * to null.
- */
- public function __construct($entityId, $maxCache = NULL, $maxDuration = NULL) {
- assert('is_string($entityId)');
-
- $this->maxCache = $maxCache;
- $this->maxDuration = $maxDuration;
-
- $this->entityDescriptor = new SAML2_XML_md_EntityDescriptor();
- $this->entityDescriptor->entityID = $entityId;
- }
-
- private function setExpiration($metadata) {
-
- if (array_key_exists('expire', $metadata)) {
- if ($metadata['expire'] - time() < $this->maxDuration)
- $this->maxDuration = $metadata['expire'] - time();
- }
-
- if ($this->maxCache !== NULL)
- $this->entityDescriptor->cacheDuration = 'PT' . $this->maxCache . 'S';
- if ($this->maxDuration !== NULL)
- $this->entityDescriptor->validUntil = time() + $this->maxDuration;
- }
-
-
- /**
- * Retrieve the EntityDescriptor element which is generated for this entity.
- *
- * @return DOMElement The EntityDescriptor element of this entity.
- */
- public function getEntityDescriptor() {
-
- $xml = $this->entityDescriptor->toXML();
- $xml->ownerDocument->appendChild($xml);
-
- return $xml;
- }
-
-
- /**
- * Retrieve the EntityDescriptor as text.
- *
- * This function serializes this EntityDescriptor, and returns it as text.
- *
- * @param bool $formatted Whether the returned EntityDescriptor should be formatted first.
- * @return string The serialized EntityDescriptor.
- */
- public function getEntityDescriptorText($formatted = TRUE) {
- assert('is_bool($formatted)');
-
- $xml = $this->getEntityDescriptor();
- if ($formatted) {
- SimpleSAML\Utils\XML::formatDOMElement($xml);
- }
-
- return $xml->ownerDocument->saveXML();
- }
-
-
- /**
- * Add a SecurityTokenServiceType for ADFS metadata.
- *
- * @param array $metadata The metadata with the information about the SecurityTokenServiceType.
- */
- public function addSecurityTokenServiceType($metadata) {
- assert('is_array($metadata)');
- assert('isset($metadata["entityid"])');
- assert('isset($metadata["metadata-set"])');
-
- $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $defaultEndpoint = $metadata->getDefaultEndpoint('SingleSignOnService');
- $e = new sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType();
- $e->Location = $defaultEndpoint['Location'];
-
- $this->addCertificate($e, $metadata);
-
- $this->entityDescriptor->RoleDescriptor[] = $e;
- }
-
- /**
- * Add extensions to the metadata.
- *
- * @param SimpleSAML_Configuration $metadata The metadata to get extensions from.
- * @param SAML2_XML_md_RoleDescriptor $e Reference to the element where the Extensions element should be included.
- */
- private function addExtensions(SimpleSAML_Configuration $metadata, SAML2_XML_md_RoleDescriptor $e) {
-
- if ($metadata->hasValue('tags')) {
- $a = new SAML2_XML_saml_Attribute();
- $a->Name = 'tags';
- foreach ($metadata->getArray('tags') as $tag) {
- $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($tag);
- }
- $e->Extensions[] = $a;
- }
-
- if ($metadata->hasValue('hint.cidr')) {
- $a = new SAML2_XML_saml_Attribute();
- $a->Name = 'hint.cidr';
- foreach ($metadata->getArray('hint.cidr') as $hint) {
- $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($hint);
- }
- $e->Extensions[] = $a;
- }
-
- if ($metadata->hasValue('scope')) {
- foreach ($metadata->getArray('scope') as $scopetext) {
- $s = new SAML2_XML_shibmd_Scope();
- $s->scope = $scopetext;
- // Check whether $ ^ ( ) * | \ are in a scope -> assume regex.
- if (1 === preg_match('/[\$\^\)\(\*\|\\\\]/', $scopetext)) {
- $s->regexp = TRUE;
- } else {
- $s->regexp = FALSE;
- }
- $e->Extensions[] = $s;
- }
- }
-
- if ($metadata->hasValue('EntityAttributes')) {
- $ea = new SAML2_XML_mdattr_EntityAttributes();
- foreach ($metadata->getArray('EntityAttributes') as $attributeName => $attributeValues) {
- $a = new SAML2_XML_saml_Attribute();
- $a->Name = $attributeName;
- $a->NameFormat = 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri';
-
- // Attribute names that is not URI is prefixed as this: '{nameformat}name'
- if (preg_match('/^\{(.*?)\}(.*)$/', $attributeName, $matches)) {
- $a->Name = $matches[2];
- $nameFormat = $matches[1];
- if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
- $a->NameFormat = $nameFormat;
- }
- }
- foreach ($attributeValues as $attributeValue) {
- $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($attributeValue);
- }
- $ea->children[] = $a;
- }
- $this->entityDescriptor->Extensions[] = $ea;
- }
-
- if ($metadata->hasValue('RegistrationInfo')) {
- $ri = new SAML2_XML_mdrpi_RegistrationInfo();
- foreach ($metadata->getArray('RegistrationInfo') as $riName => $riValues) {
- switch ($riName) {
- case 'authority':
- $ri->registrationAuthority = $riValues;
- break;
- case 'instant':
- $ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues);
- break;
- case 'policies':
- $ri->RegistrationPolicy = $riValues;
- break;
- }
- }
- $this->entityDescriptor->Extensions[] = $ri;
-
- }
-
- if ($metadata->hasValue('UIInfo')) {
- $ui = new SAML2_XML_mdui_UIInfo();
- foreach ($metadata->getArray('UIInfo') as $uiName => $uiValues) {
- switch ($uiName) {
- case 'DisplayName':
- $ui->DisplayName = $uiValues;
- break;
- case 'Description':
- $ui->Description = $uiValues;
- break;
- case 'InformationURL':
- $ui->InformationURL = $uiValues;
- break;
- case 'PrivacyStatementURL':
- $ui->PrivacyStatementURL = $uiValues;
- break;
- case 'Keywords':
- foreach ($uiValues as $lang => $keywords) {
- $uiItem = new SAML2_XML_mdui_Keywords();
- $uiItem->lang = $lang;
- $uiItem->Keywords = $keywords;
- $ui->Keywords[] = $uiItem;
- }
- break;
- case 'Logo':
- foreach ($uiValues as $logo) {
- $uiItem = new SAML2_XML_mdui_Logo();
- $uiItem->url = $logo['url'];
- $uiItem->width = $logo['width'];
- $uiItem->height = $logo['height'];
- if (isset($logo['lang'])) {
- $uiItem->lang = $logo['lang'];
- }
- $ui->Logo[] = $uiItem;
- }
- break;
- }
- }
- $e->Extensions[] = $ui;
- }
-
- if ($metadata->hasValue('DiscoHints')) {
- $dh = new SAML2_XML_mdui_DiscoHints();
- foreach ($metadata->getArray('DiscoHints') as $dhName => $dhValues) {
- switch ($dhName) {
- case 'IPHint':
- $dh->IPHint = $dhValues;
- break;
- case 'DomainHint':
- $dh->DomainHint = $dhValues;
- break;
- case 'GeolocationHint':
- $dh->GeolocationHint = $dhValues;
- break;
- }
- }
- $e->Extensions[] = $dh;
- }
- }
-
-
- /**
- * Add an Organization element based on data passed as parameters
- *
- * @param array $orgName An array with the localized OrganizationName.
- * @param array $orgDisplayName An array with the localized OrganizationDisplayName.
- * @param array $orgURL An array with the localized OrganizationURL.
- */
- public function addOrganization(array $orgName, array $orgDisplayName, array $orgURL) {
-
- $org = new SAML2_XML_md_Organization();
-
- $org->OrganizationName = $orgName;
- $org->OrganizationDisplayName = $orgDisplayName;
- $org->OrganizationURL = $orgURL;
-
- $this->entityDescriptor->Organization = $org;
- }
-
-
- /**
- * Add an Organization element based on metadata array.
- *
- * @param array $metadata The metadata we should extract the organization information from.
- */
- public function addOrganizationInfo(array $metadata) {
-
- if (
- empty($metadata['OrganizationName']) ||
- empty($metadata['OrganizationDisplayName']) ||
- empty($metadata['OrganizationURL'])
- ) {
- /* Empty or incomplete organization information. */
- return;
- }
-
- $orgName = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationName'], 'en');
- $orgDisplayName = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationDisplayName'], 'en');
- $orgURL = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationURL'], 'en');
-
- $this->addOrganization($orgName, $orgDisplayName, $orgURL);
- }
-
-
- /**
- * Add a list of endpoints to metadata.
- *
- * @param array $endpoints The endpoints.
- * @param bool $indexed Whether the endpoints should be indexed.
- * @return SAML2_XML_md_IndexedEndpointType[]|SAML2_XML_md_EndpointType[] An array of endpoint objects.
- */
- private static function createEndpoints(array $endpoints, $indexed) {
- assert('is_bool($indexed)');
-
- $ret = array();
-
- foreach ($endpoints as &$ep) {
- if ($indexed) {
- $t = new SAML2_XML_md_IndexedEndpointType();
- } else {
- $t = new SAML2_XML_md_EndpointType();
- }
-
- $t->Binding = $ep['Binding'];
- $t->Location = $ep['Location'];
- if (isset($ep['ResponseLocation'])) {
- $t->ResponseLocation = $ep['ResponseLocation'];
- }
- if (isset($ep['hoksso:ProtocolBinding'])) {
- $t->setAttributeNS(SAML2_Const::NS_HOK, 'hoksso:ProtocolBinding', SAML2_Const::BINDING_HTTP_REDIRECT);
- }
-
- if ($indexed) {
- if (!isset($ep['index'])) {
- /* Find the maximum index. */
- $maxIndex = -1;
- foreach ($endpoints as $ep) {
- if (!isset($ep['index'])) {
- continue;
- }
-
- if ($ep['index'] > $maxIndex) {
- $maxIndex = $ep['index'];
- }
- }
-
- $ep['index'] = $maxIndex + 1;
- }
-
- $t->index = $ep['index'];
- }
-
- $ret[] = $t;
- }
-
- return $ret;
- }
-
-
- /**
- * Add an AttributeConsumingService element to the metadata.
- *
- * @param SAML2_XML_md_SPSSODescriptor $spDesc The SPSSODescriptor element.
- * @param SimpleSAML_Configuration $metadata The metadata.
- */
- private function addAttributeConsumingService(SAML2_XML_md_SPSSODescriptor $spDesc, SimpleSAML_Configuration $metadata) {
- $attributes = $metadata->getArray('attributes', array());
- $name = $metadata->getLocalizedString('name', NULL);
-
- if ($name === NULL || count($attributes) == 0) {
- /* We cannot add an AttributeConsumingService without name and attributes. */
- return;
- }
-
- $attributesrequired = $metadata->getArray('attributes.required', array());
-
- /*
- * Add an AttributeConsumingService element with information as name and description and list
- * of requested attributes
- */
- $attributeconsumer = new SAML2_XML_md_AttributeConsumingService();
-
- $attributeconsumer->index = 0;
-
- $attributeconsumer->ServiceName = $name;
- $attributeconsumer->ServiceDescription = $metadata->getLocalizedString('description', array());
-
- $nameFormat = $metadata->getString('attributes.NameFormat', SAML2_Const::NAMEFORMAT_UNSPECIFIED);
- foreach ($attributes as $friendlyName => $attribute) {
- $t = new SAML2_XML_md_RequestedAttribute();
- $t->Name = $attribute;
- if (!is_int($friendlyName)) {
- $t->FriendlyName = $friendlyName;
- }
- if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
- $t->NameFormat = $nameFormat;
- }
- if (in_array($attribute, $attributesrequired)) {
- $t->isRequired = true;
- }
- $attributeconsumer->RequestedAttribute[] = $t;
- }
-
- $spDesc->AttributeConsumingService[] = $attributeconsumer;
- }
-
-
- /**
- * Add a specific type of metadata to an entity.
- *
- * @param string $set The metadata set this metadata comes from.
- * @param array $metadata The metadata.
- */
- public function addMetadata($set, $metadata) {
- assert('is_string($set)');
- assert('is_array($metadata)');
-
- $this->setExpiration($metadata);
-
- switch ($set) {
- case 'saml20-sp-remote':
- $this->addMetadataSP20($metadata);
- break;
- case 'saml20-idp-remote':
- $this->addMetadataIdP20($metadata);
- break;
- case 'shib13-sp-remote':
- $this->addMetadataSP11($metadata);
- break;
- case 'shib13-idp-remote':
- $this->addMetadataIdP11($metadata);
- break;
- case 'attributeauthority-remote':
- $this->addAttributeAuthority($metadata);
- break;
- default:
- SimpleSAML_Logger::warning('Unable to generate metadata for unknown type \'' . $set . '\'.');
- }
-
- }
-
- /**
- * Add SAML 2.0 SP metadata.
- *
- * @param array $metadata The metadata.
- * @param array $protocols The protocols supported. Defaults to SAML2_Const::NS_SAMLP.
- */
- public function addMetadataSP20($metadata, $protocols = array(SAML2_Const::NS_SAMLP)) {
- assert('is_array($metadata)');
- assert('is_array($protocols)');
- assert('isset($metadata["entityid"])');
- assert('isset($metadata["metadata-set"])');
-
- $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
-
- $e = new SAML2_XML_md_SPSSODescriptor();
- $e->protocolSupportEnumeration = $protocols;
-
- if ($metadata->hasValue('saml20.sign.assertion')) {
- $e->WantAssertionsSigned = $metadata->getBoolean('saml20.sign.assertion');
- }
-
- if ($metadata->hasValue('redirect.validate')) {
- $e->AuthnRequestsSigned = $metadata->getBoolean('redirect.validate');
- } elseif ($metadata->hasValue('validate.authnrequest')) {
- $e->AuthnRequestsSigned = $metadata->getBoolean('validate.authnrequest');
- }
-
- $this->addExtensions($metadata, $e);
-
- $this->addCertificate($e, $metadata);
-
- $e->SingleLogoutService = self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), FALSE);
-
- $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
-
- $endpoints = $metadata->getEndpoints('AssertionConsumerService');
- foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', array()) as $acs) {
- $endpoints[] = array(
- 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
- 'Location' => $acs,
- );
- }
- $e->AssertionConsumerService = self::createEndpoints($endpoints, TRUE);
-
- $this->addAttributeConsumingService($e, $metadata);
-
- $this->entityDescriptor->RoleDescriptor[] = $e;
-
- foreach ($metadata->getArray('contacts', array()) as $contact) {
- if (array_key_exists('contactType', $contact) && array_key_exists('emailAddress', $contact)) {
- $this->addContact($contact['contactType'], \SimpleSAML\Utils\Config\Metadata::getContact($contact));
- }
- }
-
- }
-
-
- /**
- * Add metadata of a SAML 2.0 identity provider.
- *
- * @param array $metadata The metadata.
- */
- public function addMetadataIdP20($metadata) {
- assert('is_array($metadata)');
- assert('isset($metadata["entityid"])');
- assert('isset($metadata["metadata-set"])');
-
- $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
-
- $e = new SAML2_XML_md_IDPSSODescriptor();
- $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:2.0:protocol';
-
- if ($metadata->hasValue('sign.authnrequest')) {
- $e->WantAuthnRequestsSigned = $metadata->getBoolean('sign.authnrequest');
- } elseif ($metadata->hasValue('redirect.sign')) {
- $e->WantAuthnRequestsSigned = $metadata->getBoolean('redirect.sign');
- }
+class SimpleSAML_Metadata_SAMLBuilder
+{
+
+
+ /**
+ * The EntityDescriptor we are building.
+ *
+ * @var string
+ */
+ private $entityDescriptor;
+
+
+ /**
+ * The maximum time in seconds the metadata should be cached.
+ *
+ * @var int|null
+ */
+ private $maxCache = null;
+
+
+ /**
+ * The maximum time in seconds since the current time that this metadata should be considered valid.
+ *
+ * @var int|null
+ */
+ private $maxDuration = null;
+
+
+ /**
+ * Initialize the SAML builder.
+ *
+ * @param string $entityId The entity id of the entity.
+ * @param int|null $maxCache The maximum time in seconds the metadata should be cached. Defaults to null
+ * @param int|null $maxDuration The maximum time in seconds this metadata should be considered valid. Defaults
+ * to null.
+ */
+ public function __construct($entityId, $maxCache = null, $maxDuration = null)
+ {
+ assert('is_string($entityId)');
+
+ $this->maxCache = $maxCache;
+ $this->maxDuration = $maxDuration;
+
+ $this->entityDescriptor = new SAML2_XML_md_EntityDescriptor();
+ $this->entityDescriptor->entityID = $entityId;
+ }
+
+
+ private function setExpiration($metadata)
+ {
+ if (array_key_exists('expire', $metadata)) {
+ if ($metadata['expire'] - time() < $this->maxDuration) {
+ $this->maxDuration = $metadata['expire'] - time();
+ }
+ }
+
+ if ($this->maxCache !== null) {
+ $this->entityDescriptor->cacheDuration = 'PT'.$this->maxCache.'S';
+ }
+ if ($this->maxDuration !== null) {
+ $this->entityDescriptor->validUntil = time() + $this->maxDuration;
+ }
+ }
+
+
+ /**
+ * Retrieve the EntityDescriptor element which is generated for this entity.
+ *
+ * @return DOMElement The EntityDescriptor element of this entity.
+ */
+ public function getEntityDescriptor()
+ {
+ $xml = $this->entityDescriptor->toXML();
+ $xml->ownerDocument->appendChild($xml);
+
+ return $xml;
+ }
+
+
+ /**
+ * Retrieve the EntityDescriptor as text.
+ *
+ * This function serializes this EntityDescriptor, and returns it as text.
+ *
+ * @param bool $formatted Whether the returned EntityDescriptor should be formatted first.
+ *
+ * @return string The serialized EntityDescriptor.
+ */
+ public function getEntityDescriptorText($formatted = true)
+ {
+ assert('is_bool($formatted)');
- $this->addExtensions($metadata, $e);
+ $xml = $this->getEntityDescriptor();
+ if ($formatted) {
+ SimpleSAML\Utils\XML::formatDOMElement($xml);
+ }
- $this->addCertificate($e, $metadata);
+ return $xml->ownerDocument->saveXML();
+ }
- if ($metadata->hasValue('ArtifactResolutionService')){
- $e->ArtifactResolutionService = self::createEndpoints($metadata->getEndpoints('ArtifactResolutionService'), TRUE);
- }
- $e->SingleLogoutService = self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), FALSE);
+ /**
+ * Add a SecurityTokenServiceType for ADFS metadata.
+ *
+ * @param array $metadata The metadata with the information about the SecurityTokenServiceType.
+ */
+ public function addSecurityTokenServiceType($metadata)
+ {
+ assert('is_array($metadata)');
+ assert('isset($metadata["entityid"])');
+ assert('isset($metadata["metadata-set"])');
- $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+ $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+ $defaultEndpoint = $metadata->getDefaultEndpoint('SingleSignOnService');
+ $e = new sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType();
+ $e->Location = $defaultEndpoint['Location'];
- $e->SingleSignOnService = self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), FALSE);
+ $this->addCertificate($e, $metadata);
- $this->entityDescriptor->RoleDescriptor[] = $e;
+ $this->entityDescriptor->RoleDescriptor[] = $e;
+ }
- foreach ($metadata->getArray('contacts', array()) as $contact) {
- if (array_key_exists('contactType', $contact) && array_key_exists('emailAddress', $contact)) {
- $this->addContact($contact['contactType'], \SimpleSAML\Utils\Config\Metadata::getContact($contact));
- }
- }
- }
+ /**
+ * Add extensions to the metadata.
+ *
+ * @param SimpleSAML_Configuration $metadata The metadata to get extensions from.
+ * @param SAML2_XML_md_RoleDescriptor $e Reference to the element where the Extensions element should be included.
+ */
+ private function addExtensions(SimpleSAML_Configuration $metadata, SAML2_XML_md_RoleDescriptor $e)
+ {
+ if ($metadata->hasValue('tags')) {
+ $a = new SAML2_XML_saml_Attribute();
+ $a->Name = 'tags';
+ foreach ($metadata->getArray('tags') as $tag) {
+ $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($tag);
+ }
+ $e->Extensions[] = $a;
+ }
+
+ if ($metadata->hasValue('hint.cidr')) {
+ $a = new SAML2_XML_saml_Attribute();
+ $a->Name = 'hint.cidr';
+ foreach ($metadata->getArray('hint.cidr') as $hint) {
+ $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($hint);
+ }
+ $e->Extensions[] = $a;
+ }
+
+ if ($metadata->hasValue('scope')) {
+ foreach ($metadata->getArray('scope') as $scopetext) {
+ $s = new SAML2_XML_shibmd_Scope();
+ $s->scope = $scopetext;
+ // Check whether $ ^ ( ) * | \ are in a scope -> assume regex.
+ if (1 === preg_match('/[\$\^\)\(\*\|\\\\]/', $scopetext)) {
+ $s->regexp = true;
+ } else {
+ $s->regexp = false;
+ }
+ $e->Extensions[] = $s;
+ }
+ }
+
+ if ($metadata->hasValue('EntityAttributes')) {
+ $ea = new SAML2_XML_mdattr_EntityAttributes();
+ foreach ($metadata->getArray('EntityAttributes') as $attributeName => $attributeValues) {
+ $a = new SAML2_XML_saml_Attribute();
+ $a->Name = $attributeName;
+ $a->NameFormat = 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri';
+
+ // Attribute names that is not URI is prefixed as this: '{nameformat}name'
+ if (preg_match('/^\{(.*?)\}(.*)$/', $attributeName, $matches)) {
+ $a->Name = $matches[2];
+ $nameFormat = $matches[1];
+ if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
+ $a->NameFormat = $nameFormat;
+ }
+ }
+ foreach ($attributeValues as $attributeValue) {
+ $a->AttributeValue[] = new SAML2_XML_saml_AttributeValue($attributeValue);
+ }
+ $ea->children[] = $a;
+ }
+ $this->entityDescriptor->Extensions[] = $ea;
+ }
+
+ if ($metadata->hasValue('RegistrationInfo')) {
+ $ri = new SAML2_XML_mdrpi_RegistrationInfo();
+ foreach ($metadata->getArray('RegistrationInfo') as $riName => $riValues) {
+ switch ($riName) {
+ case 'authority':
+ $ri->registrationAuthority = $riValues;
+ break;
+ case 'instant':
+ $ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues);
+ break;
+ case 'policies':
+ $ri->RegistrationPolicy = $riValues;
+ break;
+ }
+ }
+ $this->entityDescriptor->Extensions[] = $ri;
+ }
+
+ if ($metadata->hasValue('UIInfo')) {
+ $ui = new SAML2_XML_mdui_UIInfo();
+ foreach ($metadata->getArray('UIInfo') as $uiName => $uiValues) {
+ switch ($uiName) {
+ case 'DisplayName':
+ $ui->DisplayName = $uiValues;
+ break;
+ case 'Description':
+ $ui->Description = $uiValues;
+ break;
+ case 'InformationURL':
+ $ui->InformationURL = $uiValues;
+ break;
+ case 'PrivacyStatementURL':
+ $ui->PrivacyStatementURL = $uiValues;
+ break;
+ case 'Keywords':
+ foreach ($uiValues as $lang => $keywords) {
+ $uiItem = new SAML2_XML_mdui_Keywords();
+ $uiItem->lang = $lang;
+ $uiItem->Keywords = $keywords;
+ $ui->Keywords[] = $uiItem;
+ }
+ break;
+ case 'Logo':
+ foreach ($uiValues as $logo) {
+ $uiItem = new SAML2_XML_mdui_Logo();
+ $uiItem->url = $logo['url'];
+ $uiItem->width = $logo['width'];
+ $uiItem->height = $logo['height'];
+ if (isset($logo['lang'])) {
+ $uiItem->lang = $logo['lang'];
+ }
+ $ui->Logo[] = $uiItem;
+ }
+ break;
+ }
+ }
+ $e->Extensions[] = $ui;
+ }
+
+ if ($metadata->hasValue('DiscoHints')) {
+ $dh = new SAML2_XML_mdui_DiscoHints();
+ foreach ($metadata->getArray('DiscoHints') as $dhName => $dhValues) {
+ switch ($dhName) {
+ case 'IPHint':
+ $dh->IPHint = $dhValues;
+ break;
+ case 'DomainHint':
+ $dh->DomainHint = $dhValues;
+ break;
+ case 'GeolocationHint':
+ $dh->GeolocationHint = $dhValues;
+ break;
+ }
+ }
+ $e->Extensions[] = $dh;
+ }
+ }
+
+
+ /**
+ * Add an Organization element based on data passed as parameters
+ *
+ * @param array $orgName An array with the localized OrganizationName.
+ * @param array $orgDisplayName An array with the localized OrganizationDisplayName.
+ * @param array $orgURL An array with the localized OrganizationURL.
+ */
+ public function addOrganization(array $orgName, array $orgDisplayName, array $orgURL)
+ {
+ $org = new SAML2_XML_md_Organization();
+ $org->OrganizationName = $orgName;
+ $org->OrganizationDisplayName = $orgDisplayName;
+ $org->OrganizationURL = $orgURL;
- /**
- * Add metadata of a SAML 1.1 service provider.
- *
- * @param array $metadata The metadata.
- */
- public function addMetadataSP11($metadata) {
- assert('is_array($metadata)');
- assert('isset($metadata["entityid"])');
- assert('isset($metadata["metadata-set"])');
+ $this->entityDescriptor->Organization = $org;
+ }
- $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e = new SAML2_XML_md_SPSSODescriptor();
- $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
+ /**
+ * Add an Organization element based on metadata array.
+ *
+ * @param array $metadata The metadata we should extract the organization information from.
+ */
+ public function addOrganizationInfo(array $metadata)
+ {
+ if (
+ empty($metadata['OrganizationName']) ||
+ empty($metadata['OrganizationDisplayName']) ||
+ empty($metadata['OrganizationURL'])
+ ) {
+ // empty or incomplete organization information
+ return;
+ }
+
+ $orgName = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationName'], 'en');
+ $orgDisplayName = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationDisplayName'], 'en');
+ $orgURL = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationURL'], 'en');
+
+ $this->addOrganization($orgName, $orgDisplayName, $orgURL);
+ }
+
+
+ /**
+ * Add a list of endpoints to metadata.
+ *
+ * @param array $endpoints The endpoints.
+ * @param bool $indexed Whether the endpoints should be indexed.
+ *
+ * @return SAML2_XML_md_IndexedEndpointType[]|SAML2_XML_md_EndpointType[] An array of endpoint objects.
+ */
+ private static function createEndpoints(array $endpoints, $indexed)
+ {
+ assert('is_bool($indexed)');
+
+ $ret = array();
+
+ foreach ($endpoints as &$ep) {
+ if ($indexed) {
+ $t = new SAML2_XML_md_IndexedEndpointType();
+ } else {
+ $t = new SAML2_XML_md_EndpointType();
+ }
+
+ $t->Binding = $ep['Binding'];
+ $t->Location = $ep['Location'];
+ if (isset($ep['ResponseLocation'])) {
+ $t->ResponseLocation = $ep['ResponseLocation'];
+ }
+ if (isset($ep['hoksso:ProtocolBinding'])) {
+ $t->setAttributeNS(SAML2_Const::NS_HOK, 'hoksso:ProtocolBinding', SAML2_Const::BINDING_HTTP_REDIRECT);
+ }
+
+ if ($indexed) {
+ if (!isset($ep['index'])) {
+ /* Find the maximum index. */
+ $maxIndex = -1;
+ foreach ($endpoints as $ep) {
+ if (!isset($ep['index'])) {
+ continue;
+ }
+
+ if ($ep['index'] > $maxIndex) {
+ $maxIndex = $ep['index'];
+ }
+ }
+
+ $ep['index'] = $maxIndex + 1;
+ }
+
+ $t->index = $ep['index'];
+ }
+
+ $ret[] = $t;
+ }
+
+ return $ret;
+ }
+
+
+ /**
+ * Add an AttributeConsumingService element to the metadata.
+ *
+ * @param SAML2_XML_md_SPSSODescriptor $spDesc The SPSSODescriptor element.
+ * @param SimpleSAML_Configuration $metadata The metadata.
+ */
+ private function addAttributeConsumingService(
+ SAML2_XML_md_SPSSODescriptor $spDesc,
+ SimpleSAML_Configuration $metadata
+ ) {
+ $attributes = $metadata->getArray('attributes', array());
+ $name = $metadata->getLocalizedString('name', null);
+
+ if ($name === null || count($attributes) == 0) {
+ // we cannot add an AttributeConsumingService without name and attributes
+ return;
+ }
+
+ $attributesrequired = $metadata->getArray('attributes.required', array());
+
+ /*
+ * Add an AttributeConsumingService element with information as name and description and list
+ * of requested attributes
+ */
+ $attributeconsumer = new SAML2_XML_md_AttributeConsumingService();
+
+ $attributeconsumer->index = 0;
+
+ $attributeconsumer->ServiceName = $name;
+ $attributeconsumer->ServiceDescription = $metadata->getLocalizedString('description', array());
+
+ $nameFormat = $metadata->getString('attributes.NameFormat', SAML2_Const::NAMEFORMAT_UNSPECIFIED);
+ foreach ($attributes as $friendlyName => $attribute) {
+ $t = new SAML2_XML_md_RequestedAttribute();
+ $t->Name = $attribute;
+ if (!is_int($friendlyName)) {
+ $t->FriendlyName = $friendlyName;
+ }
+ if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) {
+ $t->NameFormat = $nameFormat;
+ }
+ if (in_array($attribute, $attributesrequired)) {
+ $t->isRequired = true;
+ }
+ $attributeconsumer->RequestedAttribute[] = $t;
+ }
+
+ $spDesc->AttributeConsumingService[] = $attributeconsumer;
+ }
+
+
+ /**
+ * Add a specific type of metadata to an entity.
+ *
+ * @param string $set The metadata set this metadata comes from.
+ * @param array $metadata The metadata.
+ */
+ public function addMetadata($set, $metadata)
+ {
+ assert('is_string($set)');
+ assert('is_array($metadata)');
+
+ $this->setExpiration($metadata);
+
+ switch ($set) {
+ case 'saml20-sp-remote':
+ $this->addMetadataSP20($metadata);
+ break;
+ case 'saml20-idp-remote':
+ $this->addMetadataIdP20($metadata);
+ break;
+ case 'shib13-sp-remote':
+ $this->addMetadataSP11($metadata);
+ break;
+ case 'shib13-idp-remote':
+ $this->addMetadataIdP11($metadata);
+ break;
+ case 'attributeauthority-remote':
+ $this->addAttributeAuthority($metadata);
+ break;
+ default:
+ SimpleSAML_Logger::warning('Unable to generate metadata for unknown type \''.$set.'\'.');
+ }
+ }
+
+
+ /**
+ * Add SAML 2.0 SP metadata.
+ *
+ * @param array $metadata The metadata.
+ * @param array $protocols The protocols supported. Defaults to SAML2_Const::NS_SAMLP.
+ */
+ public function addMetadataSP20($metadata, $protocols = array(SAML2_Const::NS_SAMLP))
+ {
+ assert('is_array($metadata)');
+ assert('is_array($protocols)');
+ assert('isset($metadata["entityid"])');
+ assert('isset($metadata["metadata-set"])');
+
+ $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $this->addCertificate($e, $metadata);
+ $e = new SAML2_XML_md_SPSSODescriptor();
+ $e->protocolSupportEnumeration = $protocols;
- $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+ if ($metadata->hasValue('saml20.sign.assertion')) {
+ $e->WantAssertionsSigned = $metadata->getBoolean('saml20.sign.assertion');
+ }
- $endpoints = $metadata->getEndpoints('AssertionConsumerService');
- foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', array()) as $acs) {
- $endpoints[] = array(
- 'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01',
- 'Location' => $acs,
- );
- }
- $e->AssertionConsumerService = self::createEndpoints($endpoints, TRUE);
+ if ($metadata->hasValue('redirect.validate')) {
+ $e->AuthnRequestsSigned = $metadata->getBoolean('redirect.validate');
+ } elseif ($metadata->hasValue('validate.authnrequest')) {
+ $e->AuthnRequestsSigned = $metadata->getBoolean('validate.authnrequest');
+ }
- $this->addAttributeConsumingService($e, $metadata);
+ $this->addExtensions($metadata, $e);
- $this->entityDescriptor->RoleDescriptor[] = $e;
- }
+ $this->addCertificate($e, $metadata);
+ $e->SingleLogoutService = self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), false);
- /**
- * Add metadata of a SAML 1.1 identity provider.
- *
- * @param array $metadata The metadata.
- */
- public function addMetadataIdP11($metadata) {
- assert('is_array($metadata)');
- assert('isset($metadata["entityid"])');
- assert('isset($metadata["metadata-set"])');
+ $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
- $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+ $endpoints = $metadata->getEndpoints('AssertionConsumerService');
+ foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', array()) as $acs) {
+ $endpoints[] = array(
+ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
+ 'Location' => $acs,
+ );
+ }
+ $e->AssertionConsumerService = self::createEndpoints($endpoints, true);
- $e = new SAML2_XML_md_IDPSSODescriptor();
- $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
- $e->protocolSupportEnumeration[] = 'urn:mace:shibboleth:1.0';
+ $this->addAttributeConsumingService($e, $metadata);
- $this->addCertificate($e, $metadata);
+ $this->entityDescriptor->RoleDescriptor[] = $e;
+
+ foreach ($metadata->getArray('contacts', array()) as $contact) {
+ if (array_key_exists('contactType', $contact) && array_key_exists('emailAddress', $contact)) {
+ $this->addContact($contact['contactType'], \SimpleSAML\Utils\Config\Metadata::getContact($contact));
+ }
+ }
+ }
+
+
+ /**
+ * Add metadata of a SAML 2.0 identity provider.
+ *
+ * @param array $metadata The metadata.
+ */
+ public function addMetadataIdP20($metadata)
+ {
+ assert('is_array($metadata)');
+ assert('isset($metadata["entityid"])');
+ assert('isset($metadata["metadata-set"])');
- $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+ $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
- $e->SingleSignOnService = self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), FALSE);
+ $e = new SAML2_XML_md_IDPSSODescriptor();
+ $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:2.0:protocol';
- $this->entityDescriptor->RoleDescriptor[] = $e;
- }
+ if ($metadata->hasValue('sign.authnrequest')) {
+ $e->WantAuthnRequestsSigned = $metadata->getBoolean('sign.authnrequest');
+ } elseif ($metadata->hasValue('redirect.sign')) {
+ $e->WantAuthnRequestsSigned = $metadata->getBoolean('redirect.sign');
+ }
+ $this->addExtensions($metadata, $e);
- /**
- * Add metadata of a SAML attribute authority.
- *
- * @param array $metadata The AttributeAuthorityDescriptor, in the format returned by
- * SimpleSAML_Metadata_SAMLParser.
- */
- public function addAttributeAuthority(array $metadata) {
- assert('is_array($metadata)');
- assert('isset($metadata["entityid"])');
- assert('isset($metadata["metadata-set"])');
+ $this->addCertificate($e, $metadata);
- $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+ if ($metadata->hasValue('ArtifactResolutionService')) {
+ $e->ArtifactResolutionService = self::createEndpoints(
+ $metadata->getEndpoints('ArtifactResolutionService'),
+ true
+ );
+ }
- $e = new SAML2_XML_md_AttributeAuthorityDescriptor();
- $e->protocolSupportEnumeration = $metadata->getArray('protocols', array());
+ $e->SingleLogoutService = self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), false);
- $this->addExtensions($metadata, $e);
- $this->addCertificate($e, $metadata);
+ $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
- $e->AttributeService = self::createEndpoints($metadata->getEndpoints('AttributeService'), FALSE);
- $e->AssertionIDRequestService = self::createEndpoints($metadata->getEndpoints('AssertionIDRequestService'), FALSE);
+ $e->SingleSignOnService = self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), false);
- $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+ $this->entityDescriptor->RoleDescriptor[] = $e;
- $this->entityDescriptor->RoleDescriptor[] = $e;
- }
+ foreach ($metadata->getArray('contacts', array()) as $contact) {
+ if (array_key_exists('contactType', $contact) && array_key_exists('emailAddress', $contact)) {
+ $this->addContact($contact['contactType'], \SimpleSAML\Utils\Config\Metadata::getContact($contact));
+ }
+ }
+ }
- /**
- * Add contact information.
- *
- * Accepts a contact type, and a contact array that must be previously sanitized.
- *
- * @param string $type The type of contact. Deprecated.
- * @param array $details The details about the contact.
- *
- * @todo Change the signature to remove $type.
- * @todo Remove the capability to pass a name and parse it inside the method.
+ /**
+ * Add metadata of a SAML 1.1 service provider.
*
- * @deprecated This function will change its signature and no longer parse a 'name' element.
- */
- public function addContact($type, $details) {
- assert('is_string($type)');
- assert('is_array($details)');
- assert('in_array($type, array("technical", "support", "administrative", "billing", "other"), TRUE)');
-
- // TODO: remove this check as soon as getContact() is called always before calling this function.
- $details = \SimpleSAML\Utils\Config\Metadata::getContact($details);
-
- $e = new SAML2_XML_md_ContactPerson();
- $e->contactType = $type;
-
- if (isset($details['company'])) {
- $e->Company = $details['company'];
- }
- if (isset($details['givenName'])) {
- $e->GivenName = $details['givenName'];
- }
- if (isset($details['surName'])) {
- $e->SurName = $details['surName'];
- }
-
- if (isset($details['emailAddress'])) {
- $eas = $details['emailAddress'];
- if (!is_array($eas)) {
- $eas = array($eas);
- }
- foreach ($eas as $ea) {
- $e->EmailAddress[] = $ea;
- }
- }
-
- if (isset($details['telephoneNumber'])) {
- $tlfNrs = $details['telephoneNumber'];
- if (!is_array($tlfNrs)) {
- $tlfNrs = array($tlfNrs);
- }
- foreach ($tlfNrs as $tlfNr) {
- $e->TelephoneNumber[] = $tlfNr;
- }
- }
-
- $this->entityDescriptor->ContactPerson[] = $e;
- }
-
-
- /**
- * Add a KeyDescriptor with an X509 certificate.
- *
- * @param SAML2_XML_md_RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
- * @param string $use The value of the 'use' attribute.
- * @param string $x509data The certificate data.
- */
- private function addX509KeyDescriptor(SAML2_XML_md_RoleDescriptor $rd, $use, $x509data) {
- assert('in_array($use, array("encryption", "signing"), TRUE)');
- assert('is_string($x509data)');
-
- $keyDescriptor = SAML2_Utils::createKeyDescriptor($x509data);
- $keyDescriptor->use = $use;
- $rd->KeyDescriptor[] = $keyDescriptor;
- }
-
-
- /**
- * Add a certificate.
- *
- * Helper function for adding a certificate to the metadata.
- *
- * @param SAML2_XML_md_RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
- * @param SimpleSAML_Configuration $metadata The metadata of the entity.
- */
- private function addCertificate(SAML2_XML_md_RoleDescriptor $rd, SimpleSAML_Configuration $metadata) {
-
- $keys = $metadata->getPublicKeys();
- if ($keys !== NULL) {
- foreach ($keys as $key) {
- if ($key['type'] !== 'X509Certificate') {
- continue;
- }
- if (!isset($key['signing']) || $key['signing'] === TRUE) {
- $this->addX509KeyDescriptor($rd, 'signing', $key['X509Certificate']);
- }
- if (!isset($key['encryption']) || $key['encryption'] === TRUE) {
- $this->addX509KeyDescriptor($rd, 'encryption', $key['X509Certificate']);
- }
- }
- }
-
- if ($metadata->hasValue('https.certData')) {
- $this->addX509KeyDescriptor($rd, 'signing', $metadata->getString('https.certData'));
- }
- }
+ * @param array $metadata The metadata.
+ */
+ public function addMetadataSP11($metadata)
+ {
+ assert('is_array($metadata)');
+ assert('isset($metadata["entityid"])');
+ assert('isset($metadata["metadata-set"])');
+ $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+
+ $e = new SAML2_XML_md_SPSSODescriptor();
+ $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
+
+ $this->addCertificate($e, $metadata);
+
+ $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+
+ $endpoints = $metadata->getEndpoints('AssertionConsumerService');
+ foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', array()) as $acs) {
+ $endpoints[] = array(
+ 'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01',
+ 'Location' => $acs,
+ );
+ }
+ $e->AssertionConsumerService = self::createEndpoints($endpoints, true);
+
+ $this->addAttributeConsumingService($e, $metadata);
+
+ $this->entityDescriptor->RoleDescriptor[] = $e;
+ }
+
+
+ /**
+ * Add metadata of a SAML 1.1 identity provider.
+ *
+ * @param array $metadata The metadata.
+ */
+ public function addMetadataIdP11($metadata)
+ {
+ assert('is_array($metadata)');
+ assert('isset($metadata["entityid"])');
+ assert('isset($metadata["metadata-set"])');
+
+ $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+
+ $e = new SAML2_XML_md_IDPSSODescriptor();
+ $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
+ $e->protocolSupportEnumeration[] = 'urn:mace:shibboleth:1.0';
+
+ $this->addCertificate($e, $metadata);
+
+ $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+
+ $e->SingleSignOnService = self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), false);
+
+ $this->entityDescriptor->RoleDescriptor[] = $e;
+ }
+
+
+ /**
+ * Add metadata of a SAML attribute authority.
+ *
+ * @param array $metadata The AttributeAuthorityDescriptor, in the format returned by
+ * SimpleSAML_Metadata_SAMLParser.
+ */
+ public function addAttributeAuthority(array $metadata)
+ {
+ assert('is_array($metadata)');
+ assert('isset($metadata["entityid"])');
+ assert('isset($metadata["metadata-set"])');
+
+ $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+
+ $e = new SAML2_XML_md_AttributeAuthorityDescriptor();
+ $e->protocolSupportEnumeration = $metadata->getArray('protocols', array());
+
+ $this->addExtensions($metadata, $e);
+ $this->addCertificate($e, $metadata);
+
+ $e->AttributeService = self::createEndpoints($metadata->getEndpoints('AttributeService'), false);
+ $e->AssertionIDRequestService = self::createEndpoints(
+ $metadata->getEndpoints('AssertionIDRequestService'),
+ false
+ );
+
+ $e->NameIDFormat = $metadata->getArrayizeString('NameIDFormat', array());
+
+ $this->entityDescriptor->RoleDescriptor[] = $e;
+ }
+
+
+ /**
+ * Add contact information.
+ *
+ * Accepts a contact type, and a contact array that must be previously sanitized.
+ *
+ * WARNING: This function will change its signature and no longer parse a 'name' element.
+ *
+ * @param string $type The type of contact. Deprecated.
+ * @param array $details The details about the contact.
+ *
+ * @todo Change the signature to remove $type.
+ * @todo Remove the capability to pass a name and parse it inside the method.
+ */
+ public function addContact($type, $details)
+ {
+ assert('is_string($type)');
+ assert('is_array($details)');
+ assert('in_array($type, array("technical", "support", "administrative", "billing", "other"), TRUE)');
+
+ // TODO: remove this check as soon as getContact() is called always before calling this function.
+ $details = \SimpleSAML\Utils\Config\Metadata::getContact($details);
+
+ $e = new SAML2_XML_md_ContactPerson();
+ $e->contactType = $type;
+
+ if (isset($details['company'])) {
+ $e->Company = $details['company'];
+ }
+ if (isset($details['givenName'])) {
+ $e->GivenName = $details['givenName'];
+ }
+ if (isset($details['surName'])) {
+ $e->SurName = $details['surName'];
+ }
+
+ if (isset($details['emailAddress'])) {
+ $eas = $details['emailAddress'];
+ if (!is_array($eas)) {
+ $eas = array($eas);
+ }
+ foreach ($eas as $ea) {
+ $e->EmailAddress[] = $ea;
+ }
+ }
+
+ if (isset($details['telephoneNumber'])) {
+ $tlfNrs = $details['telephoneNumber'];
+ if (!is_array($tlfNrs)) {
+ $tlfNrs = array($tlfNrs);
+ }
+ foreach ($tlfNrs as $tlfNr) {
+ $e->TelephoneNumber[] = $tlfNr;
+ }
+ }
+
+ $this->entityDescriptor->ContactPerson[] = $e;
+ }
+
+
+ /**
+ * Add a KeyDescriptor with an X509 certificate.
+ *
+ * @param SAML2_XML_md_RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
+ * @param string $use The value of the 'use' attribute.
+ * @param string $x509data The certificate data.
+ */
+ private function addX509KeyDescriptor(SAML2_XML_md_RoleDescriptor $rd, $use, $x509data)
+ {
+ assert('in_array($use, array("encryption", "signing"), TRUE)');
+ assert('is_string($x509data)');
+
+ $keyDescriptor = SAML2_Utils::createKeyDescriptor($x509data);
+ $keyDescriptor->use = $use;
+ $rd->KeyDescriptor[] = $keyDescriptor;
+ }
+
+
+ /**
+ * Add a certificate.
+ *
+ * Helper function for adding a certificate to the metadata.
+ *
+ * @param SAML2_XML_md_RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
+ * @param SimpleSAML_Configuration $metadata The metadata of the entity.
+ */
+ private function addCertificate(SAML2_XML_md_RoleDescriptor $rd, SimpleSAML_Configuration $metadata)
+ {
+ $keys = $metadata->getPublicKeys();
+ if ($keys !== null) {
+ foreach ($keys as $key) {
+ if ($key['type'] !== 'X509Certificate') {
+ continue;
+ }
+ if (!isset($key['signing']) || $key['signing'] === true) {
+ $this->addX509KeyDescriptor($rd, 'signing', $key['X509Certificate']);
+ }
+ if (!isset($key['encryption']) || $key['encryption'] === true) {
+ $this->addX509KeyDescriptor($rd, 'encryption', $key['X509Certificate']);
+ }
+ }
+ }
+
+ if ($metadata->hasValue('https.certData')) {
+ $this->addX509KeyDescriptor($rd, 'signing', $metadata->getString('https.certData'));
+ }
+ }
}