import uuid from typing import Any import bcrypt from passlib.context import CryptContext from sqlalchemy import String, LargeBinary, select from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import mapped_column, Mapped from app import config from app.models.base import Base global_settings = config.get_settings() pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") class User(Base): id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), default=uuid.uuid4, primary_key=True) email: Mapped[str] = mapped_column(String, nullable=False, unique=True) first_name: Mapped[str] = mapped_column(String, nullable=False) last_name: Mapped[str] = mapped_column(String, nullable=False) _password: Mapped[bytes] = mapped_column(LargeBinary, nullable=False) @property def password(self): return self._password.decode("utf-8") @password.setter def password(self, password: str): self._password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) def check_password(self, password: str): return pwd_context.verify(password, self.password) @classmethod async def find(cls, database_session: AsyncSession, where_conditions: list[Any]): _stmt = select(cls).where(*where_conditions) _result = await database_session.execute(_stmt) return _result.scalars().first()