Put exceptions in a dedicated module to avoid circular imports

This commit is contained in:
François Voron
2022-05-06 13:17:22 +02:00
parent 5f57c75813
commit 78be936297
15 changed files with 118 additions and 141 deletions

View File

@ -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)

View File

@ -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",

View File

@ -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:

View File

@ -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:

View File

@ -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:

View 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

View File

@ -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]]

View File

@ -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={

View File

@ -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={

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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,