Projet

Général

Profil

0001-auth-separate-OIDC-providers-in-blocks-on-login-page.patch

Serghei Mihai, 01 avril 2019 19:07

Télécharger (5,76 ko)

Voir les différences:

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 | 10 +++----
 tests/test_auth_oidc.py                       | 29 +++++++++++++++++++
 4 files changed, 60 insertions(+), 17 deletions(-)
src/authentic2/views.py
322 322
                block['form'] = form_class()
323 323
            blocks.append(block)
324 324
        else: # New frontends API
325
            auth_blocks = []
325 326
            parameters = {'request': request,
326 327
                          'context': context}
327
            block = utils.get_authenticator_method(authenticator, 'login', parameters)
328
            # check if the authenticator has multiple instances
329
            if hasattr(authenticator, 'instances'):
330
                for instance_id, instance in authenticator.instances(**parameters):
331
                    parameters['instance'] = instance
332
                    block = utils.get_authenticator_method(authenticator, 'login', parameters)
333
                    # update block id in order to separate instances
334
                    block['id'] = instance_id
335
                    auth_blocks.append(block)
336
            else:
337
                auth_blocks.append(utils.get_authenticator_method(authenticator, 'login', parameters))
328 338
            # If a login frontend method returns an HttpResponse with a status code != 200
329 339
            # this response is returned.
330
            if block:
331
                if block['status_code'] != 200:
332
                    return block['response']
333
                blocks.append(block)
334
        if hasattr(authenticator, 'is_hidden'):
335
            blocks[-1]['is_hidden'] = authenticator.is_hidden(request)
336
        else:
337
            blocks[-1]['is_hidden'] = False
340
            for block in auth_blocks:
341
                if block:
342
                    if block['status_code'] != 200:
343
                        return block['response']
344
                    blocks.append(block)
345
                if hasattr(authenticator, 'is_hidden'):
346
                    blocks[-1]['is_hidden'] = authenticator.is_hidden(request)
347
                else:
348
                    blocks[-1]['is_hidden'] = False
338 349

  
339 350

  
340 351
    # Old frontends API
src/authentic2_auth_oidc/authenticators.py
14 14
    def id(self):
15 15
        return 'oidc'
16 16

  
17
    def instances(self, request, *args, **kwargs):
18
        for p in utils.get_providers(shown=True):
19
            yield (p.slug, p)
20

  
17 21
    def login(self, request, *args, **kwargs):
18 22
        context = kwargs.get('context', {})
19
        context['providers'] = utils.get_providers(shown=True)
20
        return render(request, 'authentic2_auth_oidc/login.html', context)
23
        if kwargs.get('instance'):
24
            context['provider'] = kwargs['instance']
25
            return render(request, 'authentic2_auth_oidc/login.html', context)
src/authentic2_auth_oidc/templates/authentic2_auth_oidc/login.html
1
{% for provider in providers %}
2
  <p id="oidc-p-{% firstof provider.slug provider.name|slugify %}">
3
    <a id="oidc-a-{% firstof provider.slug  provider.name|slugify %}"
4
       href="{% url "oidc-login" pk=provider.pk %}?{{ request.GET.urlencode }}">{{ provider.name }}</a>
5
  </p>
6
{% endfor %}
1
<p id="oidc-p-{% firstof provider.slug provider.name|slugify %}">
2
  <a id="oidc-a-{% firstof provider.slug  provider.name|slugify %}"
3
     href="{% url "oidc-login" pk=provider.pk %}?{{ request.GET.urlencode }}">{{ provider.name }}</a>
4
</p>
tests/test_auth_oidc.py
260 260
    return qs
261 261

  
262 262

  
263
def test_providers_on_login_page(oidc_provider, app):
264
    response = app.get('/login/')
265
    # two frontends should be present on login page
266
    assert response.pyquery('p#oidc-p-oididp')
267
    OIDCProvider.objects.create(
268
        id=2,
269
        ou=get_default_ou(),
270
        name='OIDCIDP 2',
271
        slug='oidcidp-2',
272
        issuer='https://idp2.example.com/',
273
        authorization_endpoint='https://idp2.example.com/authorize',
274
        token_endpoint='https://idp2.example.com/token',
275
        end_session_endpoint='https://idp2.example.com/logout',
276
        userinfo_endpoint='https://idp*é.example.com/user_info',
277
        token_revocation_endpoint='https://idp2.example.com/revoke',
278
        max_auth_age=10,
279
        strategy=OIDCProvider.STRATEGY_CREATE,
280
        jwkset_json=None,
281
        idtoken_algo=OIDCProvider.ALGO_RSA,
282
        claims_parameter_supported=False
283
    )
284

  
285
    response = app.get('/login/')
286
    assert response.pyquery('p#oidc-p-oididp')
287
    assert response.pyquery('p#oidc-p-oidcidp-2')
288

  
289

  
290

  
291

  
263 292
def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url, login_callback_url, hooks):
264 293
    OU = get_ou_model()
265 294
    cassis = OU.objects.create(name='Cassis', slug='cassis')
266
-