Files
BanGUI/backend/app/utils/constants.py
2026-05-04 07:20:16 +02:00

182 lines
6.3 KiB
Python

"""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."""
# ---------------------------------------------------------------------------
# Authentication penalty (brute-force resistance)
# ---------------------------------------------------------------------------
LOGIN_PENALTY_BASE_SECONDS: Final[float] = 1.0
"""Base penalty (seconds) for a failed login attempt."""
LOGIN_PENALTY_MAX_SECONDS: Final[float] = 10.0
"""Maximum penalty (seconds) for failed login attempts."""
LOGIN_PENALTY_MULTIPLIER: Final[float] = 2.0
"""Exponential multiplier applied per failed attempt."""
# ---------------------------------------------------------------------------
# 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] = 100
"""Max ban requests per IP per minute."""
RATE_LIMIT_BANS_UNBAN_REQUESTS: Final[int] = 100
"""Max unban requests per IP per minute."""
RATE_LIMIT_BLOCKLIST_IMPORT_REQUESTS: Final[int] = 10
"""Max blocklist import requests per IP per hour."""
RATE_LIMIT_CONFIG_UPDATE_REQUESTS: Final[int] = 50
"""Max config update requests per IP per minute."""
RATE_LIMIT_FILTER_UPDATE_REQUESTS: Final[int] = 50
"""Max filter config update requests per IP per minute."""
RATE_LIMIT_FILTER_CREATE_REQUESTS: Final[int] = 50
"""Max filter config create requests per IP per minute."""
RATE_LIMIT_FILTER_DELETE_REQUESTS: Final[int] = 50
"""Max filter config delete requests per IP per minute."""
RATE_LIMIT_ACTION_UPDATE_REQUESTS: Final[int] = 50
"""Max action config update requests per IP per minute."""
RATE_LIMIT_ACTION_CREATE_REQUESTS: Final[int] = 50
"""Max action config create requests per IP per minute."""
RATE_LIMIT_ACTION_DELETE_REQUESTS: Final[int] = 50
"""Max action config delete requests per IP per minute."""
RATE_LIMIT_JAIL_UPDATE_REQUESTS: Final[int] = 100
"""Max jail config update requests per IP per minute."""
RATE_LIMIT_JAIL_CREATE_REQUESTS: Final[int] = 100
"""Max jail config create requests per IP per minute."""
RATE_LIMIT_JAIL_DELETE_REQUESTS: Final[int] = 100
"""Max jail config delete requests per IP per minute."""
RATE_LIMIT_JAIL_ACTIVATE_REQUESTS: Final[int] = 100
"""Max jail activation requests per IP per minute."""
RATE_LIMIT_JAIL_DEACTIVATE_REQUESTS: Final[int] = 100
"""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."""