45 lines
1.5 KiB
Python
45 lines
1.5 KiB
Python
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:]}"
|