Projet

Général

Profil

0001-authenticators-select-default-OU-based-on-service-s-.patch

Benjamin Dauvergne, 06 août 2019 16:54

Télécharger (6,55 ko)

Voir les différences:

Subject: [PATCH] authenticators: select default OU based on service's ACL
 (#35213)

 src/authentic2/authenticators.py | 32 +++++++++++++++++++++++--------
 tests/test_login.py              | 33 +++++++++++++++++++++++++++++---
 2 files changed, 54 insertions(+), 11 deletions(-)
src/authentic2/authenticators.py
17 17
from django.shortcuts import render
18 18
from django.utils.translation import ugettext as _, ugettext_lazy
19 19

  
20
from authentic2.a2_rbac.models import OrganizationalUnit as OU
21
from . import views, app_settings, utils, constants
20
from authentic2.a2_rbac.models import OrganizationalUnit as OU, Role
21
from authentic2.custom_user.models import User
22
from . import views, app_settings, utils, constants, models
22 23
from .forms import authentication as authentication_forms
23 24

  
24 25

  
......
35 36
        return 'password'
36 37

  
37 38
    def login(self, request, *args, **kwargs):
39
        service_slug = request.GET.get(constants.SERVICE_FIELD_NAME)
38 40
        context = kwargs.get('context', {})
39 41
        is_post = request.method == 'POST' and self.submit_name in request.POST
40 42
        data = request.POST if is_post else None
41
        preferred_ous = utils.get_remember_cookie(request, 'preferred-ous')
42
        if preferred_ous:
43
            preferred_ous = OU.objects.filter(pk__in=preferred_ous)
44 43
        initial = {}
45
        if preferred_ous:
46
            initial['ou'] = preferred_ous[0]
44
        preferred_ous = []
45

  
46
        # Special handling when the form contains an OU selector
47
        if app_settings.A2_LOGIN_FORM_OU_SELECTOR:
48
            default_ou = None
49
            # for the special case of services open to only one OU, pre-select it
50
            if service_slug:
51
                roles = Role.objects.filter(allowed_services__slug=service_slug).children()
52
                ous = OU.objects.filter(id__in=User.objects.filter(roles__in=roles).values_list('ou_id', flat=True))
53
                if len(ous) == 1:
54
                    default_ou = ous[0]
55
            preferred_ous = utils.get_remember_cookie(request, 'preferred-ous')
56
            if preferred_ous:
57
                preferred_ous = OU.objects.filter(pk__in=preferred_ous)
58
            if not default_ou and preferred_ous:
59
                default_ou = preferred_ous[0]
60
            if default_ou:
61
                initial['ou'] = default_ou
62

  
47 63
        form = authentication_forms.AuthenticationForm(
48 64
            request=request,
49 65
            data=data,
......
66 82
                    request.session['remember_me'] = True
67 83
                    request.session.set_expiry(app_settings.A2_USER_REMEMBER_ME)
68 84
                response = utils.login(request, form.get_user(), how,
69
                                       service_slug=request.GET.get(constants.SERVICE_FIELD_NAME))
85
                                       service_slug=service_slug)
70 86
                if 'ou' in form.fields:
71 87
                    utils.prepend_remember_cookie(request, response, 'preferred-ous', form.cleaned_data['ou'].pk)
72 88
                return response
tests/test_login.py
19 19
from django.utils.six.moves.urllib.parse import quote
20 20
from django.contrib.auth import get_user_model
21 21

  
22
from authentic2 import models
23

  
22 24
from utils import login
23 25

  
24 26

  
......
135 137
    assert simple_user.first_name not in response
136 138

  
137 139

  
138
def test_ou_selector(app, settings, simple_user, ou1):
140
def test_ou_selector(app, settings, simple_user, ou1, ou2, user_ou1, role_ou1):
139 141
    settings.A2_LOGIN_FORM_OU_SELECTOR = True
140 142
    response = app.get('/login/')
141 143
    # Check selector is here and there are no errors
......
143 145
    assert response.pyquery.find('select#id_ou')
144 146
    assert len(response.pyquery.find('select#id_ou optgroup')) == 0
145 147
    assert (set([elt.text for elt in response.pyquery.find('select#id_ou option')])
146
            == set([u'Default organizational unit', u'OU1', u'---------']))
148
            == set([u'Default organizational unit', u'OU1', u'OU2', u'---------']))
147 149
    # Check selector is required
148 150
    response.form.set('username', simple_user.username)
149 151
    response.form.set('password', simple_user.username)
......
170 172
    assert response.pyquery.find('select#id_ou')
171 173
    assert len(response.pyquery.find('select#id_ou optgroup')) == 2
172 174
    assert (set([elt.text for elt in response.pyquery.find('select#id_ou option')])
173
            == set([u'Default organizational unit', u'OU1', u'---------']))
175
            == set([u'Default organizational unit', u'OU1', u'OU2', u'---------']))
176
    assert response.pyquery.find('select#id_ou option[selected]')[0].text == u'Default organizational unit'
177

  
178
    # Create a service
179
    service = models.Service.objects.create(name='Service', slug='service', ou=ou1)
180
    response = app.get('/login/')
181
    assert response.pyquery.find('select#id_ou option[selected]')[0].text == u'Default organizational unit'
182

  
183
    # service is specified but not access-control is defined, default for user is selected
184
    response = app.get('/login/?service=service')
185
    assert response.pyquery.find('select#id_ou option[selected]')[0].text == u'Default organizational unit'
186

  
187
    # service is specified, access control is defined but role is empty, default for user is selected
188
    service.authorized_roles.through.objects.create(service=service, role=role_ou1)
189
    response = app.get('/login/?service=service')
174 190
    assert response.pyquery.find('select#id_ou option[selected]')[0].text == u'Default organizational unit'
191

  
192
    # user is added to role_ou1, now the OU of the only user is selected
193
    user_ou1.roles.add(role_ou1)
194
    response = app.get('/login/?service=service')
195
    assert response.pyquery.find('select#id_ou option[selected]')[0].text == u'OU1'
196

  
197
    # if we change the user's ou, then default selected OU changes
198
    user_ou1.ou = ou2
199
    user_ou1.save()
200
    response = app.get('/login/?service=service')
201
    assert response.pyquery.find('select#id_ou option[selected]')[0].text == u'OU2'
175
-