diff --git a/awx/api/serializers.py b/awx/api/serializers.py index b42783eb2a..0932763843 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1038,7 +1038,9 @@ class UserSerializer(BaseSerializer): # 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 c19192c90c..f762990a55 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()))