81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
"""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"<SuperadminSession superadmin_id={self.superadmin_id}>"
|
|
|
|
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)
|