mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2025-08-15 11:11:16 +08:00
Put exceptions in a dedicated module to avoid circular imports
This commit is contained in:
@ -3,7 +3,7 @@ import contextlib
|
|||||||
from app.db import get_async_session, get_user_db
|
from app.db import get_async_session, get_user_db
|
||||||
from app.schemas import UserCreate
|
from app.schemas import UserCreate
|
||||||
from app.users import get_user_manager
|
from app.users import get_user_manager
|
||||||
from fastapi_users.manager import UserAlreadyExists
|
from fastapi_users.exceptions import UserAlreadyExists
|
||||||
|
|
||||||
get_async_session_context = contextlib.asynccontextmanager(get_async_session)
|
get_async_session_context = contextlib.asynccontextmanager(get_async_session)
|
||||||
get_user_db_context = contextlib.asynccontextmanager(get_user_db)
|
get_user_db_context = contextlib.asynccontextmanager(get_user_db)
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
__version__ = "10.0.0"
|
__version__ = "10.0.0"
|
||||||
|
|
||||||
from fastapi_users import models, schemas # noqa: F401
|
from fastapi_users import models, schemas # noqa: F401
|
||||||
|
from fastapi_users.exceptions import InvalidID, InvalidPasswordException
|
||||||
from fastapi_users.fastapi_users import FastAPIUsers # noqa: F401
|
from fastapi_users.fastapi_users import FastAPIUsers # noqa: F401
|
||||||
from fastapi_users.manager import ( # noqa: F401
|
from fastapi_users.manager import ( # noqa: F401
|
||||||
BaseUserManager,
|
BaseUserManager,
|
||||||
IntegerIDMixin,
|
IntegerIDMixin,
|
||||||
InvalidID,
|
|
||||||
InvalidPasswordException,
|
|
||||||
UUIDIDMixin,
|
UUIDIDMixin,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"models",
|
||||||
"schemas",
|
"schemas",
|
||||||
"FastAPIUsers",
|
"FastAPIUsers",
|
||||||
"BaseUserManager",
|
"BaseUserManager",
|
||||||
|
@ -2,11 +2,11 @@ import secrets
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from typing import Any, Dict, Generic, Optional
|
from typing import Any, Dict, Generic, Optional
|
||||||
|
|
||||||
from fastapi_users import models
|
from fastapi_users import exceptions, models
|
||||||
from fastapi_users.authentication.strategy.base import Strategy
|
from fastapi_users.authentication.strategy.base import Strategy
|
||||||
from fastapi_users.authentication.strategy.db.adapter import AccessTokenDatabase
|
from fastapi_users.authentication.strategy.db.adapter import AccessTokenDatabase
|
||||||
from fastapi_users.authentication.strategy.db.models import AP
|
from fastapi_users.authentication.strategy.db.models import AP
|
||||||
from fastapi_users.manager import BaseUserManager, InvalidID, UserNotExists
|
from fastapi_users.manager import BaseUserManager
|
||||||
|
|
||||||
|
|
||||||
class DatabaseStrategy(
|
class DatabaseStrategy(
|
||||||
@ -37,7 +37,7 @@ class DatabaseStrategy(
|
|||||||
try:
|
try:
|
||||||
parsed_id = user_manager.parse_id(access_token.user_id)
|
parsed_id = user_manager.parse_id(access_token.user_id)
|
||||||
return await user_manager.get(parsed_id)
|
return await user_manager.get(parsed_id)
|
||||||
except (UserNotExists, InvalidID):
|
except (exceptions.UserNotExists, exceptions.InvalidID):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def write_token(self, user: models.UP) -> str:
|
async def write_token(self, user: models.UP) -> str:
|
||||||
|
@ -2,13 +2,13 @@ from typing import Generic, List, Optional
|
|||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
|
|
||||||
from fastapi_users import models
|
from fastapi_users import exceptions, models
|
||||||
from fastapi_users.authentication.strategy.base import (
|
from fastapi_users.authentication.strategy.base import (
|
||||||
Strategy,
|
Strategy,
|
||||||
StrategyDestroyNotSupportedError,
|
StrategyDestroyNotSupportedError,
|
||||||
)
|
)
|
||||||
from fastapi_users.jwt import SecretType, decode_jwt, generate_jwt
|
from fastapi_users.jwt import SecretType, decode_jwt, generate_jwt
|
||||||
from fastapi_users.manager import BaseUserManager, InvalidID, UserNotExists
|
from fastapi_users.manager import BaseUserManager
|
||||||
|
|
||||||
|
|
||||||
class JWTStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID]):
|
class JWTStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID]):
|
||||||
@ -53,7 +53,7 @@ class JWTStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID])
|
|||||||
try:
|
try:
|
||||||
parsed_id = user_manager.parse_id(user_id)
|
parsed_id = user_manager.parse_id(user_id)
|
||||||
return await user_manager.get(parsed_id)
|
return await user_manager.get(parsed_id)
|
||||||
except (UserNotExists, InvalidID):
|
except (exceptions.UserNotExists, exceptions.InvalidID):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def write_token(self, user: models.UP) -> str:
|
async def write_token(self, user: models.UP) -> str:
|
||||||
|
@ -3,9 +3,9 @@ from typing import Generic, Optional
|
|||||||
|
|
||||||
import aioredis
|
import aioredis
|
||||||
|
|
||||||
from fastapi_users import models
|
from fastapi_users import exceptions, models
|
||||||
from fastapi_users.authentication.strategy.base import Strategy
|
from fastapi_users.authentication.strategy.base import Strategy
|
||||||
from fastapi_users.manager import BaseUserManager, InvalidID, UserNotExists
|
from fastapi_users.manager import BaseUserManager
|
||||||
|
|
||||||
|
|
||||||
class RedisStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID]):
|
class RedisStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID]):
|
||||||
@ -26,7 +26,7 @@ class RedisStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID
|
|||||||
try:
|
try:
|
||||||
parsed_id = user_manager.parse_id(user_id)
|
parsed_id = user_manager.parse_id(user_id)
|
||||||
return await user_manager.get(parsed_id)
|
return await user_manager.get(parsed_id)
|
||||||
except (UserNotExists, InvalidID):
|
except (exceptions.UserNotExists, exceptions.InvalidID):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def write_token(self, user: models.UP) -> str:
|
async def write_token(self, user: models.UP) -> str:
|
||||||
|
38
fastapi_users/exceptions.py
Normal file
38
fastapi_users/exceptions.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
class FastAPIUsersException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidID(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UserAlreadyExists(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotExists(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UserInactive(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UserAlreadyVerified(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidVerifyToken(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidResetPasswordToken(FastAPIUsersException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidPasswordException(FastAPIUsersException):
|
||||||
|
def __init__(self, reason: Any) -> None:
|
||||||
|
self.reason = reason
|
@ -5,7 +5,7 @@ import jwt
|
|||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from fastapi.security import OAuth2PasswordRequestForm
|
from fastapi.security import OAuth2PasswordRequestForm
|
||||||
|
|
||||||
from fastapi_users import models, schemas
|
from fastapi_users import exceptions, models, schemas
|
||||||
from fastapi_users.db import BaseUserDatabase
|
from fastapi_users.db import BaseUserDatabase
|
||||||
from fastapi_users.jwt import SecretType, decode_jwt, generate_jwt
|
from fastapi_users.jwt import SecretType, decode_jwt, generate_jwt
|
||||||
from fastapi_users.password import PasswordHelper, PasswordHelperProtocol
|
from fastapi_users.password import PasswordHelper, PasswordHelperProtocol
|
||||||
@ -15,43 +15,6 @@ RESET_PASSWORD_TOKEN_AUDIENCE = "fastapi-users:reset"
|
|||||||
VERIFY_USER_TOKEN_AUDIENCE = "fastapi-users:verify"
|
VERIFY_USER_TOKEN_AUDIENCE = "fastapi-users:verify"
|
||||||
|
|
||||||
|
|
||||||
class FastAPIUsersException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidID(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UserAlreadyExists(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UserNotExists(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UserInactive(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UserAlreadyVerified(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidVerifyToken(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidResetPasswordToken(FastAPIUsersException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidPasswordException(FastAPIUsersException):
|
|
||||||
def __init__(self, reason: Any) -> None:
|
|
||||||
self.reason = reason
|
|
||||||
|
|
||||||
|
|
||||||
class BaseUserManager(Generic[models.UP, models.ID]):
|
class BaseUserManager(Generic[models.UP, models.ID]):
|
||||||
"""
|
"""
|
||||||
User management logic.
|
User management logic.
|
||||||
@ -109,7 +72,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
user = await self.user_db.get(id)
|
user = await self.user_db.get(id)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
raise UserNotExists()
|
raise exceptions.UserNotExists()
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
@ -124,7 +87,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
user = await self.user_db.get_by_email(user_email)
|
user = await self.user_db.get_by_email(user_email)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
raise UserNotExists()
|
raise exceptions.UserNotExists()
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
@ -140,7 +103,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
user = await self.user_db.get_by_oauth_account(oauth, account_id)
|
user = await self.user_db.get_by_oauth_account(oauth, account_id)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
raise UserNotExists()
|
raise exceptions.UserNotExists()
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
@ -167,7 +130,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
|
|
||||||
existing_user = await self.user_db.get_by_email(user_create.email)
|
existing_user = await self.user_db.get_by_email(user_create.email)
|
||||||
if existing_user is not None:
|
if existing_user is not None:
|
||||||
raise UserAlreadyExists()
|
raise exceptions.UserAlreadyExists()
|
||||||
|
|
||||||
user_dict = (
|
user_dict = (
|
||||||
user_create.create_update_dict()
|
user_create.create_update_dict()
|
||||||
@ -226,12 +189,12 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
user = await self.get_by_oauth_account(oauth_name, account_id)
|
user = await self.get_by_oauth_account(oauth_name, account_id)
|
||||||
except UserNotExists:
|
except exceptions.UserNotExists:
|
||||||
try:
|
try:
|
||||||
# Link account
|
# Link account
|
||||||
user = await self.get_by_email(account_email)
|
user = await self.get_by_email(account_email)
|
||||||
user = await self.user_db.add_oauth_account(user, oauth_account_dict)
|
user = await self.user_db.add_oauth_account(user, oauth_account_dict)
|
||||||
except UserNotExists:
|
except exceptions.UserNotExists:
|
||||||
# Create account
|
# Create account
|
||||||
password = self.password_helper.generate()
|
password = self.password_helper.generate()
|
||||||
user_dict = {
|
user_dict = {
|
||||||
@ -269,9 +232,9 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
:raises UserAlreadyVerified: The user is already verified.
|
:raises UserAlreadyVerified: The user is already verified.
|
||||||
"""
|
"""
|
||||||
if not user.is_active:
|
if not user.is_active:
|
||||||
raise UserInactive()
|
raise exceptions.UserInactive()
|
||||||
if user.is_verified:
|
if user.is_verified:
|
||||||
raise UserAlreadyVerified()
|
raise exceptions.UserAlreadyVerified()
|
||||||
|
|
||||||
token_data = {
|
token_data = {
|
||||||
"user_id": str(user.id),
|
"user_id": str(user.id),
|
||||||
@ -307,29 +270,29 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
[self.verification_token_audience],
|
[self.verification_token_audience],
|
||||||
)
|
)
|
||||||
except jwt.PyJWTError:
|
except jwt.PyJWTError:
|
||||||
raise InvalidVerifyToken()
|
raise exceptions.InvalidVerifyToken()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_id = data["user_id"]
|
user_id = data["user_id"]
|
||||||
email = data["email"]
|
email = data["email"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise InvalidVerifyToken()
|
raise exceptions.InvalidVerifyToken()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = await self.get_by_email(email)
|
user = await self.get_by_email(email)
|
||||||
except UserNotExists:
|
except exceptions.UserNotExists:
|
||||||
raise InvalidVerifyToken()
|
raise exceptions.InvalidVerifyToken()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed_id = self.parse_id(user_id)
|
parsed_id = self.parse_id(user_id)
|
||||||
except InvalidID:
|
except exceptions.InvalidID:
|
||||||
raise InvalidVerifyToken()
|
raise exceptions.InvalidVerifyToken()
|
||||||
|
|
||||||
if parsed_id != user.id:
|
if parsed_id != user.id:
|
||||||
raise InvalidVerifyToken()
|
raise exceptions.InvalidVerifyToken()
|
||||||
|
|
||||||
if user.is_verified:
|
if user.is_verified:
|
||||||
raise UserAlreadyVerified()
|
raise exceptions.UserAlreadyVerified()
|
||||||
|
|
||||||
verified_user = await self._update(user, {"is_verified": True})
|
verified_user = await self._update(user, {"is_verified": True})
|
||||||
|
|
||||||
@ -351,7 +314,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
:raises UserInactive: The user is inactive.
|
:raises UserInactive: The user is inactive.
|
||||||
"""
|
"""
|
||||||
if not user.is_active:
|
if not user.is_active:
|
||||||
raise UserInactive()
|
raise exceptions.UserInactive()
|
||||||
|
|
||||||
token_data = {
|
token_data = {
|
||||||
"user_id": str(user.id),
|
"user_id": str(user.id),
|
||||||
@ -388,22 +351,22 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
[self.reset_password_token_audience],
|
[self.reset_password_token_audience],
|
||||||
)
|
)
|
||||||
except jwt.PyJWTError:
|
except jwt.PyJWTError:
|
||||||
raise InvalidResetPasswordToken()
|
raise exceptions.InvalidResetPasswordToken()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_id = data["user_id"]
|
user_id = data["user_id"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise InvalidResetPasswordToken()
|
raise exceptions.InvalidResetPasswordToken()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed_id = self.parse_id(user_id)
|
parsed_id = self.parse_id(user_id)
|
||||||
except InvalidID:
|
except exceptions.InvalidID:
|
||||||
raise InvalidResetPasswordToken()
|
raise exceptions.InvalidResetPasswordToken()
|
||||||
|
|
||||||
user = await self.get(parsed_id)
|
user = await self.get(parsed_id)
|
||||||
|
|
||||||
if not user.is_active:
|
if not user.is_active:
|
||||||
raise UserInactive()
|
raise exceptions.UserInactive()
|
||||||
|
|
||||||
updated_user = await self._update(user, {"password": password})
|
updated_user = await self._update(user, {"password": password})
|
||||||
|
|
||||||
@ -565,7 +528,7 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
user = await self.get_by_email(credentials.username)
|
user = await self.get_by_email(credentials.username)
|
||||||
except UserNotExists:
|
except exceptions.UserNotExists:
|
||||||
# Run the hasher to mitigate timing attack
|
# Run the hasher to mitigate timing attack
|
||||||
# Inspired from Django: https://code.djangoproject.com/ticket/20760
|
# Inspired from Django: https://code.djangoproject.com/ticket/20760
|
||||||
self.password_helper.hash(credentials.password)
|
self.password_helper.hash(credentials.password)
|
||||||
@ -588,8 +551,8 @@ class BaseUserManager(Generic[models.UP, models.ID]):
|
|||||||
if field == "email" and value != user.email:
|
if field == "email" and value != user.email:
|
||||||
try:
|
try:
|
||||||
await self.get_by_email(value)
|
await self.get_by_email(value)
|
||||||
raise UserAlreadyExists()
|
raise exceptions.UserAlreadyExists()
|
||||||
except UserNotExists:
|
except exceptions.UserNotExists:
|
||||||
validated_update_dict["email"] = value
|
validated_update_dict["email"] = value
|
||||||
validated_update_dict["is_verified"] = False
|
validated_update_dict["is_verified"] = False
|
||||||
elif field == "password":
|
elif field == "password":
|
||||||
@ -609,17 +572,17 @@ class UUIDIDMixin:
|
|||||||
try:
|
try:
|
||||||
return uuid.UUID(value)
|
return uuid.UUID(value)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise InvalidID() from e
|
raise exceptions.InvalidID() from e
|
||||||
|
|
||||||
|
|
||||||
class IntegerIDMixin:
|
class IntegerIDMixin:
|
||||||
def parse_id(self, value: Any) -> int:
|
def parse_id(self, value: Any) -> int:
|
||||||
if isinstance(value, float):
|
if isinstance(value, float):
|
||||||
raise InvalidID()
|
raise exceptions.InvalidID()
|
||||||
try:
|
try:
|
||||||
return int(value)
|
return int(value)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise InvalidID() from e
|
raise exceptions.InvalidID() from e
|
||||||
|
|
||||||
|
|
||||||
UserManagerDependency = DependencyCallable[BaseUserManager[models.UP, models.ID]]
|
UserManagerDependency = DependencyCallable[BaseUserManager[models.UP, models.ID]]
|
||||||
|
@ -2,13 +2,8 @@ from typing import Type
|
|||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||||
|
|
||||||
from fastapi_users import models, schemas
|
from fastapi_users import exceptions, models, schemas
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.manager import BaseUserManager, UserManagerDependency
|
||||||
BaseUserManager,
|
|
||||||
InvalidPasswordException,
|
|
||||||
UserAlreadyExists,
|
|
||||||
UserManagerDependency,
|
|
||||||
)
|
|
||||||
from fastapi_users.router.common import ErrorCode, ErrorModel
|
from fastapi_users.router.common import ErrorCode, ErrorModel
|
||||||
|
|
||||||
|
|
||||||
@ -62,12 +57,12 @@ def get_register_router(
|
|||||||
created_user = await user_manager.create(
|
created_user = await user_manager.create(
|
||||||
user_create, safe=True, request=request
|
user_create, safe=True, request=request
|
||||||
)
|
)
|
||||||
except UserAlreadyExists:
|
except exceptions.UserAlreadyExists:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ErrorCode.REGISTER_USER_ALREADY_EXISTS,
|
detail=ErrorCode.REGISTER_USER_ALREADY_EXISTS,
|
||||||
)
|
)
|
||||||
except InvalidPasswordException as e:
|
except exceptions.InvalidPasswordException as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail={
|
detail={
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
from fastapi import APIRouter, Body, Depends, HTTPException, Request, status
|
from fastapi import APIRouter, Body, Depends, HTTPException, Request, status
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr
|
||||||
|
|
||||||
from fastapi_users import models
|
from fastapi_users import exceptions, models
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.manager import BaseUserManager, UserManagerDependency
|
||||||
BaseUserManager,
|
|
||||||
InvalidPasswordException,
|
|
||||||
InvalidResetPasswordToken,
|
|
||||||
UserInactive,
|
|
||||||
UserManagerDependency,
|
|
||||||
UserNotExists,
|
|
||||||
)
|
|
||||||
from fastapi_users.openapi import OpenAPIResponseType
|
from fastapi_users.openapi import OpenAPIResponseType
|
||||||
from fastapi_users.router.common import ErrorCode, ErrorModel
|
from fastapi_users.router.common import ErrorCode, ErrorModel
|
||||||
|
|
||||||
@ -57,12 +50,12 @@ def get_reset_password_router(
|
|||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
user = await user_manager.get_by_email(email)
|
user = await user_manager.get_by_email(email)
|
||||||
except UserNotExists:
|
except exceptions.UserNotExists:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await user_manager.forgot_password(user, request)
|
await user_manager.forgot_password(user, request)
|
||||||
except UserInactive:
|
except exceptions.UserInactive:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return None
|
return None
|
||||||
@ -80,12 +73,16 @@ def get_reset_password_router(
|
|||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
await user_manager.reset_password(token, password, request)
|
await user_manager.reset_password(token, password, request)
|
||||||
except (InvalidResetPasswordToken, UserNotExists, UserInactive):
|
except (
|
||||||
|
exceptions.InvalidResetPasswordToken,
|
||||||
|
exceptions.UserNotExists,
|
||||||
|
exceptions.UserInactive,
|
||||||
|
):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
|
detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
|
||||||
)
|
)
|
||||||
except InvalidPasswordException as e:
|
except exceptions.InvalidPasswordException as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail={
|
detail={
|
||||||
|
@ -2,16 +2,9 @@ from typing import Any, Type
|
|||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
|
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
|
||||||
|
|
||||||
from fastapi_users import models, schemas
|
from fastapi_users import exceptions, models, schemas
|
||||||
from fastapi_users.authentication import Authenticator
|
from fastapi_users.authentication import Authenticator
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.manager import BaseUserManager, UserManagerDependency
|
||||||
BaseUserManager,
|
|
||||||
InvalidID,
|
|
||||||
InvalidPasswordException,
|
|
||||||
UserAlreadyExists,
|
|
||||||
UserManagerDependency,
|
|
||||||
UserNotExists,
|
|
||||||
)
|
|
||||||
from fastapi_users.router.common import ErrorCode, ErrorModel
|
from fastapi_users.router.common import ErrorCode, ErrorModel
|
||||||
|
|
||||||
|
|
||||||
@ -39,7 +32,7 @@ def get_users_router(
|
|||||||
try:
|
try:
|
||||||
parsed_id = user_manager.parse_id(id)
|
parsed_id = user_manager.parse_id(id)
|
||||||
return await user_manager.get(parsed_id)
|
return await user_manager.get(parsed_id)
|
||||||
except (UserNotExists, InvalidID) as e:
|
except (exceptions.UserNotExists, exceptions.InvalidID) as e:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) from e
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) from e
|
||||||
|
|
||||||
@router.get(
|
@router.get(
|
||||||
@ -103,7 +96,7 @@ def get_users_router(
|
|||||||
return await user_manager.update(
|
return await user_manager.update(
|
||||||
user_update, user, safe=True, request=request
|
user_update, user, safe=True, request=request
|
||||||
)
|
)
|
||||||
except InvalidPasswordException as e:
|
except exceptions.InvalidPasswordException as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail={
|
detail={
|
||||||
@ -111,7 +104,7 @@ def get_users_router(
|
|||||||
"reason": e.reason,
|
"reason": e.reason,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
except UserAlreadyExists:
|
except exceptions.UserAlreadyExists:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status.HTTP_400_BAD_REQUEST,
|
status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ErrorCode.UPDATE_USER_EMAIL_ALREADY_EXISTS,
|
detail=ErrorCode.UPDATE_USER_EMAIL_ALREADY_EXISTS,
|
||||||
@ -189,7 +182,7 @@ def get_users_router(
|
|||||||
return await user_manager.update(
|
return await user_manager.update(
|
||||||
user_update, user, safe=False, request=request
|
user_update, user, safe=False, request=request
|
||||||
)
|
)
|
||||||
except InvalidPasswordException as e:
|
except exceptions.InvalidPasswordException as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail={
|
detail={
|
||||||
@ -197,7 +190,7 @@ def get_users_router(
|
|||||||
"reason": e.reason,
|
"reason": e.reason,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
except UserAlreadyExists:
|
except exceptions.UserAlreadyExists:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status.HTTP_400_BAD_REQUEST,
|
status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ErrorCode.UPDATE_USER_EMAIL_ALREADY_EXISTS,
|
detail=ErrorCode.UPDATE_USER_EMAIL_ALREADY_EXISTS,
|
||||||
|
@ -3,15 +3,8 @@ from typing import Type
|
|||||||
from fastapi import APIRouter, Body, Depends, HTTPException, Request, status
|
from fastapi import APIRouter, Body, Depends, HTTPException, Request, status
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr
|
||||||
|
|
||||||
from fastapi_users import models, schemas
|
from fastapi_users import exceptions, models, schemas
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.manager import BaseUserManager, UserManagerDependency
|
||||||
BaseUserManager,
|
|
||||||
InvalidVerifyToken,
|
|
||||||
UserAlreadyVerified,
|
|
||||||
UserInactive,
|
|
||||||
UserManagerDependency,
|
|
||||||
UserNotExists,
|
|
||||||
)
|
|
||||||
from fastapi_users.router.common import ErrorCode, ErrorModel
|
from fastapi_users.router.common import ErrorCode, ErrorModel
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +27,11 @@ def get_verify_router(
|
|||||||
try:
|
try:
|
||||||
user = await user_manager.get_by_email(email)
|
user = await user_manager.get_by_email(email)
|
||||||
await user_manager.request_verify(user, request)
|
await user_manager.request_verify(user, request)
|
||||||
except (UserNotExists, UserInactive, UserAlreadyVerified):
|
except (
|
||||||
|
exceptions.UserNotExists,
|
||||||
|
exceptions.UserInactive,
|
||||||
|
exceptions.UserAlreadyVerified,
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return None
|
return None
|
||||||
@ -73,12 +70,12 @@ def get_verify_router(
|
|||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
return await user_manager.verify(token, request)
|
return await user_manager.verify(token, request)
|
||||||
except (InvalidVerifyToken, UserNotExists):
|
except (exceptions.InvalidVerifyToken, exceptions.UserNotExists):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
|
detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
|
||||||
)
|
)
|
||||||
except UserAlreadyVerified:
|
except exceptions.UserAlreadyVerified:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail=ErrorCode.VERIFY_USER_ALREADY_VERIFIED,
|
detail=ErrorCode.VERIFY_USER_ALREADY_VERIFIED,
|
||||||
|
@ -22,18 +22,12 @@ from httpx_oauth.oauth2 import OAuth2
|
|||||||
from pydantic import UUID4, SecretStr
|
from pydantic import UUID4, SecretStr
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from fastapi_users import models, schemas
|
from fastapi_users import exceptions, models, schemas
|
||||||
from fastapi_users.authentication import AuthenticationBackend, BearerTransport
|
from fastapi_users.authentication import AuthenticationBackend, BearerTransport
|
||||||
from fastapi_users.authentication.strategy import Strategy
|
from fastapi_users.authentication.strategy import Strategy
|
||||||
from fastapi_users.db import BaseUserDatabase
|
from fastapi_users.db import BaseUserDatabase
|
||||||
from fastapi_users.jwt import SecretType
|
from fastapi_users.jwt import SecretType
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.manager import BaseUserManager, UUIDIDMixin
|
||||||
BaseUserManager,
|
|
||||||
InvalidID,
|
|
||||||
InvalidPasswordException,
|
|
||||||
UserNotExists,
|
|
||||||
UUIDIDMixin,
|
|
||||||
)
|
|
||||||
from fastapi_users.openapi import OpenAPIResponseType
|
from fastapi_users.openapi import OpenAPIResponseType
|
||||||
from fastapi_users.password import PasswordHelper
|
from fastapi_users.password import PasswordHelper
|
||||||
|
|
||||||
@ -101,7 +95,7 @@ class BaseTestUserManager(
|
|||||||
self, password: str, user: Union[schemas.UC, models.UP]
|
self, password: str, user: Union[schemas.UC, models.UP]
|
||||||
) -> None:
|
) -> None:
|
||||||
if len(password) < 3:
|
if len(password) < 3:
|
||||||
raise InvalidPasswordException(
|
raise exceptions.InvalidPasswordException(
|
||||||
reason="Password should be at least 3 characters"
|
reason="Password should be at least 3 characters"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -533,7 +527,7 @@ class MockStrategy(Strategy[UserModel, IDType]):
|
|||||||
try:
|
try:
|
||||||
parsed_id = user_manager.parse_id(token)
|
parsed_id = user_manager.parse_id(token)
|
||||||
return await user_manager.get(parsed_id)
|
return await user_manager.get(parsed_id)
|
||||||
except (InvalidID, UserNotExists):
|
except (exceptions.InvalidID, exceptions.UserNotExists):
|
||||||
return None
|
return None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -5,9 +5,7 @@ from fastapi.security import OAuth2PasswordRequestForm
|
|||||||
from pydantic import UUID4
|
from pydantic import UUID4
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from fastapi_users.jwt import decode_jwt, generate_jwt
|
from fastapi_users.exceptions import (
|
||||||
from fastapi_users.manager import (
|
|
||||||
IntegerIDMixin,
|
|
||||||
InvalidID,
|
InvalidID,
|
||||||
InvalidPasswordException,
|
InvalidPasswordException,
|
||||||
InvalidResetPasswordToken,
|
InvalidResetPasswordToken,
|
||||||
@ -17,6 +15,8 @@ from fastapi_users.manager import (
|
|||||||
UserInactive,
|
UserInactive,
|
||||||
UserNotExists,
|
UserNotExists,
|
||||||
)
|
)
|
||||||
|
from fastapi_users.jwt import decode_jwt, generate_jwt
|
||||||
|
from fastapi_users.manager import IntegerIDMixin
|
||||||
from tests.conftest import (
|
from tests.conftest import (
|
||||||
UserCreate,
|
UserCreate,
|
||||||
UserManagerMock,
|
UserManagerMock,
|
||||||
|
@ -4,7 +4,7 @@ import httpx
|
|||||||
import pytest
|
import pytest
|
||||||
from fastapi import FastAPI, status
|
from fastapi import FastAPI, status
|
||||||
|
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.exceptions import (
|
||||||
InvalidPasswordException,
|
InvalidPasswordException,
|
||||||
InvalidResetPasswordToken,
|
InvalidResetPasswordToken,
|
||||||
UserInactive,
|
UserInactive,
|
||||||
|
@ -4,7 +4,7 @@ import httpx
|
|||||||
import pytest
|
import pytest
|
||||||
from fastapi import FastAPI, status
|
from fastapi import FastAPI, status
|
||||||
|
|
||||||
from fastapi_users.manager import (
|
from fastapi_users.exceptions import (
|
||||||
InvalidVerifyToken,
|
InvalidVerifyToken,
|
||||||
UserAlreadyVerified,
|
UserAlreadyVerified,
|
||||||
UserInactive,
|
UserInactive,
|
||||||
|
Reference in New Issue
Block a user