You are here

SamlSPMetadata.php in SAML Service Provider 3.x

Same filename and directory in other branches
  1. 8.3 src/SAML/SamlSPMetadata.php
  2. 4.x src/SAML/SamlSPMetadata.php

File

src/SAML/SamlSPMetadata.php
View source
<?php

namespace Drupal\saml_sp\SAML;

use Drupal\Core\Url;
use OneLogin\Saml2\Metadata;
use OneLogin\Saml2\Utils;

/**
 * {@inheritdoc}
 */
class SamlSPMetadata extends Metadata {

  /**
   * {@inheritdoc}
   */
  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;
  }

}

Classes

Namesort descending Description
SamlSPMetadata