Commit Graph

94 Commits

Author SHA1 Message Date
3b6e39ddad Separate bootstrap settings from runtime overrides with a dedicated runtime settings manager 2026-04-10 19:31:51 +02:00
9b4cd17e3b Harden SQLite connection defaults with WAL and busy timeout 2026-04-10 19:24:21 +02:00
1dfc17f4f5 Replace process-local session cache with pluggable session cache backend 2026-04-10 19:22:02 +02:00
ff92733f90 Move runtime application state into a dedicated runtime state manager 2026-04-10 19:07:35 +02:00
6b177f1881 Mark async socket handling task done and implement startup cleanup 2026-04-09 22:13:22 +02:00
148756fb79 Finish external HTTP client resilience: add shared aiohttp config, retry support, and update task status 2026-04-09 22:01:11 +02:00
e1d741956e Disable session cache by default and make it opt-in for single-process deployments 2026-04-09 21:52:57 +02:00
4043cdfa3c Harden session cookie security with configurable cookie flags 2026-04-09 21:43:32 +02:00
208f98dc97 Use session_secret for signed auth session tokens 2026-04-09 21:30:08 +02:00
6eab47f7ba Fix setup persistence and load persisted runtime configuration 2026-04-07 21:41:55 +02:00
1fc04ed978 Extract startup resource initialization from main.py
Move lifespan startup logic into app.startup and remove local imports from app.main._lifespan. Mark startup wiring issue as done.
2026-04-07 20:48:29 +02:00
59a56f2e4f Use dependency injection for health status and add health router regression test 2026-04-07 20:05:54 +02:00
e21f153946 Remove dead task DB fast-path and update task tests 2026-04-07 20:00:13 +02:00
95f72018f7 Add backend lifecycle regression tests and fix lifespan cleanup 2026-04-06 20:56:57 +02:00
c2982116a8 Add deployment-safe backend config and production-safe CORS defaults 2026-04-06 20:47:31 +02:00
1a7096b276 Add environment-driven CORS settings and backend regression tests 2026-04-06 20:42:33 +02:00
89ab41cc9e Convert setup guard to startup-driven cache and update tests 2026-04-06 20:38:15 +02:00
3ccfc20c64 Harden fail2ban integration and mark task complete 2026-04-06 20:20:14 +02:00
5107ff10d7 Mark backend SQLite request-scoping task done and clean up test fixture 2026-04-06 19:49:29 +02:00
c51858ec71 Add country-specific companion table filtering for map page 2026-04-05 22:12:06 +02:00
ffaa14f864 Switch dashboard/map/history views to archive source for long-term data
Update fail2ban dbpurgeage to 648000 and history sync backfill/pagination for archive-based 7.5 day history.
2026-04-05 20:21:54 +02:00
9f05da2d4d Complete history archive support for dashboard/map data and mark task finished
Add source=archive option for dashboard endpoints and history service; update Docs/Tasks.md; include archive branch for list_bans, bans_by_country, ban_trend, bans_by_jail; tests for archive paths.
2026-03-28 12:39:47 +01:00
876af46955 history archive router precedence + endpoint/source tests + history sync register test + task status update 2026-03-24 21:06:58 +01:00
0d4a2a3311 history archive purge uses current age and test uses dynamic timestamps 2026-03-24 20:52:40 +01:00
f555b1b0a2 Add server dbpurgeage warning state in API and mark task complete 2026-03-24 20:45:07 +01:00
2ea4a8304f backup 2026-03-24 19:46:12 +01:00
798ed08ddd Refactor service status response: migrate bangui_version into version field 2026-03-22 21:42:08 +01:00
ed184f1c84 Fix config status and missing historical filter imports
1) Added _get_active_jail_names import in jail_config_service 2) Added _get_active_jail_names and _parse_jails_sync imports in filter_config_service and resolved constants/exceptions 3) Added bangui_version=__version__ in config_service.get_service_status and tests
2026-03-22 20:54:44 +01:00
8e1b4fa978 test: add regression test for 500 errors 2026-03-22 20:33:43 +01:00
cf721513e8 Fix history origin filter path and add regression tests 2026-03-22 20:32:40 +01:00
bf2abda595 chore: commit local changes 2026-03-22 14:24:32 +01:00
05dc9fa1e3 Fix backend tests by using per-test temp config dir, align router mocks to service modules, fix log tail helper reference, and add JailNotFoundError.name 2026-03-22 14:24:28 +01:00
471eed9664 Rename file_config_service to raw_config_io_service and update references 2026-03-22 14:24:28 +01:00
1f272dc348 Refactor config regex/log preview into dedicated log_service 2026-03-22 14:24:28 +01:00
a442836c5c refactor: complete Task 2/3 geo decouple + exceptions centralization; mark as done 2026-03-22 14:24:25 +01:00
1c0bac1353 refactor: improve backend type safety and import organization
- Add TYPE_CHECKING guards for runtime-expensive imports (aiohttp, aiosqlite)
- Reorganize imports to follow PEP 8 conventions
- Convert TypeAlias to modern PEP 695 type syntax (where appropriate)
- Use Sequence/Mapping from collections.abc for type hints (covariant)
- Replace string literals with cast() for improved type inference
- Fix casting of Fail2BanResponse and TypedDict patterns
- Add IpLookupResult TypedDict for precise return type annotation
- Reformat overlong lines for readability (120 char limit)
- Add asyncio_mode and filterwarnings to pytest config
- Update test fixtures with improved type hints

This improves mypy type checking and makes type relationships explicit.
2026-03-22 14:24:24 +01:00
bdcdd5d672 Fix geo_re_resolve async mocks and mark tasks complete 2026-03-22 14:24:24 +01:00
ce59a66973 Move conffile_parser from services to utils 2026-03-22 14:24:24 +01:00
c9e688cc52 Refactor geo cache persistence into repository + remove raw SQL from tasks/main, update task list 2026-03-22 14:24:24 +01:00
1ce5da9e23 Refactor blocklist log retrieval via service layer and add fail2ban DB repo 2026-03-22 14:24:24 +01:00
1cc9968d31 Expose BanGUI version in API responses (dashboard + config) 2026-03-19 19:19:42 +01:00
80a6bac33e Sync backend/frontend versions to Docker/VERSION and read version from it 2026-03-19 19:13:38 +01:00
bf82e38b6e Fix blocklist-import bantime, unify filter bar, and improve config navigation 2026-03-17 11:31:46 +01:00
57cf93b1e5 Add ensure_jail_configs startup check for required jail config files
On startup BanGUI now verifies that the four fail2ban jail config files
required by its two custom jails (manual-Jail and blocklist-import) are
present in `$fail2ban_config_dir/jail.d`.  Any missing file is created
with the correct default content; existing files are never overwritten.

Files managed:
  - manual-Jail.conf        (enabled=false template)
  - manual-Jail.local       (enabled=true override)
  - blocklist-import.conf   (enabled=false template)
  - blocklist-import.local  (enabled=true override)

The check runs in the lifespan hook immediately after logging is
configured, before the database is opened.
2026-03-16 16:26:39 +01:00
21753c4f06 Fix Stage 0 bootstrap and startup regression
Task 0.1: Create database parent directory before connecting
- main.py _lifespan now calls Path(database_path).parent.mkdir(parents=True,
  exist_ok=True) before aiosqlite.connect() so the app starts cleanly on
  a fresh Docker volume with a nested database path.

Task 0.2: SetupRedirectMiddleware redirects when db is None
- Guard now reads: if db is None or not is_setup_complete(db)
  A missing database (startup still in progress) is treated as setup not
  complete instead of silently allowing all API routes through.

Task 0.3: SetupGuard redirects to /setup on API failure
- .catch() handler now sets status to 'pending' instead of 'done'.
  A crashed backend cannot serve protected routes; conservative fallback
  is to redirect to /setup.

Task 0.4: SetupPage shows spinner while checking setup status
- Added 'checking' boolean state; full-screen Spinner is rendered until
  getSetupStatus() resolves, preventing form flash before redirect.
- Added console.warn in catch block; cleanup return added to useEffect.

Also: remove unused type: ignore[call-arg] from config.py.

Tests: 18 backend tests pass; 117 frontend tests pass.
2026-03-15 18:05:53 +01:00
b81e0cdbb4 Fix raw action config endpoint shadowed by config router
Rename GET/PUT /api/config/actions/{name} to /actions/{name}/raw in
file_config.py to eliminate the route-shadowing conflict with config.py,
which registers its own GET /actions/{name} returning ActionConfig.

Add configActionRaw endpoint helper in endpoints.ts and update
fetchActionFile/updateActionFile in config.ts to use it. Add
TestGetActionFileRaw and TestUpdateActionFileRaw test classes.
2026-03-15 14:09:37 +01:00
d4d04491d2 Add Deactivate Jail button for inactive jails with local override
- Add has_local_override field to InactiveJail model
- Update _build_inactive_jail and list_inactive_jails to compute the field
- Add delete_jail_local_override() service function
- Add DELETE /api/config/jails/{name}/local router endpoint
- Surface has_local_override in frontend InactiveJail type
- Show Deactivate Jail button in JailsTab when has_local_override is true
- Add tests: TestBuildInactiveJail, TestListInactiveJails, TestDeleteJailLocalOverride
2026-03-15 13:41:00 +01:00
93dc699825 Fix restart/reload endpoint correctness and safety
- jail_service.restart(): replace invalid ["restart"] socket command with
  ["stop"], matching fail2ban transmitter protocol. The daemon is now
  stopped via socket; the caller starts it via subprocess.

- config_file_service: expose _start_daemon and _wait_for_fail2ban as
  public start_daemon / wait_for_fail2ban functions.

- restart_fail2ban router: orchestrate stop (socket) → start (subprocess)
  → probe (socket). Returns 204 on success, 503 when fail2ban does not
  come back within 10 s. Catches JailOperationError → 409.

- reload_fail2ban router: add JailOperationError catch → 409 Conflict,
  consistent with other jail control endpoints.

- Tests: add TestJailControls.test_restart_* (3 cases), TestReloadFail2ban
  502/409 cases, TestRestartFail2ban (5 cases), TestRollbackJail (6
  integration tests verifying file-write, subprocess invocation, socket-
  probe truthiness, active_jails count, and offline-at-call-time).
2026-03-15 12:59:17 +01:00
f62785aaf2 Fix fail2ban runtime errors: jail not found, action locks, log noise
This commit implements fixes for three independent bugs in the fail2ban configuration and integration layer:

1. Task 1: Detect UnknownJailException and prevent silent failures
   - Added JailNotFoundError detection in jail_service.reload_all()
   - Enhanced error handling in config_file_service to catch JailNotFoundError
   - Added specific error message with logpath validation hints
   - Added rollback test for this scenario

2. Task 2: Fix iptables-allports exit code 4 (xtables lock contention)
   - Added global banaction setting in jail.conf with -w 5 lockingopt
   - Removed redundant per-jail banaction overrides from bangui-sim and blocklist-import
   - Added production compose documentation note

3. Task 3: Suppress log noise from unsupported backend/idle commands
   - Implemented capability detection to cache command support status
   - Double-check locking to minimize lock contention
   - Avoids sending unsupported get <jail> backend/idle commands
   - Returns default values without socket calls when unsupported

All changes include comprehensive tests and maintain backward compatibility.
2026-03-15 10:57:00 +01:00
4be2469f92 Implement tasks 1-3: sidebar order, jail activation rollback, pie chart colors
Task 1: Move Configuration to last position in sidebar NAV_ITEMS

Task 2: Add automatic rollback when jail activation fails
- Back up .local override file before writing
- Restore original file (or delete) on reload failure, health-check
  failure, or jail not appearing post-reload
- Return recovered=True/False in JailActivationResponse
- Show warning/critical banner in ActivateJailDialog based on recovery
- Add _restore_local_file_sync and _rollback_activation_async helpers
- Add 3 new tests: rollback on reload failure, health-check failure,
  and double failure (recovered=False)

Task 3: Color pie chart legend labels to match their slice color
- legendFormatter now returns ReactNode with span style={{ color }}
- Import LegendPayload from recharts/types/component/DefaultLegendContent
2026-03-14 21:16:58 +01:00