From 563292efffc01156db2296aaf524594d89c6bec3 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Wed, 10 Feb 2010 11:32:00 +0000
Subject: [PATCH] Move all organization info to Organization* metadata options.

This patch changes the metadata parsing and generation to use
OrganizationName, OrganizationDisplayName and OrganizationURL.

It also updates users of 'name' to check 'OrganizationDisplayName'
if 'name' is unset.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2166 44740490-163a-0410-bde0-09ae8108e29a
---
 docs/simplesamlphp-reference-idp-hosted.txt   | 29 +++++++++++++
 docs/simplesamlphp-reference-idp-remote.txt   | 33 +++++++++++++-
 docs/simplesamlphp-reference-sp-hosted.txt    | 29 +++++++++++++
 docs/simplesamlphp-reference-sp-remote.txt    | 33 +++++++++++++-
 lib/SimpleSAML/IdP.php                        |  8 +++-
 lib/SimpleSAML/Metadata/SAMLBuilder.php       | 43 +++++++++----------
 lib/SimpleSAML/Metadata/SAMLParser.php        |  7 ++-
 modules/adfs/www/idp/prp.php                  |  2 -
 modules/consent/templates/consentform.php     | 18 +++++---
 modules/consentAdmin/www/consentAdmin.php     |  8 ++--
 .../templates/frontpage_federation.tpl.php    |  2 +
 modules/discopower/templates/disco-tpl.php    |  6 +++
 modules/saml/hooks/hook_metadata_hosted.php   |  3 ++
 templates/metadata.php                        |  4 +-
 templates/selectidp-dropdown.php              |  5 ++-
 templates/selectidp-links.php                 |  5 ++-
 www/admin/metadata.php                        | 16 +++----
 www/auth/login-feide.php                      |  2 +
 www/saml2/idp/metadata.php                    | 24 +++++++----
 www/saml2/sp/metadata.php                     | 20 +++++++--
 www/shib13/idp/metadata.php                   | 23 ++++++----
 www/shib13/sp/metadata.php                    | 19 ++++++--
 22 files changed, 265 insertions(+), 74 deletions(-)

diff --git a/docs/simplesamlphp-reference-idp-hosted.txt b/docs/simplesamlphp-reference-idp-hosted.txt
index 759c41b8f..1e836342c 100644
--- a/docs/simplesamlphp-reference-idp-hosted.txt
+++ b/docs/simplesamlphp-reference-idp-hosted.txt
@@ -53,6 +53,35 @@ Common options
     set to `__DEFAULT__`, and that IdP will be used when no other
     entries in the metadata matches.
 
+`OrganizationName`
+:   The name of the organization responsible for this IdP.
+    This name does not need to be suitable for display to end users.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name:
+
+        'OrganizationName' => array(
+            'en' => 'Example organization',
+            'no' => 'Eksempel organisation',
+        ),
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationURL` option.
+
+`OrganizationDisplayName`
+:   The name of the organization responsible for this IdP.
+    This name must be suitable for display to end users.
+    If this option isn't specified, `OrganizationName` will be used instead.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
+`OrganizationURL`
+:   An URL the end user can access for more information about the organization.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated URL.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
 `privacypolicy`
 :   This is an absolute URL for where an user can find a
     privacypolicy. If set, this will be shown on the consent page.
diff --git a/docs/simplesamlphp-reference-idp-remote.txt b/docs/simplesamlphp-reference-idp-remote.txt
index 5a8ee250e..eff3183c2 100644
--- a/docs/simplesamlphp-reference-idp-remote.txt
+++ b/docs/simplesamlphp-reference-idp-remote.txt
@@ -47,8 +47,39 @@ The following options are common between both the SAML 2.0 protocol and Shibbole
 `icon`
 :   A logo which will be shown next to this IdP in the discovery service.
 
+`OrganizationName`
+:   The name of the organization responsible for this SPP.
+    This name does not need to be suitable for display to end users.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name:
+
+        'OrganizationName' => array(
+            'en' => 'Example organization',
+            'no' => 'Eksempel organisation',
+        ),
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationURL` option.
+
+`OrganizationDisplayName`
+:   The name of the organization responsible for this IdP.
+    This name must be suitable for display to end users.
+    If this option isn't specified, `OrganizationName` will be used instead.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
+`OrganizationURL`
+:   An URL the end user can access for more information about the organization.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated URL.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
 `name`
-:   The name of this IdP. Will be used by various modules when they need to show a name of the SP to the user.</p>
+:   The name of this IdP. Will be used by various modules when they need to show a name of the SP to the user.
+
+:   If this option is unset, the organization name will be used instead (if it is available).
 
 :   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name:
 
diff --git a/docs/simplesamlphp-reference-sp-hosted.txt b/docs/simplesamlphp-reference-sp-hosted.txt
index 2b79a1422..f6c0a913e 100644
--- a/docs/simplesamlphp-reference-sp-hosted.txt
+++ b/docs/simplesamlphp-reference-sp-hosted.txt
@@ -53,6 +53,35 @@ Common options
 `idpdisco.url`
 :   Set which IdP discovery service this SP should use. If this is unset, the IdP discovery service specified in the global option `idpdisco.url.{saml20|shib13}` in `config/config.php` will be used. If that one is also unset, the builtin default discovery service will be used.
 
+`OrganizationName`
+:   The name of the organization responsible for this SPP.
+    This name does not need to be suitable for display to end users.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name:
+
+        'OrganizationName' => array(
+            'en' => 'Example organization',
+            'no' => 'Eksempel organisation',
+        ),
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationURL` option.
+
+`OrganizationDisplayName`
+:   The name of the organization responsible for this SPP.
+    This name must be suitable for display to end users.
+    If this option isn't specified, `OrganizationName` will be used instead.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
+`OrganizationURL`
+:   An URL the end user can access for more information about the organization.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated URL.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
 `name`
 :   The name of this SP. Will be added to the generated metadata.
 
diff --git a/docs/simplesamlphp-reference-sp-remote.txt b/docs/simplesamlphp-reference-sp-remote.txt
index f0cb1979f..2f89ff913 100644
--- a/docs/simplesamlphp-reference-sp-remote.txt
+++ b/docs/simplesamlphp-reference-sp-remote.txt
@@ -45,7 +45,9 @@ and Shibboleth 1.3 protocol:
 
 `name`
 :   The name of this SP. Will be used by various modules when they need
-    to show a name of the SP to the user.</p>
+    to show a name of the SP to the user.
+
+:   If this option is unset, the organization name will be used instead (if it is available).
 
 :   This option can be translated into multiple languages by specifying
     the value as an array of language-code to translated name:
@@ -55,6 +57,35 @@ and Shibboleth 1.3 protocol:
             'no' => 'En tjeneste',
         ),
 
+`OrganizationName`
+:   The name of the organization responsible for this SPP.
+    This name does not need to be suitable for display to end users.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name:
+
+        'OrganizationName' => array(
+            'en' => 'Example organization',
+            'no' => 'Eksempel organisation',
+        ),
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationURL` option.
+
+`OrganizationDisplayName`
+:   The name of the organization responsible for this IdP.
+    This name must be suitable for display to end users.
+    If this option isn't specified, `OrganizationName` will be used instead.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated name.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
+`OrganizationURL`
+:   An URL the end user can access for more information about the organization.
+
+:   This option can be translated into multiple languages by specifying the value as an array of language-code to translated URL.
+
+:   *Note*: If you specify this option, you must also specify the `OrganizationName` option.
+
 `privacypolicy`
 :   This is an absolute URL for where an user can find a privacypolicy
     for this SP. If set, this will be shown on the consent page.
diff --git a/lib/SimpleSAML/IdP.php b/lib/SimpleSAML/IdP.php
index 136c40da7..958377d6d 100644
--- a/lib/SimpleSAML/IdP.php
+++ b/lib/SimpleSAML/IdP.php
@@ -132,7 +132,13 @@ class SimpleSAML_IdP {
 			}
 		}
 
-		return $spMetadata->getLocalizedString('name', array('en' => $spEntityId));
+		if ($spMetadata->hasValue('name')) {
+			return $spMetadata->getLocalizedString('name');
+		} elseif ($spMetadata->hasValue('OrganizationDisplayName')) {
+			return $spMetadata->getLocalizedString('OrganizationDisplayName');
+		} else {
+			return array('en' => $spEntityId);
+		}
 	}
 
 
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 5b3c2bc9f..598c2eb51 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -173,33 +173,30 @@ class SimpleSAML_Metadata_SAMLBuilder {
 		$this->entityDescriptor->appendChild($org);
 	}
 
-	
-	public function addOrganizationInfo($metadata) {
-		if (array_key_exists('name', $metadata)) {
-
-			if (is_array($metadata['name'])) {
-				$name = $metadata['name'];
-			} else {
-				$name = array('en' => $metadata['name']);
-			}
 
+	/**
+	 * Add 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;
+		}
 
-			if (!array_key_exists('url', $metadata)) {
-				/*
-				 * The specification requires an OrganizationURL element, but
-				 * we haven't got an URL. Insert an empty element instead.
-				 */
-				$url = array('en' => '');
-			} elseif (is_array($metadata['url'])) {
-				$url = $metadata['url'];
-			} else {
-				$url = array('en' => $metadata['url']);
-			}
+		$orgName = SimpleSAML_Utilities::arrayize($metadata['OrganizationName'], 'en');
+		$orgDisplayName = SimpleSAML_Utilities::arrayize($metadata['OrganizationDisplayName'], 'en');
+		$orgURL = SimpleSAML_Utilities::arrayize($metadata['OrganizationURL'], 'en');
 
-			$this->addOrganization($name, $name, $url);
-		}
+		$this->addOrganization($orgName, $orgDisplayName, $orgURL);
 	}
-	
+
 
 	/**
 	 * Add endpoint list to metadata.
diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php
index f06bceb82..54f1d9062 100644
--- a/lib/SimpleSAML/Metadata/SAMLParser.php
+++ b/lib/SimpleSAML/Metadata/SAMLParser.php
@@ -444,14 +444,13 @@ class SimpleSAML_Metadata_SAMLParser {
 		 * Add organizational metadata
 		 */
 		if (!empty($this->organizationName)) {
-			$ret['name'] = $this->organizationName;
-			$ret['description'] = $this->organizationName;
+			$ret['OrganizationName'] = $this->organizationName;
 		}
 		if (!empty($this->organizationDisplayName)) {
-			$ret['name'] = $this->organizationDisplayName;
+			$ret['OrganizationDisplayName'] = $this->organizationDisplayName;
 		}
 		if (!empty($this->organizationURL)) {
-			$ret['url'] = $this->organizationURL;
+			$ret['OrganizationURL'] = $this->organizationURL;
 		}
 
 		return $ret;
diff --git a/modules/adfs/www/idp/prp.php b/modules/adfs/www/idp/prp.php
index c184fda1f..3b38ccb44 100644
--- a/modules/adfs/www/idp/prp.php
+++ b/modules/adfs/www/idp/prp.php
@@ -202,8 +202,6 @@ if (!$session->isValid($authority) ) {
 		}
 		$spmetadata = SimpleSAML_Configuration::loadFromArray($arr);
 
-		$sp_name = $spmetadata->getValue('name', $spentityid);
-
 		SimpleSAML_Logger::info('ADFS - IdP.SSOService: Sending back AuthnResponse to ' . $spentityid);
 		
 		$attributes = $session->getAttributes();
diff --git a/modules/consent/templates/consentform.php b/modules/consent/templates/consentform.php
index c435481ef..b5d49cb1a 100644
--- a/modules/consent/templates/consentform.php
+++ b/modules/consent/templates/consentform.php
@@ -31,22 +31,28 @@ assert('$this->data["sppp"] === FALSE || is_string($this->data["sppp"])');
 
 if (array_key_exists('name', $this->data['srcMetadata'])) {
 	$srcName = $this->data['srcMetadata']['name'];
-	if (is_array($srcName)) {
-		$srcName = $this->t($srcName);
-	}
+} elseif (array_key_exists('OrganizationDisplayName', $this->data['srcMetadata'])) {
+	$srcName = $this->data['srcMetadata']['OrganizationDisplayName'];
 } else {
 	$srcName = $this->data['srcMetadata']['entityid'];
 }
 
+if (is_array($srcName)) {
+	$srcName = $this->t($srcName);
+}
+
 if (array_key_exists('name', $this->data['dstMetadata'])) {
 	$dstName = $this->data['dstMetadata']['name'];
-	if (is_array($dstName)) {
-		$dstName = $this->t($dstName);
-	}
+} elseif (array_key_exists('OrganizationDisplayName', $this->data['dstMetadata'])) {
+	$dstName = $this->data['dstMetadata']['OrganizationDisplayName'];
 } else {
 	$dstName = $this->data['dstMetadata']['entityid'];
 }
 
+if (is_array($dstName)) {
+	$dstName = $this->t($dstName);
+}
+
 
 $attributes = $this->data['attributes'];
 
diff --git a/modules/consentAdmin/www/consentAdmin.php b/modules/consentAdmin/www/consentAdmin.php
index 5361c1932..81d229c49 100644
--- a/modules/consentAdmin/www/consentAdmin.php
+++ b/modules/consentAdmin/www/consentAdmin.php
@@ -220,10 +220,12 @@ foreach ($all_sp_metadata as $sp_entityid => $sp_values) {
 	}
 
 	// Set name of SP
-	if(empty($sp_values['name']) || !is_array($sp_values['name'])) {
-		$sp_name = $sp_empty_name;
-	} else {
+	if(isset($sp_values['name']) && is_array($sp_values['name'])) {
 		$sp_name = $sp_metadata['name'];
+	} elseif(isset($sp_values['OrganizationDisplayName']) && is_array($sp_values['OrganizationDisplayName'])) {
+		$sp_name = $sp_metadata['OrganizationDisplayName'];
+	} else {
+		$sp_name = $sp_empty_name;
 	}
 
 	// Set description of SP
diff --git a/modules/core/templates/frontpage_federation.tpl.php b/modules/core/templates/frontpage_federation.tpl.php
index 2d5d134bf..e1b3ce4f8 100644
--- a/modules/core/templates/frontpage_federation.tpl.php
+++ b/modules/core/templates/frontpage_federation.tpl.php
@@ -82,6 +82,8 @@ foreach($this->data['metaentries']['remote'] AS $setkey => $set) {
 			'">');
 		if (array_key_exists('name', $entry)) {
 			echo $this->getTranslation(SimpleSAML_Utilities::arrayize($entry['name'], 'en'));
+		} elseif (array_key_exists('OrganizationDisplayName', $entry)) {
+			echo $this->getTranslation(SimpleSAML_Utilities::arrayize($entry['OrganizationDisplayName'], 'en'));
 		} else {
 			echo $entry['entityid'];
 		}
diff --git a/modules/discopower/templates/disco-tpl.php b/modules/discopower/templates/disco-tpl.php
index eaf01929b..9791f79e0 100644
--- a/modules/discopower/templates/disco-tpl.php
+++ b/modules/discopower/templates/disco-tpl.php
@@ -108,6 +108,12 @@ function getTranslatedName($t, $metadata) {
 		} else {
 			return $metadata['name'];
 		}
+	} elseif (array_key_exists('OrganizationDisplayName', $metadata)) {
+		if (is_array($metadata['OrganizationDisplayName'])) {
+			return $t->getTranslation($metadata['OrganizationDisplayName']);
+		} else {
+			return $metadata['OrganizationDisplayName'];
+		}
 	}
 	return $metadata['entityid'];
 }
diff --git a/modules/saml/hooks/hook_metadata_hosted.php b/modules/saml/hooks/hook_metadata_hosted.php
index f22f265cc..f42ca72d5 100644
--- a/modules/saml/hooks/hook_metadata_hosted.php
+++ b/modules/saml/hooks/hook_metadata_hosted.php
@@ -15,6 +15,9 @@ function saml_hook_metadata_hosted(&$metadataHosted) {
 		$metadata = $source->getMetadata();
 
 		$name = $metadata->getValue('name', NULL);
+		if ($name === NULL) {
+			$name = $metadata->getValue('OrganizationDisplayName', NULL);
+		}
 		if ($name === NULL) {
 			$name = $source->getAuthID();
 		}
diff --git a/templates/metadata.php b/templates/metadata.php
index 82c74a75b..48bc46128 100644
--- a/templates/metadata.php
+++ b/templates/metadata.php
@@ -37,7 +37,9 @@ $this->includeAtTemplateBase('includes/header.php');
 					<select name="sendtoidp">
 					<?php
 						foreach ($this->data['idpsend'] AS $entityid => $idpmeta) {
-							$name = array_key_exists('name', $idpmeta) ? $idpmeta['name'] : $entityid;
+							$name = array_key_exists('name', $idpmeta) ? $idpmeta['name'] :
+								array_key_exists('OrganizationDisplayName', $idpmeta) ? $idpmeta['OrganizationDisplayName'] :
+								$entityid;
 							echo '<option value="' . htmlspecialchars($entityid) . '">';
 							if (is_array($name)) {
 								echo htmlspecialchars($this->t($name));
diff --git a/templates/selectidp-dropdown.php b/templates/selectidp-dropdown.php
index 937d2ec83..c7aaa1c60 100644
--- a/templates/selectidp-dropdown.php
+++ b/templates/selectidp-dropdown.php
@@ -10,8 +10,11 @@ $this->data['autofocus'] = 'dropdownlist';
 $this->includeAtTemplateBase('includes/header.php');
 
 foreach ($this->data['idplist'] AS $idpentry) {
-	if (isset($idpentry['name']))
+	if (isset($idpentry['name'])) {
 		$this->includeInlineTranslation('idpname_' . $idpentry['entityid'], $idpentry['name']);
+	} elseif (isset($idpentry['OrganizationDisplayName'])) {
+		$this->includeInlineTranslation('idpname_' . $idpentry['entityid'], $idpentry['OrganizationDisplayName']);
+	}
 	if (isset($idpentry['description']))
 		$this->includeInlineTranslation('idpdesc_' . $idpentry['entityid'], $idpentry['description']);
 }
diff --git a/templates/selectidp-links.php b/templates/selectidp-links.php
index 81c981d7c..1153a84c1 100644
--- a/templates/selectidp-links.php
+++ b/templates/selectidp-links.php
@@ -10,8 +10,11 @@ $this->data['autofocus'] = 'preferredidp';
 $this->includeAtTemplateBase('includes/header.php');
 
 foreach ($this->data['idplist'] AS $idpentry) {
-	if (isset($idpentry['name']))
+	if (isset($idpentry['name'])) {
 		$this->includeInlineTranslation('idpname_' . $idpentry['entityid'], $idpentry['name']);
+	} elseif (isset($idpentry['OrganizationDisplayName'])) {
+		$this->includeInlineTranslation('idpname_' . $idpentry['entityid'], $idpentry['OrganizationDisplayName']);
+	}
 	if (isset($idpentry['description']))
 		$this->includeInlineTranslation('idpdesc_' . $idpentry['entityid'], $idpentry['description']);
 }
diff --git a/www/admin/metadata.php b/www/admin/metadata.php
index f4875463b..8caab3063 100644
--- a/www/admin/metadata.php
+++ b/www/admin/metadata.php
@@ -25,7 +25,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host'),
-				array('redirect.sign','redirect.validate','certificate','privatekey', 'privatekey_pass', 'NameIDFormat', 'ForceAuthn', 'AuthnContextClassRef', 'SPNameQualifier', 'attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'idpdisco.url', 'authproc', 'certData')
+				array('redirect.sign','redirect.validate','certificate','privatekey', 'privatekey_pass', 'NameIDFormat', 'ForceAuthn', 'AuthnContextClassRef', 'SPNameQualifier', 'attributes', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'idpdisco.url', 'authproc', 'certData', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.saml20-sp-hosted'] = $results;
@@ -35,7 +35,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'SingleSignOnService', 'SingleLogoutService', 'certFingerprint'),
-				array('name', 'description', 'base64attributes', 'certificate', 'hint.cidr', 'saml2.relaxvalidation', 'SingleLogoutServiceResponse', 'redirect.sign', 'redirect.validate', 'sharedkey', 'assertion.encryption', 'icon', 'authproc', 'certData', 'send_metadata_email')
+				array('name', 'description', 'base64attributes', 'certificate', 'hint.cidr', 'saml2.relaxvalidation', 'SingleLogoutServiceResponse', 'redirect.sign', 'redirect.validate', 'sharedkey', 'assertion.encryption', 'icon', 'authproc', 'certData', 'send_metadata_email', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 			$index = array_search('certFingerprint', $results[$entityid]['required.notfound']);
 			if ($index !== FALSE) {
@@ -54,7 +54,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host', 'privatekey', 'certificate', 'auth'),
-				array('redirect.sign', 'redirect.validate', 'privatekey_pass', 'authority', 'userid.attribute', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'AttributeNameFormat', 'name', 'authproc', 'saml20.sign.assertion', 'saml20.sign.response', 'certData')
+				array('redirect.sign', 'redirect.validate', 'privatekey_pass', 'authority', 'userid.attribute', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'AttributeNameFormat', 'name', 'authproc', 'saml20.sign.assertion', 'saml20.sign.response', 'certData', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.saml20-idp-hosted'] = $results;
@@ -64,7 +64,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'AssertionConsumerService'),
-				array('SingleLogoutService', 'NameIDFormat', 'SPNameQualifier', 'base64attributes', 'simplesaml.nameidattribute', 'simplesaml.attributes', 'attributes', 'name', 'description', 'redirect.sign', 'redirect.validate', 'certificate', 'ForceAuthn', 'sharedkey', 'assertion.encryption', 'userid.attribute', 'AttributeNameFormat', 'authproc', 'saml20.sign.assertion', 'saml20.sign.response', 'certData')
+				array('SingleLogoutService', 'NameIDFormat', 'SPNameQualifier', 'base64attributes', 'simplesaml.nameidattribute', 'simplesaml.attributes', 'attributes', 'name', 'description', 'redirect.sign', 'redirect.validate', 'certificate', 'ForceAuthn', 'sharedkey', 'assertion.encryption', 'userid.attribute', 'AttributeNameFormat', 'authproc', 'saml20.sign.assertion', 'saml20.sign.response', 'certData', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.saml20-sp-remote'] = $results;
@@ -81,7 +81,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host'),
-				array('NameIDFormat', 'ForceAuthn', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'idpdisco.url', 'authproc')
+				array('NameIDFormat', 'ForceAuthn', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'idpdisco.url', 'authproc', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.shib13-sp-hosted'] = $results;
@@ -91,7 +91,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'SingleSignOnService', 'certFingerprint'),
-				array('name', 'description', 'base64attributes', 'icon', 'authproc')
+				array('name', 'description', 'base64attributes', 'icon', 'authproc', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.shib13-idp-remote'] = $results;
@@ -104,7 +104,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'host', 'privatekey', 'certificate', 'auth'),
-				array('name', 'authority', 'privatekey_pass', 'scopedattributes', 'authproc')
+				array('name', 'authority', 'privatekey_pass', 'scopedattributes', 'authproc', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.shib13-idp-hosted'] = $results;
@@ -114,7 +114,7 @@ try {
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
 				array('entityid', 'AssertionConsumerService'),
-				array('base64attributes', 'audience', 'simplesaml.attributes', 'attributes', 'name', 'description', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'scopedattributes', 'authproc')
+				array('base64attributes', 'audience', 'simplesaml.attributes', 'attributes', 'name', 'description', 'metadata.sign.enable', 'metadata.sign.privatekey', 'metadata.sign.privatekey_pass', 'metadata.sign.certificate', 'scopedattributes', 'authproc', 'OrganizationName', 'OrganizationDisplayName', 'OrganizationURL')
 			);
 		}
 		$et->data['metadata.shib13-sp-remote'] = $results;
diff --git a/www/auth/login-feide.php b/www/auth/login-feide.php
index 38365766b..8439c9aca 100644
--- a/www/auth/login-feide.php
+++ b/www/auth/login-feide.php
@@ -288,6 +288,8 @@ if(array_key_exists('description', $spmetadata)) {
 }
 if(array_key_exists('name', $spmetadata)) {
 	$t->data['spname'] = $spmetadata['name'];
+} elseif(array_key_exists('OrganizationDisplayName', $spmetadata)) {
+	$t->data['spname'] = $spmetadata['OrganizationDisplayName'];
 } else {
 	$t->data['spname'] = NULL;
 }
diff --git a/www/saml2/idp/metadata.php b/www/saml2/idp/metadata.php
index 95fae46f4..ee2b1f947 100644
--- a/www/saml2/idp/metadata.php
+++ b/www/saml2/idp/metadata.php
@@ -50,15 +50,22 @@ try {
 	} else {
 		$metaArray['NameIDFormat'] = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient';
 	}
-	if (array_key_exists('name', $idpmeta)) {
-		$metaArray['name'] = $idpmeta['name'];
-	}
-	if (array_key_exists('description', $idpmeta)) {
-		$metaArray['description'] = $idpmeta['description'];
-	}
-	if (array_key_exists('url', $idpmeta)) {
-		$metaArray['url'] = $idpmeta['url'];
+
+	if (!empty($idpmeta['OrganizationName'])) {
+		$metaArray['OrganizationName'] = $idpmeta['OrganizationName'];
+
+		if (!empty($idpmeta['OrganizationDisplayName'])) {
+			$metaArray['OrganizationDisplayName'] = $idpmeta['OrganizationDisplayName'];
+		} else {
+			$metaArray['OrganizationDisplayName'] = $idpmeta['OrganizationName'];
+		}
+
+		if (empty($idpmeta['OrganizationURL'])) {
+			throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+		}
+		$metaArray['OrganizationURL'] = $idpmeta['OrganizationURL'];
 	}
+
 	if (array_key_exists('scope', $idpmeta)) {
 		$metaArray['scope'] = $idpmeta['scope'];
 	}
@@ -69,6 +76,7 @@ try {
 	$metaArray['certData'] = $certInfo['certData'];
 	$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
 	$metaBuilder->addMetadataIdP20($metaArray);
+	$metaBuilder->addOrganizationInfo($metaArray);
 	$metaBuilder->addContact('technical', array(
 		'emailAddress' => $config->getString('technicalcontact_email', NULL),
 		'name' => $config->getString('technicalcontact_name', NULL),
diff --git a/www/saml2/sp/metadata.php b/www/saml2/sp/metadata.php
index 795793306..f2d29914f 100644
--- a/www/saml2/sp/metadata.php
+++ b/www/saml2/sp/metadata.php
@@ -34,15 +34,29 @@ try {
 	} else {
 		$metaArray['NameIDFormat'] = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient';
 	}
+
+	if (!empty($spmeta['OrganizationName'])) {
+		$metaArray['OrganizationName'] = $spmeta['OrganizationName'];
+
+		if (!empty($spmeta['OrganizationDisplayName'])) {
+			$metaArray['OrganizationDisplayName'] = $spmeta['OrganizationDisplayName'];
+		} else {
+			$metaArray['OrganizationDisplayName'] = $spmeta['OrganizationName'];
+		}
+
+		if (empty($spmeta['OrganizationURL'])) {
+			throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+		}
+		$metaArray['OrganizationURL'] = $spmeta['OrganizationURL'];
+	}
+
+
 	if (array_key_exists('name', $spmeta)) {
 		$metaArray['name'] = $spmeta['name'];
 	}
 	if (array_key_exists('description', $spmeta)) {
 		$metaArray['description'] = $spmeta['description'];
 	}
-	if (array_key_exists('url', $spmeta)) {
-		$metaArray['url'] = $spmeta['url'];
-	}
 
 	$certInfo = SimpleSAML_Utilities::loadPublicKey($spmeta);
 	if ($certInfo !== NULL && array_key_exists('certData', $certInfo)) {
diff --git a/www/shib13/idp/metadata.php b/www/shib13/idp/metadata.php
index f6e9ae239..4b37a17e0 100644
--- a/www/shib13/idp/metadata.php
+++ b/www/shib13/idp/metadata.php
@@ -40,14 +40,20 @@ try {
 	} else {
 		$metaArray['NameIDFormat'] = 'urn:mace:shibboleth:1.0:nameIdentifier';
 	}
-	if (array_key_exists('name', $idpmeta)) {
-		$metaArray['name'] = $idpmeta['name'];
-	}
-	if (array_key_exists('description', $idpmeta)) {
-		$metaArray['description'] = $idpmeta['description'];
-	}
-	if (array_key_exists('url', $idpmeta)) {
-		$metaArray['url'] = $idpmeta['url'];
+
+	if (!empty($idpmeta['OrganizationName'])) {
+		$metaArray['OrganizationName'] = $idpmeta['OrganizationName'];
+
+		if (!empty($idpmeta['OrganizationDisplayName'])) {
+			$metaArray['OrganizationDisplayName'] = $idpmeta['OrganizationDisplayName'];
+		} else {
+			$metaArray['OrganizationDisplayName'] = $idpmeta['OrganizationName'];
+		}
+
+		if (empty($idpmeta['OrganizationURL'])) {
+			throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+		}
+		$metaArray['OrganizationURL'] = $idpmeta['OrganizationURL'];
 	}
 
 
@@ -56,6 +62,7 @@ try {
 	$metaArray['certData'] = $certInfo['certData'];
 	$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
 	$metaBuilder->addMetadataIdP11($metaArray);
+	$metaBuilder->addOrganizationInfo($metaArray);
 	$metaBuilder->addContact('technical', array(
 		'emailAddress' => $config->getString('technicalcontact_email', NULL),
 		'name' => $config->getString('technicalcontact_name', NULL),
diff --git a/www/shib13/sp/metadata.php b/www/shib13/sp/metadata.php
index 89a62b609..111e95062 100644
--- a/www/shib13/sp/metadata.php
+++ b/www/shib13/sp/metadata.php
@@ -39,15 +39,28 @@ try {
 	} else {
 		$metaArray['NameIDFormat'] = 'urn:mace:shibboleth:1.0:nameIdentifier';
 	}
+
+	if (!empty($spmeta['OrganizationName'])) {
+		$metaArray['OrganizationName'] = $spmeta['OrganizationName'];
+
+		if (!empty($spmeta['OrganizationDisplayName'])) {
+			$metaArray['OrganizationDisplayName'] = $spmeta['OrganizationDisplayName'];
+		} else {
+			$metaArray['OrganizationDisplayName'] = $spmeta['OrganizationName'];
+		}
+
+		if (empty($spmeta['OrganizationURL'])) {
+			throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+		}
+		$metaArray['OrganizationURL'] = $spmeta['OrganizationURL'];
+	}
+
 	if (array_key_exists('name', $spmeta)) {
 		$metaArray['name'] = $spmeta['name'];
 	}
 	if (array_key_exists('description', $spmeta)) {
 		$metaArray['description'] = $spmeta['description'];
 	}
-	if (array_key_exists('url', $spmeta)) {
-		$metaArray['url'] = $spmeta['url'];
-	}
 
 
 	$metaflat = '$metadata[' . var_export($spentityid, TRUE) . '] = ' . var_export($metaArray, TRUE) . ';';
-- 
GitLab