From 220e90e32eb311bed5d8228b49b9a2d2637e095d Mon Sep 17 00:00:00 2001 From: Vincent Simonin Date: Thu, 23 Nov 2023 16:27:50 +0100 Subject: [PATCH] Fixed password was not hashed on REST API update * When we updated a user password with a REST API call the password was stored in clear in plain text in the database. --- netbox/users/api/serializers.py | 12 ++++++++++++ netbox/users/tests/test_api.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/netbox/users/api/serializers.py b/netbox/users/api/serializers.py index 75ab877cf..8d3bffba4 100644 --- a/netbox/users/api/serializers.py +++ b/netbox/users/api/serializers.py @@ -52,6 +52,18 @@ class UserSerializer(ValidatedModelSerializer): return user + def update(self, instance, validated_data): + """ + Ensure proper updated password hash generation. + """ + password = validated_data.pop('password', None) + if password is not None: + instance.set_password(password) + + instance.save() + + return instance + @extend_schema_field(OpenApiTypes.STR) def get_display(self, obj): if full_name := obj.get_full_name(): diff --git a/netbox/users/tests/test_api.py b/netbox/users/tests/test_api.py index 001142410..a43077442 100644 --- a/netbox/users/tests/test_api.py +++ b/netbox/users/tests/test_api.py @@ -55,6 +55,37 @@ class UserTest(APIViewTestCases.APIViewTestCase): User.objects.bulk_create(users) +class ChangeUserPasswordTest(APITestCase): + + user_permissions = ['auth.change_user'] + + def test_that_password_is_changed(self): + """ + Test that password is changed + """ + + user_credentials = { + 'username': 'user1', + 'password': 'abc123', + } + user = User.objects.create_user(**user_credentials) + + print(user.id) + + data = { + 'password': 'newpassword' + } + url = reverse('users-api:user-detail', kwargs={'pk': user.id}) + + response = self.client.patch(url, data, format='json', **self.header) + + self.assertEqual(response.status_code, 200) + + updated_user = User.objects.get(id=user.id) + + self.assertTrue(updated_user.check_password(data['password'])) + + class GroupTest(APIViewTestCases.APIViewTestCase): model = Group view_namespace = 'users'