import uuid from typing import Any import bcrypt from passlib.context import CryptContext from sqlalchemy import Column, 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()