"""Servicio de autenticación y gestión de usuarios.""" from __future__ import annotations from pymongo.asynchronous.database import AsyncDatabase from pymongo.errors import DuplicateKeyError from app.core.security import hash_password, verify_password from app.database import collections from app.exceptions import AuthenticationError, ConflictError from app.models.common import utcnow from app.schemas.auth import UserCreate from app.services.base import BaseService, Document class AuthService(BaseService): """Registro y autenticación de usuarios.""" collection_name = collections.USERS recurso = "Usuario" def __init__(self, db: AsyncDatabase) -> None: super().__init__(db) async def register(self, payload: UserCreate) -> Document: """Registra un nuevo usuario con la contraseña ya hasheada.""" document: Document = { "username": payload.username, "email": payload.email, "hashed_password": hash_password(payload.password), "is_active": True, "is_superuser": False, "fecha_creacion": utcnow(), } try: return await self._insert(document) except DuplicateKeyError as exc: raise ConflictError( "El nombre de usuario o el correo ya están registrados." ) from exc async def authenticate(self, identifier: str, password: str) -> Document: """Valida credenciales por nombre de usuario o correo.""" document = await self.collection.find_one( {"$or": [{"username": identifier}, {"email": identifier}]} ) if document is None or not verify_password( password, document.get("hashed_password", "") ): raise AuthenticationError("Usuario o contraseña incorrectos.") if not document.get("is_active", True): raise AuthenticationError("La cuenta está desactivada.") return document