"""Player authentication configuration (token reset policy). Stores the single-row policy that controls how often a player's authentication token is invalidated so that the client restarts its authentication flow on the next heartbeat. """ from datetime import datetime from typing import Optional from app.extensions import db class PlayerAuthConfig(db.Model): """Single-row settings for player authentication tokens. Attributes: id: Primary key reset_interval_days: Automatically require re-authentication once a token is older than this many days. ``0`` (the default) disables automatic expiry; tokens are then only reset manually from the maintenance page. updated_at: Last modification timestamp updated_by: Username of the last editor """ __tablename__ = 'player_auth_config' id = db.Column(db.Integer, primary_key=True) reset_interval_days = db.Column(db.Integer, default=0, nullable=False) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) updated_by = db.Column(db.String(255), nullable=True) def __repr__(self) -> str: """String representation of PlayerAuthConfig.""" return f'' @classmethod def get_config(cls) -> Optional['PlayerAuthConfig']: """Return the current configuration row, or ``None`` if unset.""" return cls.query.first() @classmethod def get_interval_days(cls) -> int: """Return the configured reset interval in days (0 = disabled). Defensive against an unset row or a NULL/negative value so callers can use the result directly without extra guards. """ config = cls.get_config() if not config or not config.reset_interval_days: return 0 return max(0, int(config.reset_interval_days)) @classmethod def create_or_update(cls, reset_interval_days: int, updated_by: str = None) -> 'PlayerAuthConfig': """Create or update the authentication reset policy. Args: reset_interval_days: Days before a token is auto-expired (0 disables automatic expiry) updated_by: Username of the editor Returns: The persisted ``PlayerAuthConfig`` instance. """ config = cls.get_config() if not config: config = cls() config.reset_interval_days = max(0, int(reset_interval_days or 0)) config.updated_by = updated_by config.updated_at = datetime.utcnow() db.session.add(config) db.session.commit() return config def to_dict(self) -> dict: """Convert configuration to a dictionary.""" return { 'id': self.id, 'reset_interval_days': self.reset_interval_days, 'updated_at': self.updated_at.isoformat() if self.updated_at else None, 'updated_by': self.updated_by, }