0001-authenticators-select-default-OU-based-on-service-s-.patch
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 |
- |