import hashlib import secrets from datetime import datetime from sqlalchemy import Boolean, String from sqlalchemy.orm import Mapped, mapped_column from app.core.database import Base class ApiKeyModel(Base): """Гостевой API-ключ с ограниченными правами.""" __tablename__ = "api_keys" key: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String) # "Вася", "гости" is_admin: Mapped[bool] = mapped_column( Boolean, default=False ) # доступ к CRUD групп, расписаниям active: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[str] = mapped_column( String, default=lambda: datetime.now().isoformat() ) @staticmethod def generate_key() -> str: """Генерация безопасного случайного токена.""" return secrets.token_urlsafe(32) @staticmethod def public_id_for(key: str) -> str: """ Возвращает безопасный публичный идентификатор ключа. Его можно отдавать клиенту и использовать в операциях revoke/activate вместо самого секрета. """ return hashlib.sha256(key.encode("utf-8")).hexdigest()[:16] @property def public_id(self) -> str: return self.public_id_for(self.key) @property def preview(self) -> str: return f"{self.key[:6]}...{self.key[-4:]}"