Spaces:
Sleeping
Sleeping
| """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 | |