Add support for users ACLs. Add support for groups ACLs.
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -103,7 +103,11 @@
|
|||||||
- Mark the feature to detect and fix the orientatin of PDF as experimental.
|
- Mark the feature to detect and fix the orientatin of PDF as experimental.
|
||||||
- Don't show documents with 0 duplicates in the duplicated document list.
|
- Don't show documents with 0 duplicates in the duplicated document list.
|
||||||
- Clean up the duplicated document model after a document is deleted.
|
- Clean up the duplicated document model after a document is deleted.
|
||||||
- Add support Role ACLs.
|
- Add support for roles ACLs.
|
||||||
|
- Add support for users ACLs.
|
||||||
|
- Add support for groups ACLs.
|
||||||
|
- Sort permission namespaces and permissions in the role permission views.
|
||||||
|
|
||||||
|
|
||||||
2.7.3 (2017-09-11)
|
2.7.3 (2017-09-11)
|
||||||
==================
|
==================
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ from django.contrib.auth import get_user_model
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from acls import ModelPermission
|
from acls import ModelPermission
|
||||||
|
from acls.links import link_acl_list
|
||||||
|
from acls.permissions import permission_acl_edit, permission_acl_view
|
||||||
from common import menu_multi_item, menu_object, menu_secondary, menu_setup
|
from common import menu_multi_item, menu_object, menu_secondary, menu_setup
|
||||||
from common.apps import MayanAppConfig
|
from common.apps import MayanAppConfig
|
||||||
from common.widgets import two_state_template
|
from common.widgets import two_state_template
|
||||||
@@ -70,12 +72,14 @@ class UserManagementApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
model=Group, permissions=(
|
model=Group, permissions=(
|
||||||
|
permission_acl_edit, permission_acl_view,
|
||||||
permission_group_delete, permission_group_edit,
|
permission_group_delete, permission_group_edit,
|
||||||
permission_group_view,
|
permission_group_view,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
model=User, permissions=(
|
model=User, permissions=(
|
||||||
|
permission_acl_edit, permission_acl_view,
|
||||||
permission_user_delete, permission_user_edit,
|
permission_user_delete, permission_user_edit,
|
||||||
permission_user_view
|
permission_user_view
|
||||||
)
|
)
|
||||||
@@ -112,12 +116,12 @@ class UserManagementApp(MayanAppConfig):
|
|||||||
sources=(Group,)
|
sources=(Group,)
|
||||||
)
|
)
|
||||||
menu_object.bind_links(
|
menu_object.bind_links(
|
||||||
links=(link_group_delete,), position=99, sources=(Group,)
|
links=(link_acl_list, link_group_delete,), position=99, sources=(Group,)
|
||||||
)
|
)
|
||||||
menu_object.bind_links(
|
menu_object.bind_links(
|
||||||
links=(
|
links=(
|
||||||
link_user_edit, link_user_set_password, link_user_groups,
|
link_user_edit, link_user_set_password, link_user_groups,
|
||||||
link_user_delete
|
link_acl_list, link_user_delete
|
||||||
), sources=(User,)
|
), sources=(User,)
|
||||||
)
|
)
|
||||||
menu_secondary.bind_links(
|
menu_secondary.bind_links(
|
||||||
|
|||||||
@@ -14,10 +14,14 @@ from metadata.tests.literals import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from ..permissions import (
|
from ..permissions import (
|
||||||
permission_user_delete, permission_user_edit, permission_user_view
|
permission_user_create, permission_user_delete, permission_user_edit,
|
||||||
|
permission_user_view
|
||||||
)
|
)
|
||||||
|
|
||||||
from .literals import TEST_USER_PASSWORD_EDITED, TEST_USER_USERNAME
|
from .literals import (
|
||||||
|
TEST_USER_PASSWORD_EDITED, TEST_USER_USERNAME, TEST_USER_2_USERNAME,
|
||||||
|
TEST_USER_2_USERNAME_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
TEST_USER_TO_DELETE_USERNAME = 'user_to_delete'
|
TEST_USER_TO_DELETE_USERNAME = 'user_to_delete'
|
||||||
|
|
||||||
@@ -27,157 +31,157 @@ class UserManagementViewTestCase(GenericViewTestCase):
|
|||||||
super(UserManagementViewTestCase, self).setUp()
|
super(UserManagementViewTestCase, self).setUp()
|
||||||
self.login_user()
|
self.login_user()
|
||||||
|
|
||||||
|
def _request_user_create_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='user_management:user_add', data={
|
||||||
|
'username': TEST_USER_2_USERNAME
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_user_create_view_no_permission(self):
|
||||||
|
response = self._request_user_create_view()
|
||||||
|
self.assertEqual(response.status_code, 403)
|
||||||
|
self.assertEqual(get_user_model().objects.count(), 2)
|
||||||
|
self.assertFalse(TEST_USER_2_USERNAME in get_user_model().objects.values_list('username', flat=True))
|
||||||
|
|
||||||
|
def test_user_create_view_with_permission(self):
|
||||||
|
self.grant_permission(permission=permission_user_create)
|
||||||
|
response = self._request_user_create_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(get_user_model().objects.count(), 3)
|
||||||
|
self.assertTrue(TEST_USER_2_USERNAME in get_user_model().objects.values_list('username', flat=True))
|
||||||
|
|
||||||
def _request_set_password(self, password):
|
def _request_set_password(self, password):
|
||||||
return self.post(
|
return self.post(
|
||||||
'user_management:user_set_password', args=(self.user.pk,), data={
|
viewname='user_management:user_set_password', args=(self.user_2.pk,),
|
||||||
|
data={
|
||||||
'new_password1': password, 'new_password2': password
|
'new_password1': password, 'new_password2': password
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _create_test_user_2(self):
|
||||||
|
self.user_2 = get_user_model().objects.create(
|
||||||
|
username=TEST_USER_2_USERNAME
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_user_set_password_view_no_access(self):
|
||||||
|
self._create_test_user_2()
|
||||||
|
response = self._request_set_password(
|
||||||
|
password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
|
self.logout()
|
||||||
|
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.login(
|
||||||
|
username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.get('common:current_user_details')
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
def test_user_set_password_view_with_access(self):
|
||||||
|
self._create_test_user_2()
|
||||||
|
self.grant_access(permission=permission_user_edit, obj=self.user_2)
|
||||||
|
|
||||||
|
response = self._request_set_password(
|
||||||
|
password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.logout()
|
||||||
|
self.login(
|
||||||
|
username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
response = self.get('common:current_user_details')
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def _request_multiple_user_set_password(self, password):
|
def _request_multiple_user_set_password(self, password):
|
||||||
return self.post(
|
return self.post(
|
||||||
'user_management:user_multiple_set_password', data={
|
'user_management:user_multiple_set_password', data={
|
||||||
'id_list': self.user.pk,
|
'id_list': self.user_2.pk,
|
||||||
'new_password1': password,
|
'new_password1': password,
|
||||||
'new_password2': password
|
'new_password2': password
|
||||||
}, follow=True
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_user_set_password_view_no_permissions(self):
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self._request_set_password(
|
|
||||||
password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
self.logout()
|
|
||||||
|
|
||||||
with self.assertRaises(AssertionError):
|
|
||||||
self.login(
|
|
||||||
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
|
|
||||||
response = self.get('common:current_user_details')
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
|
|
||||||
def test_user_set_password_view_with_permissions(self):
|
|
||||||
self.grant_permission(permission=permission_user_edit)
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self._request_set_password(
|
|
||||||
password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
|
|
||||||
self.logout()
|
|
||||||
self.login(
|
|
||||||
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
response = self.get('common:current_user_details')
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
def test_user_multiple_set_password_view_no_permissions(self):
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self._request_multiple_user_set_password(
|
|
||||||
password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
self.logout()
|
|
||||||
|
|
||||||
with self.assertRaises(AssertionError):
|
|
||||||
self.login(
|
|
||||||
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
|
|
||||||
response = self.get('common:current_user_details')
|
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
|
|
||||||
def test_user_multiple_set_password_view_with_permissions(self):
|
|
||||||
self.grant_permission(permission=permission_user_edit)
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self._request_multiple_user_set_password(
|
|
||||||
password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
self.logout()
|
|
||||||
self.login(
|
|
||||||
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
|
||||||
)
|
|
||||||
response = self.get('common:current_user_details')
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
def test_user_delete_view_no_permissions(self):
|
|
||||||
user = get_user_model().objects.create(
|
|
||||||
username=TEST_USER_TO_DELETE_USERNAME
|
|
||||||
)
|
|
||||||
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self.post(
|
|
||||||
'user_management:user_delete', args=(user.pk,)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
self.assertEqual(get_user_model().objects.count(), 3)
|
|
||||||
|
|
||||||
def test_user_delete_view_with_permissions(self):
|
|
||||||
user = get_user_model().objects.create(
|
|
||||||
username=TEST_USER_TO_DELETE_USERNAME
|
|
||||||
)
|
|
||||||
|
|
||||||
self.grant_permission(permission=permission_user_delete)
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self.post(
|
|
||||||
'user_management:user_delete', args=(user.pk,), follow=True
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertContains(response, text='deleted', status_code=200)
|
|
||||||
self.assertEqual(get_user_model().objects.count(), 2)
|
|
||||||
|
|
||||||
def test_user_multiple_delete_view_no_permissions(self):
|
|
||||||
user = get_user_model().objects.create(
|
|
||||||
username=TEST_USER_TO_DELETE_USERNAME
|
|
||||||
)
|
|
||||||
|
|
||||||
self.grant_permission(permission=permission_user_view)
|
|
||||||
|
|
||||||
response = self.post(
|
|
||||||
'user_management:user_multiple_delete', data={
|
|
||||||
'id_list': user.pk
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_user_multiple_set_password_view_no_access(self):
|
||||||
|
self._create_test_user_2()
|
||||||
|
response = self._request_multiple_user_set_password(
|
||||||
|
password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
|
self.logout()
|
||||||
|
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
self.login(
|
||||||
|
username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.get('common:current_user_details')
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
def test_user_multiple_set_password_view_with_access(self):
|
||||||
|
self._create_test_user_2()
|
||||||
|
self.grant_access(permission=permission_user_edit, obj=self.user_2)
|
||||||
|
|
||||||
|
response = self._request_multiple_user_set_password(
|
||||||
|
password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.logout()
|
||||||
|
self.login(
|
||||||
|
username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
|
||||||
|
)
|
||||||
|
response = self.get('common:current_user_details')
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def _request_user_delete(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='user_management:user_delete', args=(self.user_2.pk,)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_user_delete_view_no_access(self):
|
||||||
|
self._create_test_user_2()
|
||||||
|
response = self._request_user_delete()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertEqual(get_user_model().objects.count(), 3)
|
self.assertEqual(get_user_model().objects.count(), 3)
|
||||||
|
|
||||||
def test_user_multiple_delete_view_with_permissions(self):
|
def test_user_delete_view_with_access(self):
|
||||||
user = get_user_model().objects.create(
|
self._create_test_user_2()
|
||||||
username=TEST_USER_TO_DELETE_USERNAME
|
self.grant_access(permission=permission_user_delete, obj=self.user_2)
|
||||||
|
response = self._request_user_delete()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(get_user_model().objects.count(), 2)
|
||||||
|
|
||||||
|
def _request_user_multiple_delete_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='user_management:user_multiple_delete', data={
|
||||||
|
'id_list': self.user_2.pk
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
self.grant_permission(permission=permission_user_delete)
|
def test_user_multiple_delete_view_no_access(self):
|
||||||
self.grant_permission(permission=permission_user_view)
|
self._create_test_user_2()
|
||||||
|
response = self._request_user_multiple_delete_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(get_user_model().objects.count(), 3)
|
||||||
|
|
||||||
response = self.post(
|
def test_user_multiple_delete_view_with_access(self):
|
||||||
'user_management:user_multiple_delete', data={
|
self._create_test_user_2()
|
||||||
'id_list': user.pk,
|
self.grant_access(permission=permission_user_delete, obj=self.user_2)
|
||||||
}, follow=True
|
response = self._request_user_multiple_delete_view()
|
||||||
)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertContains(response, text='deleted', status_code=200)
|
|
||||||
self.assertEqual(get_user_model().objects.count(), 2)
|
self.assertEqual(get_user_model().objects.count(), 2)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from django.contrib.auth import get_user_model
|
|||||||
from django.contrib.auth.forms import SetPasswordForm
|
from django.contrib.auth.forms import SetPasswordForm
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
@@ -35,8 +36,8 @@ class GroupCreateView(SingleObjectCreateView):
|
|||||||
class GroupEditView(SingleObjectEditView):
|
class GroupEditView(SingleObjectEditView):
|
||||||
fields = ('name',)
|
fields = ('name',)
|
||||||
model = Group
|
model = Group
|
||||||
|
object_permission = permission_group_edit
|
||||||
post_action_redirect = reverse_lazy('user_management:group_list')
|
post_action_redirect = reverse_lazy('user_management:group_list')
|
||||||
view_permission = permission_group_edit
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -51,13 +52,13 @@ class GroupListView(SingleObjectListView):
|
|||||||
'title': _('Groups'),
|
'title': _('Groups'),
|
||||||
}
|
}
|
||||||
model = Group
|
model = Group
|
||||||
view_permission = permission_group_view
|
object_permission = permission_group_view
|
||||||
|
|
||||||
|
|
||||||
class GroupDeleteView(SingleObjectDeleteView):
|
class GroupDeleteView(SingleObjectDeleteView):
|
||||||
model = Group
|
model = Group
|
||||||
|
object_permission = permission_group_delete
|
||||||
post_action_redirect = reverse_lazy('user_management:group_list')
|
post_action_redirect = reverse_lazy('user_management:group_list')
|
||||||
view_permission = permission_group_delete
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -70,7 +71,7 @@ class GroupMembersView(AssignRemoveView):
|
|||||||
decode_content_type = True
|
decode_content_type = True
|
||||||
left_list_title = _('Available users')
|
left_list_title = _('Available users')
|
||||||
right_list_title = _('Users in group')
|
right_list_title = _('Users in group')
|
||||||
view_permission = permission_group_edit
|
object_permission = permission_group_edit
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_choices(choices):
|
def generate_choices(choices):
|
||||||
@@ -133,11 +134,11 @@ class UserCreateView(SingleObjectCreateView):
|
|||||||
|
|
||||||
class UserDeleteView(MultipleObjectConfirmActionView):
|
class UserDeleteView(MultipleObjectConfirmActionView):
|
||||||
model = get_user_model()
|
model = get_user_model()
|
||||||
|
object_permission = permission_user_delete
|
||||||
success_message = _('User delete request performed on %(count)d user')
|
success_message = _('User delete request performed on %(count)d user')
|
||||||
success_message_plural = _(
|
success_message_plural = _(
|
||||||
'User delete request performed on %(count)d users'
|
'User delete request performed on %(count)d users'
|
||||||
)
|
)
|
||||||
view_permission = permission_user_delete
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
queryset = self.get_queryset()
|
queryset = self.get_queryset()
|
||||||
@@ -187,11 +188,11 @@ class UserDeleteView(MultipleObjectConfirmActionView):
|
|||||||
|
|
||||||
class UserEditView(SingleObjectEditView):
|
class UserEditView(SingleObjectEditView):
|
||||||
fields = ('username', 'first_name', 'last_name', 'email', 'is_active',)
|
fields = ('username', 'first_name', 'last_name', 'email', 'is_active',)
|
||||||
|
object_permission = permission_user_edit
|
||||||
post_action_redirect = reverse_lazy('user_management:user_list')
|
post_action_redirect = reverse_lazy('user_management:user_list')
|
||||||
queryset = get_user_model().objects.filter(
|
queryset = get_user_model().objects.filter(
|
||||||
is_superuser=False, is_staff=False
|
is_superuser=False, is_staff=False
|
||||||
)
|
)
|
||||||
view_permission = permission_user_edit
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -204,7 +205,7 @@ class UserGroupsView(AssignRemoveView):
|
|||||||
decode_content_type = True
|
decode_content_type = True
|
||||||
left_list_title = _('Available groups')
|
left_list_title = _('Available groups')
|
||||||
right_list_title = _('Groups joined')
|
right_list_title = _('Groups joined')
|
||||||
view_permission = permission_user_edit
|
object_permission = permission_user_edit
|
||||||
|
|
||||||
def add(self, item):
|
def add(self, item):
|
||||||
item.user_set.add(self.get_object())
|
item.user_set.add(self.get_object())
|
||||||
@@ -233,7 +234,7 @@ class UserGroupsView(AssignRemoveView):
|
|||||||
|
|
||||||
|
|
||||||
class UserListView(SingleObjectListView):
|
class UserListView(SingleObjectListView):
|
||||||
view_permission = permission_user_view
|
object_permission = permission_user_view
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -250,11 +251,11 @@ class UserListView(SingleObjectListView):
|
|||||||
class UserSetPasswordView(MultipleObjectFormActionView):
|
class UserSetPasswordView(MultipleObjectFormActionView):
|
||||||
form_class = SetPasswordForm
|
form_class = SetPasswordForm
|
||||||
model = get_user_model()
|
model = get_user_model()
|
||||||
|
object_permission = permission_user_edit
|
||||||
success_message = _('Password change request performed on %(count)d user')
|
success_message = _('Password change request performed on %(count)d user')
|
||||||
success_message_plural = _(
|
success_message_plural = _(
|
||||||
'Password change request performed on %(count)d users'
|
'Password change request performed on %(count)d users'
|
||||||
)
|
)
|
||||||
view_permission = permission_user_edit
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
queryset = self.get_queryset()
|
queryset = self.get_queryset()
|
||||||
@@ -283,8 +284,9 @@ class UserSetPasswordView(MultipleObjectFormActionView):
|
|||||||
result = {}
|
result = {}
|
||||||
if queryset:
|
if queryset:
|
||||||
result['user'] = queryset.first()
|
result['user'] = queryset.first()
|
||||||
|
return result
|
||||||
return result
|
else:
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
def object_action(self, form, instance):
|
def object_action(self, form, instance):
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user