Projet

Général

Profil

0001-misc-allow-authenticator-autorun-if-only-one-availab.patch

Serghei Mihai, 02 juillet 2020 14:18

Télécharger (7,19 ko)

Voir les différences:

Subject: [PATCH] misc: allow authenticator autorun if only one available
 (#28216)

 src/authentic2/views.py                    |  7 +++++++
 src/authentic2_auth_fc/authenticators.py   |  4 ++++
 src/authentic2_auth_oidc/authenticators.py | 12 ++++++++++++
 src/authentic2_auth_saml/authenticators.py | 13 ++++++++++++-
 tests/auth_fc/test_auth_fc.py              |  7 +++++++
 tests/test_auth_oidc.py                    | 11 +++++++++++
 tests/test_auth_saml.py                    | 13 +++++++++++++
 7 files changed, 66 insertions(+), 1 deletion(-)
src/authentic2/views.py
341 341
                        return block['response']
342 342
                    blocks.append(block)
343 343

  
344
    # run the only available authenticator if able to autorun
345
    if len(blocks) == 1:
346
        block = blocks[0]
347
        authenticator = block['authenticator']
348
        if hasattr(authenticator, 'autorun'):
349
            return authenticator.autorun(request, block['id'])
350

  
344 351
    # Old frontends API
345 352
    for block in blocks:
346 353
        fid = block['id']
src/authentic2_auth_fc/authenticators.py
20 20

  
21 21
from authentic2 import app_settings as a2_app_settings, utils as a2_utils
22 22
from authentic2.authenticators import BaseAuthenticator
23
from authentic2.utils import redirect_to_login
23 24

  
24 25
from . import app_settings
25 26

  
......
39 40
    def id(self):
40 41
        return 'fc'
41 42

  
43
    def autorun(self, request, block_id):
44
        return redirect_to_login(request, login_url='fc-login-or-link')
45

  
42 46
    def login(self, request, *args, **kwargs):
43 47
        if 'nofc' in request.GET:
44 48
            return
src/authentic2_auth_oidc/authenticators.py
18 18
from django.shortcuts import render
19 19

  
20 20
from . import app_settings, utils
21
from .models import OIDCProvider
21 22
from authentic2.utils import make_url
23
from authentic2.utils import redirect_to_login
22 24
from authentic2.authenticators import BaseAuthenticator
23 25

  
24 26

  
......
36 38
        for p in utils.get_providers(shown=True):
37 39
            yield (p.slug, p)
38 40

  
41
    def autorun(self, request, block_id):
42
        auth_id, instance_slug = block_id.split('_')
43
        assert auth_id == self.id
44

  
45
        try:
46
            provider = OIDCProvider.objects.get(slug=instance_slug)
47
        except OIDCProvider.DoesNotExist():
48
            return redirect_to_login(request)
49
        return redirect_to_login(request, login_url='oidc-login', kwargs={'pk': provider.pk})
50

  
39 51
    def login(self, request, *args, **kwargs):
40 52
        context = kwargs.get('context', {})
41 53
        if kwargs.get('instance'):
src/authentic2_auth_saml/authenticators.py
19 19
from django.shortcuts import render
20 20
from mellon.utils import get_idp, get_idps
21 21

  
22
from authentic2.utils import redirect_to_login
23 22
from authentic2.authenticators import BaseAuthenticator
23
from authentic2.utils import redirect_to_login
24 24

  
25 25
from . import app_settings
26 26

  
......
38 38
        for idx, idp in enumerate(get_idps()):
39 39
            yield(idp.get('SLUG') or str(idx), idp)
40 40

  
41
    def autorun(self, request, block_id):
42
        auth_id, instance_slug = block_id.split('_')
43
        assert auth_id == self.id
44

  
45
        for slug, instance in self.instances(request):
46
            if slug == instance_slug:
47
                return redirect_to_login(request, login_url='mellon_login',
48
                                         params={'entityID': instance['ENTITY_ID']})
49
        return redirect_to_login(request)
50

  
51

  
41 52
    def login(self, request, *args, **kwargs):
42 53
        context = kwargs.pop('context', {})
43 54
        instance_id = kwargs.get('instance_id')
tests/auth_fc/test_auth_fc.py
98 98
    assert 'fc-button' not in response
99 99

  
100 100

  
101
def test_login_autorun(app, fc_settings, settings):
102
    # hide password block
103
    settings.AUTH_FRONTENDS_KWARGS = {'password': {'show_condition': 'remote_addr==\'0.0.0.0\''}}
104
    response = app.get('/login/')
105
    assert response['Location'] == reverse('fc-login-or-link')
106

  
107

  
101 108
@pytest.mark.parametrize('exp', [timestamp_from_datetime(now() + datetime.timedelta(seconds=1000)),
102 109
                                 timestamp_from_datetime(now() - datetime.timedelta(seconds=1000))])
103 110
def test_login_simple(app, fc_settings, caplog, hooks, exp):
tests/test_auth_oidc.py
471 471
    assert 'My IDP' not in response
472 472

  
473 473

  
474
def test_login_autorun(oidc_provider, app, settings):
475
    response = app.get('/login/')
476
    assert 'OIDIDP' in response
477

  
478
    # hide password block
479
    settings.AUTH_FRONTENDS_KWARGS = {'password': {'show_condition': 'remote_addr==\'0.0.0.0\''}}
480
    response = app.get('/login/', status=302)
481
    assert response['Location'] == '/accounts/oidc/login/%s/' % oidc_provider.pk
482

  
483

  
484

  
474 485
def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, hooks):
475 486
    OU = get_ou_model()
476 487
    cassis = OU.objects.create(name='Cassis', slug='cassis')
tests/test_auth_saml.py
177 177
    response = app.get('/login/')
178 178
    assert 'login-saml-0' not in response
179 179
    assert 'login-saml-1' not in response
180

  
181

  
182
def test_login_autorun(db, app, settings):
183
    response = app.get('/login/')
184

  
185
    settings.A2_AUTH_SAML_ENABLE = True
186
    settings.MELLON_IDENTITY_PROVIDERS = [
187
        {"METADATA": os.path.join(os.path.dirname(__file__), 'metadata.xml')}
188
    ]
189
    # hide password block
190
    settings.AUTH_FRONTENDS_KWARGS = {'password': {'show_condition': 'remote_addr==\'0.0.0.0\''}}
191
    response = app.get('/login/', status=302)
192
    assert '/accounts/saml/login/?entityID=' in response['Location']
180
-