mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2025-08-15 03:04:27 +08:00
Finalize user activation feature (#439)
* Add routes for user activation (#403) * Add routes for user activation Generate a token after creating the user in register route, passing to `activation_callback`, if `activation_callback` supplied Create new `/activate` route that will verify the token and activate the user Add new error codes to `fastapi_users/router/common.py` Update documentation Add tests Co-authored-by: Mark Todd <markpeter.todd@hotmail.co.uk> * Rework routes for user activation * Separate verification logic and token generation into `/fastapi_users/router/verify.py`, with per-route callbacks for custom behaviour * Return register router to original state * Added `is_verified` property to user models * Added `requires_verification` argument to `get_users_router`and `get_auth_router` * Additional dependencies added for verification in `fastapi_users/authentication/__init__.py` * Update tests for new behaviour * Update `README.md` to describe a workaround for possible problems during testing, by exceeding ulimit file descriptor limit Co-authored-by: Mark Todd <markpeter.todd@hotmail.co.uk> * Restored docs to original state. * All other modifications reqested added Kebab-case on request-verify-token SECRET now used as test string Other minor changes Co-authored-by: Mark Todd <markpeter.todd@hotmail.co.uk> * Embed token in body in verify route * Reorganize checks in verify route and add unit test * Ignore coverage on Protocol classes * Tweak verify_user function to take full user in parameter * Improve unit tests structure regarding parametrized test client * Make after_verification_request optional to be more consistent with other routers * Tweak status codes on verify routes * Write documentation for verification feature * Add not released warning on verify docs Co-authored-by: Edd Salkield <edd@salkield.uk> Co-authored-by: Mark Todd <markpeter.todd@hotmail.co.uk>
This commit is contained in:
@ -10,8 +10,16 @@ from fastapi_users.router import (
|
||||
get_register_router,
|
||||
get_reset_password_router,
|
||||
get_users_router,
|
||||
get_verify_router,
|
||||
)
|
||||
from fastapi_users.user import (
|
||||
CreateUserProtocol,
|
||||
GetUserProtocol,
|
||||
VerifyUserProtocol,
|
||||
get_create_user,
|
||||
get_get_user,
|
||||
get_verify_user,
|
||||
)
|
||||
from fastapi_users.user import CreateUserProtocol, get_create_user
|
||||
|
||||
try:
|
||||
from httpx_oauth.oauth2 import BaseOAuth2
|
||||
@ -35,12 +43,16 @@ class FastAPIUsers:
|
||||
:attribute create_user: Helper function to create a user programmatically.
|
||||
:attribute get_current_user: Dependency callable to inject authenticated user.
|
||||
:attribute get_current_active_user: Dependency callable to inject active user.
|
||||
:attribute get_current_verified_user: Dependency callable to inject verified user.
|
||||
:attribute get_current_superuser: Dependency callable to inject superuser.
|
||||
:attribute get_current_verified_superuser: Dependency callable to inject verified superuser.
|
||||
"""
|
||||
|
||||
db: BaseUserDatabase
|
||||
authenticator: Authenticator
|
||||
create_user: CreateUserProtocol
|
||||
verify_user: VerifyUserProtocol
|
||||
get_user: GetUserProtocol
|
||||
_user_model: Type[models.BaseUser]
|
||||
_user_create_model: Type[models.BaseUserCreate]
|
||||
_user_update_model: Type[models.BaseUserUpdate]
|
||||
@ -65,17 +77,29 @@ class FastAPIUsers:
|
||||
self._user_db_model = user_db_model
|
||||
|
||||
self.create_user = get_create_user(db, user_db_model)
|
||||
self.verify_user = get_verify_user(db)
|
||||
self.get_user = get_get_user(db)
|
||||
|
||||
self.get_current_user = self.authenticator.get_current_user
|
||||
self.get_current_active_user = self.authenticator.get_current_active_user
|
||||
self.get_current_verified_user = self.authenticator.get_current_verified_user
|
||||
self.get_current_superuser = self.authenticator.get_current_superuser
|
||||
self.get_current_verified_superuser = (
|
||||
self.authenticator.get_current_verified_superuser
|
||||
)
|
||||
self.get_optional_current_user = self.authenticator.get_optional_current_user
|
||||
self.get_optional_current_active_user = (
|
||||
self.authenticator.get_optional_current_active_user
|
||||
)
|
||||
self.get_optional_current_verified_user = (
|
||||
self.authenticator.get_optional_current_verified_user
|
||||
)
|
||||
self.get_optional_current_superuser = (
|
||||
self.authenticator.get_optional_current_superuser
|
||||
)
|
||||
self.get_optional_current_verified_superuser = (
|
||||
self.authenticator.get_optional_current_verified_superuser
|
||||
)
|
||||
|
||||
def get_register_router(
|
||||
self,
|
||||
@ -94,6 +118,31 @@ class FastAPIUsers:
|
||||
after_register,
|
||||
)
|
||||
|
||||
def get_verify_router(
|
||||
self,
|
||||
verification_token_secret: str,
|
||||
verification_token_lifetime_seconds: int = 3600,
|
||||
after_verification_request: Optional[
|
||||
Callable[[models.UD, str, Request], None]
|
||||
] = None,
|
||||
after_verification: Optional[Callable[[models.UD, Request], None]] = None,
|
||||
) -> APIRouter:
|
||||
"""
|
||||
Return a router with a register route.
|
||||
|
||||
:param after_register: Optional function called
|
||||
after a successful registration.
|
||||
"""
|
||||
return get_verify_router(
|
||||
self.verify_user,
|
||||
self.get_user,
|
||||
self._user_model,
|
||||
verification_token_secret,
|
||||
verification_token_lifetime_seconds,
|
||||
after_verification_request,
|
||||
after_verification,
|
||||
)
|
||||
|
||||
def get_reset_password_router(
|
||||
self,
|
||||
reset_password_token_secret: str,
|
||||
@ -117,13 +166,20 @@ class FastAPIUsers:
|
||||
after_forgot_password,
|
||||
)
|
||||
|
||||
def get_auth_router(self, backend: BaseAuthentication) -> APIRouter:
|
||||
def get_auth_router(
|
||||
self, backend: BaseAuthentication, requires_verification: bool = False
|
||||
) -> APIRouter:
|
||||
"""
|
||||
Return an auth router for a given authentication backend.
|
||||
|
||||
:param backend: The authentication backend instance.
|
||||
"""
|
||||
return get_auth_router(backend, self.db, self.authenticator)
|
||||
return get_auth_router(
|
||||
backend,
|
||||
self.db,
|
||||
self.authenticator,
|
||||
requires_verification,
|
||||
)
|
||||
|
||||
def get_oauth_router(
|
||||
self,
|
||||
@ -157,6 +213,7 @@ class FastAPIUsers:
|
||||
after_update: Optional[
|
||||
Callable[[models.UD, Dict[str, Any], Request], None]
|
||||
] = None,
|
||||
requires_verification: bool = False,
|
||||
) -> APIRouter:
|
||||
"""
|
||||
Return a router with routes to manage users.
|
||||
@ -171,4 +228,5 @@ class FastAPIUsers:
|
||||
self._user_db_model,
|
||||
self.authenticator,
|
||||
after_update,
|
||||
requires_verification,
|
||||
)
|
||||
|
Reference in New Issue
Block a user