manager: look for duplicates on user creation (#45419)
This commit is contained in:
parent
41ef79557c
commit
8ae42a05d8
|
@ -28,6 +28,7 @@ class AppSettings(object):
|
||||||
'USER_SEARCH_MINIMUM_CHARS': 0,
|
'USER_SEARCH_MINIMUM_CHARS': 0,
|
||||||
'LOGIN_URL': None,
|
'LOGIN_URL': None,
|
||||||
'SITE_TITLE': None,
|
'SITE_TITLE': None,
|
||||||
|
'CHECK_DUPLICATE_USERS': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'a2-manager-user-detail' pk=user.pk %}">{{ user.get_full_name }}</a>
|
||||||
|
{% if user.email %}- {{ user.email }}{% endif %}
|
||||||
|
{% for attribute in user.attribute_values.all %}
|
||||||
|
{% if attribute.content and attribute.attribute.name != "first_name" and attribute.attribute.name != "last_name" %}
|
||||||
|
- {{ attribute.content }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
- {% blocktrans with date=user.date_joined %}Created on {{ date }}{% endblocktrans %}
|
||||||
|
{% if user.last_login %}
|
||||||
|
- {% blocktrans with date=user.last_login %}Last login on {{ date }}{% endblocktrans %}
|
||||||
|
{% else %}
|
||||||
|
- {% trans "Never logged in" %}
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
|
@ -5,6 +5,20 @@
|
||||||
{% trans "Add an user" %}
|
{% trans "Add an user" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block beforeform %}
|
||||||
|
{% if duplicate_users %}
|
||||||
|
<input type="hidden" name="confirm-creation-token" value="{{ form.cleaned_data.first_name }} {{ form.cleaned_data.last_name }}">
|
||||||
|
<div class=warningnotice>
|
||||||
|
<p>{% trans "This user may already exist, please check the list below before creating it :" %}</p>
|
||||||
|
<ul class="user-duplicates">
|
||||||
|
{% for user in duplicate_users %}
|
||||||
|
{% include "authentic2/manager/duplicate_user_add.html" with user=user %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block hidden_inputs %}
|
{% block hidden_inputs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
{% if next %}<input type="hidden" name="next" value="{{ next }}">{% endif %}
|
{% if next %}<input type="hidden" name="next" value="{{ next }}">{% endif %}
|
||||||
|
|
|
@ -148,6 +148,7 @@ class UserAddView(BaseAddView):
|
||||||
form_class = UserAddForm
|
form_class = UserAddForm
|
||||||
permissions = ['custom_user.add_user']
|
permissions = ['custom_user.add_user']
|
||||||
template_name = 'authentic2/manager/user_add.html'
|
template_name = 'authentic2/manager/user_add.html'
|
||||||
|
duplicate_users = None
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
qs = request.user.ous_with_perm('custom_user.add_user')
|
qs = request.user.ous_with_perm('custom_user.add_user')
|
||||||
|
@ -193,9 +194,24 @@ class UserAddView(BaseAddView):
|
||||||
field_name='cancel')
|
field_name='cancel')
|
||||||
context['next'] = select_next_url(self.request, default=None, include_post=True)
|
context['next'] = select_next_url(self.request, default=None, include_post=True)
|
||||||
context['ou'] = self.ou
|
context['ou'] = self.ou
|
||||||
|
context['duplicate_users'] = self.duplicate_users
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
if app_settings.CHECK_DUPLICATE_USERS:
|
||||||
|
first_name = form.cleaned_data['first_name']
|
||||||
|
last_name = form.cleaned_data['last_name']
|
||||||
|
duplicate_users = User.objects.find_duplicates(
|
||||||
|
first_name=first_name,
|
||||||
|
last_name=last_name,
|
||||||
|
birthdate=form.cleaned_data.get('birthdate'),
|
||||||
|
)
|
||||||
|
token = self.request.POST.get('confirm-creation-token')
|
||||||
|
valid_confirmation_token = bool(token == '%s %s' % (first_name, last_name))
|
||||||
|
if duplicate_users and not valid_confirmation_token:
|
||||||
|
self.duplicate_users = duplicate_users
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
response = super(UserAddView, self).form_valid(form)
|
response = super(UserAddView, self).form_valid(form)
|
||||||
hooks.call_hooks('event', name='manager-add-user', user=self.request.user,
|
hooks.call_hooks('event', name='manager-add-user', user=self.request.user,
|
||||||
instance=form.instance, form=form)
|
instance=form.instance, form=form)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
|
import datetime
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
@ -987,3 +988,50 @@ def test_manager_user_roles_breadcrumb(app, superuser, simple_user):
|
||||||
assert [x.text for x in resp.html.find('span', {'id': 'breadcrumb'}).find_all('a')] == [
|
assert [x.text for x in resp.html.find('span', {'id': 'breadcrumb'}).find_all('a')] == [
|
||||||
'Homepage', 'Administration', 'Users',
|
'Homepage', 'Administration', 'Users',
|
||||||
'super user', 'Roles']
|
'super user', 'Roles']
|
||||||
|
|
||||||
|
|
||||||
|
def test_manager_create_user_duplicates(admin, app, ou1, settings):
|
||||||
|
settings.A2_MANAGER_CHECK_DUPLICATE_USERS = True
|
||||||
|
Attribute.objects.create(
|
||||||
|
kind='birthdate', name='birthdate', label='birthdate', required=False, searchable=True
|
||||||
|
)
|
||||||
|
|
||||||
|
user = User.objects.create(
|
||||||
|
first_name='Alexander', last_name='Longname', email='alexandre.longname@entrouvert.com'
|
||||||
|
)
|
||||||
|
user.attributes.birthdate = datetime.date(1980, 1, 2)
|
||||||
|
user2 = User.objects.create(first_name='Alexandra', last_name='Longname')
|
||||||
|
user3 = User.objects.create(first_name='Alex', last_name='Shortname')
|
||||||
|
|
||||||
|
login(app, admin)
|
||||||
|
resp = app.get('/manage/users/%s/add/' % ou1.pk)
|
||||||
|
|
||||||
|
form = resp.form
|
||||||
|
form.set('first_name', 'Alexandre')
|
||||||
|
form.set('last_name', 'Longname')
|
||||||
|
form.set('email', 'alex@entrouvert.com')
|
||||||
|
form.set('password1', 'ABcd1234')
|
||||||
|
form.set('password2', 'ABcd1234')
|
||||||
|
resp = form.submit()
|
||||||
|
|
||||||
|
assert 'user may already exist' in resp.text
|
||||||
|
assert 'Alexander Longname' in resp.text
|
||||||
|
assert '- alexandre.longname@entrouvert.com' in resp.text
|
||||||
|
assert '- 1980-01-02' in resp.text
|
||||||
|
assert '/users/%s/' % user.pk in resp.text
|
||||||
|
assert 'Alexandra Longname' in resp.text
|
||||||
|
assert '/users/%s/' % user2.pk in resp.text
|
||||||
|
|
||||||
|
# This user was in fact duplicate. Agent reuses the form to fill details on another user
|
||||||
|
form = resp.form
|
||||||
|
form.set('first_name', 'Alexa')
|
||||||
|
form.set('last_name', 'Shortname')
|
||||||
|
form.set('email', 'ashortname@entrouvert.com')
|
||||||
|
resp = form.submit()
|
||||||
|
|
||||||
|
assert 'user may already exist' in resp.text
|
||||||
|
assert '/users/%s/' % user3.pk in resp.text
|
||||||
|
|
||||||
|
# Not a duplicate this time. Simply submitting again creates user
|
||||||
|
resp = resp.form.submit().follow()
|
||||||
|
assert User.objects.filter(first_name='Alexa').count() == 1
|
||||||
|
|
Loading…
Reference in New Issue