From cb220718864353eaaafaa2ae76a299ca31a90611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Sat, 9 Jan 2016 11:59:34 +0100 Subject: [PATCH] Added lockout protection, see #1452. --- openslides/users/views.py | 15 ++++++++++++++ tests/integration/users/test_viewset.py | 27 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/openslides/users/views.py b/openslides/users/views.py index 104afef1d..33936246a 100644 --- a/openslides/users/views.py +++ b/openslides/users/views.py @@ -105,6 +105,9 @@ class UserViewSet(ModelViewSet): # Check manager perms if (request.user.has_perm('users.can_see_extra_data') and request.user.has_perm('users.can_manage')): + if request.data.get('is_active') is False and self.get_object() == request.user: + # A user can not deactivate himself. + raise ValidationError({'detail': _('You can not deactivate yourself.')}) response = super().update(request, *args, **kwargs) else: # Get user. @@ -134,6 +137,18 @@ class UserViewSet(ModelViewSet): response = Response(serializer.data) return response + def destroy(self, request, *args, **kwargs): + """ + Customized view endpoint to delete an user. + + Ensures that no one can delete himself. + """ + instance = self.get_object() + if instance == self.request.user: + raise ValidationError({'detail': _('You can not delete yourself.')}) + self.perform_destroy(instance) + return Response(status=status.HTTP_204_NO_CONTENT) + @detail_route(methods=['post']) def reset_password(self, request, pk=None): """ diff --git a/tests/integration/users/test_viewset.py b/tests/integration/users/test_viewset.py index 2650cb702..9e36c9516 100644 --- a/tests/integration/users/test_viewset.py +++ b/tests/integration/users/test_viewset.py @@ -112,6 +112,23 @@ class UserUpdate(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.get(pk=1).username, 'New name Ohy4eeyei5') + def test_update_deactivate_yourselfself(self): + """ + Tests that an user can not deactivate himself. + """ + admin_client = APIClient() + admin_client.login(username='admin', password='admin') + # This is the builtin user 'Administrator'. The pk is valid. + user_pk = 1 + + response = admin_client.patch( + reverse('user-detail', args=[user_pk]), + {'username': 'admin', + 'is_active': False}, + format='json') + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + class UserDelete(TestCase): """ @@ -127,6 +144,16 @@ class UserDelete(TestCase): self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertFalse(User.objects.filter(username='Test name bo3zieT3iefahng0ahqu').exists()) + def test_delete_yourself(self): + admin_client = APIClient() + admin_client.login(username='admin', password='admin') + # This is the builtin user 'Administrator'. The pk is valid. + admin_user_pk = 1 + + response = admin_client.delete(reverse('user-detail', args=[admin_user_pk])) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + class UserResetPassword(TestCase): """