0001-manager-look-for-duplicates-on-user-creation-45419.patch
src/authentic2/manager/app_settings.py | ||
---|---|---|
28 | 28 |
'USER_SEARCH_MINIMUM_CHARS': 0, |
29 | 29 |
'LOGIN_URL': None, |
30 | 30 |
'SITE_TITLE': None, |
31 |
'CHECK_DUPLICATE_USERS': False, |
|
31 | 32 |
} |
32 | 33 | |
33 | 34 |
def __getattr__(self, name): |
src/authentic2/manager/templates/authentic2/manager/duplicate_user_add.html | ||
---|---|---|
1 |
{% load i18n %} |
|
2 | ||
3 |
<li> |
|
4 |
<a href="{% url 'a2-manager-user-detail' pk=user.pk %}">{{ user.get_full_name }}</a> |
|
5 |
{% if user.email %}- {{ user.email }}{% endif %} |
|
6 |
{% for attribute in user.attribute_values.all %} |
|
7 |
{% if attribute.content and attribute.attribute.name != "first_name" and attribute.attribute.name != "last_name" %} |
|
8 |
- {{ attribute.content }} |
|
9 |
{% endif %} |
|
10 |
{% endfor %} |
|
11 |
- {% blocktrans with date=user.date_joined %}Created on {{ date }}{% endblocktrans %} |
|
12 |
{% if user.last_login %} |
|
13 |
- {% blocktrans with date=user.last_login %}Last login on {{ date }}{% endblocktrans %} |
|
14 |
{% else %} |
|
15 |
- {% trans "Never logged in" %} |
|
16 |
{% endif %} |
|
17 |
</li> |
src/authentic2/manager/templates/authentic2/manager/user_add.html | ||
---|---|---|
5 | 5 |
{% trans "Add an user" %} |
6 | 6 |
{% endblock %} |
7 | 7 | |
8 |
{% block beforeform %} |
|
9 |
{% if duplicate_users %} |
|
10 |
<input type="hidden" name="confirm-creation-token" value="{{ form.cleaned_data.first_name }} {{ form.cleaned_data.last_name }}"> |
|
11 |
<div class=warningnotice> |
|
12 |
<p>{% trans "This user may already exist, please check the list below before creating it :" %}</p> |
|
13 |
<ul class="user-duplicates"> |
|
14 |
{% for user in duplicate_users %} |
|
15 |
{% include "authentic2/manager/duplicate_user_add.html" with user=user %} |
|
16 |
{% endfor %} |
|
17 |
</ul> |
|
18 |
</div> |
|
19 |
{% endif %} |
|
20 |
{% endblock %} |
|
21 | ||
8 | 22 |
{% block hidden_inputs %} |
9 | 23 |
{{ block.super }} |
10 | 24 |
{% if next %}<input type="hidden" name="next" value="{{ next }}">{% endif %} |
src/authentic2/manager/user_views.py | ||
---|---|---|
148 | 148 |
form_class = UserAddForm |
149 | 149 |
permissions = ['custom_user.add_user'] |
150 | 150 |
template_name = 'authentic2/manager/user_add.html' |
151 |
duplicate_users = None |
|
151 | 152 | |
152 | 153 |
def dispatch(self, request, *args, **kwargs): |
153 | 154 |
qs = request.user.ous_with_perm('custom_user.add_user') |
... | ... | |
193 | 194 |
field_name='cancel') |
194 | 195 |
context['next'] = select_next_url(self.request, default=None, include_post=True) |
195 | 196 |
context['ou'] = self.ou |
197 |
context['duplicate_users'] = self.duplicate_users |
|
196 | 198 |
return context |
197 | 199 | |
198 | 200 |
def form_valid(self, form): |
201 |
if app_settings.CHECK_DUPLICATE_USERS: |
|
202 |
first_name = form.cleaned_data['first_name'] |
|
203 |
last_name = form.cleaned_data['last_name'] |
|
204 |
duplicate_users = User.objects.find_duplicates( |
|
205 |
first_name=first_name, |
|
206 |
last_name=last_name, |
|
207 |
birthdate=form.cleaned_data.get('birthdate'), |
|
208 |
) |
|
209 |
token = self.request.POST.get('confirm-creation-token') |
|
210 |
valid_confirmation_token = bool(token == '%s %s' % (first_name, last_name)) |
|
211 |
if duplicate_users and not valid_confirmation_token: |
|
212 |
self.duplicate_users = duplicate_users |
|
213 |
return self.form_invalid(form) |
|
214 | ||
199 | 215 |
response = super(UserAddView, self).form_valid(form) |
200 | 216 |
hooks.call_hooks('event', name='manager-add-user', user=self.request.user, |
201 | 217 |
instance=form.instance, form=form) |
tests/test_user_manager.py | ||
---|---|---|
18 | 18 |
from __future__ import unicode_literals |
19 | 19 | |
20 | 20 |
import csv |
21 |
import datetime |
|
21 | 22 |
import re |
22 | 23 |
import time |
23 | 24 |
from urllib.parse import urlparse |
... | ... | |
987 | 988 |
assert [x.text for x in resp.html.find('span', {'id': 'breadcrumb'}).find_all('a')] == [ |
988 | 989 |
'Homepage', 'Administration', 'Users', |
989 | 990 |
'super user', 'Roles'] |
991 | ||
992 | ||
993 |
def test_manager_create_user_duplicates(admin, app, ou1, settings): |
|
994 |
settings.A2_MANAGER_CHECK_DUPLICATE_USERS = True |
|
995 |
Attribute.objects.create( |
|
996 |
kind='birthdate', name='birthdate', label='birthdate', required=False, searchable=True |
|
997 |
) |
|
998 | ||
999 |
user = User.objects.create( |
|
1000 |
first_name='Alexander', last_name='Longname', email='alexandre.longname@entrouvert.com' |
|
1001 |
) |
|
1002 |
user.attributes.birthdate = datetime.date(1980, 1, 2) |
|
1003 |
user2 = User.objects.create(first_name='Alexandra', last_name='Longname') |
|
1004 |
user3 = User.objects.create(first_name='Alex', last_name='Shortname') |
|
1005 | ||
1006 |
login(app, admin) |
|
1007 |
resp = app.get('/manage/users/%s/add/' % ou1.pk) |
|
1008 | ||
1009 |
form = resp.form |
|
1010 |
form.set('first_name', 'Alexandre') |
|
1011 |
form.set('last_name', 'Longname') |
|
1012 |
form.set('email', 'alex@entrouvert.com') |
|
1013 |
form.set('password1', 'ABcd1234') |
|
1014 |
form.set('password2', 'ABcd1234') |
|
1015 |
resp = form.submit() |
|
1016 | ||
1017 |
assert 'user may already exist' in resp.text |
|
1018 |
assert 'Alexander Longname' in resp.text |
|
1019 |
assert '- alexandre.longname@entrouvert.com' in resp.text |
|
1020 |
assert '- 1980-01-02' in resp.text |
|
1021 |
assert '/users/%s/' % user.pk in resp.text |
|
1022 |
assert 'Alexandra Longname' in resp.text |
|
1023 |
assert '/users/%s/' % user2.pk in resp.text |
|
1024 | ||
1025 |
# This user was in fact duplicate. Agent reuses the form to fill details on another user |
|
1026 |
form = resp.form |
|
1027 |
form.set('first_name', 'Alexa') |
|
1028 |
form.set('last_name', 'Shortname') |
|
1029 |
form.set('email', 'ashortname@entrouvert.com') |
|
1030 |
resp = form.submit() |
|
1031 | ||
1032 |
assert 'user may already exist' in resp.text |
|
1033 |
assert '/users/%s/' % user3.pk in resp.text |
|
1034 | ||
1035 |
# Not a duplicate this time. Simply submitting again creates user |
|
1036 |
resp = resp.form.submit().follow() |
|
1037 |
assert User.objects.filter(first_name='Alexa').count() == 1 |
|
990 |
- |