Projet

Général

Profil

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

Serghei Mihai, 12 mars 2019 21:03

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

  
340 351

  
341 352
    # 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
        return [('%s-%s' % (self.id, p.slug), p) for p in utils.get_providers(shown=True)]
19

  
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>
5

  
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 presnt on login page
266
    assert "css-tab2" in response
267
    assert "OIDIDP" in response
268
    OIDCProvider.objects.create(
269
        id=2,
270
        ou=get_default_ou(),
271
        name='OIDIDP 2',
272
        slug='oididp-2',
273
        issuer='https://idp2.example.com/',
274
        authorization_endpoint='https://idp2.example.com/authorize',
275
        token_endpoint='https://idp2.example.com/token',
276
        end_session_endpoint='https://idp2.example.com/logout',
277
        userinfo_endpoint='https://idp*é.example.com/user_info',
278
        token_revocation_endpoint='https://idp2.example.com/revoke',
279
        max_auth_age=10,
280
        strategy=OIDCProvider.STRATEGY_CREATE,
281
        jwkset_json=None,
282
        idtoken_algo=OIDCProvider.ALGO_RSA,
283
        claims_parameter_supported=False
284
    )
285
    response = app.get('/login/')
286
    assert "css-tab3" in response
287
    assert 'OIDIDP 2' in response
288

  
289

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