From e49ac278ad136891e52c704f6c703c98d892339b Mon Sep 17 00:00:00 2001
From: Thijs Kinkhorst <thijs@kinkhorst.com>
Date: Sun, 7 Oct 2018 18:19:49 +0000
Subject: [PATCH] Add twig templates for built-in idp discovery.

There's some redundancy now since the code must support the old
and new template. The links variety is not very beautiful, but the
old one wasn't either..
---
 lib/SimpleSAML/XHTML/IdPDisco.php | 48 ++++++++++++++++++++++++++++++-
 templates/selectidp-dropdown.twig | 27 +++++++++++++++++
 templates/selectidp-links.twig    | 45 +++++++++++++++++++++++++++++
 www/assets/css/src/default.css    |  5 ++++
 4 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 templates/selectidp-dropdown.twig
 create mode 100644 templates/selectidp-links.twig

diff --git a/lib/SimpleSAML/XHTML/IdPDisco.php b/lib/SimpleSAML/XHTML/IdPDisco.php
index 33faec235..0cf77f0d6 100644
--- a/lib/SimpleSAML/XHTML/IdPDisco.php
+++ b/lib/SimpleSAML/XHTML/IdPDisco.php
@@ -587,7 +587,41 @@ class IdPDisco
         }
 
         $t = new Template($this->config, $templateFile, 'disco');
-        $t->data['idplist'] = $idpList;
+
+        $fallbackLanguage = 'en';
+        $defaultLanguage = $this->config->getString('language.default', $fallbackLanguage);
+        $translator = $t->getTranslator();
+        $language = $translator->getLanguage()->getLanguage();
+        $tryLanguages = [0 => $language, 1 => $defaultLanguage, 2 => $fallbackLanguage];
+
+        $newlist = [];
+        foreach($idpList as $entityid => $data) {
+            $newlist[$entityid]['entityid'] = $entityid;
+            foreach ( $tryLanguages as $lang ) {
+                if ( $name = $this->getEntityDisplayName($data, $lang) ) {
+                    $newlist[$entityid]['name'] = $name;
+                    continue;
+                }
+            }
+            if ( empty($newlist[$entityid]['name']) ) {
+                $newlist[$entityid]['name'] = $entityid;
+            }
+            foreach ( $tryLanguages as $lang ) {
+                if ( !empty($data['description'][$lang]) ) {
+                    $newlist[$entityid]['description'] = $data['description'][$lang];
+                    continue;
+                }
+            }
+            if ( !empty($data['icon']) ) {
+                $newlist[$entityid]['icon'] = $data['icon'];
+                $newlist[$entityid]['iconurl'] = \SimpleSAML\Utils\HTTP::resolveURL($data['icon']);
+            }
+        }
+        usort($newlist, function($idpentry1, $idpentry2) {
+            return strcasecmp($idpentry1['name'],$idpentry2['name']);
+            });
+
+        $t->data['idplist'] = $newlist;
         $t->data['preferredidp'] = $preferredIdP;
         $t->data['return'] = $this->returnURL;
         $t->data['returnIDParam'] = $this->returnIdParam;
@@ -596,4 +630,16 @@ class IdPDisco
         $t->data['rememberenabled'] = $this->config->getBoolean('idpdisco.enableremember', false);
         $t->show();
     }
+
+    private function getEntityDisplayName(array $idpData, $language)
+    {
+        if(isset($idpData['UIInfo']['DisplayName'][$language]) ) {
+            return $idpData['UIInfo']['DisplayName'][$language];
+        } elseif ( isset($idpData['name'][$language]) ) {
+            return $idpData['name'][$language];
+        } elseif ( isset($idpData['OrganizationDisplayName'][$language]) ) {
+            return $idpData['OrganizationDisplayName'][$language];
+        }
+        return null;
+    }
 }
diff --git a/templates/selectidp-dropdown.twig b/templates/selectidp-dropdown.twig
new file mode 100644
index 000000000..48f042d0c
--- /dev/null
+++ b/templates/selectidp-dropdown.twig
@@ -0,0 +1,27 @@
+{% set pagetitle = "Select your identity provider"|trans %}
+{% extends "base.twig" %}
+
+{% block content %}
+    <h2>{{ pagetitle }}</h2>
+
+    <p>{{ "Please select the identity provider where you want to authenticate:" | trans }}</p>
+    <form method="get" action="{{ urlpattern }}">
+        <input type="hidden" name="entityID" value="{{ entityID }}">
+        <input type="hidden" name="return" value="{{ return }}">
+        <input type="hidden" name="returnIDParam" value="{{ returnIDParam }}">
+        <select id="dropdownlist" name="idpentityid" autofocus>
+        {% for idpentry in idplist %}
+            <option value="{{ idpentry.entityid }}"
+            {% if idpentry.entityid == preferredidp %}
+                 selected
+            {% endif %}
+            >{{ idpentry.name }}</option>
+        {% endfor %}
+        </select>
+        <button class="btn" type="submit">{{ 'Select' | trans }}</button>
+	{% if rememberenabled %}
+            <br/><input type="checkbox" name="remember" id="remember" value="1">
+            <label for="remember">{{ 'Remember my choice' | trans }}</label>
+        {% endif %}
+    </form>
+{% endblock %}
diff --git a/templates/selectidp-links.twig b/templates/selectidp-links.twig
new file mode 100644
index 000000000..a7bf1103f
--- /dev/null
+++ b/templates/selectidp-links.twig
@@ -0,0 +1,45 @@
+{% set pagetitle = "Select your identity provider"|trans %}
+{% extends "base.twig" %}
+
+{% block content %}
+    <h2>{{ pagetitle }}</h2>
+
+    <p>{{ "Please select the identity provider where you want to authenticate:" | trans }}</p>
+    <form method="get" action="{{ urlpattern }}">
+        <input type="hidden" name="entityID" value="{{ entityID }}">
+        <input type="hidden" name="return" value="{{ return }}">
+        <input type="hidden" name="returnIDParam" value="{{ returnIDParam }}">
+        {% if rememberenabled %}
+            <p><input type="checkbox" name="remember" id="remember" value="1">
+            <label for="remember">{{ 'Remember my choice' | trans }}</label></p>
+        {% endif %}
+
+        {% for idpentry in idplist %}
+        {% if idpentry.entityid == preferredidp %}
+                <div class="preferredidp">
+                {% if idpentry.iconurl %}
+                    <img class="float-l" src="{{ idpentry.iconurl }}">
+                {% endif %}
+                <h3><i class="fa fa-star"></i> {{ idpentry.name }}</h3>
+                {% if idpentry.description %}
+                    <p>{{ idpentry.description }}</p>
+                {% endif %}
+                <button type="submit" class="btn" name="idp_{{ idpentry.entityid }}">{{'Select'|trans}}</button>
+                </div>
+        {% endif %}
+        {% endfor %}
+
+        {% for idpentry in idplist %}
+        {% if idpentry.entityid != preferredidp %}
+                {% if idpentry.iconurl %}
+                    <img class="float-l" src="{{ idpentry.iconurl }}">
+                {% endif %}
+                <h3>{{ idpentry.name }}</h3>
+                {% if idpentry.description %}
+                    <p>{{ idpentry.description }}</p>
+                {% endif %}
+                <button type="submit" class="btn" name="idp_{{ idpentry.entityid }}">{{'Select'|trans}}</button>
+        {% endif %}
+        {% endfor %}
+    </form>
+{% endblock %}
diff --git a/www/assets/css/src/default.css b/www/assets/css/src/default.css
index ae1ae6ef3..d4ea241bc 100644
--- a/www/assets/css/src/default.css
+++ b/www/assets/css/src/default.css
@@ -652,3 +652,8 @@ dt {
 .entity-expired {
     color: #500;
 }
+div.preferredidp {
+    border: 1px dashed #ccc;
+    background: #eee;
+    padding: 2px 2em 2px 2em;
+}
-- 
GitLab