Merge ~blake-rouse/maas:fix-1844793 into maas:master

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: e128f94d025350034e340eae0c48c92680dda2fb
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~blake-rouse/maas:fix-1844793
Merge into: maas:master
Diff against target: 87 lines (+38/-0)
2 files modified
src/maasserver/websockets/handlers/tests/test_user.py (+23/-0)
src/maasserver/websockets/handlers/user.py (+15/-0)
Reviewer Review Type Date Requested Status
Alberto Donato (community) Approve
Review via email: mp+373134@code.launchpad.net

Commit message

Fixes LP: #1844793 - Add ability for a user to change password over the websocket API.

To post a comment you must log in.
Revision history for this message
Alberto Donato (ack) :
Revision history for this message
Blake Rouse (blake-rouse) :
Revision history for this message
Alberto Donato (ack) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/websockets/handlers/tests/test_user.py b/src/maasserver/websockets/handlers/tests/test_user.py
2index ae0e8ee..2c69685 100644
3--- a/src/maasserver/websockets/handlers/tests/test_user.py
4+++ b/src/maasserver/websockets/handlers/tests/test_user.py
5@@ -30,6 +30,7 @@ from maasserver.websockets.base import (
6 dehydrate_datetime,
7 HandlerDoesNotExistError,
8 HandlerPermissionError,
9+ HandlerValidationError,
10 )
11 from maasserver.websockets.handlers.user import UserHandler
12 from maastesting.djangotestcase import count_queries
13@@ -348,3 +349,25 @@ class TestUserHandler(MAASServerTestCase):
14 handler = UserHandler(user, {}, None)
15 last_login_serialised = handler.get({"id": user.id})['last_login']
16 self.assertEqual(last_login_serialised, now.strftime(DATETIME_FORMAT))
17+
18+ def test_change_password_invalid(self):
19+ user = factory.make_User()
20+ user.set_password("oldpassword")
21+ handler = UserHandler(user, {}, None)
22+ self.assertRaises(HandlerValidationError, handler.change_password, {
23+ "new_password1": "newpassword",
24+ "new_password2": "mismatchpassword",
25+ "old_password": "oldpassword",
26+ })
27+
28+ def test_change_password(self):
29+ user = factory.make_User()
30+ user.set_password("oldpassword")
31+ handler = UserHandler(user, {}, None)
32+ observed = handler.change_password({
33+ "new_password1": "newpassword",
34+ "new_password2": "newpassword",
35+ "old_password": "oldpassword",
36+ })
37+ self.assertEqual(self.dehydrate_user(user, for_self=True), observed)
38+ self.assertTrue(user.check_password("newpassword"))
39diff --git a/src/maasserver/websockets/handlers/user.py b/src/maasserver/websockets/handlers/user.py
40index d9ea2cc..c046a91 100644
41--- a/src/maasserver/websockets/handlers/user.py
42+++ b/src/maasserver/websockets/handlers/user.py
43@@ -7,6 +7,7 @@ __all__ = [
44 "UserHandler",
45 ]
46
47+from django.contrib.auth.forms import PasswordChangeForm
48 from django.contrib.auth.models import User
49 from django.db.models import Count
50 from django.http import HttpRequest
51@@ -22,11 +23,13 @@ from maasserver.permissions import (
52 PodPermission,
53 ResourcePoolPermission,
54 )
55+from maasserver.utils.forms import get_QueryDict
56 from maasserver.websockets.base import (
57 dehydrate_datetime,
58 Handler,
59 HandlerDoesNotExistError,
60 HandlerPermissionError,
61+ HandlerValidationError,
62 )
63 from provisioningserver.events import EVENT_TYPES
64
65@@ -50,6 +53,7 @@ class UserHandler(Handler):
66 'create_authorisation_token',
67 'update_token_name',
68 'delete_authorisation_token',
69+ 'change_password',
70 ]
71 fields = [
72 "id",
73@@ -232,3 +236,14 @@ class UserHandler(Handler):
74 profile.delete_authorisation_token(params['key'])
75 self.create_audit_event(EVENT_TYPES.AUTHORISATION, "Deleted token.")
76 return {}
77+
78+ def change_password(self, params):
79+ """Update the authenticated user password."""
80+ form = PasswordChangeForm(user=self.user, data=get_QueryDict(params))
81+ if form.is_valid():
82+ form.save()
83+ self.user.sshkeys_count = self.user.sshkey_set.count()
84+ self.user.machines_count = self.user.node_set.count()
85+ return self.full_dehydrate(self.user)
86+ else:
87+ raise HandlerValidationError(form.errors)

Subscribers

People subscribed via source and target branches