From efe5e047605ffc97c96a1a9a55312cd9c79b7b47 Mon Sep 17 00:00:00 2001
From: Serghei Mihai <smihai@entrouvert.com>
Date: Fri, 8 Mar 2019 14:57:45 +0100
Subject: [PATCH] auth: separate OIDC providers in blocks on login page
 (#31259)

---
 src/authentic2/views.py                       | 29 +++++++++++++------
 src/authentic2_auth_oidc/authenticators.py    |  9 ++++--
 .../templates/authentic2_auth_oidc/login.html | 11 ++++---
 3 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/authentic2/views.py b/src/authentic2/views.py
index 51b58708..ec547ec5 100644
--- a/src/authentic2/views.py
+++ b/src/authentic2/views.py
@@ -323,19 +323,30 @@ def login(request, template_name='authentic2/login.html',
                 block['form'] = form_class()
             blocks.append(block)
         else: # New frontends API
+            auth_blocks = []
             parameters = {'request': request,
                           'context': context}
-            block = utils.get_authenticator_method(authenticator, 'login', parameters)
+            # check if the authenticator has multiple instances
+            if hasattr(authenticator, 'instances'):
+                for instance_id, instance in authenticator.instances(**parameters):
+                    parameters['instance'] = instance
+                    block = utils.get_authenticator_method(authenticator, 'login', parameters)
+                    # update block id in order
+                    block['id'] = instance_id
+                    auth_blocks.append(block)
+            else:
+                auth_blocks.append(utils.get_authenticator_method(authenticator, 'login', parameters))
             # If a login frontend method returns an HttpResponse with a status code != 200
             # this response is returned.
-            if block:
-                if block['status_code'] != 200:
-                    return block['response']
-                blocks.append(block)
-        if hasattr(authenticator, 'is_hidden'):
-            blocks[-1]['is_hidden'] = authenticator.is_hidden(request)
-        else:
-            blocks[-1]['is_hidden'] = False
+            for block in auth_blocks:
+                if block:
+                    if block['status_code'] != 200:
+                        return block['response']
+                    blocks.append(block)
+                if hasattr(authenticator, 'is_hidden'):
+                    blocks[-1]['is_hidden'] = authenticator.is_hidden(request)
+                else:
+                    blocks[-1]['is_hidden'] = False
 
 
     # Old frontends API
diff --git a/src/authentic2_auth_oidc/authenticators.py b/src/authentic2_auth_oidc/authenticators.py
index 4cac9a77..bf1258e4 100644
--- a/src/authentic2_auth_oidc/authenticators.py
+++ b/src/authentic2_auth_oidc/authenticators.py
@@ -14,7 +14,12 @@ class OIDCAuthenticator(object):
     def id(self):
         return 'oidc'
 
+    def instances(self, request, *args, **kwargs):
+        return [(p.slug, p) for p in utils.get_providers(shown=True)]
+
+
     def login(self, request, *args, **kwargs):
         context = kwargs.get('context', {})
-        context['providers'] = utils.get_providers(shown=True)
-        return render(request, 'authentic2_auth_oidc/login.html', context)
+        if kwargs.get('instance'):
+            context['provider'] = kwargs['instance']
+            return render(request, 'authentic2_auth_oidc/login.html', context)
diff --git a/src/authentic2_auth_oidc/templates/authentic2_auth_oidc/login.html b/src/authentic2_auth_oidc/templates/authentic2_auth_oidc/login.html
index 18f6d3bc..af3bf5f2 100644
--- a/src/authentic2_auth_oidc/templates/authentic2_auth_oidc/login.html
+++ b/src/authentic2_auth_oidc/templates/authentic2_auth_oidc/login.html
@@ -1,6 +1,5 @@
-{% for provider in providers %}
-  <p id="oidc-p-{% firstof provider.slug provider.name|slugify %}">
-    <a id="oidc-a-{% firstof provider.slug  provider.name|slugify %}"
-       href="{% url "oidc-login" pk=provider.pk %}?{{ request.GET.urlencode }}">{{ provider.name }}</a>
-  </p>
-{% endfor %}
+<p id="oidc-p-{% firstof provider.slug provider.name|slugify %}">
+  <a id="oidc-a-{% firstof provider.slug  provider.name|slugify %}"
+     href="{% url "oidc-login" pk=provider.pk %}?{{ request.GET.urlencode }}">{{ provider.name }}</a>
+</p>
+
-- 
2.20.1

