Changed module name from my_auth to myauth
Changed encryption algorithm to argon2 Added unit tests
This commit is contained in:
6
src/myauth/__init__.py
Normal file
6
src/myauth/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from .factory import create_sqlite_auth_service, create_app_router_for_sqlite
|
||||
|
||||
__all__ = [
|
||||
'create_sqlite_auth_service',
|
||||
'create_app_router_for_sqlite',
|
||||
]
|
||||
3
src/myauth/api/__init__.py
Normal file
3
src/myauth/api/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .routes import create_auth_router
|
||||
|
||||
__all__ = ["create_auth_router"]
|
||||
5
src/myauth/core/__init__.py
Normal file
5
src/myauth/core/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .auth import AuthService
|
||||
from .password import PasswordManager
|
||||
from .token import TokenManager
|
||||
|
||||
__all__ = ["AuthService", "PasswordManager", "TokenManager"]
|
||||
@@ -14,7 +14,7 @@ from .token import TokenManager
|
||||
from ..persistence.base import UserRepository, TokenRepository
|
||||
from ..models.user import UserCreate, UserInDB, UserUpdate
|
||||
from ..models.token import AccessTokenResponse, TokenData
|
||||
from ..email.base import EmailService
|
||||
from ..emailing.base import EmailService
|
||||
from ..exceptions import (
|
||||
InvalidCredentialsError,
|
||||
UserNotFoundError,
|
||||
@@ -12,31 +12,21 @@ class PasswordManager:
|
||||
"""
|
||||
Manager for password hashing and verification operations.
|
||||
|
||||
This class uses bcrypt for secure password hashing with configurable
|
||||
cost factor (rounds). Higher rounds provide better security but slower
|
||||
performance.
|
||||
|
||||
Attributes:
|
||||
rounds: Bcrypt cost factor (default: 12). Higher values increase
|
||||
security but also increase computation time.
|
||||
This class uses argon2 for secure password hashing
|
||||
"""
|
||||
|
||||
def __init__(self, rounds: int = 12):
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the password manager.
|
||||
|
||||
Args:
|
||||
rounds: Bcrypt cost factor (4-31). Default is 12 which provides
|
||||
a good balance between security and performance.
|
||||
"""
|
||||
if rounds < 4 or rounds > 31:
|
||||
raise ValueError("Bcrypt rounds must be between 4 and 31")
|
||||
|
||||
self.rounds = rounds
|
||||
self._context = CryptContext(
|
||||
schemes=["bcrypt"],
|
||||
schemes=["argon2"],
|
||||
deprecated="auto",
|
||||
bcrypt__rounds=self.rounds
|
||||
# argon2__time_cost=3, # number of iterations (increases CPU time)
|
||||
# argon2__memory_cost=65536, # memory usage in KiB (64 MiB)
|
||||
# argon2__parallelism=2, # number of parallel threads
|
||||
# argon2__salt_len=16 # length of the random salt in bytes
|
||||
)
|
||||
|
||||
def hash_password(self, password: str) -> str:
|
||||
4
src/myauth/emailing/__init__.py
Normal file
4
src/myauth/emailing/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .base import EmailService
|
||||
from .smtp import SMTPEmailService
|
||||
|
||||
__all__ = ["EmailService", "SMTPEmailService"]
|
||||
78
src/myauth/factory.py
Normal file
78
src/myauth/factory.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from typing import Optional
|
||||
|
||||
from .core import AuthService
|
||||
from .core.password import PasswordManager
|
||||
from .core.token import TokenManager
|
||||
from .emailing.base import EmailService
|
||||
|
||||
|
||||
def create_sqlite_auth_service(db_path: str,
|
||||
jwt_secret: str,
|
||||
email_service: Optional[EmailService],
|
||||
password_manager: PasswordManager = None,
|
||||
token_manager: TokenManager = None,
|
||||
):
|
||||
"""
|
||||
Creates and configures an authentication service using SQLite as the underlying
|
||||
data store.
|
||||
|
||||
This function is responsible for setting up the necessary repositories
|
||||
and managers required for the AuthService. It uses SQLite repositories
|
||||
for user and token data and initializes the required managers for password
|
||||
and token processing, as well as an optional email service.
|
||||
|
||||
:param db_path: Path to the SQLite database file used to persist authentication
|
||||
data.
|
||||
:type db_path: str
|
||||
:param jwt_secret: Secret key used to encode and decode JSON Web Tokens (JWTs).
|
||||
:type jwt_secret: str
|
||||
:param email_service: Optional email service instance for managing email-based
|
||||
communication.
|
||||
:type email_service: Optional[EmailService]
|
||||
:param password_manager: Optional custom PasswordManager instance responsible for
|
||||
password-related operations. Defaults to a new instance.
|
||||
:type password_manager: PasswordManager
|
||||
:param token_manager: Optional custom TokenManager instance responsible for token
|
||||
generation and verification. Defaults to a new instance
|
||||
configured with `jwt_secret`.
|
||||
:type token_manager: TokenManager
|
||||
:return: A fully configured instance of AuthService with the specified
|
||||
repositories and managers.
|
||||
:rtype: AuthService
|
||||
"""
|
||||
from .persistence.sqlite import SQLiteUserRepository
|
||||
from .persistence.sqlite import SQLiteTokenRepository
|
||||
user_repository = SQLiteUserRepository(db_path)
|
||||
token_repository = SQLiteTokenRepository(db_path)
|
||||
password_manager = password_manager or PasswordManager()
|
||||
token_manager = token_manager or TokenManager(jwt_secret)
|
||||
|
||||
auth_service = AuthService(
|
||||
user_repository=user_repository,
|
||||
token_repository=token_repository,
|
||||
password_manager=password_manager,
|
||||
token_manager=token_manager,
|
||||
email_service=email_service)
|
||||
|
||||
return auth_service
|
||||
|
||||
|
||||
def create_app_router_for_sqlite(db_path: str,
|
||||
jwt_secret: str,
|
||||
email_service: Optional[EmailService] = None):
|
||||
"""
|
||||
Creates an application router designed to use with an SQLite database backend.
|
||||
This function initializes an authentication service using the provided database
|
||||
path and JWT secret, optionally integrating an email service for email-based
|
||||
authentication functionalities. The authentication service is then used to
|
||||
create an application router for handling authentication-related API routes.
|
||||
|
||||
:param db_path: Path to the SQLite database file.
|
||||
:param jwt_secret: A secret string used for signing and verifying JWT tokens.
|
||||
:param email_service: An optional email service instance for managing email-related
|
||||
communication and functionalities during authentication.
|
||||
:return: An application router configured for handling authentication API routes.
|
||||
"""
|
||||
auth_service = create_sqlite_auth_service(db_path, jwt_secret, email_service)
|
||||
from .api.routes import create_auth_router
|
||||
return create_auth_router(auth_service)
|
||||
@@ -7,7 +7,7 @@ reset operations including request and confirmation models.
|
||||
|
||||
from pydantic import BaseModel, EmailStr, field_validator
|
||||
|
||||
from my_auth.models.validators import validate_password_strength
|
||||
from ..models.validators import validate_password_strength
|
||||
|
||||
|
||||
class EmailVerificationRequest(BaseModel):
|
||||
@@ -10,7 +10,7 @@ from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, EmailStr, Field, field_validator
|
||||
|
||||
from my_auth.models.validators import validate_password_strength, validate_username_not_empty
|
||||
from ..models.validators import validate_password_strength, validate_username_not_empty
|
||||
|
||||
|
||||
class UserBase(BaseModel):
|
||||
6
src/myauth/persistence/__init__.py
Normal file
6
src/myauth/persistence/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from .sqlite import UserRepository, TokenRepository
|
||||
|
||||
__all__ = [
|
||||
"UserRepository",
|
||||
"TokenRepository",
|
||||
]
|
||||
Reference in New Issue
Block a user