You are here

public static function SamlSPMetadata::builder in SAML Service Provider 3.x

Same name and namespace in other branches
  1. 8.3 src/SAML/SamlSPMetadata.php \Drupal\saml_sp\SAML\SamlSPMetadata::builder()
  2. 4.x src/SAML/SamlSPMetadata.php \Drupal\saml_sp\SAML\SamlSPMetadata::builder()
1 call to SamlSPMetadata::builder()
SamlSPSettings::getSPMetadata in src/SAML/SamlSPSettings.php

File

src/SAML/SamlSPMetadata.php, line 17

Class

SamlSPMetadata

Namespace

Drupal\saml_sp\SAML

Code

public static function builder($sp, $authnsign = FALSE, $wsign = FALSE, $validUntil = NULL, $cacheDuration = NULL, $contacts = [], $organization = [], $attributes = []) {
  if (!isset($validUntil)) {
    $validUntil = time() + self::TIME_VALID;
  }
  $validUntilTime = Utils::parseTime2SAML($validUntil);
  if (!isset($cacheDuration)) {
    $cacheDuration = self::TIME_CACHED;
  }
  $sls = '';
  if (isset($sp['singleLogoutService'])) {
    $slsUrl = htmlspecialchars($sp['singleLogoutService']['url'], ENT_QUOTES);
    $sls = <<<SLS_TEMPLATE
        <md:SingleLogoutService Binding="{<span class="php-variable">$sp</span>[<span class="php-string">'singleLogoutService'</span>][<span class="php-string">'binding'</span>]}"
                                Location="{<span class="php-variable">$slsUrl</span>}" />

SLS_TEMPLATE;
  }
  if ($authnsign) {
    $strAuthnsign = 'true';
  }
  else {
    $strAuthnsign = 'false';
  }
  if ($wsign) {
    $strWsign = 'true';
  }
  else {
    $strWsign = 'false';
  }
  $strOrganization = '';
  if (!empty($organization)) {
    $organizationInfoNames = [];
    $organizationInfoDisplaynames = [];
    $organizationInfoUrls = [];
    foreach ($organization as $lang => $info) {
      $organizationInfoNames[] = <<<ORGANIZATION_NAME
       <md:OrganizationName xml:lang="{<span class="php-variable">$lang</span>}">{<span class="php-variable">$info</span>[<span class="php-string">'name'</span>]}</md:OrganizationName>
ORGANIZATION_NAME;
      $organizationInfoDisplaynames[] = <<<ORGANIZATION_DISPLAY
       <md:OrganizationDisplayName xml:lang="{<span class="php-variable">$lang</span>}">{<span class="php-variable">$info</span>[<span class="php-string">'displayname'</span>]}</md:OrganizationDisplayName>
ORGANIZATION_DISPLAY;
      $organizationInfoUrls[] = <<<ORGANIZATION_URL
       <md:OrganizationURL xml:lang="{<span class="php-variable">$lang</span>}">{<span class="php-variable">$info</span>[<span class="php-string">'url'</span>]}</md:OrganizationURL>
ORGANIZATION_URL;
    }
    $orgData = implode("\n", $organizationInfoNames) . "\n" . implode("\n", $organizationInfoDisplaynames) . "\n" . implode("\n", $organizationInfoUrls);
    $strOrganization = <<<ORGANIZATIONSTR

    <md:Organization>
{<span class="php-variable">$orgData</span>}
    </md:Organization>
ORGANIZATIONSTR;
  }
  $strContacts = '';
  if (!empty($contacts)) {
    $contactsInfo = [];
    foreach ($contacts as $type => $info) {
      $contactsInfo[] = <<<CONTACT
    <md:ContactPerson contactType="{<span class="php-variable">$type</span>}">
        <md:GivenName>{<span class="php-variable">$info</span>[<span class="php-string">'givenName'</span>]}</md:GivenName>
        <md:EmailAddress>{<span class="php-variable">$info</span>[<span class="php-string">'emailAddress'</span>]}</md:EmailAddress>
    </md:ContactPerson>
CONTACT;
    }
    $strContacts = "\n" . implode("\n", $contactsInfo);
  }
  $strAttributeConsumingService = '';
  if (isset($sp['attributeConsumingService'])) {
    $attrCsDesc = '';
    if (isset($sp['attributeConsumingService']['serviceDescription'])) {
      $attrCsDesc = sprintf('            <md:ServiceDescription xml:lang="en">%s</md:ServiceDescription>' . PHP_EOL, $sp['attributeConsumingService']['serviceDescription']);
    }
    if (!isset($sp['attributeConsumingService']['serviceName'])) {
      $sp['attributeConsumingService']['serviceName'] = 'Service';
    }
    $requestedAttributeData = [];
    foreach ($sp['attributeConsumingService']['requestedAttributes'] as $attribute) {
      $requestedAttributeStr = sprintf('            <md:RequestedAttribute Name="%s"', $attribute['name']);
      if (isset($attribute['nameFormat'])) {
        $requestedAttributeStr .= sprintf(' NameFormat="%s"', $attribute['nameFormat']);
      }
      if (isset($attribute['friendlyName'])) {
        $requestedAttributeStr .= sprintf(' FriendlyName="%s"', $attribute['friendlyName']);
      }
      if (isset($attribute['isRequired'])) {
        $requestedAttributeStr .= sprintf(' isRequired="%s"', $attribute['isRequired'] === TRUE ? 'true' : 'false');
      }
      $reqAttrAuxStr = " />";
      if (isset($attribute['attributeValue']) && !empty($attribute['attributeValue'])) {
        $reqAttrAuxStr = '>';
        if (is_string($attribute['attributeValue'])) {
          $attribute['attributeValue'] = [
            $attribute['attributeValue'],
          ];
        }
        foreach ($attribute['attributeValue'] as $attrValue) {
          $reqAttrAuxStr .= <<<ATTRIBUTEVALUE

                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">{<span class="php-variable">$attrValue</span>}</saml:AttributeValue>
ATTRIBUTEVALUE;
        }
        $reqAttrAuxStr .= "\n            </md:RequestedAttribute>";
      }
      $requestedAttributeData[] = $requestedAttributeStr . $reqAttrAuxStr;
    }
    $requestedAttributeStr = implode(PHP_EOL, $requestedAttributeData);
    $strAttributeConsumingService = <<<METADATA_TEMPLATE
<md:AttributeConsumingService index="1">
            <md:ServiceName xml:lang="en">{<span class="php-variable">$sp</span>[<span class="php-string">'attributeConsumingService'</span>][<span class="php-string">'serviceName'</span>]}</md:ServiceName>
{<span class="php-variable">$attrCsDesc</span>}{<span class="php-variable">$requestedAttributeStr</span>}
        </md:AttributeConsumingService>
METADATA_TEMPLATE;
  }
  $spEntityId = htmlspecialchars($sp['entityId'], ENT_QUOTES);
  $acsUrl = htmlspecialchars($sp['assertionConsumerService']['url'], ENT_QUOTES);
  $config = \Drupal::config('saml_sp.settings');

  // The consumer endpoint will always be /saml/consume.
  $endpoint_url = Url::fromRoute('saml_sp.consume', [], [
    'absolute' => TRUE,
  ]);

  // Drupal URL to consume the response from the IdP:
  $assertion_urls = trim($config
    ->get('assertion_urls'));
  if (empty($assertion_urls)) {
    $assertion_urls = [
      $endpoint_url
        ->toString(),
    ];
  }
  else {
    $assertion_urls = explode("\n", $config
      ->get('assertion_urls'));
    $assertion_urls = array_map('trim', $assertion_urls);
  }
  $acs = '';
  $acs_count = 0;
  foreach ($assertion_urls as $url) {
    if ($acs_count == 0) {
      $default = 'true';
    }
    else {
      $default = 'false';
    }
    $acs .= <<<ACS
<md:AssertionConsumerService Binding="{<span class="php-variable">$sp</span>[<span class="php-string">'assertionConsumerService'</span>][<span class="php-string">'binding'</span>]}"
                                     Location="{<span class="php-variable">$url</span>}"
                                     index="{<span class="php-variable">$acs_count</span>}"
                                     isDefault="{<span class="php-variable">$default</span>}"/>
ACS;
    $acs_count++;
  }
  $metadata = <<<METADATA_TEMPLATE
<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
                     validUntil="{<span class="php-variable">$validUntilTime</span>}"
                     cacheDuration="PT{<span class="php-variable">$cacheDuration</span>}S"
                     entityID="{<span class="php-variable">$spEntityId</span>}">
    <md:SPSSODescriptor AuthnRequestsSigned="{<span class="php-variable">$strAuthnsign</span>}" WantAssertionsSigned="{<span class="php-variable">$strWsign</span>}" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
{<span class="php-variable">$sls</span>}        <md:NameIDFormat>{<span class="php-variable">$sp</span>[<span class="php-string">'NameIDFormat'</span>]}</md:NameIDFormat>
        {<span class="php-variable">$acs</span>}
        {<span class="php-variable">$strAttributeConsumingService</span>}
    </md:SPSSODescriptor>{<span class="php-variable">$strOrganization</span>}{<span class="php-variable">$strContacts</span>}
</md:EntityDescriptor>
METADATA_TEMPLATE;
  return $metadata;
}