Add Request in event_handlers arguments

This commit is contained in:
François Voron
2020-01-20 10:46:45 +01:00
parent 7279b44e19
commit 57a37150a0
3 changed files with 22 additions and 8 deletions

View File

@ -42,7 +42,7 @@ In order to be as unopinionated as possible, we expose decorators that allow you
### After register ### After register
This event handler is called after a successful registration. It is called with **one argument**: the **user** that has just registered. This event handler is called after a successful registration. It is called with **two argument**: the **user** that has just registered, and the original **`Request` object**.
Typically, you'll want to **send a welcome e-mail** or add it to your marketing analytics pipeline. Typically, you'll want to **send a welcome e-mail** or add it to your marketing analytics pipeline.
@ -52,13 +52,17 @@ Example:
```py ```py
@fastapi_users.on_after_register() @fastapi_users.on_after_register()
def on_after_register(user: User): def on_after_register(user: User, request: Request):
print(f"User {user.id} has registered.") print(f"User {user.id} has registered.")
``` ```
### After forgot password ### After forgot password
This event handler is called after a successful forgot password request. It is called with **two arguments**: the **user** which has requested to reset their password and a ready-to-use **JWT token** that will be accepted by the reset password route. This event handler is called after a successful forgot password request. It is called with **three arguments**:
* The **user** which has requested to reset their password.
* A ready-to-use **JWT token** that will be accepted by the reset password route.
* The original **`Request` object**.
Typically, you'll want to **send an e-mail** with the link (and the token) that allows the user to reset their password. Typically, you'll want to **send an e-mail** with the link (and the token) that allows the user to reset their password.
@ -68,7 +72,7 @@ Example:
```py ```py
@fastapi_users.on_after_forgot_password() @fastapi_users.on_after_forgot_password()
def on_after_forgot_password(user: User, token: str): def on_after_forgot_password(user: User, token: str, request: Request):
print(f"User {user.id} has forgot their password. Reset token: {token}") print(f"User {user.id} has forgot their password. Reset token: {token}")
``` ```

View File

@ -5,6 +5,7 @@ from fastapi import Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordRequestForm
from pydantic import EmailStr from pydantic import EmailStr
from starlette import status from starlette import status
from starlette.requests import Request
from starlette.responses import Response from starlette.responses import Response
from fastapi_users import models from fastapi_users import models
@ -74,7 +75,7 @@ def get_user_router(
@router.post( @router.post(
"/register", response_model=user_model, status_code=status.HTTP_201_CREATED "/register", response_model=user_model, status_code=status.HTTP_201_CREATED
) )
async def register(user: user_create_model): # type: ignore async def register(request: Request, user: user_create_model): # type: ignore
user = cast(models.BaseUserCreate, user) # Prevent mypy complain user = cast(models.BaseUserCreate, user) # Prevent mypy complain
existing_user = await user_db.get_by_email(user.email) existing_user = await user_db.get_by_email(user.email)
@ -90,12 +91,14 @@ def get_user_router(
) )
created_user = await user_db.create(db_user) created_user = await user_db.create(db_user)
await router.run_handlers(Event.ON_AFTER_REGISTER, created_user) await router.run_handlers(Event.ON_AFTER_REGISTER, created_user, request)
return created_user return created_user
@router.post("/forgot-password", status_code=status.HTTP_202_ACCEPTED) @router.post("/forgot-password", status_code=status.HTTP_202_ACCEPTED)
async def forgot_password(email: EmailStr = Body(..., embed=True)): async def forgot_password(
request: Request, email: EmailStr = Body(..., embed=True)
):
user = await user_db.get_by_email(email) user = await user_db.get_by_email(email)
if user is not None and user.is_active: if user is not None and user.is_active:
@ -105,7 +108,9 @@ def get_user_router(
reset_password_token_lifetime_seconds, reset_password_token_lifetime_seconds,
reset_password_token_secret, reset_password_token_secret,
) )
await router.run_handlers(Event.ON_AFTER_FORGOT_PASSWORD, user, token) await router.run_handlers(
Event.ON_AFTER_FORGOT_PASSWORD, user, token, request
)
return None return None

View File

@ -5,6 +5,7 @@ import jwt
import pytest import pytest
from fastapi import FastAPI from fastapi import FastAPI
from starlette import status from starlette import status
from starlette.requests import Request
from starlette.testclient import TestClient from starlette.testclient import TestClient
from fastapi_users.authentication import Authenticator from fastapi_users.authentication import Authenticator
@ -106,6 +107,8 @@ class TestRegister:
actual_user = event_handler.call_args[0][0] actual_user = event_handler.call_args[0][0]
assert actual_user.id == response_json["id"] assert actual_user.id == response_json["id"]
request = event_handler.call_args[0][1]
assert isinstance(request, Request)
def test_valid_body_is_superuser(self, test_app_client: TestClient, event_handler): def test_valid_body_is_superuser(self, test_app_client: TestClient, event_handler):
json = { json = {
@ -211,6 +214,8 @@ class TestForgotPassword:
algorithms=[JWT_ALGORITHM], algorithms=[JWT_ALGORITHM],
) )
assert decoded_token["user_id"] == user.id assert decoded_token["user_id"] == user.id
request = event_handler.call_args[0][2]
assert isinstance(request, Request)
@pytest.mark.router @pytest.mark.router