Add deployment-safe backend config and production-safe CORS defaults
This commit is contained in:
@@ -4,9 +4,15 @@ Follows pydantic-settings patterns: all values are prefixed with BANGUI_
|
||||
and validated at startup via the Settings singleton.
|
||||
"""
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic import Field, field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
from app.utils.constants import (
|
||||
DEFAULT_DATABASE_PATH,
|
||||
DEFAULT_FAIL2BAN_SOCKET,
|
||||
DEFAULT_SESSION_DURATION_MINUTES,
|
||||
)
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""BanGUI runtime configuration.
|
||||
@@ -18,11 +24,11 @@ class Settings(BaseSettings):
|
||||
"""
|
||||
|
||||
database_path: str = Field(
|
||||
default="bangui.db",
|
||||
default=DEFAULT_DATABASE_PATH,
|
||||
description="Filesystem path to the BanGUI SQLite application database.",
|
||||
)
|
||||
fail2ban_socket: str = Field(
|
||||
default="/var/run/fail2ban/fail2ban.sock",
|
||||
default=DEFAULT_FAIL2BAN_SOCKET,
|
||||
description="Path to the fail2ban Unix domain socket.",
|
||||
)
|
||||
session_secret: str = Field(
|
||||
@@ -33,7 +39,7 @@ class Settings(BaseSettings):
|
||||
),
|
||||
)
|
||||
session_duration_minutes: int = Field(
|
||||
default=60,
|
||||
default=DEFAULT_SESSION_DURATION_MINUTES,
|
||||
ge=1,
|
||||
description="Number of minutes a session token remains valid after creation.",
|
||||
)
|
||||
@@ -41,14 +47,24 @@ class Settings(BaseSettings):
|
||||
default="UTC",
|
||||
description="IANA timezone name used when displaying timestamps in the UI.",
|
||||
)
|
||||
cors_allowed_origins: list[str] = Field(
|
||||
default_factory=lambda: ["http://localhost:5173"],
|
||||
cors_allowed_origins: str | list[str] = Field(
|
||||
default_factory=list,
|
||||
description=(
|
||||
"Comma-separated list of allowed CORS origins when the frontend is "
|
||||
"served from a different origin than the backend. "
|
||||
"Leave empty to disable cross-origin requests in production."
|
||||
),
|
||||
)
|
||||
|
||||
@field_validator("cors_allowed_origins", mode="before")
|
||||
@classmethod
|
||||
def _normalize_cors_origins(cls, value: str | list[str] | None) -> list[str]:
|
||||
if value is None:
|
||||
return []
|
||||
if isinstance(value, str):
|
||||
return [origin.strip() for origin in value.split(",") if origin.strip()]
|
||||
return value
|
||||
|
||||
log_level: str = Field(
|
||||
default="info",
|
||||
description="Application log level: debug | info | warning | error | critical.",
|
||||
@@ -72,8 +88,8 @@ class Settings(BaseSettings):
|
||||
default="fail2ban-client start",
|
||||
description=(
|
||||
"Shell command used to start (not reload) the fail2ban daemon during "
|
||||
"recovery rollback. Split by whitespace to build the argument list — "
|
||||
"no shell interpretation is performed. "
|
||||
"recovery rollback. Split by whitespace to build the argument list — "
|
||||
"no shell interpretation is performed. "
|
||||
"Example: 'systemctl start fail2ban' or 'fail2ban-client start'."
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user