Big-Link-Man/src/auth/service.py

101 lines
2.9 KiB
Python

"""
Authentication service for user login and password management
"""
from typing import Optional
from passlib.context import CryptContext
from src.database.models import User
from src.database.repositories import UserRepository
# Configure password hashing context using bcrypt
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
class AuthService:
"""Service for handling user authentication and password operations"""
def __init__(self, user_repository: UserRepository):
"""
Initialize the authentication service
Args:
user_repository: Repository for user data access
"""
self.user_repository = user_repository
@staticmethod
def hash_password(password: str) -> str:
"""
Securely hash a password using bcrypt
Args:
password: The plain text password to hash
Returns:
The hashed password string
"""
return pwd_context.hash(password)
@staticmethod
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""
Verify a plain text password against a hashed password
Args:
plain_password: The plain text password to verify
hashed_password: The hashed password to compare against
Returns:
True if password matches, False otherwise
"""
return pwd_context.verify(plain_password, hashed_password)
def authenticate_user(self, username: str, password: str) -> Optional[User]:
"""
Authenticate a user by username and password
Args:
username: The username to authenticate
password: The plain text password to verify
Returns:
User object if authentication succeeds, None if credentials are invalid
"""
# Get user by username
user = self.user_repository.get_by_username(username)
# Return None if user doesn't exist
if not user:
return None
# Verify password
if not self.verify_password(password, user.hashed_password):
return None
# Return authenticated user
return user
def create_user_with_hashed_password(
self,
username: str,
password: str,
role: str
) -> User:
"""
Create a new user with a hashed password
Args:
username: The username for the new user
password: The plain text password (will be hashed)
role: The role ("Admin" or "User")
Returns:
The created User object
Raises:
ValueError: If username already exists or role is invalid
"""
hashed_password = self.hash_password(password)
return self.user_repository.create(username, hashed_password, role)