REFACTOR - Database logic
This commit is contained in:
101
services/auth/app/repositories/base.py
Normal file
101
services/auth/app/repositories/base.py
Normal file
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
Base Repository for Auth Service
|
||||
Service-specific repository base class with auth service utilities
|
||||
"""
|
||||
|
||||
from typing import Optional, List, Dict, Any, Type
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from datetime import datetime, timezone
|
||||
import structlog
|
||||
|
||||
from shared.database.repository import BaseRepository
|
||||
from shared.database.exceptions import DatabaseError, ValidationError
|
||||
|
||||
logger = structlog.get_logger()
|
||||
|
||||
|
||||
class AuthBaseRepository(BaseRepository):
|
||||
"""Base repository for auth service with common auth operations"""
|
||||
|
||||
def __init__(self, model: Type, session: AsyncSession, cache_ttl: Optional[int] = 600):
|
||||
# Auth data benefits from longer caching (10 minutes)
|
||||
super().__init__(model, session, cache_ttl)
|
||||
|
||||
async def get_active_records(self, skip: int = 0, limit: int = 100) -> List:
|
||||
"""Get active records (if model has is_active field)"""
|
||||
if hasattr(self.model, 'is_active'):
|
||||
return await self.get_multi(
|
||||
skip=skip,
|
||||
limit=limit,
|
||||
filters={"is_active": True},
|
||||
order_by="created_at",
|
||||
order_desc=True
|
||||
)
|
||||
return await self.get_multi(skip=skip, limit=limit)
|
||||
|
||||
async def get_by_email(self, email: str) -> Optional:
|
||||
"""Get record by email (if model has email field)"""
|
||||
if hasattr(self.model, 'email'):
|
||||
return await self.get_by_field("email", email)
|
||||
return None
|
||||
|
||||
async def get_by_username(self, username: str) -> Optional:
|
||||
"""Get record by username (if model has username field)"""
|
||||
if hasattr(self.model, 'username'):
|
||||
return await self.get_by_field("username", username)
|
||||
return None
|
||||
|
||||
async def deactivate_record(self, record_id: Any) -> Optional:
|
||||
"""Deactivate a record instead of deleting it"""
|
||||
if hasattr(self.model, 'is_active'):
|
||||
return await self.update(record_id, {"is_active": False})
|
||||
return await self.delete(record_id)
|
||||
|
||||
async def activate_record(self, record_id: Any) -> Optional:
|
||||
"""Activate a record"""
|
||||
if hasattr(self.model, 'is_active'):
|
||||
return await self.update(record_id, {"is_active": True})
|
||||
return await self.get_by_id(record_id)
|
||||
|
||||
async def cleanup_expired_records(self, field_name: str = "expires_at") -> int:
|
||||
"""Clean up expired records (for tokens, sessions, etc.)"""
|
||||
try:
|
||||
if not hasattr(self.model, field_name):
|
||||
logger.warning(f"Model {self.model.__name__} has no {field_name} field for cleanup")
|
||||
return 0
|
||||
|
||||
# This would need custom implementation with raw SQL for date comparison
|
||||
# For now, return 0 to indicate no cleanup performed
|
||||
logger.info(f"Cleanup requested for {self.model.__name__} but not implemented")
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Failed to cleanup expired records",
|
||||
model=self.model.__name__,
|
||||
error=str(e))
|
||||
raise DatabaseError(f"Cleanup failed: {str(e)}")
|
||||
|
||||
def _validate_auth_data(self, data: Dict[str, Any], required_fields: List[str]) -> Dict[str, Any]:
|
||||
"""Validate authentication-related data"""
|
||||
errors = []
|
||||
|
||||
for field in required_fields:
|
||||
if field not in data or not data[field]:
|
||||
errors.append(f"Missing required field: {field}")
|
||||
|
||||
# Validate email format if present
|
||||
if "email" in data and data["email"]:
|
||||
email = data["email"]
|
||||
if "@" not in email or "." not in email.split("@")[-1]:
|
||||
errors.append("Invalid email format")
|
||||
|
||||
# Validate password strength if present
|
||||
if "password" in data and data["password"]:
|
||||
password = data["password"]
|
||||
if len(password) < 8:
|
||||
errors.append("Password must be at least 8 characters long")
|
||||
|
||||
return {
|
||||
"is_valid": len(errors) == 0,
|
||||
"errors": errors
|
||||
}
|
||||
Reference in New Issue
Block a user