Add better jail configuration: file CRUD, enable/disable, log paths
Task 4 (Better Jail Configuration) implementation:
- Add fail2ban_config_dir setting to app/config.py
- New file_config_service: list/view/edit/create jail.d, filter.d, action.d files
with path-traversal prevention and 512 KB content size limit
- New file_config router: GET/PUT/POST endpoints for jail files, filter files,
and action files; PUT .../enabled for toggle on/off
- Extend config_service with delete_log_path() and add_log_path()
- Add DELETE /api/config/jails/{name}/logpath and POST /api/config/jails/{name}/logpath
- Extend geo router with re-resolve endpoint; add geo_re_resolve background task
- Update blocklist_service with revised scheduling helpers
- Update Docker compose files with BANGUI_FAIL2BAN_CONFIG_DIR env var and
rw volume mount for the fail2ban config directory
- Frontend: new Jail Files, Filters, Actions tabs in ConfigPage; file editor
with accordion-per-file, editable textarea, save/create; add/delete log paths
- Frontend: types in types/config.ts; API calls in api/config.ts and api/endpoints.ts
- 63 new backend tests (test_file_config_service, test_file_config, test_geo_re_resolve)
- 6 new frontend tests in ConfigPageLogPath.test.tsx
- ruff, mypy --strict, tsc --noEmit, eslint: all clean; 617 backend tests pass
This commit is contained in:
@@ -2,12 +2,19 @@
|
||||
* API functions for the configuration and server settings endpoints.
|
||||
*/
|
||||
|
||||
import { get, post, put } from "./client";
|
||||
import { del, get, post, put } from "./client";
|
||||
import { ENDPOINTS } from "./endpoints";
|
||||
import type {
|
||||
AddLogPathRequest,
|
||||
ConfFileContent,
|
||||
ConfFileCreateRequest,
|
||||
ConfFilesResponse,
|
||||
ConfFileUpdateRequest,
|
||||
GlobalConfig,
|
||||
GlobalConfigUpdate,
|
||||
JailConfigFileContent,
|
||||
JailConfigFileEnabledUpdate,
|
||||
JailConfigFilesResponse,
|
||||
JailConfigListResponse,
|
||||
JailConfigResponse,
|
||||
JailConfigUpdate,
|
||||
@@ -88,6 +95,15 @@ export async function addLogPath(
|
||||
await post<undefined>(ENDPOINTS.configJailLogPath(jailName), req);
|
||||
}
|
||||
|
||||
export async function deleteLogPath(
|
||||
jailName: string,
|
||||
logPath: string
|
||||
): Promise<void> {
|
||||
await del<undefined>(
|
||||
`${ENDPOINTS.configJailLogPath(jailName)}?log_path=${encodeURIComponent(logPath)}`
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Log preview
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -139,3 +155,74 @@ export async function updateMapColorThresholds(
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Jail config files (Task 4a)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function fetchJailConfigFiles(): Promise<JailConfigFilesResponse> {
|
||||
return get<JailConfigFilesResponse>(ENDPOINTS.configJailFiles);
|
||||
}
|
||||
|
||||
export async function fetchJailConfigFileContent(
|
||||
filename: string
|
||||
): Promise<JailConfigFileContent> {
|
||||
return get<JailConfigFileContent>(ENDPOINTS.configJailFile(filename));
|
||||
}
|
||||
|
||||
export async function setJailConfigFileEnabled(
|
||||
filename: string,
|
||||
update: JailConfigFileEnabledUpdate
|
||||
): Promise<void> {
|
||||
await put<undefined>(ENDPOINTS.configJailFileEnabled(filename), update);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Filter files (Task 4d)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function fetchFilterFiles(): Promise<ConfFilesResponse> {
|
||||
return get<ConfFilesResponse>(ENDPOINTS.configFilters);
|
||||
}
|
||||
|
||||
export async function fetchFilterFile(name: string): Promise<ConfFileContent> {
|
||||
return get<ConfFileContent>(ENDPOINTS.configFilter(name));
|
||||
}
|
||||
|
||||
export async function updateFilterFile(
|
||||
name: string,
|
||||
req: ConfFileUpdateRequest
|
||||
): Promise<void> {
|
||||
await put<undefined>(ENDPOINTS.configFilter(name), req);
|
||||
}
|
||||
|
||||
export async function createFilterFile(
|
||||
req: ConfFileCreateRequest
|
||||
): Promise<ConfFileContent> {
|
||||
return post<ConfFileContent>(ENDPOINTS.configFilters, req);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Action files (Task 4e)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function fetchActionFiles(): Promise<ConfFilesResponse> {
|
||||
return get<ConfFilesResponse>(ENDPOINTS.configActions);
|
||||
}
|
||||
|
||||
export async function fetchActionFile(name: string): Promise<ConfFileContent> {
|
||||
return get<ConfFileContent>(ENDPOINTS.configAction(name));
|
||||
}
|
||||
|
||||
export async function updateActionFile(
|
||||
name: string,
|
||||
req: ConfFileUpdateRequest
|
||||
): Promise<void> {
|
||||
await put<undefined>(ENDPOINTS.configAction(name), req);
|
||||
}
|
||||
|
||||
export async function createActionFile(
|
||||
req: ConfFileCreateRequest
|
||||
): Promise<ConfFileContent> {
|
||||
return post<ConfFileContent>(ENDPOINTS.configActions, req);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user