"""Superadmin session model.""" import logging from datetime import datetime, timezone, timedelta from gatehouse_app.extensions import db from gatehouse_app.models.base import BaseModel logger = logging.getLogger(__name__) class SuperadminSessionStatus: """Session status constants.""" ACTIVE = "active" REVOKED = "revoked" EXPIRED = "expired" class SuperadminSession(BaseModel): """Session model for superadmin authentication.""" __tablename__ = "superadmin_sessions" superadmin_id = db.Column( db.String(36), db.ForeignKey("superadmins.id"), nullable=False, index=True ) token = db.Column(db.String(255), unique=True, nullable=False, index=True) expires_at = db.Column(db.DateTime, nullable=False) last_activity_at = db.Column( db.DateTime, nullable=False, default=lambda: datetime.now(timezone.utc) ) ip_address = db.Column(db.String(45), nullable=True) user_agent = db.Column(db.Text, nullable=True) revoked_at = db.Column(db.DateTime, nullable=True) revoked_reason = db.Column(db.String(255), nullable=True) # Relationship superadmin = db.relationship("Superadmin", back_populates="sessions") def __repr__(self): return f"" def is_active(self): """Check if session is currently active.""" now = datetime.now(timezone.utc) expires_at = self.expires_at if expires_at.tzinfo is None: expires_at = expires_at.replace(tzinfo=timezone.utc) return ( self.deleted_at is None and self.revoked_at is None and expires_at > now ) def is_expired(self): """Check if session has expired.""" now = datetime.now(timezone.utc) expires_at = self.expires_at if expires_at.tzinfo is None: expires_at = expires_at.replace(tzinfo=timezone.utc) return now > expires_at def revoke(self, reason: str = None): """Revoke the session.""" self.revoked_at = datetime.now(timezone.utc) if reason: self.revoked_reason = reason from gatehouse_app import db db.session.commit() def to_dict(self, exclude=None): """Convert to dictionary, excluding sensitive fields.""" exclude = exclude or [] exclude.append("token") return super().to_dict(exclude=exclude)