"""API key model for service authentication.""" from datetime import datetime from enum import Enum from uuid import UUID, uuid4 from sqlalchemy import String, ForeignKey, Integer, DateTime, JSON from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base class ApiKeyStatus(str, Enum): ACTIVE = "active" REVOKED = "revoked" EXPIRED = "expired" class ApiKey(Base): __tablename__ = "api_keys" id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4) tenant_id: Mapped[UUID] = mapped_column( ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False ) name: Mapped[str] = mapped_column(String(100), nullable=False) key_hash: Mapped[str] = mapped_column(String(255), nullable=False) key_prefix: Mapped[str] = mapped_column(String(8), nullable=False) scopes: Mapped[list[str]] = mapped_column(JSON, default=list) rate_limit: Mapped[int] = mapped_column(Integer, default=1000) expires_at: Mapped[datetime | None] last_used_at: Mapped[datetime | None] created_by: Mapped[UUID | None] = mapped_column(ForeignKey("users.id")) status: Mapped[ApiKeyStatus] = mapped_column(default=ApiKeyStatus.ACTIVE) created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow) # Relationships tenant: Mapped["Tenant"] = relationship(back_populates="api_keys") creator: Mapped["User | None"] = relationship(back_populates="api_keys_created") def __repr__(self) -> str: return f"" def is_valid(self) -> bool: """Check if key is active and not expired.""" if self.status != ApiKeyStatus.ACTIVE: return False if self.expires_at and self.expires_at < datetime.utcnow(): return False return True