From 73b153635630610c978f24923b9ced4306ea7895 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Wed, 7 Aug 2024 17:04:19 -0400 Subject: [PATCH] Only refresh session if updating own password (#15426) Fixes bug where creating a new user will request a new awx_sessionid cookie, invalidating the previous session. Do not refresh session if updating or creating a password for a different user. Signed-off-by: Seth Foster --- awx/api/serializers.py | 4 +++- awx/main/tests/functional/api/test_user.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index b42783eb2a4d..09327638436c 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1038,7 +1038,9 @@ def _update_password(self, obj, new_password): # as the modified user then inject a session key derived from # the updated user to prevent logout. This is the logic used by # the Django admin's own user_change_password view. - update_session_auth_hash(self.context['request'], obj) + if self.instance and self.context['request'].user.username == obj.username: + update_session_auth_hash(self.context['request'], obj) + elif not obj.password: obj.set_unusable_password() obj.save(update_fields=['password']) diff --git a/awx/main/tests/functional/api/test_user.py b/awx/main/tests/functional/api/test_user.py index c19192c90caa..f762990a55bc 100644 --- a/awx/main/tests/functional/api/test_user.py +++ b/awx/main/tests/functional/api/test_user.py @@ -33,6 +33,27 @@ def test_fail_double_create_user(post, admin): assert response.status_code == 400 +@pytest.mark.django_db +def test_creating_user_retains_session(post, admin): + ''' + Creating a new user should not refresh a new session id for the current user. + ''' + with mock.patch('awx.api.serializers.update_session_auth_hash') as update_session_auth_hash: + response = post(reverse('api:user_list'), EXAMPLE_USER_DATA, admin) + assert response.status_code == 201 + assert not update_session_auth_hash.called + + +@pytest.mark.django_db +def test_updating_own_password_refreshes_session(patch, admin): + ''' + Updating your own password should refresh the session id. + ''' + with mock.patch('awx.api.serializers.update_session_auth_hash') as update_session_auth_hash: + patch(reverse('api:user_detail', kwargs={'pk': admin.pk}), {'password': 'newpassword'}, admin, middleware=SessionMiddleware(mock.Mock())) + assert update_session_auth_hash.called + + @pytest.mark.django_db def test_create_delete_create_user(post, delete, admin): response = post(reverse('api:user_list'), EXAMPLE_USER_DATA, admin, middleware=SessionMiddleware(mock.Mock()))