mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2025-11-02 21:24:34 +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):
|
async def on_after_reset_password(self, user: User, request: Optional[Request] = None):
|
||||||
print(f"User {user.id} has reset their password.")
|
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)
|
await self.on_after_update(updated_user, updated_user_data, request)
|
||||||
return updated_user
|
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.
|
Delete a user.
|
||||||
|
|
||||||
:param user: The user to delete.
|
:param user: The user to delete.
|
||||||
"""
|
"""
|
||||||
|
await self.on_before_delete(user, request)
|
||||||
await self.user_db.delete(user)
|
await self.user_db.delete(user)
|
||||||
|
await self.on_after_delete(user, request)
|
||||||
|
|
||||||
async def validate_password(
|
async def validate_password(
|
||||||
self, password: str, user: Union[schemas.UC, models.UP]
|
self, password: str, user: Union[schemas.UC, models.UP]
|
||||||
@ -516,6 +522,34 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
"""
|
"""
|
||||||
return # pragma: no cover
|
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(
|
async def authenticate(
|
||||||
self, credentials: OAuth2PasswordRequestForm
|
self, credentials: OAuth2PasswordRequestForm
|
||||||
) -> Optional[models.UP]:
|
) -> Optional[models.UP]:
|
||||||
|
|||||||
@ -120,6 +120,8 @@ class UserManagerMock(BaseTestUserManager[models.UP]):
|
|||||||
on_after_forgot_password: MagicMock
|
on_after_forgot_password: MagicMock
|
||||||
on_after_reset_password: MagicMock
|
on_after_reset_password: MagicMock
|
||||||
on_after_update: MagicMock
|
on_after_update: MagicMock
|
||||||
|
on_before_delete: MagicMock
|
||||||
|
on_after_delete: MagicMock
|
||||||
_update: 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_forgot_password")
|
||||||
mocker.spy(user_manager, "on_after_reset_password")
|
mocker.spy(user_manager, "on_after_reset_password")
|
||||||
mocker.spy(user_manager, "on_after_update")
|
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")
|
mocker.spy(user_manager, "_update")
|
||||||
return user_manager
|
return user_manager
|
||||||
|
|
||||||
|
|||||||
@ -532,6 +532,10 @@ class TestDelete:
|
|||||||
):
|
):
|
||||||
await user_manager.delete(user)
|
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.asyncio
|
||||||
@pytest.mark.manager
|
@pytest.mark.manager
|
||||||
|
|||||||
Reference in New Issue
Block a user