View source
<?php
namespace Drupal\saml_sp\SAML;
use Drupal\Core\Url;
use OneLogin\Saml2\Metadata;
use OneLogin\Saml2\Utils;
class SamlSPMetadata extends Metadata {
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');
$endpoint_url = Url::fromRoute('saml_sp.consume', [], [
'absolute' => TRUE,
]);
$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;
}
}