Skip to content

Commit 74dcc99

Browse files
author
Matthew Fisher
committed
Merge pull request #4147 from Joshua-Anderson/admin-user-cancelation
feat(controller): allow admins to delete users
2 parents e2438e4 + a2b23fd commit 74dcc99

2 files changed

Lines changed: 49 additions & 7 deletions

File tree

api/tests/test_auth.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,31 @@ def test_cancel(self):
170170
"""Test that a registered user can cancel her account."""
171171
# test registration workflow
172172
username, password = 'newuser', 'password'
173-
first_name, last_name = 'Otto', 'Test'
174-
email = 'autotest@deis.io'
175173
submit = {
176174
'username': username,
177175
'password': password,
178-
'first_name': first_name,
179-
'last_name': last_name,
180-
'email': email,
176+
'first_name': 'Otto',
177+
'last_name': 'Test',
178+
'email': 'autotest@deis.io',
181179
# try to abuse superuser/staff level perms
182180
'is_superuser': True,
183181
'is_staff': True,
184182
}
183+
184+
other_username, other_password = 'newuser2', 'password'
185+
other_submit = {
186+
'username': other_username,
187+
'password': other_password,
188+
'first_name': 'Test',
189+
'last_name': 'Tester',
190+
'email': 'autotest-2@deis.io',
191+
'is_superuser': False,
192+
'is_staff': False,
193+
}
185194
url = '/v1/auth/register'
186195
response = self.client.post(url, json.dumps(submit), content_type='application/json')
187196
self.assertEqual(response.status_code, 201)
197+
188198
# cancel the account
189199
url = '/v1/auth/cancel'
190200
user = User.objects.get(username=username)
@@ -193,6 +203,25 @@ def test_cancel(self):
193203
HTTP_AUTHORIZATION='token {}'.format(token))
194204
self.assertEqual(response.status_code, 204)
195205

206+
url = '/v1/auth/register'
207+
response = self.client.post(url, json.dumps(other_submit), content_type='application/json')
208+
self.assertEqual(response.status_code, 201)
209+
210+
# normal user can't delete another user
211+
url = '/v1/auth/cancel'
212+
other_user = User.objects.get(username=other_username)
213+
other_token = Token.objects.get(user=other_user).key
214+
response = self.client.delete(url, json.dumps({'username': self.admin.username}),
215+
content_type='application/json',
216+
HTTP_AUTHORIZATION='token {}'.format(other_token))
217+
self.assertEqual(response.status_code, 403)
218+
219+
# admin can delete another user
220+
response = self.client.delete(url, json.dumps({'username': other_username}),
221+
content_type='application/json',
222+
HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
223+
self.assertEqual(response.status_code, 204)
224+
196225
def test_passwd(self):
197226
"""Test that a registered user can change the password."""
198227
# test registration workflow

api/views.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ class UserRegistrationViewSet(GenericViewSet,
2626
serializer_class = serializers.UserSerializer
2727

2828

29-
class UserManagementViewSet(GenericViewSet,
30-
mixins.DestroyModelMixin):
29+
class UserManagementViewSet(GenericViewSet):
3130
serializer_class = serializers.UserSerializer
3231

3332
def get_queryset(self):
@@ -36,6 +35,20 @@ def get_queryset(self):
3635
def get_object(self):
3736
return self.get_queryset()[0]
3837

38+
def destroy(self, request, **kwargs):
39+
calling_obj = self.get_object()
40+
target_obj = calling_obj
41+
42+
if request.data.get('username'):
43+
# if you "accidentally" target yourself, that should be fine
44+
if calling_obj.username == request.data['username'] or calling_obj.is_superuser:
45+
target_obj = get_object_or_404(User, username=request.data['username'])
46+
else:
47+
raise PermissionDenied()
48+
49+
target_obj.delete()
50+
return Response(status=status.HTTP_204_NO_CONTENT)
51+
3952
def passwd(self, request, **kwargs):
4053
caller_obj = self.get_object()
4154
target_obj = self.get_object()

0 commit comments

Comments
 (0)