Skip to content

Commit 69db1db

Browse files
author
Joshua Anderson
committed
feat(controller): allow admins to change a user's password.
1 parent e187255 commit 69db1db

3 files changed

Lines changed: 21 additions & 14 deletions

File tree

api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
The **api** Django app presents a RESTful web API for interacting with the **deis** system.
33
"""
44

5-
__version__ = '1.5.0'
5+
__version__ = '1.6.0'

api/tests/test_auth.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,11 @@ def test_change_user_passwd(self):
251251
new_password = 'password'
252252
submit = {
253253
'username': self.user1.username,
254-
'password': old_password,
255254
'new_password': new_password,
256255
}
257256
response = self.client.post(url, json.dumps(submit), content_type='application/json',
258257
HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
259-
self.assertEqual(response.status_code, 400)
258+
self.assertEqual(response.status_code, 200)
260259
# test login with old password
261260
url = '/v1/auth/login/'
262261
payload = urllib.urlencode({'username': self.user1.username, 'password': old_password})
@@ -268,16 +267,22 @@ def test_change_user_passwd(self):
268267
response = self.client.post(url, data=payload,
269268
content_type='application/x-www-form-urlencoded')
270269
self.assertEqual(response.status_code, 200)
271-
# try to change back password with a regular user
272-
submit['password'], submit['new_password'] = submit['new_password'], submit['password']
270+
# Non-admins can't change another user's password
271+
submit['password'], submit['new_password'] = submit['new_password'], old_password
273272
url = '/v1/auth/passwd'
274273
response = self.client.post(url, json.dumps(submit), content_type='application/json',
275274
HTTP_AUTHORIZATION='token {}'.format(self.user2_token))
276275
self.assertEqual(response.status_code, 403)
277-
# however, targeting yourself should be fine.
276+
# change back password with a regular user
278277
response = self.client.post(url, json.dumps(submit), content_type='application/json',
279278
HTTP_AUTHORIZATION='token {}'.format(self.user1_token))
280279
self.assertEqual(response.status_code, 200)
280+
# test login with new password
281+
url = '/v1/auth/login/'
282+
payload = urllib.urlencode({'username': self.user1.username, 'password': old_password})
283+
response = self.client.post(url, data=payload,
284+
content_type='application/x-www-form-urlencoded')
285+
self.assertEqual(response.status_code, 200)
281286

282287
def test_regenerate(self):
283288
""" Test that token regeneration works"""

api/views.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,20 @@ def get_object(self):
3737
return self.get_queryset()[0]
3838

3939
def passwd(self, request, **kwargs):
40-
obj = self.get_object()
40+
caller_obj = self.get_object()
41+
target_obj = self.get_object()
4142
if request.data.get('username'):
4243
# if you "accidentally" target yourself, that should be fine
43-
if obj.username == request.data['username'] or obj.is_superuser:
44-
obj = get_object_or_404(User, username=request.data['username'])
44+
if caller_obj.username == request.data['username'] or caller_obj.is_superuser:
45+
target_obj = get_object_or_404(User, username=request.data['username'])
4546
else:
4647
raise PermissionDenied()
47-
if not obj.check_password(request.data['password']):
48-
return Response({'detail': 'Current password does not match'},
49-
status=status.HTTP_400_BAD_REQUEST)
50-
obj.set_password(request.data['new_password'])
51-
obj.save()
48+
if request.data.get('password') or not caller_obj.is_superuser:
49+
if not target_obj.check_password(request.data['password']):
50+
return Response({'detail': 'Current password does not match'},
51+
status=status.HTTP_400_BAD_REQUEST)
52+
target_obj.set_password(request.data['new_password'])
53+
target_obj.save()
5254
return Response({'status': 'password set'})
5355

5456

0 commit comments

Comments
 (0)