mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2025-11-02 12:21:53 +08:00
add on delete hook (#1014)
Co-authored-by: Schwannden Kuo <schwannden@mobagel.com>
This commit is contained in:
@ -263,3 +263,50 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):
|
||||
async def on_after_reset_password(self, user: User, request: Optional[Request] = None):
|
||||
print(f"User {user.id} has reset their password.")
|
||||
```
|
||||
|
||||
#### `on_before_delete`
|
||||
|
||||
Perform logic before user delete.
|
||||
|
||||
For example, you may want to **valide user resource integrity** to see if any related user resource need to be marked inactive, or delete
|
||||
them recursively.
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `user` (`User`): the user to be deleted.
|
||||
* `request` (`Optional[Request]`): optional FastAPI request object that triggered the operation. Defaults to None.
|
||||
|
||||
**Example**
|
||||
|
||||
```py
|
||||
from fastapi_users import BaseUserManager, UUIDIDMixin
|
||||
|
||||
|
||||
class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):
|
||||
# ...
|
||||
async def on_before_delete(self, user: User, request: Optional[Request] = None):
|
||||
print(f"User {user.id} is going to be deleted")
|
||||
```
|
||||
|
||||
#### `on_after_delete`
|
||||
|
||||
Perform logic after user delete.
|
||||
|
||||
For example, you may want to **send an email** to the administrator about the event.
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `user` (`User`): the user to be deleted.
|
||||
* `request` (`Optional[Request]`): optional FastAPI request object that triggered the operation. Defaults to None.
|
||||
|
||||
**Example**
|
||||
|
||||
```py
|
||||
from fastapi_users import BaseUserManager, UUIDIDMixin
|
||||
|
||||
|
||||
class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):
|
||||
# ...
|
||||
async def on_after_delete(self, user: User, request: Optional[Request] = None):
|
||||
print(f"User {user.id} is successfully deleted")
|
||||
```
|
||||
|
||||
@ -403,13 +403,19 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
||||
await self.on_after_update(updated_user, updated_user_data, request)
|
||||
return updated_user
|
||||
|
||||
async def delete(self, user: models.UP) -> None:
|
||||
async def delete(
|
||||
self,
|
||||
user: models.UP,
|
||||
request: Optional[Request] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Delete a user.
|
||||
|
||||
:param user: The user to delete.
|
||||
"""
|
||||
await self.on_before_delete(user, request)
|
||||
await self.user_db.delete(user)
|
||||
await self.on_after_delete(user, request)
|
||||
|
||||
async def validate_password(
|
||||
self, password: str, user: Union[schemas.UC, models.UP]
|
||||
@ -516,6 +522,34 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
||||
"""
|
||||
return # pragma: no cover
|
||||
|
||||
async def on_before_delete(
|
||||
self, user: models.UP, request: Optional[Request] = None
|
||||
) -> None:
|
||||
"""
|
||||
Perform logic before user delete.
|
||||
|
||||
*You should overload this method to add your own logic.*
|
||||
|
||||
:param user: The user to be deleted
|
||||
:param request: Optional FastAPI request that
|
||||
triggered the operation, defaults to None.
|
||||
"""
|
||||
return # pragma: no cover
|
||||
|
||||
async def on_after_delete(
|
||||
self, user: models.UP, request: Optional[Request] = None
|
||||
) -> None:
|
||||
"""
|
||||
Perform logic before user delete.
|
||||
|
||||
*You should overload this method to add your own logic.*
|
||||
|
||||
:param user: The user to be deleted
|
||||
:param request: Optional FastAPI request that
|
||||
triggered the operation, defaults to None.
|
||||
"""
|
||||
return # pragma: no cover
|
||||
|
||||
async def authenticate(
|
||||
self, credentials: OAuth2PasswordRequestForm
|
||||
) -> Optional[models.UP]:
|
||||
|
||||
@ -120,6 +120,8 @@ class UserManagerMock(BaseTestUserManager[models.UP]):
|
||||
on_after_forgot_password: MagicMock
|
||||
on_after_reset_password: MagicMock
|
||||
on_after_update: MagicMock
|
||||
on_before_delete: MagicMock
|
||||
on_after_delete: MagicMock
|
||||
_update: MagicMock
|
||||
|
||||
|
||||
@ -475,6 +477,8 @@ def make_user_manager(mocker: MockerFixture):
|
||||
mocker.spy(user_manager, "on_after_forgot_password")
|
||||
mocker.spy(user_manager, "on_after_reset_password")
|
||||
mocker.spy(user_manager, "on_after_update")
|
||||
mocker.spy(user_manager, "on_before_delete")
|
||||
mocker.spy(user_manager, "on_after_delete")
|
||||
mocker.spy(user_manager, "_update")
|
||||
return user_manager
|
||||
|
||||
|
||||
@ -532,6 +532,10 @@ class TestDelete:
|
||||
):
|
||||
await user_manager.delete(user)
|
||||
|
||||
assert user_manager.on_before_delete.called is True
|
||||
|
||||
assert user_manager.on_after_delete.called is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.manager
|
||||
|
||||
Reference in New Issue
Block a user