diff --git a/mayan/apps/user_management/api_views.py b/mayan/apps/user_management/api_views.py
index 2d914424db..47b467fe72 100644
--- a/mayan/apps/user_management/api_views.py
+++ b/mayan/apps/user_management/api_views.py
@@ -7,6 +7,7 @@ from django.shortcuts import get_object_or_404
from rest_framework import generics
from mayan.apps.acls.models import AccessControlList
+from mayan.apps.common.mixins import ExternalObjectMixin
from mayan.apps.rest_api.filters import MayanObjectPermissionsFilter
from mayan.apps.rest_api.permissions import MayanPermission
@@ -16,7 +17,7 @@ from .permissions import (
permission_user_edit, permission_user_view
)
from .serializers import (
- GroupSerializer, UserSerializer, UserGroupListSerializer
+ GroupSerializer, UserSerializer#, UserGroupListSerializer
)
@@ -53,6 +54,7 @@ class APIGroupView(generics.RetrieveUpdateDestroyAPIView):
patch: Partially edit the selected group.
put: Edit the selected group.
"""
+ lookup_url_kwarg = 'group_pk'
mayan_object_permissions = {
'GET': (permission_group_view,),
'PUT': (permission_group_edit,),
@@ -84,6 +86,7 @@ class APIUserView(generics.RetrieveUpdateDestroyAPIView):
patch: Partially edit the selected user.
put: Edit the selected user.
"""
+ lookup_url_kwarg = 'user_pk'
mayan_object_permissions = {
'GET': (permission_user_view,),
'PUT': (permission_user_edit,),
@@ -95,16 +98,28 @@ class APIUserView(generics.RetrieveUpdateDestroyAPIView):
serializer_class = UserSerializer
-class APIUserGroupList(generics.ListCreateAPIView):
+class APIUserGroupList(ExternalObjectMixin, generics.ListCreateAPIView):
"""
get: Returns a list of all the groups to which an user belongs.
post: Add a user to a list of groups.
"""
+ external_object_pk_url_kwarg = 'user_pk'
+ filter_backends = (MayanObjectPermissionsFilter,)
mayan_object_permissions = {
- 'GET': (permission_user_view,),
- 'POST': (permission_user_edit,)
+ 'GET': (permission_group_view,),
+ 'POST': (permission_group_edit,)
}
- permission_classes = (MayanPermission,)
+
+ def get_external_object_permission(self):
+ if self.request.method == 'POST':
+ return permission_user_edit
+ else:
+ return permission_user_view
+
+ def get_external_object_queryset(self):
+ return get_user_model().objects.exclude(is_staff=True).exclude(
+ is_superuser=True
+ )
def get_serializer(self, *args, **kwargs):
if not self.request:
@@ -113,10 +128,10 @@ class APIUserGroupList(generics.ListCreateAPIView):
return super(APIUserGroupList, self).get_serializer(*args, **kwargs)
def get_serializer_class(self):
- if self.request.method == 'GET':
+ if self.request.method == 'POST':
+ return UserSerializer
+ else:
return GroupSerializer
- elif self.request.method == 'POST':
- return UserGroupListSerializer
def get_serializer_context(self):
"""
@@ -133,26 +148,10 @@ class APIUserGroupList(generics.ListCreateAPIView):
return context
def get_queryset(self):
- user = self.get_user()
-
- return AccessControlList.objects.filter_by_access(
- permission_group_view, self.request.user,
- queryset=user.groups.order_by('id')
- )
+ return self.get_user().groups.order_by('id')
def get_user(self):
- if self.request.method == 'GET':
- permission = permission_user_view
- else:
- permission = permission_user_edit
-
- user = get_object_or_404(klass=get_user_model(), pk=self.kwargs['pk'])
-
- AccessControlList.objects.check_access(
- permissions=(permission,), user=self.request.user,
- obj=user
- )
- return user
+ return self.get_external_object()
def perform_create(self, serializer):
- serializer.save(user=self.get_user(), _user=self.request.user)
+ return serializer.save(user=self.get_object(), _user=self.request.user)
diff --git a/mayan/apps/user_management/apps.py b/mayan/apps/user_management/apps.py
index 875fc8066c..2ce6953c21 100644
--- a/mayan/apps/user_management/apps.py
+++ b/mayan/apps/user_management/apps.py
@@ -40,7 +40,7 @@ from .permissions import (
permission_user_view
)
from .search import * # NOQA
-from .utils import get_groups, get_users
+from .utils import lookup_get_groups, lookup_get_users
class UserManagementApp(MayanAppConfig):
@@ -65,15 +65,15 @@ class UserManagementApp(MayanAppConfig):
MetadataLookup(
description=_('All the groups.'), name='groups',
- value=get_groups
+ value=lookup_get_groups
)
MetadataLookup(
description=_('All the users.'), name='users',
- value=get_users
+ value=lookup_get_users
)
ModelEventType.register(
- model=User, event_types=(event_user_edited,)
+ event_types=(event_user_edited,), model=User
)
ModelPermission.register(
@@ -129,7 +129,9 @@ class UserManagementApp(MayanAppConfig):
menu_list_facet.bind_links(
links=(
- link_acl_list, link_group_members,
+ link_acl_list, link_events_for_object,
+ link_object_event_types_user_subcriptions_list,
+ link_group_members,
), sources=(Group,)
)
@@ -138,8 +140,7 @@ class UserManagementApp(MayanAppConfig):
link_acl_list, link_events_for_object,
link_object_event_types_user_subcriptions_list,
link_user_groups,
- ),
- sources=(User,)
+ ), sources=(User,)
)
menu_multi_item.bind_links(
@@ -147,12 +148,10 @@ class UserManagementApp(MayanAppConfig):
sources=('user_management:user_list',)
)
menu_object.bind_links(
- links=(link_group_edit,),
- sources=(Group,)
+ links=(link_group_edit,), sources=(Group,)
)
menu_object.bind_links(
- links=(link_group_delete,), position=99,
- sources=(Group,)
+ links=(link_group_delete,), position=99, sources=(Group,)
)
menu_object.bind_links(
links=(
diff --git a/mayan/apps/user_management/events.py b/mayan/apps/user_management/events.py
index 571e1427aa..2d18763e36 100644
--- a/mayan/apps/user_management/events.py
+++ b/mayan/apps/user_management/events.py
@@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.events import EventTypeNamespace
namespace = EventTypeNamespace(
- name='user_management', label=_('User management')
+ label=_('User management'), name='user_management'
)
event_group_created = namespace.add_event_type(
diff --git a/mayan/apps/user_management/icons.py b/mayan/apps/user_management/icons.py
index cf942721d5..934894b748 100644
--- a/mayan/apps/user_management/icons.py
+++ b/mayan/apps/user_management/icons.py
@@ -16,7 +16,7 @@ icon_user_delete = Icon(driver_name='fontawesome', symbol='times')
icon_user_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
icon_user_list = Icon(driver_name='fontawesome', symbol='user')
icon_user_multiple_delete = icon_user_delete
+icon_user_multiple_set_password = Icon(driver_name='fontawesome', symbol='key')
icon_user_set_options = Icon(driver_name='fontawesome', symbol='cog')
icon_user_set_password = Icon(driver_name='fontawesome', symbol='key')
icon_user_setup = Icon(driver_name='fontawesome', symbol='user')
-icon_user_multiple_set_password = icon_user_set_password
diff --git a/mayan/apps/user_management/links.py b/mayan/apps/user_management/links.py
index ed75f17ab8..bab25debcc 100644
--- a/mayan/apps/user_management/links.py
+++ b/mayan/apps/user_management/links.py
@@ -38,24 +38,23 @@ link_group_create = Link(
text=_('Create new group'), view='user_management:group_create'
)
link_group_delete = Link(
- args='object.id', icon_class=icon_group_delete,
+ icon_class=icon_group_delete, kwargs={'group_id': 'object.pk'},
permission=permission_group_delete, tags='dangerous',
- text=_('Delete'), view='user_management:group_delete',
+ text=_('Delete'), view='user_management:group_delete'
)
link_group_edit = Link(
- args='object.id', icon_class=icon_group_edit,
+ icon_class=icon_group_edit, kwargs={'group_id': 'object.pk'},
permission=permission_group_edit, text=_('Edit'),
- view='user_management:group_edit',
+ view='user_management:group_edit'
)
link_group_list = Link(
icon_class=icon_group_list, permission=permission_group_view,
- text=_('Groups'),
- view='user_management:group_list'
+ text=_('Groups'), view='user_management:group_list'
)
link_group_members = Link(
- args='object.id', icon_class=icon_group_members,
+ icon_class=icon_group_members, kwargs={'group_id': 'object.pk'},
permission=permission_group_edit, text=_('Users'),
- view='user_management:group_members',
+ view='user_management:group_members'
)
link_group_setup = Link(
icon_class=icon_group_setup, permission=permission_group_view,
@@ -66,19 +65,19 @@ link_user_create = Link(
text=_('Create new user'), view='user_management:user_create'
)
link_user_delete = Link(
- args='object.id', icon_class=icon_user_delete,
+ icon_class=icon_user_delete, kwargs={'user_id': 'object.pk'},
permission=permission_user_delete, tags='dangerous', text=_('Delete'),
- view='user_management:user_delete',
+ view='user_management:user_delete'
)
link_user_edit = Link(
- args='object.id', icon_class=icon_user_edit,
+ icon_class=icon_user_edit, kwargs={'user_id': 'object.pk'},
permission=permission_user_edit, text=_('Edit'),
- view='user_management:user_edit',
+ view='user_management:user_edit'
)
link_user_groups = Link(
- args='object.id', condition=condition_is_not_superuser,
- icon_class=icon_group, permission=permission_user_edit,
- text=_('Groups'), view='user_management:user_groups',
+ condition=condition_is_not_superuser, icon_class=icon_group,
+ kwargs={'user_id': 'object.pk'}, permission=permission_user_edit,
+ text=_('Groups'), view='user_management:user_groups'
)
link_user_list = Link(
icon_class=icon_user_list, permission=permission_user_view,
@@ -95,14 +94,14 @@ link_user_multiple_set_password = Link(
view='user_management:user_multiple_set_password'
)
link_user_set_options = Link(
- args='object.id', icon_class=icon_user_set_options,
+ icon_class=icon_user_set_options, kwargs={'user_id': 'object.pk'},
permission=permission_user_edit, text=_('User options'),
- view='user_management:user_options',
+ view='user_management:user_options'
)
link_user_set_password = Link(
- args='object.id', icon_class=icon_user_set_password,
+ icon_class=icon_user_set_password, kwargs={'user_id': 'object.pk'},
permission=permission_user_edit, text=_('Set password'),
- view='user_management:user_set_password',
+ view='user_management:user_set_password'
)
link_user_setup = Link(
icon_class=icon_user_setup, permission=permission_user_view,
diff --git a/mayan/apps/user_management/methods.py b/mayan/apps/user_management/methods.py
index 06baed3e71..23bd71b0a8 100644
--- a/mayan/apps/user_management/methods.py
+++ b/mayan/apps/user_management/methods.py
@@ -4,4 +4,6 @@ from django.shortcuts import reverse
def method_get_absolute_url(self):
- return reverse(viewname='user_management:user_details', args=(self.pk,))
+ return reverse(
+ viewname='user_management:user_details', kwargs={'user_id': self.pk}
+ )
diff --git a/mayan/apps/user_management/models.py b/mayan/apps/user_management/models.py
index 878a8c1bc6..a0a98a5713 100644
--- a/mayan/apps/user_management/models.py
+++ b/mayan/apps/user_management/models.py
@@ -18,8 +18,9 @@ class UserOptions(models.Model):
to=settings.AUTH_USER_MODEL, unique=True, verbose_name=_('User')
)
block_password_change = models.BooleanField(
- default=False,
- verbose_name=_('Forbid this user from changing their password.')
+ default=False, verbose_name=_(
+ 'Forbid this user from changing their password.'
+ )
)
objects = UserOptionsManager()
diff --git a/mayan/apps/user_management/permissions.py b/mayan/apps/user_management/permissions.py
index 944bbc3ef3..08328a0d24 100644
--- a/mayan/apps/user_management/permissions.py
+++ b/mayan/apps/user_management/permissions.py
@@ -4,29 +4,31 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.permissions import PermissionNamespace
-namespace = PermissionNamespace(label=_('User management'), name='user_management')
+namespace = PermissionNamespace(
+ label=_('User management'), name='user_management'
+)
permission_group_create = namespace.add_permission(
- name='group_create', label=_('Create new groups')
+ label=_('Create new groups'), name='group_create'
)
permission_group_delete = namespace.add_permission(
- name='group_delete', label=_('Delete existing groups')
+ label=_('Delete existing groups'), name='group_delete'
)
permission_group_edit = namespace.add_permission(
- name='group_edit', label=_('Edit existing groups')
+ label=_('Edit existing groups'), name='group_edit'
)
permission_group_view = namespace.add_permission(
- name='group_view', label=_('View existing groups')
+ label=_('View existing groups'), name='group_view'
)
permission_user_create = namespace.add_permission(
- name='user_create', label=_('Create new users')
+ label=_('Create new users'), name='user_create'
)
permission_user_delete = namespace.add_permission(
- name='user_delete', label=_('Delete existing users')
+ label=_('Delete existing users'), name='user_delete'
)
permission_user_edit = namespace.add_permission(
- name='user_edit', label=_('Edit existing users')
+ label=_('Edit existing users'), name='user_edit'
)
permission_user_view = namespace.add_permission(
- name='user_view', label=_('View existing users')
+ label=_('View existing users'), name='user_view'
)
diff --git a/mayan/apps/user_management/search.py b/mayan/apps/user_management/search.py
index 6ebf50546b..370b733fb7 100644
--- a/mayan/apps/user_management/search.py
+++ b/mayan/apps/user_management/search.py
@@ -32,8 +32,7 @@ user_search.add_model_field(
)
group_search = SearchModel(
- app_label='auth', model_name='Group',
- permission=permission_group_view,
+ app_label='auth', model_name='Group', permission=permission_group_view,
serializer_path='user_management.serializers.GroupSerializer'
)
diff --git a/mayan/apps/user_management/serializers.py b/mayan/apps/user_management/serializers.py
index 559b2c6969..6cd8205d46 100644
--- a/mayan/apps/user_management/serializers.py
+++ b/mayan/apps/user_management/serializers.py
@@ -11,7 +11,7 @@ from rest_framework.exceptions import ValidationError
from mayan.apps.acls.models import AccessControlList
-from .permissions import permission_group_view
+from .permissions import permission_group_edit, permission_group_view
class GroupSerializer(serializers.HyperlinkedModelSerializer):
@@ -19,7 +19,10 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
extra_kwargs = {
- 'url': {'view_name': 'rest_api:group-detail'}
+ 'url': {
+ 'lookup_field': 'pk', 'lookup_url_kwarg': 'group_pk',
+ 'view_name': 'rest_api:group-detail'
+ }
}
fields = ('id', 'name', 'url', 'users_count')
model = Group
@@ -28,41 +31,13 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer):
return instance.user_set.count()
-class UserGroupListSerializer(serializers.Serializer):
- group_pk_list = serializers.CharField(
+class UserSerializer(serializers.HyperlinkedModelSerializer):
+ groups = GroupSerializer(many=True, read_only=True, required=False)
+ groups_pk_list = serializers.CharField(
help_text=_(
'Comma separated list of group primary keys to assign this '
'user to.'
- )
- )
-
- def create(self, validated_data):
- validated_data['user'].groups.clear()
- try:
- pk_list = validated_data['group_pk_list'].split(',')
-
- for group in Group.objects.filter(pk__in=pk_list):
- try:
- AccessControlList.objects.check_access(
- permissions=(permission_group_view,),
- user=self.context['request'].user, obj=group
- )
- except PermissionDenied:
- pass
- else:
- validated_data['user'].groups.add(group)
- except Exception as exception:
- raise ValidationError(exception)
-
- return {'group_pk_list': validated_data['group_pk_list']}
-
-
-class UserSerializer(serializers.HyperlinkedModelSerializer):
- groups = GroupSerializer(many=True, read_only=True)
- groups_pk_list = serializers.CharField(
- help_text=_(
- 'List of group primary keys to which to add the user.'
- ), required=False
+ ), required=False, write_only=True
)
password = serializers.CharField(
required=False, style={'input_type': 'password'}, write_only=True
@@ -70,7 +45,10 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
extra_kwargs = {
- 'url': {'view_name': 'rest_api:user-detail'}
+ 'url': {
+ 'lookup_field': 'pk', 'lookup_url_kwarg': 'user_pk',
+ 'view_name': 'rest_api:user-detail'
+ }
}
fields = (
'first_name', 'date_joined', 'email', 'groups', 'groups_pk_list',
@@ -81,13 +59,19 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
read_only_fields = ('groups', 'is_active', 'last_login', 'date_joined')
write_only_fields = ('password', 'group_pk_list')
- def _add_groups(self, instance):
- instance.groups.add(
- *Group.objects.filter(pk__in=self.groups_pk_list.split(','))
+ def _add_groups(self, instance, groups_pk_list):
+ instance.groups.clear()
+
+ queryset = AccessControlList.objects.restrict_queryset(
+ permission=permission_group_edit,
+ queryset=Group.objects.filter(pk__in=groups_pk_list.split(',')),
+ user=self.context['request'].user
)
+ instance.groups.add(*queryset)
+
def create(self, validated_data):
- self.groups_pk_list = validated_data.pop('groups_pk_list', '')
+ groups_pk_list = validated_data.pop('groups_pk_list', '')
password = validated_data.pop('password', None)
instance = super(UserSerializer, self).create(validated_data)
@@ -95,13 +79,13 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
instance.set_password(password)
instance.save()
- if self.groups_pk_list:
- self._add_groups(instance=instance)
+ if groups_pk_list:
+ self._add_groups(instance=instance, groups_pk_list=groups_pk_list)
return instance
def update(self, instance, validated_data):
- self.groups_pk_list = validated_data.pop('groups_pk_list', '')
+ groups_pk_list = validated_data.pop('groups_pk_list', '')
if 'password' in validated_data:
instance.set_password(validated_data['password'])
@@ -109,9 +93,8 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
instance = super(UserSerializer, self).update(instance, validated_data)
- if self.groups_pk_list:
- instance.groups.clear()
- self._add_groups(instance=instance)
+ if groups_pk_list:
+ self._add_groups(instance=instance, groups_pk_list=groups_pk_list)
return instance
diff --git a/mayan/apps/user_management/tests/__init__.py b/mayan/apps/user_management/tests/__init__.py
index 124ec460a6..33ff9e78ba 100644
--- a/mayan/apps/user_management/tests/__init__.py
+++ b/mayan/apps/user_management/tests/__init__.py
@@ -1 +1,2 @@
from .literals import * # NOQA
+from .mixins import * # NOQA
diff --git a/mayan/apps/user_management/tests/literals.py b/mayan/apps/user_management/tests/literals.py
index 0cc6ddadc8..9b9b7db24a 100644
--- a/mayan/apps/user_management/tests/literals.py
+++ b/mayan/apps/user_management/tests/literals.py
@@ -5,26 +5,28 @@ __all__ = (
'TEST_USER_PASSWORD', 'TEST_USER_PASSWORD_EDITED', 'TEST_USER_USERNAME'
)
-TEST_CASE_ADMIN_EMAIL = 'admin@example.com'
-TEST_CASE_ADMIN_PASSWORD = 'test admin password'
-TEST_CASE_ADMIN_USERNAME = 'test_admin'
+TEST_CASE_ADMIN_EMAIL = 'case_admin@example.com'
+TEST_CASE_ADMIN_PASSWORD = 'test case admin password'
+TEST_CASE_ADMIN_USERNAME = 'test_case_admin'
-TEST_CASE_GROUP_NAME = 'test group'
-TEST_CASE_USER_EMAIL = 'user@example.com'
-TEST_CASE_USER_PASSWORD = 'test user password'
-TEST_CASE_USER_USERNAME = 'test_user'
+TEST_CASE_GROUP_NAME = 'test case group'
+
+TEST_CASE_USER_EMAIL = 'test_case_user@example.com'
+TEST_CASE_USER_PASSWORD = 'test case user password'
+TEST_CASE_USER_USERNAME = 'test_case_user'
TEST_GROUP_NAME = 'test group'
TEST_GROUP_NAME_EDITED = 'test group edited'
TEST_GROUP_2_NAME = 'test group 2'
TEST_GROUP_2_NAME_EDITED = 'test group 2 edited'
-TEST_USER_EMAIL = 'user@example.com'
+
+TEST_USER_EMAIL = 'testuser@example.com'
TEST_USER_PASSWORD = 'test user password'
TEST_USER_PASSWORD_EDITED = 'test user password edited'
TEST_USER_USERNAME = 'test_user'
TEST_USER_USERNAME_EDITED = 'test_user_edited'
-TEST_USER_2_EMAIL = 'user2@example.com'
+TEST_USER_2_EMAIL = 'testuser2@example.com'
TEST_USER_2_PASSWORD = 'test user 2 password'
TEST_USER_2_PASSWORD_EDITED = 'test user 2 password edited'
TEST_USER_2_USERNAME = 'test_user_2'
diff --git a/mayan/apps/user_management/tests/mixins.py b/mayan/apps/user_management/tests/mixins.py
index 81643866ef..cd2c26ec43 100644
--- a/mayan/apps/user_management/tests/mixins.py
+++ b/mayan/apps/user_management/tests/mixins.py
@@ -5,97 +5,117 @@ from django.contrib.auth.models import Group
from .literals import (
TEST_CASE_ADMIN_EMAIL, TEST_CASE_ADMIN_PASSWORD, TEST_CASE_ADMIN_USERNAME,
- TEST_CASE_GROUP_NAME, TEST_CASE_USER_EMAIL, TEST_CASE_USER_PASSWORD,
- TEST_CASE_USER_USERNAME, TEST_GROUP_NAME, TEST_GROUP_2_NAME,
- TEST_GROUP_2_NAME_EDITED, TEST_USER_2_EMAIL, TEST_USER_2_PASSWORD,
- TEST_USER_EMAIL, TEST_USER_USERNAME, TEST_USER_PASSWORD,
- TEST_USER_2_USERNAME, TEST_USER_2_USERNAME_EDITED
+ TEST_CASE_GROUP_NAME, TEST_GROUP_NAME_EDITED, TEST_CASE_USER_EMAIL,
+ TEST_CASE_USER_PASSWORD, TEST_CASE_USER_USERNAME, TEST_GROUP_NAME,
+ TEST_USER_EMAIL, TEST_USER_USERNAME, TEST_USER_USERNAME_EDITED,
+ TEST_USER_PASSWORD
)
+__all__ = ('GroupTestMixin', 'UserTestCaseMixin', 'UserTestMixin')
+
class UserTestCaseMixin(object):
- auto_login_admin = False
+ """
+ This TestCaseMixin is used to create an user and group to execute the
+ test case, these are used to just create an identity which is required by
+ most of the code in the project, these are not meant to be acted upon
+ (edited, deleted, etc). To create a test users or groups to modify, use
+ the UserTestMixin instead and the respective test_user and test_group.
+ The user and group created by this mixin will be prepended with
+ _test_case_{...}. The _test_case_user and _test_case_group are meant
+ to be used by other test case mixins like the ACLs test case mixin which
+ adds shorthand methods to create ACL entries to test access control.
+ """
+ auto_login_superuser = False
auto_login_user = True
+ create_test_case_superuser = False
+ create_test_case_user = True
def setUp(self):
super(UserTestCaseMixin, self).setUp()
- if self.auto_login_user:
- self._test_case_user = get_user_model().objects.create_user(
- username=TEST_CASE_USER_USERNAME, email=TEST_CASE_USER_EMAIL,
- password=TEST_CASE_USER_PASSWORD
- )
- self.login_user()
- self._test_case_group = Group.objects.create(name=TEST_GROUP_NAME)
+ if self.create_test_case_user:
+ self._create_test_case_user()
+ self._create_test_case_group()
self._test_case_group.user_set.add(self._test_case_user)
- elif self.auto_login_admin:
- self._test_case_admin_user = get_user_model().objects.create_superuser(
- username=TEST_CASE_ADMIN_USERNAME, email=TEST_CASE_ADMIN_EMAIL,
- password=TEST_CASE_ADMIN_PASSWORD
- )
- self.login_admin_user()
+
+ if self.auto_login_user:
+ self.login_user()
+
+ elif self.create_test_case_superuser:
+ self._create_test_case_superuser()
+
+ if self.auto_login_superuser:
+ self.login_superuser()
def tearDown(self):
self.client.logout()
super(UserTestCaseMixin, self).tearDown()
+ def _create_test_case_group(self):
+ self._test_case_group = Group.objects.create(name=TEST_CASE_GROUP_NAME)
+
+ def _create_test_case_superuser(self):
+ self._test_case_superuser = get_user_model().objects.create_superuser(
+ username=TEST_CASE_ADMIN_USERNAME, email=TEST_CASE_ADMIN_EMAIL,
+ password=TEST_CASE_ADMIN_PASSWORD
+ )
+
+ def _create_test_case_user(self):
+ self._test_case_user = get_user_model().objects.create_user(
+ username=TEST_CASE_USER_USERNAME, email=TEST_CASE_USER_EMAIL,
+ password=TEST_CASE_USER_PASSWORD
+ )
+
def login(self, *args, **kwargs):
logged_in = self.client.login(*args, **kwargs)
return logged_in
- def login_user(self):
- self.login(
- username=TEST_CASE_USER_USERNAME, password=TEST_CASE_USER_PASSWORD
- )
-
- def login_admin_user(self):
+ def login_superuser(self):
self.login(
username=TEST_CASE_ADMIN_USERNAME,
password=TEST_CASE_ADMIN_PASSWORD
)
+ def login_user(self):
+ self.login(
+ username=TEST_CASE_USER_USERNAME, password=TEST_CASE_USER_PASSWORD
+ )
+
def logout(self):
self.client.logout()
-class UserTestMixin(object):
+class GroupTestMixin(object):
def _create_test_group(self):
- self.test_group = Group.objects.create(name=TEST_GROUP_2_NAME)
+ self.test_group = Group.objects.create(name=TEST_GROUP_NAME)
def _edit_test_group(self):
- self.test_group.name = TEST_GROUP_2_NAME_EDITED
+ self.test_group.name = TEST_GROUP_NAME_EDITED
self.test_group.save()
- def _create_test_user(self):
- self.test_user = get_user_model().objects.create(
- username=TEST_USER_2_USERNAME, email=TEST_USER_2_EMAIL,
- password=TEST_USER_2_PASSWORD
- )
-
- # Group views
-
def _request_test_group_create_view(self):
reponse = self.post(
viewname='user_management:group_create', data={
- 'name': TEST_GROUP_2_NAME
+ 'name': TEST_GROUP_NAME
}
)
- self.test_group = Group.objects.filter(name=TEST_GROUP_2_NAME).first()
+ self.test_group = Group.objects.filter(name=TEST_GROUP_NAME).first()
return reponse
def _request_test_group_delete_view(self):
return self.post(
viewname='user_management:group_delete', kwargs={
- 'group_pk': self.test_group.pk
+ 'group_id': self.test_group.pk
}
)
def _request_test_group_edit_view(self):
return self.post(
viewname='user_management:group_edit', kwargs={
- 'group_pk': self.test_group.pk
+ 'group_id': self.test_group.pk
}, data={
- 'name': TEST_GROUP_2_NAME_EDITED
+ 'name': TEST_GROUP_NAME_EDITED
}
)
@@ -105,41 +125,65 @@ class UserTestMixin(object):
def _request_test_group_members_view(self):
return self.get(
viewname='user_management:group_members',
- kwargs={'group_pk': self.test_group.pk}
+ kwargs={'group_id': self.test_group.pk}
)
- # User views
+
+class UserTestMixin(object):
+ def _create_test_superuser(self):
+ self.test_superuser = get_user_model().objects.create_superuser(
+ username=TEST_CASE_ADMIN_USERNAME, email=TEST_CASE_ADMIN_EMAIL,
+ password=TEST_CASE_ADMIN_PASSWORD
+ )
+
+ def _create_test_user(self):
+ self.test_user = get_user_model().objects.create(
+ username=TEST_USER_USERNAME, email=TEST_USER_EMAIL,
+ password=TEST_USER_PASSWORD
+ )
+
+ def _request_test_superuser_delete_view(self):
+ return self.post(
+ viewname='user_management:user_delete',
+ kwargs={'user_id': self.test_superuser.pk}
+ )
+
+ def _request_test_superuser_detail_view(self):
+ return self.get(
+ viewname='user_management:user_details',
+ kwargs={'user_id': self.test_superuser.pk}
+ )
def _request_test_user_create_view(self):
reponse = self.post(
viewname='user_management:user_create', data={
- 'username': TEST_USER_2_USERNAME,
- 'password': TEST_USER_2_PASSWORD
+ 'username': TEST_USER_USERNAME,
+ 'password': TEST_USER_PASSWORD
}
)
self.test_user = get_user_model().objects.filter(
- username=TEST_USER_2_USERNAME
+ username=TEST_USER_USERNAME
).first()
return reponse
def _request_test_user_delete_view(self):
return self.post(
viewname='user_management:user_delete',
- kwargs={'user_pk': self.test_user.pk}
+ kwargs={'user_id': self.test_user.pk}
)
def _request_test_user_edit_view(self):
return self.post(
viewname='user_management:user_edit', kwargs={
- 'user_pk': self.test_user.pk
+ 'user_id': self.test_user.pk
}, data={
- 'username': TEST_USER_2_USERNAME_EDITED
+ 'username': TEST_USER_USERNAME_EDITED
}
)
def _request_test_user_groups_view(self):
return self.get(
viewname='user_management:user_groups',
- kwargs={'user_pk': self.test_user.pk}
+ kwargs={'user_id': self.test_user.pk}
)
diff --git a/mayan/apps/user_management/tests/test_api.py b/mayan/apps/user_management/tests/test_api.py
index e1cb7cc181..d30e474828 100644
--- a/mayan/apps/user_management/tests/test_api.py
+++ b/mayan/apps/user_management/tests/test_api.py
@@ -22,9 +22,9 @@ from .literals import (
from .mixins import UserTestMixin
-class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
+class UserAPITestCase(UserTestMixin, BaseAPITestCase):
def setUp(self):
- super(UserManagementUserAPITestCase, self).setUp()
+ super(UserAPITestCase, self).setUp()
self.login_user()
def _request_api_test_user_create(self):
@@ -54,22 +54,25 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
viewname='rest_api:user-list', data={
'email': TEST_USER_2_EMAIL, 'password': TEST_USER_2_PASSWORD,
'username': TEST_USER_2_USERNAME,
- 'groups_pk_list': self.test_groups_pk_list
+ 'groups_id_list': self.test_groups_id_list
}
)
+ """
def test_user_create_with_group_no_permission(self):
self._create_test_group()
- self.test_groups_pk_list = '{}'.format(self.test_group.pk)
+ self.test_groups_id_list = '{}'.format(self.test_group.pk)
response = self._request_api_create_test_user_with_extra_data()
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
- def test_user_create_with_group_with_permission(self):
+ def test_user_create_with_group_with_user_access(self):
self._create_test_group()
- self.test_groups_pk_list = '{}'.format(self.test_group.pk)
+ self.test_groups_id_list = '{}'.format(self.test_group.pk)
- self.grant_permission(permission=permission_user_create)
+ self.grant_access(
+ obj=self.test_user, permission=permission_user_create
+ )
response = self._request_api_create_test_user_with_extra_data()
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
@@ -78,22 +81,57 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
self.assertEqual(user.username, TEST_USER_2_USERNAME)
self.assertQuerysetEqual(user.groups.all(), (repr(self.test_group),))
+
+ def test_user_create_with_group_with_user_access(self):
+ self._create_test_group()
+ self.test_groups_id_list = '{}'.format(self.test_group.pk)
+
+ self.grant_access(
+ obj=self.test_user, permission=permission_user_create
+ )
+ response = self._request_api_create_test_user_with_extra_data()
+
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+
+ user = get_user_model().objects.get(pk=response.data['id'])
+ self.assertEqual(user.username, TEST_USER_2_USERNAME)
+ self.assertQuerysetEqual(user.groups.all(), (repr(self.test_group),))
+ """
+
def test_user_create_with_groups_no_permission(self):
group_1 = Group.objects.create(name='test group 1')
group_2 = Group.objects.create(name='test group 2')
- self.test_groups_pk_list = '{},{}'.format(group_1.pk, group_2.pk)
+ self.test_groups_id_list = '{},{}'.format(group_1.pk, group_2.pk)
response = self._request_api_create_test_user_with_extra_data()
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
- def test_user_create_with_groups_with_permission(self):
+ def test_user_create_with_groups_with_user_permission(self):
group_1 = Group.objects.create(name='test group 1')
group_2 = Group.objects.create(name='test group 2')
- self.test_groups_pk_list = '{},{}'.format(group_1.pk, group_2.pk)
+ self.test_groups_id_list = '{},{}'.format(group_1.pk, group_2.pk)
self.grant_permission(permission=permission_user_create)
response = self._request_api_create_test_user_with_extra_data()
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ user = get_user_model().objects.get(pk=response.data['id'])
+ self.assertEqual(user.username, TEST_USER_2_USERNAME)
+ #self.assertQuerysetEqual(
+ # user.groups.all().order_by('name'), (repr(group_1), repr(group_2))
+ #)
+ self.assertEqual(user.groups.count(), 0)
+
+ def test_user_create_with_groups_with_full_access(self):
+ group_1 = Group.objects.create(name='test group 1')
+ group_2 = Group.objects.create(name='test group 2')
+ self.test_groups_id_list = '{},{}'.format(group_1.pk, group_2.pk)
+ self.grant_permission(permission=permission_user_create)
+ self.grant_access(obj=group_1, permission=permission_group_edit)
+ self.grant_access(obj=group_2, permission=permission_group_edit)
+ response = self._request_api_create_test_user_with_extra_data()
+
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+
user = get_user_model().objects.get(pk=response.data['id'])
self.assertEqual(user.username, TEST_USER_2_USERNAME)
self.assertQuerysetEqual(
@@ -105,10 +143,6 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def test_user_create_login(self):
self._create_test_user()
- self.login(
- username=TEST_USER_2_USERNAME, password=TEST_USER_2_PASSWORD
- )
-
self.assertTrue(
self.login(
username=TEST_USER_2_USERNAME, password=TEST_USER_2_PASSWORD
@@ -117,15 +151,18 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
# User password change
- def test_user_create_login_password_change_no_access(self):
- self._create_test_user()
-
- self.patch(
- viewname='rest_api:user-detail', args=(self.test_user.pk,), data={
+ def _request_api_user_password_change(self):
+ return self.patch(
+ viewname='rest_api:user-detail',
+ kwargs={'user_id': self.test_user.pk}, data={
'password': TEST_USER_2_PASSWORD_EDITED,
}
)
+ def test_user_create_login_password_change_no_access(self):
+ self._create_test_user()
+ self._request_api_user_password_change()
+
self.assertFalse(
self.client.login(
username=TEST_USER_2_USERNAME,
@@ -136,12 +173,8 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def test_user_create_login_password_change_with_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
- self.patch(
- viewname='rest_api:user-detail', args=(self.test_user.pk,), data={
- 'password': TEST_USER_2_PASSWORD_EDITED,
- }
- )
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
+ self._request_api_user_password_change()
self.assertTrue(
self.client.login(
@@ -154,7 +187,8 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def _request_api_test_user_edit_via_put(self):
return self.put(
- viewname='rest_api:user-detail', args=(self.test_user.pk,),
+ viewname='rest_api:user-detail',
+ kwargs={'user_id': self.test_user.pk},
data={'username': TEST_USER_2_USERNAME_EDITED}
)
@@ -162,14 +196,14 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
self._create_test_user()
response = self._request_api_test_user_edit_via_put()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.test_user.refresh_from_db()
self.assertEqual(self.test_user.username, TEST_USER_2_USERNAME)
def test_user_edit_via_put_with_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
response = self._request_api_test_user_edit_via_put()
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -179,7 +213,8 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def _request_api_test_user_edit_via_patch(self):
return self.patch(
- viewname='rest_api:user-detail', args=(self.test_user.pk,),
+ viewname='rest_api:user-detail',
+ kwargs={'user_id': self.test_user.pk},
data={'username': TEST_USER_2_USERNAME_EDITED}
)
@@ -187,14 +222,14 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
self._create_test_user()
response = self._request_api_test_user_edit_via_patch()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.test_user.refresh_from_db()
self.assertEqual(self.test_user.username, TEST_USER_2_USERNAME)
def test_user_edit_via_patch_with_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
response = self._request_api_test_user_edit_via_patch()
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -204,8 +239,9 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def _request_api_test_user_edit_via_patch_with_extra_data(self):
return self.patch(
- viewname='rest_api:user-detail', args=(self.test_user.pk,),
- data={'groups_pk_list': '{}'.format(self.test_group.pk)}
+ viewname='rest_api:user-detail',
+ kwargs={'user_id': self.test_user.pk},
+ data={'groups_id_list': '{}'.format(self.test_group.pk)}
)
def test_user_edit_add_groups_via_patch_no_access(self):
@@ -214,7 +250,7 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
response = self._request_api_test_user_edit_via_patch_with_extra_data()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.test_user.refresh_from_db()
self.assertEqual(self.test_user.username, TEST_USER_2_USERNAME)
@@ -226,7 +262,8 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def test_user_edit_add_groups_via_patch_with_access(self):
self._create_test_group()
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
+ self.grant_access(obj=self.test_group, permission=permission_group_edit)
response = self._request_api_test_user_edit_via_patch_with_extra_data()
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -242,13 +279,14 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def _request_api_test_user_delete(self):
return self.delete(
- viewname='rest_api:user-detail', args=(self.test_user.pk,)
+ viewname='rest_api:user-detail',
+ kwargs={'user_id': self.test_user.pk}
)
def test_user_delete_no_access(self):
self._create_test_user()
response = self._request_api_test_user_delete()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertTrue(
get_user_model().objects.filter(pk=self.test_user.pk).exists()
@@ -257,7 +295,7 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
def test_user_delete_with_access(self):
self._create_test_user()
self.grant_access(
- permission=permission_user_delete, obj=self.test_user
+ obj=self.test_user, permission=permission_user_delete
)
response = self._request_api_test_user_delete()
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
@@ -266,11 +304,12 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
get_user_model().objects.filter(pk=self.test_user.pk).exists()
)
- # User view
+ # User group listview
def _request_api_test_user_group_view(self):
return self.get(
- viewname='rest_api:users-group-list', args=(self.test_user.pk,)
+ viewname='rest_api:users-group-list',
+ kwargs={'user_id': self.test_user.pk}
)
def test_user_group_list_no_access(self):
@@ -278,13 +317,13 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
self._create_test_user()
self.test_user.groups.add(group)
response = self._request_api_test_user_group_view()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
def test_user_group_list_with_user_access(self):
group = Group.objects.create(name=TEST_GROUP_2_NAME)
self._create_test_user()
self.test_user.groups.add(group)
- self.grant_access(permission=permission_user_view, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_view)
response = self._request_api_test_user_group_view()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 0)
@@ -294,46 +333,44 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
self._create_test_user()
self.test_user.groups.add(self.test_group)
self.grant_access(
- permission=permission_group_view, obj=self.test_group
+ obj=self.test_group, permission=permission_group_view
)
response = self._request_api_test_user_group_view()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
def test_user_group_list_with_access(self):
self._create_test_group()
self._create_test_user()
self.test_user.groups.add(self.test_group)
- self.grant_access(permission=permission_user_view, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_view)
self.grant_access(
- permission=permission_group_view, obj=self.test_group
+ obj=self.test_group, permission=permission_group_view
)
response = self._request_api_test_user_group_view()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)
def _request_api_test_user_group_add(self):
- return self.post(
- viewname='rest_api:users-group-list', args=(self.test_user.pk,),
- data={'group_pk_list': '{}'.format(self.test_group.pk)}
+ return self.patch(
+ viewname='rest_api:user-detail',
+ kwargs={'user_id': self.test_user.pk},
+ data={'group_id_list': '{}'.format(self.test_group.pk)}
)
def test_user_group_add_no_access(self):
self._create_test_group()
self._create_test_user()
response = self._request_api_test_user_group_add()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.test_user.refresh_from_db()
self.assertEqual(self.test_group.user_set.first(), None)
def test_user_group_add_with_user_access(self):
self._create_test_group()
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
response = self._request_api_test_user_group_add()
- self.assertEqual(response.status_code, status.HTTP_201_CREATED)
- # FIXME: Should this endpoint return a 201 or a 200 since
- # the user is being edited and there is not resource creation
- # happening.
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
self.test_user.refresh_from_db()
self.assertEqual(self.test_group.user_set.first(), None)
@@ -341,38 +378,32 @@ class UserManagementUserAPITestCase(UserTestMixin, BaseAPITestCase):
self._create_test_group()
self._create_test_user()
self.grant_access(
- permission=permission_group_view, obj=self.test_group
+ obj=self.test_group, permission=permission_group_edit
)
response = self._request_api_test_user_group_add()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
- # FIXME: Should this endpoint return a 201 or a 200 since
- # the user is being edited and there is not resource creation
- # happening.
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.test_user.refresh_from_db()
self.assertEqual(self.test_group.user_set.first(), None)
- def test_user_group_add_with_access(self):
+ def test_user_group_add_with_full_access(self):
self._create_test_group()
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
self.grant_access(
- permission=permission_group_view, obj=self.test_group
+ obj=self.test_group, permission=permission_group_edit
)
response = self._request_api_test_user_group_add()
- self.assertEqual(response.status_code, status.HTTP_201_CREATED)
- # FIXME: Should this endpoint return a 201 or a 200 since
- # the user is being edited and there is not resource creation
- # happening.
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
self.test_user.refresh_from_db()
self.assertEqual(self.test_group.user_set.first(), self.test_user)
-class UserManagementGroupAPITestCase(BaseAPITestCase):
+class GroupAPITestCase(UserTestMixin, BaseAPITestCase):
def setUp(self):
- super(UserManagementGroupAPITestCase, self).setUp()
+ super(GroupAPITestCase, self).setUp()
self.login_user()
- def _request_api_test_group_create(self):
+ def _request_api_test_group_create_view(self):
return self.post(
viewname='rest_api:group-list', data={
'name': TEST_GROUP_2_NAME
@@ -380,7 +411,7 @@ class UserManagementGroupAPITestCase(BaseAPITestCase):
)
def test_group_create_no_permission(self):
- response = self._request_api_test_group_create()
+ response = self._request_api_test_group_create_view()
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertFalse(
TEST_GROUP_2_NAME in list(
@@ -390,7 +421,7 @@ class UserManagementGroupAPITestCase(BaseAPITestCase):
def test_group_create_with_permission(self):
self.grant_permission(permission=permission_group_create)
- response = self._request_api_test_group_create()
+ response = self._request_api_test_group_create_view()
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertTrue(
TEST_GROUP_2_NAME in list(
@@ -398,43 +429,17 @@ class UserManagementGroupAPITestCase(BaseAPITestCase):
)
)
- def _request_api_test_group_edit_via_patch(self):
- return self.patch(
- viewname='rest_api:group-detail', args=(self.test_group.pk,),
- data={
- 'name': TEST_GROUP_2_NAME_EDITED
- }
- )
-
- def test_group_edit_via_patch_no_access(self):
- self.test_group = Group.objects.create(name=TEST_GROUP_2_NAME)
- response = self._request_api_test_group_edit_via_patch()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
-
- self.test_group.refresh_from_db()
- self.assertEqual(self.test_group.name, TEST_GROUP_2_NAME)
-
- def test_group_edit_via_patch_with_access(self):
- self.test_group = Group.objects.create(name=TEST_GROUP_2_NAME)
- self.grant_access(
- permission=permission_group_edit, obj=self.test_group
- )
- response = self._request_api_test_group_edit_via_patch()
- self.assertEqual(response.status_code, status.HTTP_200_OK)
-
- self.test_group.refresh_from_db()
- self.assertEqual(self.test_group.name, TEST_GROUP_2_NAME_EDITED)
-
- def _request_api_test_group_delete(self):
+ def _request_api_test_group_delete_view(self):
return self.delete(
- viewname='rest_api:group-detail', args=(self.test_group.pk,)
+ viewname='rest_api:group-detail',
+ kwargs={'group_id': self.test_group.pk}
)
def test_group_delete_no_access(self):
- self.test_group = Group.objects.create(name=TEST_GROUP_2_NAME)
- response = self._request_api_test_group_delete()
+ self._create_test_group()
+ response = self._request_api_test_group_delete_view()
- self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertTrue(
TEST_GROUP_2_NAME in list(
Group.objects.values_list('name', flat=True)
@@ -442,9 +447,11 @@ class UserManagementGroupAPITestCase(BaseAPITestCase):
)
def test_group_delete_with_access(self):
- self.test_group = Group.objects.create(name=TEST_GROUP_2_NAME)
- self.grant_access(permission=permission_group_delete, obj=self.test_group)
- response = self._request_api_test_group_delete()
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_delete
+ )
+ response = self._request_api_test_group_delete_view()
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertFalse(
@@ -452,3 +459,79 @@ class UserManagementGroupAPITestCase(BaseAPITestCase):
Group.objects.values_list('name', flat=True)
)
)
+
+ def _request_api_test_group_detail_view(self):
+ return self.get(
+ viewname='rest_api:group-detail',
+ kwargs={'group_id': self.test_group.pk}
+ )
+
+ def test_group_detail_no_access(self):
+ self._create_test_group()
+ response = self._request_api_test_group_detail_view()
+
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
+ self.assertNotEqual(
+ self.test_group.name, response.data.get('name', None)
+ )
+
+ def test_group_detail_with_access(self):
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_view
+ )
+ response = self._request_api_test_group_detail_view()
+
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+ self.assertEqual(self.test_group.name, response.data.get('name', None))
+
+
+ def _request_api_test_group_edit_via_patch_view(self):
+ return self.patch(
+ viewname='rest_api:group-detail',
+ kwargs={'group_id': self.test_group.pk},
+ data={
+ 'name': TEST_GROUP_2_NAME_EDITED
+ }
+ )
+
+ def test_group_edit_via_patch_no_access(self):
+ self._create_test_group()
+ response = self._request_api_test_group_edit_via_patch_view()
+ self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
+
+ self.test_group.refresh_from_db()
+ self.assertEqual(self.test_group.name, TEST_GROUP_2_NAME)
+
+ def test_group_edit_via_patch_with_access(self):
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
+ response = self._request_api_test_group_edit_via_patch_view()
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+
+ self.test_group.refresh_from_db()
+ self.assertEqual(self.test_group.name, TEST_GROUP_2_NAME_EDITED)
+
+ def _request_api_test_group_list_view(self):
+ return self.get(viewname='rest_api:group-list')
+
+ def test_group_list_no_access(self):
+ self._create_test_group()
+ response = self._request_api_test_group_list_view()
+ self.assertNotContains(
+ response=response, text=self.test_group.name,
+ status_code=status.HTTP_200_OK
+ )
+
+ def test_group_list_with_access(self):
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_view
+ )
+ response = self._request_api_test_group_list_view()
+ self.assertContains(
+ response=response, text=self.test_group.name,
+ status_code=status.HTTP_200_OK
+ )
diff --git a/mayan/apps/user_management/tests/test_events.py b/mayan/apps/user_management/tests/test_events.py
index 9e4e2c4c73..e6d630c89f 100644
--- a/mayan/apps/user_management/tests/test_events.py
+++ b/mayan/apps/user_management/tests/test_events.py
@@ -4,47 +4,60 @@ from actstream.models import Action
from mayan.apps.common.tests import GenericViewTestCase
+from ..permissions import (
+ permission_group_create, permission_group_edit, permission_user_create,
+ permission_user_edit
+)
+
from ..events import (
event_group_created, event_group_edited, event_user_created,
event_user_edited
)
-from .mixins import UserTestMixin
+from .mixins import GroupTestMixin, UserTestMixin
-class GroupEventsTestCase(UserTestMixin, GenericViewTestCase):
- auto_create_group = False
-
+class GroupEventsTestCase(GroupTestMixin, UserTestMixin, GenericViewTestCase):
def test_group_create_event(self):
- self.login_admin_user()
Action.objects.all().delete()
+
+ self.grant_permission(
+ permission=permission_group_create
+ )
self._request_test_group_create_view()
self.assertEqual(Action.objects.last().target, self.test_group)
self.assertEqual(Action.objects.last().verb, event_group_created.id)
def test_group_edit_event(self):
- self.login_admin_user()
self._create_test_group()
Action.objects.all().delete()
+
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
self._request_test_group_edit_view()
self.assertEqual(Action.objects.last().target, self.test_group)
self.assertEqual(Action.objects.last().verb, event_group_edited.id)
class UserEventsTestCase(UserTestMixin, GenericViewTestCase):
- auto_create_group = False
-
def test_user_create_event(self):
- self.login_admin_user()
Action.objects.all().delete()
+
+ self.grant_permission(
+ permission=permission_user_create
+ )
self._request_test_user_create_view()
self.assertEqual(Action.objects.last().target, self.test_user)
self.assertEqual(Action.objects.last().verb, event_user_created.id)
def test_user_edit_event(self):
- self.login_admin_user()
self._create_test_user()
Action.objects.all().delete()
+
+ self.grant_access(
+ obj=self.test_user, permission=permission_user_edit
+ )
self._request_test_user_edit_view()
self.assertEqual(Action.objects.last().target, self.test_user)
self.assertEqual(Action.objects.last().verb, event_user_edited.id)
diff --git a/mayan/apps/user_management/tests/test_models.py b/mayan/apps/user_management/tests/test_models.py
index 7e96927453..e913a1262c 100644
--- a/mayan/apps/user_management/tests/test_models.py
+++ b/mayan/apps/user_management/tests/test_models.py
@@ -7,5 +7,5 @@ from .mixins import UserTestMixin
class UserTestCase(UserTestMixin, BaseTestCase):
def test_natural_keys(self):
- self._create_user()
+ self._create_test_user()
self._test_database_conversion('auth', 'user_management')
diff --git a/mayan/apps/user_management/tests/test_views.py b/mayan/apps/user_management/tests/test_views.py
index 12a8659fe0..a3bb41ddaa 100644
--- a/mayan/apps/user_management/tests/test_views.py
+++ b/mayan/apps/user_management/tests/test_views.py
@@ -6,70 +6,253 @@ from django.contrib.auth.models import Group
from mayan.apps.common.tests import GenericViewTestCase
from mayan.apps.documents.tests import GenericDocumentViewTestCase
from mayan.apps.metadata.models import MetadataType
-from mayan.apps.metadata.permissions import permission_metadata_document_edit
+from mayan.apps.metadata.permissions import permission_document_metadata_edit
from mayan.apps.metadata.tests.literals import (
TEST_METADATA_TYPE_LABEL, TEST_METADATA_TYPE_NAME,
)
from ..permissions import (
- permission_user_create, permission_user_delete, permission_user_edit
+ permission_group_create, permission_group_delete, permission_group_edit,
+ permission_group_view, permission_user_create, permission_user_delete,
+ permission_user_edit, permission_user_view
)
from .literals import (
- TEST_USER_PASSWORD_EDITED, TEST_USER_USERNAME, TEST_USER_2_USERNAME
+ TEST_GROUP_NAME, TEST_GROUP_NAME_EDITED, TEST_USER_PASSWORD_EDITED,
+ TEST_USER_USERNAME
)
-from .mixins import UserTestMixin
+from .mixins import GroupTestMixin, UserTestMixin
TEST_USER_TO_DELETE_USERNAME = 'user_to_delete'
-class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
- def setUp(self):
- super(UserManagementViewTestCase, self).setUp()
- self.login_user()
+class GroupViewsTestCase(GroupTestMixin, UserTestMixin, GenericViewTestCase):
+ def test_group_create_view_no_permission(self):
+ response = self._request_test_group_create_view()
+ self.assertEqual(response.status_code, 403)
+ self.assertEqual(Group.objects.count(), 1)
- #def _request_test_user_create_view(self):
- # return self.post(
- # viewname='user_management:user_create', data={
- # 'username': TEST_USER_2_USERNAME
- # }
- # )
+ def test_group_create_view_with_permission(self):
+ self.grant_permission(permission=permission_group_create)
+ response = self._request_test_group_create_view()
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(Group.objects.count(), 2)
+ def test_group_delete_view_no_permission(self):
+ self._create_test_group()
+ response = self._request_test_group_delete_view()
+ self.assertEqual(response.status_code, 404)
+ self.assertEqual(Group.objects.count(), 2)
+
+ def test_group_delete_view_with_access(self):
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_delete
+ )
+ response = self._request_test_group_delete_view()
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(Group.objects.count(), 1)
+
+ def test_group_edit_view_no_permission(self):
+ self._create_test_group()
+ response = self._request_test_group_edit_view()
+ self.assertEqual(response.status_code, 404)
+ self.test_group.refresh_from_db()
+ self.assertEqual(self.test_group.name, TEST_GROUP_NAME)
+
+ def test_group_edit_view_with_access(self):
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
+ response = self._request_test_group_edit_view()
+ self.assertEqual(response.status_code, 302)
+ self.test_group.refresh_from_db()
+ self.assertEqual(self.test_group.name, TEST_GROUP_NAME_EDITED)
+
+ def test_group_list_view_no_permission(self):
+ self._create_test_group()
+ response = self._request_test_group_list_view()
+ self.assertNotContains(
+ response=response, text=self.test_group.name, status_code=200
+ )
+
+ def test_group_list_view_with_permission(self):
+ self._create_test_group()
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_view
+ )
+ response = self._request_test_group_list_view()
+ self.assertContains(
+ response=response, text=self.test_group.name, status_code=200
+ )
+
+ def test_group_members_view_no_permission(self):
+ self._create_test_user()
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ response = self._request_test_group_members_view()
+ self.assertEqual(response.status_code, 404)
+
+ def test_group_members_view_with_group_access(self):
+ self._create_test_user()
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
+ response = self._request_test_group_members_view()
+ self.assertContains(
+ response=response, text=self.test_group.name, status_code=200
+ )
+ self.assertNotContains(
+ response=response, text=self.test_user.username, status_code=200
+ )
+
+ def test_group_members_view_with_user_access(self):
+ self._create_test_user()
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
+ response = self._request_test_group_members_view()
+ self.assertNotContains(
+ response=response, text=self.test_group.name, status_code=404
+ )
+
+ def test_group_members_view_with_full_access(self):
+ self._create_test_user()
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
+ response = self._request_test_group_members_view()
+ self.assertContains(
+ response=response, text=self.test_user.username, status_code=200
+ )
+ self.assertContains(
+ response=response, text=self.test_group.name, status_code=200
+ )
+
+
+class UserViewsTestCase(GroupTestMixin, UserTestMixin, GenericViewTestCase):
def test_user_create_view_no_permission(self):
+ user_count = get_user_model().objects.count()
+
response = self._request_test_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))
+
+ self.assertEqual(get_user_model().objects.count(), user_count)
+ self.assertFalse(TEST_USER_USERNAME in get_user_model().objects.values_list('username', flat=True))
def test_user_create_view_with_permission(self):
+ user_count = get_user_model().objects.count()
+
self.grant_permission(permission=permission_user_create)
response = self._request_test_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_user_groups_view(self):
- return self.post(
- viewname='user_management:user_groups', args=(self.test_user.pk,)
+ self.assertEqual(get_user_model().objects.count(), user_count + 1)
+ self.assertTrue(TEST_USER_USERNAME in get_user_model().objects.values_list('username', flat=True))
+
+ def test_user_delete_view_no_access(self):
+ self._create_test_user()
+ user_count = get_user_model().objects.count()
+
+ response = self._request_test_user_delete_view()
+ self.assertEqual(response.status_code, 404)
+
+ self.assertEqual(get_user_model().objects.count(), user_count)
+
+ def test_user_delete_view_with_access(self):
+ self._create_test_user()
+ user_count = get_user_model().objects.count()
+
+ self.grant_access(
+ obj=self.test_user, permission=permission_user_delete
)
+ response = self._request_test_user_delete_view()
+ self.assertEqual(response.status_code, 302)
+
+ self.assertEqual(get_user_model().objects.count(), user_count - 1)
+
+ def test_superuser_delete_view_with_access(self):
+ self._create_test_superuser()
+
+ superuser_count = get_user_model().objects.filter(is_superuser=True).count()
+ self.grant_access(
+ obj=self.test_superuser, permission=permission_user_delete
+ )
+ response = self._request_test_superuser_delete_view()
+ self.assertEqual(response.status_code, 404)
+ self.assertEqual(
+ get_user_model().objects.filter(is_superuser=True).count(),
+ superuser_count
+ )
+
+ def test_superuser_detail_view_with_access(self):
+ self._create_test_superuser()
+
+ self.grant_access(
+ obj=self.test_superuser, permission=permission_user_view
+ )
+ response = self._request_test_superuser_detail_view()
+ self.assertEqual(response.status_code, 404)
def test_user_groups_view_no_permission(self):
self._create_test_user()
- response = self._request_user_groups_view()
- self.assertEqual(response.status_code, 403)
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ response = self._request_test_user_groups_view()
+ self.assertEqual(response.status_code, 404)
- def test_user_groups_view_with_access(self):
+ def test_user_groups_view_with_group_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
+ response = self._request_test_user_groups_view()
+ self.assertNotContains(
+ response=response, text=self.test_user.username, status_code=404
+ )
- response = self._request_user_groups_view()
+ def test_user_groups_view_with_user_access(self):
+ self._create_test_user()
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
+ response = self._request_test_user_groups_view()
self.assertContains(
response=response, text=self.test_user.username, status_code=200
)
+ self.assertNotContains(
+ response=response, text=self.test_group.name, status_code=200
+ )
+
+ def test_user_groups_view_with_full_access(self):
+ self._create_test_user()
+ self._create_test_group()
+ self.test_user.groups.add(self.test_group)
+ self.grant_access(
+ obj=self.test_group, permission=permission_group_edit
+ )
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
+ response = self._request_test_user_groups_view()
+
+ self.assertContains(
+ response=response, text=self.test_user.username, status_code=200
+ )
+ self.assertContains(
+ response=response, text=self.test_group.name, status_code=200
+ )
def _request_set_password_view(self, password):
return self.post(
- viewname='user_management:user_set_password', args=(self.test_user.pk,),
+ viewname='user_management:user_set_password',
+ kwargs={'user_id': self.test_user.pk},
data={
'new_password1': password, 'new_password2': password
}
@@ -81,13 +264,14 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
password=TEST_USER_PASSWORD_EDITED
)
- self.assertEqual(response.status_code, 403)
+ self.assertEqual(response.status_code, 404)
self.logout()
with self.assertRaises(AssertionError):
self.login(
- username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
+ username=self.test_user.username,
+ password=TEST_USER_PASSWORD_EDITED
)
response = self.get(viewname='user_management:current_user_details')
@@ -96,7 +280,7 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
def test_user_set_password_view_with_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
response = self._request_set_password_view(
password=TEST_USER_PASSWORD_EDITED
@@ -106,7 +290,7 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
self.logout()
self.login(
- username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
+ username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD_EDITED
)
response = self.get(viewname='user_management:current_user_details')
@@ -128,13 +312,14 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
password=TEST_USER_PASSWORD_EDITED
)
- self.assertEqual(response.status_code, 403)
+ self.assertEqual(response.status_code, 404)
self.logout()
with self.assertRaises(AssertionError):
self.login(
- username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
+ username=self.test_user.username,
+ password=TEST_USER_PASSWORD_EDITED
)
response = self.get(viewname='user_management:current_user_details')
@@ -142,7 +327,7 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
def test_user_multiple_set_password_view_with_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_edit, obj=self.test_user)
+ self.grant_access(obj=self.test_user, permission=permission_user_edit)
response = self._request_multiple_user_set_password_view(
password=TEST_USER_PASSWORD_EDITED
@@ -152,30 +337,12 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
self.logout()
self.login(
- username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED
+ username=self.test_user.username, password=TEST_USER_PASSWORD_EDITED
)
response = self.get(viewname='user_management:current_user_details')
self.assertEqual(response.status_code, 200)
- def _request_user_delete_view(self):
- return self.post(
- viewname='user_management:user_delete', args=(self.test_user.pk,)
- )
-
- def test_user_delete_view_no_access(self):
- self._create_test_user()
- response = self._request_user_delete_view()
- self.assertEqual(response.status_code, 302)
- self.assertEqual(get_user_model().objects.count(), 3)
-
- def test_user_delete_view_with_access(self):
- self._create_test_user()
- self.grant_access(permission=permission_user_delete, obj=self.test_user)
- response = self._request_user_delete_view()
- 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={
@@ -185,16 +352,24 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase):
def test_user_multiple_delete_view_no_access(self):
self._create_test_user()
+ user_count = get_user_model().objects.count()
+
response = self._request_user_multiple_delete_view()
- self.assertEqual(response.status_code, 302)
- self.assertEqual(get_user_model().objects.count(), 3)
+ self.assertEqual(response.status_code, 404)
+
+ self.assertEqual(get_user_model().objects.count(), user_count)
def test_user_multiple_delete_view_with_access(self):
self._create_test_user()
- self.grant_access(permission=permission_user_delete, obj=self.test_user)
+ user_count = get_user_model().objects.count()
+
+ self.grant_access(
+ obj=self.test_user, permission=permission_user_delete
+ )
response = self._request_user_multiple_delete_view()
self.assertEqual(response.status_code, 302)
- self.assertEqual(get_user_model().objects.count(), 2)
+
+ self.assertEqual(get_user_model().objects.count(), user_count - 1)
class MetadataLookupIntegrationTestCase(GenericDocumentViewTestCase):
@@ -212,13 +387,13 @@ class MetadataLookupIntegrationTestCase(GenericDocumentViewTestCase):
self.metadata_type.lookup = '{{ users }}'
self.metadata_type.save()
self.document.metadata.create(metadata_type=self.metadata_type)
- self.role.permissions.add(
- permission_metadata_document_edit.stored_permission
+ self.grant_access(
+ obj=self.document, permission=permission_document_metadata_edit
)
response = self.get(
viewname='metadata:document_metadata_edit',
- kwargs={'pk': self.document.pk}
+ kwargs={'document_id': self.document.pk}
)
self.assertContains(
response=response, text=''.format(
@@ -230,13 +405,13 @@ class MetadataLookupIntegrationTestCase(GenericDocumentViewTestCase):
self.metadata_type.lookup = '{{ groups }}'
self.metadata_type.save()
self.document.metadata.create(metadata_type=self.metadata_type)
- self.role.permissions.add(
- permission_metadata_document_edit.stored_permission
+ self.grant_access(
+ obj=self.document, permission=permission_document_metadata_edit
)
response = self.get(
viewname='metadata:document_metadata_edit',
- kwargs={'pk': self.document.pk}
+ kwargs={'document_id': self.document.pk}
)
self.assertContains(
diff --git a/mayan/apps/user_management/urls.py b/mayan/apps/user_management/urls.py
index 20a94f1d7b..a0c103277e 100644
--- a/mayan/apps/user_management/urls.py
+++ b/mayan/apps/user_management/urls.py
@@ -14,76 +14,93 @@ from .views import (
)
urlpatterns = [
- url(r'^groups/list/$', GroupListView.as_view(), name='group_list'),
- url(r'^groups/create/$', GroupCreateView.as_view(), name='group_create'),
url(
- r'^groups/(?P\d+)/edit/$', GroupEditView.as_view(),
- name='group_edit'
+ regex=r'^groups/$', name='group_list', view=GroupListView.as_view()
),
url(
- r'^groups/(?P\d+)/delete/$', GroupDeleteView.as_view(),
- name='group_delete'
+ regex=r'^groups/create/$', name='group_create',
+ view=GroupCreateView.as_view()
),
url(
- r'^groups/(?P\d+)/members/$', GroupMembersView.as_view(),
- name='group_members'
- ),
-
- url(
- r'^users/current/$', CurrentUserDetailsView.as_view(),
- name='current_user_details'
+ regex=r'^groups/(?P\d+)/delete/$', name='group_delete',
+ view=GroupDeleteView.as_view()
),
url(
- r'^users/current/edit/$', CurrentUserEditView.as_view(),
- name='current_user_edit'
- ),
- url(r'^users/list/$', UserListView.as_view(), name='user_list'),
- url(r'^users/create/$', UserCreateView.as_view(), name='user_create'),
- url(
- r'^users/(?P\d+)/delete/$', UserDeleteView.as_view(),
- name='user_delete'
- ),
- url(r'^users/(?P\d+)/edit/$', UserEditView.as_view(), name='user_edit'),
- url(
- r'^users/(?P\d+)/$', UserDetailsView.as_view(),
- name='user_details'
+ regex=r'^groups/(?P\d+)/edit/$', name='group_edit',
+ view=GroupEditView.as_view()
),
url(
- r'^users/multiple/delete/$', UserDeleteView.as_view(),
- name='user_multiple_delete'
+ regex=r'^groups/(?P\d+)/members/$', name='group_members',
+ view=GroupMembersView.as_view()
),
url(
- r'^users/(?P\d+)/set_password/$', UserSetPasswordView.as_view(),
- name='user_set_password'
+ regex=r'^user/$', name='current_user_details',
+ view=CurrentUserDetailsView.as_view()
),
url(
- r'^users/multiple/set_password/$', UserSetPasswordView.as_view(),
- name='user_multiple_set_password'
+ regex=r'^user/edit/$', name='current_user_edit',
+ view=CurrentUserEditView.as_view()
),
url(
- r'^users/(?P\d+)/groups/$', UserGroupsView.as_view(),
- name='user_groups'
+ regex=r'^users/$', name='user_list', view=UserListView.as_view()
),
url(
- r'^users/(?P\d+)/options/$',
- UserOptionsEditView.as_view(),
- name='user_options'
+ regex=r'^users/create/$', name='user_create',
+ view=UserCreateView.as_view()
),
+ url(
+ regex=r'^users/(?P\d+)/$', name='user_details',
+ view=UserDetailsView.as_view()
+ ),
+ url(
+ regex=r'^users/(?P\d+)/delete/$', name='user_delete',
+ view=UserDeleteView.as_view(),
+ ),
+ url(
+ regex=r'^users/(?P\d+)/edit/$', name='user_edit',
+ view=UserEditView.as_view()
+ ),
+ url(
+ regex=r'^users/(?P\d+)/groups/$', name='user_groups',
+ view=UserGroupsView.as_view()
+ ),
+ url(
+ regex=r'^users/(?P\d+)/options/$', name='user_options',
+ view=UserOptionsEditView.as_view()
+ ),
+ url(
+ regex=r'^users/(?P\d+)/set_password/$',
+ name='user_set_password', view=UserSetPasswordView.as_view()
+ ),
+ url(
+ regex=r'^users/multiple/delete/$', name='user_multiple_delete',
+ view=UserDeleteView.as_view()
+ ),
+ url(
+ regex=r'^users/multiple/set_password/$',
+ name='user_multiple_set_password', view=UserSetPasswordView.as_view()
+ )
]
api_urls = [
- url(r'^groups/$', APIGroupListView.as_view(), name='group-list'),
url(
- r'^groups/(?P[0-9]+)/$', APIGroupView.as_view(),
- name='group-detail'
- ),
- url(r'^users/$', APIUserListView.as_view(), name='user-list'),
- url(r'^users/(?P[0-9]+)/$', APIUserView.as_view(), name='user-detail'),
- url(
- r'^users/current/$', APICurrentUserView.as_view(), name='user-current'
+ regex=r'^groups/$', name='group-list', view=APIGroupListView.as_view()
),
url(
- r'^users/(?P[0-9]+)/groups/$', APIUserGroupList.as_view(),
- name='users-group-list'
+ regex=r'^groups/(?P\d+)/$', name='group-detail',
+ view=APIGroupView.as_view(),
+ ),
+ url(
+ regex=r'^user/$', name='user-current',
+ view=APICurrentUserView.as_view()
+ ),
+ url(regex=r'^users/$', name='user-list', view=APIUserListView.as_view()),
+ url(
+ regex=r'^users/(?P\d+)/$', name='user-detail',
+ view=APIUserView.as_view()
+ ),
+ url(
+ regex=r'^users/(?P\d+)/groups/$', name='users-group-list',
+ view=APIUserGroupList.as_view()
),
]
diff --git a/mayan/apps/user_management/utils.py b/mayan/apps/user_management/utils.py
index 5d5f689609..4c3b74fafe 100644
--- a/mayan/apps/user_management/utils.py
+++ b/mayan/apps/user_management/utils.py
@@ -5,22 +5,22 @@ from django.contrib.auth import get_user_model
from django.utils.translation import ugettext_lazy as _
-def get_groups():
+def get_user_label_text(context):
+ if not context['request'].user.is_authenticated:
+ return _('Anonymous')
+ else:
+ return context['request'].user.get_full_name() or context['request'].user
+
+
+def lookup_get_groups():
Group = apps.get_model(app_label='auth', model_name='Group')
return ','.join([group.name for group in Group.objects.all()])
-def get_users():
+def lookup_get_users():
return ','.join(
[
user.get_full_name() or user.username
for user in get_user_model().objects.all()
]
)
-
-
-def get_user_label_text(context):
- if not context['request'].user.is_authenticated:
- return _('Anonymous')
- else:
- return context['request'].user.get_full_name() or context['request'].user
diff --git a/mayan/apps/user_management/views.py b/mayan/apps/user_management/views.py
index 14cc8d6536..9cdd9fefd0 100644
--- a/mayan/apps/user_management/views.py
+++ b/mayan/apps/user_management/views.py
@@ -5,19 +5,21 @@ from django.contrib.auth import get_user_model
from django.contrib.auth.forms import SetPasswordForm
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
-from django.core.exceptions import PermissionDenied
+from django.db import transaction
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.template import RequestContext
from django.urls import reverse, reverse_lazy
from django.utils.translation import ungettext, ugettext_lazy as _
-from mayan.apps.common.views import (
+from mayan.apps.acls.models import AccessControlList
+from mayan.apps.common.generics import (
AssignRemoveView, MultipleObjectConfirmActionView,
MultipleObjectFormActionView, SingleObjectCreateView,
SingleObjectDeleteView, SingleObjectDetailView, SingleObjectEditView,
SingleObjectListView
)
+from mayan.apps.common.mixins import ExternalObjectMixin
from .events import (
event_group_created, event_group_edited, event_user_created,
@@ -52,7 +54,9 @@ class CurrentUserDetailsView(SingleObjectDetailView):
class CurrentUserEditView(SingleObjectEditView):
extra_context = {'object': None, 'title': _('Edit current user details')}
form_class = UserForm
- post_action_redirect = reverse_lazy('user_management:current_user_details')
+ post_action_redirect = reverse_lazy(
+ viewname='user_management:current_user_details'
+ )
def get_object(self):
return self.request.user
@@ -62,38 +66,50 @@ class GroupCreateView(SingleObjectCreateView):
extra_context = {'title': _('Create new group')}
fields = ('name',)
model = Group
- post_action_redirect = reverse_lazy('user_management:group_list')
+ post_action_redirect = reverse_lazy(viewname='user_management:group_list')
view_permission = permission_group_create
def form_valid(self, form):
- group = form.save()
+ with transaction.atomic():
+ result = super(GroupCreateView, self).form_valid(form=form)
+ event_group_created.commit(
+ actor=self.request.user, target=self.object
+ )
+ return result
- event_group_created.commit(
- actor=self.request.user, target=group
- )
- messages.success(
- self.request, _('Group "%s" created successfully.') % group
- )
- return super(GroupCreateView, self).form_valid(form=form)
+class GroupDeleteView(SingleObjectDeleteView):
+ model = Group
+ object_permission = permission_group_delete
+ pk_url_kwarg = 'group_id'
+ post_action_redirect = reverse_lazy(viewname='user_management:group_list')
+
+ def get_extra_context(self):
+ return {
+ 'object': self.object,
+ 'title': _('Delete the group: %s?') % self.object,
+ }
class GroupEditView(SingleObjectEditView):
fields = ('name',)
model = Group
object_permission = permission_group_edit
- post_action_redirect = reverse_lazy('user_management:group_list')
+ pk_url_kwarg = 'group_id'
+ post_action_redirect = reverse_lazy(viewname='user_management:group_list')
def form_valid(self, form):
- event_group_edited.commit(
- actor=self.request.user, target=self.get_object()
- )
- return super(GroupEditView, self).form_valid(form=form)
+ with transaction.atomic():
+ result = super(GroupEditView, self).form_valid(form=form)
+ event_group_edited.commit(
+ actor=self.request.user, target=self.object
+ )
+ return result
def get_extra_context(self):
return {
- 'object': self.get_object(),
- 'title': _('Edit group: %s') % self.get_object(),
+ 'object': self.object,
+ 'title': _('Edit group: %s') % self.object,
}
@@ -120,29 +136,20 @@ class GroupListView(SingleObjectListView):
}
-class GroupDeleteView(SingleObjectDeleteView):
- model = Group
- object_permission = permission_group_delete
- post_action_redirect = reverse_lazy('user_management:group_list')
-
- def get_extra_context(self):
- return {
- 'object': self.get_object(),
- 'title': _('Delete the group: %s?') % self.get_object(),
- }
-
-
-class GroupMembersView(AssignRemoveView):
+class GroupMembersView(ExternalObjectMixin, AssignRemoveView):
decode_content_type = True
+ external_object_class = Group
+ external_object_permission = permission_group_edit
+ external_object_pk_url_kwarg = 'group_id'
left_list_title = _('Available users')
- right_list_title = _('Users in group')
object_permission = permission_group_edit
+ right_list_title = _('Users in group')
@staticmethod
def generate_choices(choices):
results = []
for choice in choices:
- ct = ContentType.objects.get_for_model(choice)
+ ct = ContentType.objects.get_for_model(model=choice)
label = choice.get_full_name() if choice.get_full_name() else choice
results.append(('%s,%s' % (ct.model, choice.pk), '%s' % (label)))
@@ -151,31 +158,43 @@ class GroupMembersView(AssignRemoveView):
return sorted(results, key=lambda x: x[1])
def add(self, item):
- self.get_object().user_set.add(item)
+ self.object.user_set.add(item)
+
+ def dispatch(self, *args, **kwargs):
+ self.object = self.get_object()
+ return super(GroupMembersView, self).dispatch(*args, **kwargs)
def get_extra_context(self):
return {
- 'object': self.get_object(),
- 'title': _('Users of group: %s') % self.get_object()
+ 'object': self.object,
+ 'title': _('Users of group: %s') % self.object
}
def get_object(self):
- return get_object_or_404(klass=Group, pk=self.kwargs['pk'])
+ return self.get_external_object()
def left_list(self):
- return GroupMembersView.generate_choices(
- get_user_model().objects.exclude(
- groups=self.get_object()
- ).exclude(is_staff=True).exclude(is_superuser=True)
+ queryset = AccessControlList.objects.restrict_queryset(
+ permission=permission_user_edit,
+ queryset=get_user_model().objects.exclude(
+ groups=self.object
+ ).exclude(is_staff=True).exclude(is_superuser=True),
+ user=self.request.user
)
+ return GroupMembersView.generate_choices(choices=queryset)
+
def right_list(self):
- return GroupMembersView.generate_choices(
- self.get_object().user_set.all()
+ queryset = AccessControlList.objects.restrict_queryset(
+ permission=permission_user_edit,
+ queryset=self.object.user_set.all(),
+ user=self.request.user
)
+ return GroupMembersView.generate_choices(choices=queryset)
+
def remove(self, item):
- self.get_object().user_set.remove(item)
+ self.object.user_set.remove(item)
class UserCreateView(SingleObjectCreateView):
@@ -186,25 +205,24 @@ class UserCreateView(SingleObjectCreateView):
view_permission = permission_user_create
def form_valid(self, form):
- user = form.save(commit=False)
- user.set_unusable_password()
- user.save()
+ with transaction.atomic():
+ super(UserCreateView, self).form_valid(form=form)
+ event_user_created.commit(
+ actor=self.request.user, target=self.object
+ )
- event_user_created.commit(
- actor=self.request.user, target=user
- )
-
- messages.success(
- self.request, _('User "%s" created successfully.') % user
- )
return HttpResponseRedirect(
- reverse('user_management:user_set_password', args=(user.pk,))
+ reverse(
+ viewname='user_management:user_set_password',
+ kwargs={'user_id': self.object.pk}
+ )
)
class UserDeleteView(MultipleObjectConfirmActionView):
object_permission = permission_user_delete
- queryset = get_user_model().objects.filter(
+ pk_url_kwarg = 'user_id'
+ source_queryset = get_user_model().objects.filter(
is_superuser=False, is_staff=False
)
success_message = _('User delete request performed on %(count)d user')
@@ -213,13 +231,13 @@ class UserDeleteView(MultipleObjectConfirmActionView):
)
def get_extra_context(self):
- queryset = self.get_queryset()
+ queryset = self.get_object_list()
result = {
'title': ungettext(
- 'Delete user',
- 'Delete users',
- queryset.count()
+ singular='Delete user',
+ plural='Delete users',
+ number=queryset.count()
)
}
@@ -235,26 +253,18 @@ class UserDeleteView(MultipleObjectConfirmActionView):
def object_action(self, form, instance):
try:
- if instance.is_superuser or instance.is_staff:
- messages.error(
- self.request,
- _(
- 'Super user and staff user deleting is not '
- 'allowed, use the admin interface for these cases.'
- )
- )
- else:
- instance.delete()
- messages.success(
- self.request, _(
- 'User "%s" deleted successfully.'
- ) % instance
- )
+ instance.delete()
+ messages.success(
+ message=_(
+ 'User "%s" deleted successfully.'
+ ) % instance, request=self.request
+ )
except Exception as exception:
messages.error(
- self.request, _(
+ message=_(
'Error deleting user "%(user)s": %(error)s'
- ) % {'user': instance, 'error': exception}
+ ) % {'user': instance, 'error': exception},
+ request=self.request
)
@@ -264,7 +274,8 @@ class UserDetailsView(SingleObjectDetailView):
'date_joined', 'groups',
)
object_permission = permission_user_view
- queryset = get_user_model().objects.filter(
+ pk_url_kwarg = 'user_id'
+ source_queryset = get_user_model().objects.filter(
is_superuser=False, is_staff=False
)
@@ -278,58 +289,72 @@ class UserDetailsView(SingleObjectDetailView):
class UserEditView(SingleObjectEditView):
fields = ('username', 'first_name', 'last_name', 'email', 'is_active',)
object_permission = permission_user_edit
- post_action_redirect = reverse_lazy('user_management:user_list')
- queryset = get_user_model().objects.filter(
+ pk_url_kwarg = 'user_id'
+ post_action_redirect = reverse_lazy(viewname='user_management:user_list')
+ source_queryset = get_user_model().objects.filter(
is_superuser=False, is_staff=False
)
def form_valid(self, form):
- event_user_edited.commit(
- actor=self.request.user, target=self.get_object()
- )
- return super(UserEditView, self).form_valid(form=form)
+ with transaction.atomic():
+ result = super(UserEditView, self).form_valid(form=form)
+ event_user_edited.commit(
+ actor=self.request.user, target=self.object
+ )
+
+ return result
def get_extra_context(self):
return {
- 'object': self.get_object(),
- 'title': _('Edit user: %s') % self.get_object(),
+ 'object': self.object,
+ 'title': _('Edit user: %s') % self.object,
}
-class UserGroupsView(AssignRemoveView):
+class UserGroupsView(ExternalObjectMixin, AssignRemoveView):
decode_content_type = True
+ external_object_queryset = get_user_model().objects.filter(
+ is_staff=False, is_superuser=False
+ )
+ external_object_permission = permission_user_edit
+ external_object_pk_url_kwarg = 'user_id'
left_list_title = _('Available groups')
right_list_title = _('Groups joined')
- object_permission = permission_user_edit
def add(self, item):
- item.user_set.add(self.get_object())
+ item.user_set.add(self.object)
+
+ def dispatch(self, *args, **kwargs):
+ self.object = self.get_object()
+ return super(UserGroupsView, self).dispatch(*args, **kwargs)
def get_extra_context(self):
return {
- 'object': self.get_object(),
- 'title': _('Groups of user: %s') % self.get_object()
+ 'object': self.object,
+ 'title': _('Groups of user: %s') % self.object
}
def get_object(self):
- return get_object_or_404(
- klass=get_user_model().objects.filter(
- is_superuser=False, is_staff=False
- ), pk=self.kwargs['pk']
- )
+ return self.get_external_object()
def left_list(self):
- return AssignRemoveView.generate_choices(
- Group.objects.exclude(user=self.get_object())
+ queryset = AccessControlList.objects.restrict_queryset(
+ permission=permission_group_edit,
+ queryset=Group.objects.exclude(user=self.object),
+ user=self.request.user
)
+ return AssignRemoveView.generate_choices(choices=queryset)
def right_list(self):
- return AssignRemoveView.generate_choices(
- Group.objects.filter(user=self.get_object())
+ queryset = AccessControlList.objects.restrict_queryset(
+ permission=permission_group_edit,
+ queryset=Group.objects.filter(user=self.object),
+ user=self.request.user
)
+ return AssignRemoveView.generate_choices(choices=queryset)
def remove(self, item):
- item.user_set.remove(self.get_object())
+ item.user_set.remove(self.object)
class UserListView(SingleObjectListView):
@@ -350,7 +375,7 @@ class UserListView(SingleObjectListView):
'title': _('Users'),
}
- def get_object_list(self):
+ def get_source_queryset(self):
return get_user_model().objects.exclude(
is_superuser=True
).exclude(is_staff=True).order_by('last_name', 'first_name')
@@ -372,13 +397,13 @@ class UserOptionsEditView(SingleObjectEditView):
return self.get_user().user_options
def get_post_action_redirect(self):
- return reverse('user_management:user_list')
+ return reverse(viewname='user_management:user_list')
def get_user(self):
return get_object_or_404(
klass=get_user_model().objects.filter(
is_superuser=False, is_staff=False
- ), pk=self.kwargs['pk']
+ ), pk=self.kwargs['user_id']
)
@@ -386,66 +411,57 @@ class UserSetPasswordView(MultipleObjectFormActionView):
form_class = SetPasswordForm
model = get_user_model()
object_permission = permission_user_edit
+ pk_url_kwarg = 'user_id'
+ source_queryset = get_user_model().objects.filter(
+ is_superuser=False, is_staff=False
+ )
success_message = _('Password change request performed on %(count)d user')
success_message_plural = _(
'Password change request performed on %(count)d users'
)
def get_extra_context(self):
- queryset = self.get_queryset()
+ queryset = self.get_object_list()
result = {
'submit_label': _('Submit'),
'title': ungettext(
- 'Change user password',
- 'Change users passwords',
- queryset.count()
- )
+ singular='Change the password of the %(count)d selected user',
+ plural='Change the password of the %(count)d selected users',
+ number=queryset.count()
+ ) % {'count': queryset.count()}
}
if queryset.count() == 1:
result.update(
{
'object': queryset.first(),
- 'title': _('Change password for user: %s') % queryset.first()
+ 'title': _(
+ 'Change the password of user: %s'
+ ) % queryset.first()
}
)
return result
def get_form_extra_kwargs(self):
- queryset = self.get_queryset()
- result = {}
- if queryset:
- result['user'] = queryset.first()
- return result
- else:
- raise PermissionDenied
+ queryset = self.get_object_list()
+ return {'user': queryset.first()}
def object_action(self, form, instance):
try:
- if instance.is_superuser or instance.is_staff:
- messages.error(
- self.request,
- _(
- 'Super user and staff user password '
- 'reseting is not allowed, use the admin '
- 'interface for these cases.'
- )
- )
- else:
- instance.set_password(form.cleaned_data['new_password1'])
- instance.save()
- messages.success(
- self.request, _(
- 'Successful password reset for user: %s.'
- ) % instance
- )
+ instance.set_password(form.cleaned_data['new_password1'])
+ instance.save()
+ messages.success(
+ message=_(
+ 'Successful password reset for user: %s.'
+ ) % instance, request=self.request
+ )
except Exception as exception:
messages.error(
- self.request, _(
+ message=_(
'Error reseting password for user "%(user)s": %(error)s'
) % {
'user': instance, 'error': exception
- }
+ }, request=self.request
)