Fixed docker config. Added services
This commit is contained in:
181
src/file-processor/app/services/user_service.py
Normal file
181
src/file-processor/app/services/user_service.py
Normal file
@@ -0,0 +1,181 @@
|
||||
"""
|
||||
User service for business logic operations.
|
||||
|
||||
This module provides user-related business logic including user creation,
|
||||
retrieval, updates, and authentication operations with proper error handling.
|
||||
"""
|
||||
|
||||
from typing import Optional, List
|
||||
from pymongo.errors import DuplicateKeyError
|
||||
|
||||
from app.models.user import UserCreate, UserInDB, UserUpdate, UserResponse, UserCreateNoValidation
|
||||
from app.models.auth import UserRole
|
||||
from app.database.repositories.user_repository import UserRepository
|
||||
from app.services.auth_service import AuthService
|
||||
|
||||
|
||||
class UserService:
|
||||
"""
|
||||
Service class for user business logic operations.
|
||||
|
||||
This class handles user-related operations including creation,
|
||||
authentication, and data management with proper validation.
|
||||
"""
|
||||
|
||||
def __init__(self, user_repository: UserRepository):
|
||||
"""
|
||||
Initialize user service with repository dependency.
|
||||
|
||||
Args:
|
||||
user_repository (UserRepository): Repository for user data operations
|
||||
"""
|
||||
self.user_repository = user_repository
|
||||
self.auth_service = AuthService()
|
||||
|
||||
def create_user(self, user_data: UserCreate | UserCreateNoValidation) -> UserInDB:
|
||||
"""
|
||||
Create a new user with business logic validation.
|
||||
|
||||
Args:
|
||||
user_data (UserCreate): User creation data
|
||||
|
||||
Returns:
|
||||
UserInDB: Created user with database information
|
||||
|
||||
Raises:
|
||||
ValueError: If user already exists or validation fails
|
||||
"""
|
||||
# Check if user already exists
|
||||
if self.user_repository.user_exists(user_data.username):
|
||||
raise ValueError(f"User with username '{user_data.username}' already exists")
|
||||
|
||||
# Check if email already exists
|
||||
existing_user = self.user_repository.find_user_by_email(user_data.email)
|
||||
if existing_user:
|
||||
raise ValueError(f"User with email '{user_data.email}' already exists")
|
||||
|
||||
try:
|
||||
return self.user_repository.create_user(user_data)
|
||||
except DuplicateKeyError:
|
||||
raise ValueError(f"User with username '{user_data.username}' already exists")
|
||||
|
||||
def get_user_by_username(self, username: str) -> Optional[UserInDB]:
|
||||
"""
|
||||
Retrieve user by username.
|
||||
|
||||
Args:
|
||||
username (str): Username to search for
|
||||
|
||||
Returns:
|
||||
UserInDB or None: User if found, None otherwise
|
||||
"""
|
||||
return self.user_repository.find_user_by_username(username)
|
||||
|
||||
def get_user_by_id(self, user_id: str) -> Optional[UserInDB]:
|
||||
"""
|
||||
Retrieve user by ID.
|
||||
|
||||
Args:
|
||||
user_id (str): User ID to search for
|
||||
|
||||
Returns:
|
||||
UserInDB or None: User if found, None otherwise
|
||||
"""
|
||||
return self.user_repository.find_user_by_id(user_id)
|
||||
|
||||
def authenticate_user(self, username: str, password: str) -> Optional[UserInDB]:
|
||||
"""
|
||||
Authenticate user with username and password.
|
||||
|
||||
Args:
|
||||
username (str): Username for authentication
|
||||
password (str): Password for authentication
|
||||
|
||||
Returns:
|
||||
UserInDB or None: Authenticated user if valid, None otherwise
|
||||
"""
|
||||
user = self.user_repository.find_user_by_username(username)
|
||||
if not user:
|
||||
return None
|
||||
|
||||
if not user.is_active:
|
||||
return None
|
||||
|
||||
if not self.auth_service.verify_user_password(password, user.hashed_password):
|
||||
return None
|
||||
|
||||
return user
|
||||
|
||||
def update_user(self, user_id: str, user_update: UserUpdate) -> Optional[UserInDB]:
|
||||
"""
|
||||
Update user information.
|
||||
|
||||
Args:
|
||||
user_id (str): User ID to update
|
||||
user_update (UserUpdate): Updated user data
|
||||
|
||||
Returns:
|
||||
UserInDB or None: Updated user if successful, None otherwise
|
||||
|
||||
Raises:
|
||||
ValueError: If username or email already exists for different user
|
||||
"""
|
||||
# Validate username uniqueness if being updated
|
||||
if user_update.username is not None:
|
||||
existing_user = self.user_repository.find_user_by_username(user_update.username)
|
||||
if existing_user and str(existing_user.id) != user_id:
|
||||
raise ValueError(f"Username '{user_update.username}' is already taken")
|
||||
|
||||
# Validate email uniqueness if being updated
|
||||
if user_update.email is not None:
|
||||
existing_user = self.user_repository.find_user_by_email(user_update.email)
|
||||
if existing_user and str(existing_user.id) != user_id:
|
||||
raise ValueError(f"Email '{user_update.email}' is already taken")
|
||||
|
||||
return self.user_repository.update_user(user_id, user_update)
|
||||
|
||||
def delete_user(self, user_id: str) -> bool:
|
||||
"""
|
||||
Delete user from system.
|
||||
|
||||
Args:
|
||||
user_id (str): User ID to delete
|
||||
|
||||
Returns:
|
||||
bool: True if user was deleted, False otherwise
|
||||
"""
|
||||
return self.user_repository.delete_user(user_id)
|
||||
|
||||
def list_users(self, skip: int = 0, limit: int = 100) -> List[UserInDB]:
|
||||
"""
|
||||
List users with pagination.
|
||||
|
||||
Args:
|
||||
skip (int): Number of users to skip (default: 0)
|
||||
limit (int): Maximum number of users to return (default: 100)
|
||||
|
||||
Returns:
|
||||
List[UserInDB]: List of users
|
||||
"""
|
||||
return self.user_repository.list_users(skip=skip, limit=limit)
|
||||
|
||||
def count_users(self) -> int:
|
||||
"""
|
||||
Count total number of users.
|
||||
|
||||
Returns:
|
||||
int: Total number of users in system
|
||||
"""
|
||||
return self.user_repository.count_users()
|
||||
|
||||
def user_exists(self, username: str) -> bool:
|
||||
"""
|
||||
Check if user exists by username.
|
||||
|
||||
Args:
|
||||
username (str): Username to check
|
||||
|
||||
Returns:
|
||||
bool: True if user exists, False otherwise
|
||||
"""
|
||||
return self.user_repository.user_exists(username)
|
||||
Reference in New Issue
Block a user