Skip to content

Commit d271997

Browse files
committed
feat(controller): add "deis auth:passwd" to update password
1 parent e7b3686 commit d271997

3 files changed

Lines changed: 65 additions & 4 deletions

File tree

api/tests/test_auth.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,49 @@ def test_cancel(self):
9999
response = self.client.delete(url,
100100
HTTP_AUTHORIZATION='token {}'.format(token))
101101
self.assertEqual(response.status_code, 204)
102+
103+
def test_passwd(self):
104+
"""Test that a registered user can change the password."""
105+
# test registration workflow
106+
username, password = 'newuser', 'password'
107+
first_name, last_name = 'Otto', 'Test'
108+
email = 'autotest@deis.io'
109+
submit = {
110+
'username': username,
111+
'password': password,
112+
'first_name': first_name,
113+
'last_name': last_name,
114+
'email': email,
115+
}
116+
url = '/v1/auth/register'
117+
response = self.client.post(url, json.dumps(submit), content_type='application/json')
118+
self.assertEqual(response.status_code, 201)
119+
# change password
120+
url = '/v1/auth/passwd'
121+
user = User.objects.get(username=username)
122+
token = Token.objects.get(user=user).key
123+
submit = {
124+
'password': 'password2',
125+
'new_password': password,
126+
}
127+
response = self.client.post(url, json.dumps(submit), content_type='application/json',
128+
HTTP_AUTHORIZATION='token {}'.format(token))
129+
self.assertEqual(response.status_code, 400)
130+
submit = {
131+
'password': password,
132+
'new_password': 'password2',
133+
}
134+
response = self.client.post(url, json.dumps(submit), content_type='application/json',
135+
HTTP_AUTHORIZATION='token {}'.format(token))
136+
self.assertEqual(response.status_code, 200)
137+
# test login with old password
138+
url = '/v1/auth/login/'
139+
payload = urllib.urlencode({'username': username, 'password': password})
140+
response = self.client.post(url, data=payload,
141+
content_type='application/x-www-form-urlencoded')
142+
self.assertEqual(response.status_code, 400)
143+
# test login with new password
144+
payload = urllib.urlencode({'username': username, 'password': 'password2'})
145+
response = self.client.post(url, data=payload,
146+
content_type='application/x-www-form-urlencoded')
147+
self.assertEqual(response.status_code, 200)

api/urls.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,14 @@
169169
170170
Create a new User.
171171
172-
.. http:delete:: /v1/auth/register/
172+
.. http:delete:: /v1/auth/cancel/
173173
174174
Destroy the logged-in User.
175175
176+
.. http:post:: /v1/auth/passwd/
177+
178+
Update the password of the logged-in User.
179+
176180
.. http:get:: /v1/auth/login/
177181
178182
Generate an API key.
@@ -272,7 +276,9 @@
272276
url(r'^auth/register/?',
273277
views.UserRegistrationView.as_view({'post': 'create'})),
274278
url(r'^auth/cancel/?',
275-
views.UserCancellationView.as_view({'delete': 'destroy'})),
279+
views.UserManagementView.as_view({'delete': 'destroy'})),
280+
url(r'^auth/passwd/?',
281+
views.UserManagementView.as_view({'post': 'passwd'})),
276282
url(r'^auth/login/',
277283
'rest_framework.authtoken.views.obtain_auth_token'),
278284
# admin sharing

api/views.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,20 @@ def pre_save(self, obj):
5858
obj.is_superuser = obj.is_staff = True
5959

6060

61-
class UserCancellationView(viewsets.GenericViewSet,
62-
viewsets.mixins.DestroyModelMixin):
61+
class UserManagementView(viewsets.GenericViewSet,
62+
viewsets.mixins.CreateModelMixin,
63+
viewsets.mixins.DestroyModelMixin):
6364
model = User
6465
permission_classes = (permissions.IsAuthenticated,)
6566

67+
def passwd(self, request, *args, **kwargs):
68+
obj = self.request.user
69+
if not obj.check_password(request.DATA['password']):
70+
return Response("Current password did not match", status=status.HTTP_400_BAD_REQUEST)
71+
obj.set_password(request.DATA['new_password'])
72+
obj.save()
73+
return Response({'status': 'password set'})
74+
6675
def destroy(self, request, *args, **kwargs):
6776
obj = self.request.user
6877
obj.delete()

0 commit comments

Comments
 (0)