diff --git a/backend/app/models/config.py b/backend/app/models/config.py index 2c055be..3e6aef2 100644 --- a/backend/app/models/config.py +++ b/backend/app/models/config.py @@ -4,9 +4,14 @@ Request, response, and domain models for the config router and service. """ import datetime +from typing import Literal from pydantic import BaseModel, ConfigDict, Field +DNSMode = Literal["yes", "warn", "no", "raw"] +LogEncoding = Literal["auto", "ascii", "utf-8", "UTF-8", "latin-1"] +BackendType = Literal["auto", "polling", "pyinotify", "systemd", "gamin"] + # --------------------------------------------------------------------------- # Ban-time escalation # --------------------------------------------------------------------------- @@ -79,9 +84,9 @@ class JailConfig(BaseModel): ignore_regex: list[str] = Field(default_factory=list, description="Regex patterns that bypass the ban logic.") log_paths: list[str] = Field(default_factory=list, description="Monitored log files.") date_pattern: str | None = Field(default=None, description="Custom date pattern for log parsing.") - log_encoding: str = Field(default="UTF-8", description="Log file encoding.") - backend: str = Field(default="polling", description="Log monitoring backend.") - use_dns: str = Field(default="warn", description="DNS lookup mode: yes | warn | no | raw.") + log_encoding: LogEncoding = Field(default="UTF-8", description="Log file encoding.") + backend: BackendType = Field(default="polling", description="Log monitoring backend.") + use_dns: DNSMode = Field(default="warn", description="DNS lookup mode: yes | warn | no | raw.") prefregex: str = Field(default="", description="Prefix regex prepended to every failregex; empty means disabled.") actions: list[str] = Field(default_factory=list, description="Names of actions attached to this jail.") bantime_escalation: BantimeEscalation | None = Field( @@ -119,9 +124,9 @@ class JailConfigUpdate(BaseModel): ignore_regex: list[str] | None = Field(default=None) prefregex: str | None = Field(default=None, description="Prefix regex; None = skip, '' = clear, non-empty = set.") date_pattern: str | None = Field(default=None) - dns_mode: str | None = Field(default=None, description="DNS lookup mode: yes | warn | no | raw.") - backend: str | None = Field(default=None, description="Log monitoring backend.") - log_encoding: str | None = Field(default=None, description="Log file encoding.") + dns_mode: DNSMode | None = Field(default=None, description="DNS lookup mode: yes | warn | no | raw.") + backend: BackendType | None = Field(default=None, description="Log monitoring backend.") + log_encoding: LogEncoding | None = Field(default=None, description="Log file encoding.") enabled: bool | None = Field(default=None) bantime_escalation: BantimeEscalationUpdate | None = Field( default=None, @@ -680,7 +685,7 @@ class JailSectionConfig(BaseModel): findtime: int | None = Field(default=None, ge=1, description="Time window in seconds for counting failures.") bantime: int | None = Field(default=None, description="Ban duration in seconds. -1 for permanent.") action: list[str] = Field(default_factory=list, description="Action references.") - backend: str | None = Field(default=None, description="Log monitoring backend.") + backend: BackendType | None = Field(default=None, description="Log monitoring backend.") extra: dict[str, str] = Field(default_factory=dict, description="Additional settings not captured by named fields.") @@ -764,11 +769,11 @@ class InactiveJail(BaseModel): default=600, description="Failure-counting window in seconds, parsed from findtime string.", ) - log_encoding: str = Field( + log_encoding: LogEncoding = Field( default="auto", description="Log encoding, e.g. ``utf-8`` or ``auto``.", ) - backend: str = Field( + backend: BackendType = Field( default="auto", description="Log-monitoring backend, e.g. ``auto``, ``pyinotify``, ``polling``.", ) @@ -776,7 +781,7 @@ class InactiveJail(BaseModel): default=None, description="Date pattern for log parsing, or None for auto-detect.", ) - use_dns: str = Field( + use_dns: DNSMode = Field( default="warn", description="DNS resolution mode: ``yes``, ``warn``, ``no``, or ``raw``.", ) diff --git a/frontend/src/components/config/JailSectionPanel.tsx b/frontend/src/components/config/JailSectionPanel.tsx index 2d462c0..cd5add3 100644 --- a/frontend/src/components/config/JailSectionPanel.tsx +++ b/frontend/src/components/config/JailSectionPanel.tsx @@ -12,7 +12,7 @@ import { import { KVEditor } from "./KVEditor"; import { StringListEditor } from "./StringListEditor"; import { useConfigStyles } from "./configStyles"; -import type { JailSectionConfig } from "../../types/config"; +import type { BackendType, JailSectionConfig } from "../../types/config"; const BACKENDS = ["", "auto", "polling", "gamin", "pyinotify", "systemd"] as const; @@ -64,7 +64,9 @@ export function JailSectionPanel({ jailName, section, onChange }: JailSectionPan