0003-manager-add-a-change-email-action-on-users-fixes-197.patch
src/authentic2/a2_rbac/models.py | ||
---|---|---|
247 | 247 |
CHANGE_PASSWORD_OP = Operation(name=_('Change password'), slug='change_password') |
248 | 248 |
RESET_PASSWORD_OP = Operation(name=_('Reset password'), slug='reset_password') |
249 | 249 |
ACTIVATE_OP = Operation(name=_('Activate'), slug='activate') |
250 |
CHANGE_EMAIL_OP = Operation(name=_('Change email'), slug='change_email') |
src/authentic2/manager/forms.py | ||
---|---|---|
622 | 622 | |
623 | 623 |
class Meta: |
624 | 624 |
model = get_ou_model() |
625 |
fields = ('name', 'default', 'username_is_unique', 'email_is_unique') |
|
625 |
fields = ('name', 'default', 'username_is_unique', 'email_is_unique', 'validate_emails')
|
|
626 | 626 | |
627 | 627 | |
628 | 628 |
def get_role_form_class(): |
629 | 629 |
if app_settings.ROLE_FORM_CLASS: |
630 | 630 |
return import_module_or_class(app_settings.ROLE_FORM_CLASS) |
631 | 631 |
return RoleEditForm |
632 | ||
633 | ||
634 |
class UserChangeEmailForm(CssClass, forms.ModelForm): |
|
635 |
def save(self, *args, **kwargs): |
|
636 |
return self.instance |
|
637 | ||
638 |
class Meta: |
|
639 |
fields = ('email',) |
src/authentic2/manager/urls.py | ||
---|---|---|
36 | 36 |
url(r'^users/(?P<pk>\d+)/change-password/$', |
37 | 37 |
user_views.user_change_password, |
38 | 38 |
name='a2-manager-user-change-password'), |
39 |
url(r'^users/(?P<pk>\d+)/change-email/$', |
|
40 |
user_views.user_change_email, |
|
41 |
name='a2-manager-user-change-email'), |
|
39 | 42 |
# by uuid |
40 | 43 |
url(r'^users/uuid:(?P<slug>[a-z0-9]+)/$', user_views.user_detail, |
41 | 44 |
name='a2-manager-user-by-uuid-detail'), |
... | ... | |
47 | 50 |
url(r'^users/uuid:(?P<slug>[a-z0-9]+)/change-password/$', |
48 | 51 |
user_views.user_change_password, |
49 | 52 |
name='a2-manager-user-by-uuid-change-password'), |
53 |
url(r'^users/uuid:(?P<slug>[a-z0-9]+)/change-email/$', |
|
54 |
user_views.user_change_email, |
|
55 |
name='a2-manager-user-by-uuid-change-email'), |
|
50 | 56 | |
51 | 57 |
# Authentic2 roles |
52 | 58 |
url(r'^roles/$', role_views.listing, |
src/authentic2/manager/user_views.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from authentic2.constants import SWITCH_USER_SESSION_KEY |
18 | 18 |
from authentic2.models import Attribute, PasswordReset |
19 |
from authentic2.utils import switch_user, send_password_reset_mail, redirect |
|
19 |
from authentic2.utils import switch_user, send_password_reset_mail, redirect, send_email_change_mail
|
|
20 | 20 |
from authentic2.a2_rbac.utils import get_default_ou |
21 | 21 |
from authentic2 import hooks |
22 | 22 |
from django_rbac.utils import get_role_model, get_role_parenting_model, get_ou_model |
... | ... | |
26 | 26 |
BaseEditView, ActionMixin, OtherActionsMixin, Action, ExportMixin, \ |
27 | 27 |
BaseSubTableView, HideOUColumnMixin, BaseDeleteView, BaseDetailView |
28 | 28 |
from .tables import UserTable, UserRolesTable, OuUserRolesTable |
29 |
from .forms import UserSearchForm, UserAddForm, UserEditForm, \
|
|
30 |
UserChangePasswordForm, ChooseUserRoleForm, UserRoleSearchForm |
|
29 |
from .forms import (UserSearchForm, UserAddForm, UserEditForm,
|
|
30 |
UserChangePasswordForm, ChooseUserRoleForm, UserRoleSearchForm, UserChangeEmailForm)
|
|
31 | 31 |
from .resources import UserResource |
32 | 32 |
from . import app_settings |
33 | 33 | |
... | ... | |
164 | 164 |
permission='custom_user.change_password_user') |
165 | 165 |
if self.request.user.is_superuser: |
166 | 166 |
yield Action('switch_user', _('Impersonate this user')) |
167 |
if self.object.ou and self.object.ou.validate_emails: |
|
168 |
yield Action('change_email', _('Change user email'), |
|
169 |
url_name='a2-manager-user-change-email', |
|
170 |
permission='custom_user.change_email_user') |
|
167 | 171 | |
168 | 172 |
def action_force_password_change(self, request, *args, **kwargs): |
169 | 173 |
PasswordReset.objects.get_or_create(user=self.object) |
... | ... | |
256 | 260 |
template_name = 'authentic2/manager/user_edit.html' |
257 | 261 |
form_class = UserEditForm |
258 | 262 |
permissions = ['custom_user.change_user'] |
259 |
fields = ['username', 'ou', 'first_name', 'last_name', 'email']
|
|
263 |
fields = ['username', 'ou', 'first_name', 'last_name'] |
|
260 | 264 |
success_url = '..' |
261 | 265 |
slug_field = 'uuid' |
262 | 266 |
action = _('Change') |
... | ... | |
264 | 268 | |
265 | 269 |
def get_fields(self): |
266 | 270 |
fields = list(self.fields) |
271 |
if not self.object.ou or not self.object.ou.validate_emails: |
|
272 |
fields.append('email') |
|
267 | 273 |
for attribute in Attribute.objects.all(): |
268 | 274 |
fields.append(attribute.name) |
269 | 275 |
if self.request.user.is_superuser and \ |
... | ... | |
325 | 331 |
user_change_password = UserChangePasswordView.as_view() |
326 | 332 | |
327 | 333 | |
334 |
class UserChangeEmailView(BaseEditView): |
|
335 |
template_name = 'authentic2/manager/form.html' |
|
336 |
model = get_user_model() |
|
337 |
form_class = UserChangeEmailForm |
|
338 |
permissions = ['custom_user.change_email_user'] |
|
339 |
success_url = '..' |
|
340 |
slug_field = 'uuid' |
|
341 |
title = _('Change user email') |
|
342 | ||
343 |
def get_success_message(self, cleaned_data): |
|
344 |
return ugettext('A mail was sent to %s to verify it.') % cleaned_data['email'] |
|
345 | ||
346 |
def get_form_kwargs(self): |
|
347 |
kwargs = super(UserChangeEmailView, self).get_form_kwargs() |
|
348 |
kwargs.setdefault('initial', {})['email'] = self.object.email |
|
349 |
return kwargs |
|
350 | ||
351 |
def form_valid(self, form): |
|
352 |
response = super(UserChangeEmailView, self).form_valid(form) |
|
353 |
email = form.cleaned_data['email'] |
|
354 |
hooks.call_hooks('event', name='manager-change-email-request', user=self.request.user, |
|
355 |
instance=form.instance, form=form, email=email) |
|
356 |
send_email_change_mail(self.object, email, request=self.request) |
|
357 |
return response |
|
358 | ||
359 |
user_change_email = UserChangeEmailView.as_view() |
|
360 | ||
361 | ||
328 | 362 |
class UserRolesView(HideOUColumnMixin, BaseSubTableView): |
329 | 363 |
model = get_user_model() |
330 | 364 |
form_class = ChooseUserRoleForm |
src/authentic2/settings.py | ||
---|---|---|
299 | 299 |
DJANGO_RBAC_PERMISSIONS_HIERARCHY = { |
300 | 300 |
'view': ['search'], |
301 | 301 |
'change_password': ['view', 'search'], |
302 |
'change_email': ['view', 'search'], |
|
302 | 303 |
'reset_password': ['view', 'search'], |
303 | 304 |
'activate': ['view', 'search'], |
304 | 305 |
'admin': ['change', 'delete', 'add', 'view', 'change_password', 'reset_password', 'activate', |
305 |
'search'], |
|
306 |
'search', 'change_email'],
|
|
306 | 307 |
'change': ['view', 'search'], |
307 | 308 |
'delete': ['view', 'search'], |
308 | 309 |
'add': ['view', 'search'], |
tests/test_user_manager.py | ||
---|---|---|
1 |
from django.core.urlresolvers import reverse |
|
2 | ||
3 |
from utils import login, get_link_from_mail |
|
4 | ||
5 | ||
6 |
def test_manager_user_change_email(app, superuser_or_admin, simple_user, mailoutbox): |
|
7 |
response = login(app, superuser_or_admin, |
|
8 |
reverse('a2-manager-user-by-uuid-detail', |
|
9 |
kwargs={'slug': unicode(simple_user.uuid)})) |
|
10 |
assert 'Change user email' in response.content |
|
11 |
# cannot click it's a submit button :/ |
|
12 |
response = app.get(reverse('a2-manager-user-by-uuid-change-email', |
|
13 |
kwargs={'slug': unicode(simple_user.uuid)})) |
|
14 |
response.form.set('email', 'john.doe@example.com') |
|
15 |
assert len(mailoutbox) == 0 |
|
16 |
response = response.form.submit().follow() |
|
17 |
assert 'A mail was sent to john.doe@example.com to verify it.' in response.content |
|
18 |
assert 'Change user email' in response.content |
|
19 |
# cannot click it's a submit button :/ |
|
20 |
assert len(mailoutbox) == 1 |
|
21 |
# logout |
|
22 |
app.session.flush() |
|
23 | ||
24 |
link = get_link_from_mail(mailoutbox[0]) |
|
25 |
response = app.get(link).maybe_follow() |
|
26 |
assert ( |
|
27 |
'your request for changing your email for john.doe@example.com is successful' |
|
28 |
in response.content) |
|
29 |
simple_user.refresh_from_db() |
|
30 |
assert simple_user.email == 'john.doe@example.com' |
|
0 |
- |