mirror of
				https://github.com/fastapi-users/fastapi-users.git
				synced 2025-11-04 06:37:51 +08:00 
			
		
		
		
	Fix password update None handling. (#1275)
This commit is contained in:
		@ -672,7 +672,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
 | 
			
		||||
                except exceptions.UserNotExists:
 | 
			
		||||
                    validated_update_dict["email"] = value
 | 
			
		||||
                    validated_update_dict["is_verified"] = False
 | 
			
		||||
            elif field == "password":
 | 
			
		||||
            elif field == "password" and value is not None:
 | 
			
		||||
                await self.validate_password(value, user)
 | 
			
		||||
                validated_update_dict["hashed_password"] = self.password_helper.hash(
 | 
			
		||||
                    value
 | 
			
		||||
 | 
			
		||||
@ -585,6 +585,17 @@ class TestUpdateUser:
 | 
			
		||||
 | 
			
		||||
        assert user_manager.on_after_update.called is True
 | 
			
		||||
 | 
			
		||||
    async def test_unsafe_update_password_unchanged(
 | 
			
		||||
        self, user: UserModel, user_manager: UserManagerMock[UserModel]
 | 
			
		||||
    ):
 | 
			
		||||
        old_hashed_password = user.hashed_password
 | 
			
		||||
        user_update = UserUpdate(password=None)
 | 
			
		||||
        updated_user = await user_manager.update(user_update, user, safe=False)
 | 
			
		||||
 | 
			
		||||
        assert updated_user.hashed_password == old_hashed_password
 | 
			
		||||
 | 
			
		||||
        assert user_manager.on_after_update.called is True
 | 
			
		||||
 | 
			
		||||
    async def test_password_update_invalid(
 | 
			
		||||
        self, user: UserModel, user_manager: UserManagerMock[UserModel]
 | 
			
		||||
    ):
 | 
			
		||||
 | 
			
		||||
@ -826,6 +826,33 @@ class TestUpdateUser:
 | 
			
		||||
        updated_user = mock_user_db.update.call_args[0][0]
 | 
			
		||||
        assert updated_user.hashed_password != current_hashed_password
 | 
			
		||||
 | 
			
		||||
    async def test_valid_body_password_unchanged_unverified_superuser(
 | 
			
		||||
        self,
 | 
			
		||||
        mocker,
 | 
			
		||||
        mock_user_db,
 | 
			
		||||
        test_app_client: Tuple[httpx.AsyncClient, bool],
 | 
			
		||||
        user: UserModel,
 | 
			
		||||
        superuser: UserModel,
 | 
			
		||||
    ):
 | 
			
		||||
        client, requires_verification = test_app_client
 | 
			
		||||
        mocker.spy(mock_user_db, "update")
 | 
			
		||||
        current_hashed_password = user.hashed_password
 | 
			
		||||
 | 
			
		||||
        json = {"password": None}
 | 
			
		||||
        response = await client.patch(
 | 
			
		||||
            f"/{user.id}",
 | 
			
		||||
            json=json,
 | 
			
		||||
            headers={"Authorization": f"Bearer {superuser.id}"},
 | 
			
		||||
        )
 | 
			
		||||
        if requires_verification:
 | 
			
		||||
            assert response.status_code == status.HTTP_403_FORBIDDEN
 | 
			
		||||
        else:
 | 
			
		||||
            assert response.status_code == status.HTTP_200_OK
 | 
			
		||||
            assert mock_user_db.update.called is True
 | 
			
		||||
 | 
			
		||||
            updated_user = mock_user_db.update.call_args[0][0]
 | 
			
		||||
            assert updated_user.hashed_password == current_hashed_password
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.router
 | 
			
		||||
@pytest.mark.asyncio
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user