"""Application-wide constants. All magic numbers, default paths, and limit values live here. Import from this module rather than hard-coding values in business logic. """ from typing import Final # --------------------------------------------------------------------------- # fail2ban integration # --------------------------------------------------------------------------- DEFAULT_FAIL2BAN_SOCKET: Final[str] = "/var/run/fail2ban/fail2ban.sock" """Default path to the fail2ban Unix domain socket.""" FAIL2BAN_SOCKET_TIMEOUT_FAST: Final[float] = 5.0 """Maximum seconds for fast operations (health checks, metadata probes).""" FAIL2BAN_SOCKET_TIMEOUT: Final[float] = 10.0 """Maximum seconds for command operations (config, jail management).""" FAIL2BAN_TRUTHY_VALUES: Final[frozenset[str]] = frozenset({"true", "yes", "1"}) """String values treated as boolean true by fail2ban configuration parsers.""" # --------------------------------------------------------------------------- # Database # --------------------------------------------------------------------------- DEFAULT_DATABASE_PATH: Final[str] = "bangui.db" """Default filename for the BanGUI application SQLite database.""" # --------------------------------------------------------------------------- # Authentication # --------------------------------------------------------------------------- DEFAULT_SESSION_DURATION_MINUTES: Final[int] = 60 """Default session lifetime in minutes.""" SESSION_TOKEN_BYTES: Final[int] = 32 """Number of random bytes used when generating a session token.""" SESSION_TOKEN_SIGNATURE_SEPARATOR: Final[str] = "." """Separator used to append a signature to a signed session token.""" SESSION_COOKIE_NAME: Final[str] = "bangui_session" """Name of the session cookie used by the browser SPA.""" CSRF_HEADER_NAME: Final[str] = "X-BanGUI-Request" """Name of the custom header clients must send for state-mutating requests.""" CSRF_HEADER_VALUE: Final[str] = "1" """Required value of the CSRF header to pass validation.""" # --------------------------------------------------------------------------- # Time-range presets (used by dashboard and history endpoints) # --------------------------------------------------------------------------- TIME_RANGE_24H: Final[str] = "24h" TIME_RANGE_7D: Final[str] = "7d" TIME_RANGE_30D: Final[str] = "30d" TIME_RANGE_365D: Final[str] = "365d" VALID_TIME_RANGES: Final[frozenset[str]] = frozenset( {TIME_RANGE_24H, TIME_RANGE_7D, TIME_RANGE_30D, TIME_RANGE_365D} ) TIME_RANGE_HOURS: Final[dict[str, int]] = { TIME_RANGE_24H: 24, TIME_RANGE_7D: 7 * 24, TIME_RANGE_30D: 30 * 24, TIME_RANGE_365D: 365 * 24, } TIME_RANGE_SLACK_SECONDS: Final[int] = 60 """Clock drift and test seeding tolerance for timestamp comparisons.""" # --------------------------------------------------------------------------- # Pagination # --------------------------------------------------------------------------- DEFAULT_PAGE_SIZE: Final[int] = 100 """Default items per page for paginated endpoints.""" # --------------------------------------------------------------------------- # Blocklist import # --------------------------------------------------------------------------- BLOCKLIST_IMPORT_DEFAULT_HOUR: Final[int] = 3 """Default hour (UTC) for the nightly blocklist import job.""" # --------------------------------------------------------------------------- # Health check # --------------------------------------------------------------------------- HEALTH_CHECK_INTERVAL_SECONDS: Final[int] = 30 """How often the background health-check task polls fail2ban.""" # --------------------------------------------------------------------------- # Rate limits (per IP) # --------------------------------------------------------------------------- RATE_LIMIT_BANS_BAN_REQUESTS: Final[int] = 10000 """Max ban requests per IP per minute.""" RATE_LIMIT_BANS_UNBAN_REQUESTS: Final[int] = 10000 """Max unban requests per IP per minute.""" RATE_LIMIT_BLOCKLIST_IMPORT_REQUESTS: Final[int] = 10000 """Max blocklist import requests per IP per hour.""" RATE_LIMIT_CONFIG_UPDATE_REQUESTS: Final[int] = 5000 """Max config update requests per IP per minute.""" RATE_LIMIT_FILTER_UPDATE_REQUESTS: Final[int] = 5000 """Max filter config update requests per IP per minute.""" RATE_LIMIT_FILTER_CREATE_REQUESTS: Final[int] = 5000 """Max filter config create requests per IP per minute.""" RATE_LIMIT_FILTER_DELETE_REQUESTS: Final[int] = 5000 """Max filter config delete requests per IP per minute.""" RATE_LIMIT_ACTION_UPDATE_REQUESTS: Final[int] = 5000 """Max action config update requests per IP per minute.""" RATE_LIMIT_ACTION_CREATE_REQUESTS: Final[int] = 5000 """Max action config create requests per IP per minute.""" RATE_LIMIT_ACTION_DELETE_REQUESTS: Final[int] = 5000 """Max action config delete requests per IP per minute.""" RATE_LIMIT_JAIL_UPDATE_REQUESTS: Final[int] = 10000 """Max jail config update requests per IP per minute.""" RATE_LIMIT_JAIL_CREATE_REQUESTS: Final[int] = 10000 """Max jail config create requests per IP per minute.""" RATE_LIMIT_JAIL_DELETE_REQUESTS: Final[int] = 10000 """Max jail config delete requests per IP per minute.""" RATE_LIMIT_JAIL_ACTIVATE_REQUESTS: Final[int] = 10000 """Max jail activation requests per IP per minute.""" RATE_LIMIT_JAIL_DEACTIVATE_REQUESTS: Final[int] = 10000 """Max jail deactivation requests per IP per minute.""" # --------------------------------------------------------------------------- # Jail configuration # --------------------------------------------------------------------------- FAIL2BAN_RESERVED_JAIL_NAMES: Final[frozenset[str]] = frozenset( { "all", "status", "purge", "start", "stop", "reload", "restart", "ban", "unban", "add", "del", "set", "get", } ) """fail2ban reserved jail names. Users cannot create jails with these names."""