backup
This commit is contained in:
119
Docs/Tasks.md
119
Docs/Tasks.md
@@ -1,122 +1,3 @@
|
||||
## [E2E-3] Ban records appear in UI after simulated failed logins
|
||||
|
||||
**Where found:**
|
||||
`Docker/simulate_failed_logins.sh` exists and is used in the `make dev-ban-test` target, but there is no automated test that verifies the resulting bans are surfaced correctly in the BanGUI frontend (History page, Dashboard, or Jails detail page).
|
||||
|
||||
**Why this is needed:**
|
||||
The ban pipeline is the core feature of the product. A regression anywhere in the chain (fail2ban log parsing → fail2ban banning → backend polling → database write → API response → frontend rendering) would go undetected until a user reports it.
|
||||
|
||||
**Goal:**
|
||||
After running `simulate_failed_logins.sh` with a known IP, the ban record for that IP must appear in the BanGUI UI within a reasonable timeout.
|
||||
|
||||
**What to do:**
|
||||
1. Create `e2e/tests/02_ban_records.robot`.
|
||||
2. Suite Setup: `Login As Admin`.
|
||||
3. Test teardown: unban the test IP using `Docker/check_ban_status.sh --unban 192.168.100.99` via `Run Process`.
|
||||
4. Test case:
|
||||
```robot
|
||||
*** Test Cases ***
|
||||
Simulated Failed Logins Appear As Ban Records
|
||||
[Teardown] Run Process bash ${EXECDIR}/Docker/check_ban_status.sh
|
||||
... --unban 192.168.100.99
|
||||
# Step 1 — write failure lines
|
||||
${result}= Run Process
|
||||
... bash ${EXECDIR}/Docker/simulate_failed_logins.sh 5 192.168.100.99
|
||||
... timeout=15s
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
# Step 2 — wait for fail2ban to process and backend to pick up the ban
|
||||
Sleep 15s
|
||||
# Step 3 — check History page
|
||||
Go To ${FRONTEND_URL}/history
|
||||
Wait For Elements State css=table,tbody visible timeout=20s
|
||||
Get Text body contains 192.168.100.99
|
||||
# Step 4 — confirm jail name is shown
|
||||
Get Text body contains manual-Jail
|
||||
```
|
||||
5. Optionally add a direct API assertion before the UI check to isolate UI vs. backend failures:
|
||||
```robot
|
||||
${resp}= GET ${BACKEND_URL}/api/history expected_status=200
|
||||
Should Contain ${resp.text} 192.168.100.99
|
||||
```
|
||||
|
||||
**Possible traps and issues:**
|
||||
- The default `COUNT` for `simulate_failed_logins.sh` is 5 and the fail2ban `maxretry` for `manual-Jail` must be ≤ 5 for the ban to trigger. If the jail config has been changed locally the test may pass the script step but produce no ban.
|
||||
- `simulate_failed_logins.sh` writes to `Docker/logs/auth.log`. The fail2ban container reads from `/remotelogs/bangui/auth.log` (mapped volume). If the file mapping differs the lines will never be detected.
|
||||
- The backend polls fail2ban on a schedule (APScheduler). The 15 s sleep may not be enough if the polling interval is longer. Read the scheduler interval from the config before hardcoding the wait.
|
||||
- `check_ban_status.sh` uses `docker exec` directly. In a Podman environment the container runtime may be `podman`, making the unban teardown fail and leaving the test IP permanently banned until manual cleanup.
|
||||
- The History page paginates results. If the test IP is not on the first page the `contains` assertion will fail. Assert via the API or set a large page size query parameter in the URL.
|
||||
- Running the test suite multiple times in the same session accumulates lines in `auth.log`. Old lines do not re-trigger bans, but the counter inside fail2ban resets on container restart. Add a `truncate -s 0 Docker/logs/auth.log` step before writing new lines if idempotency is needed.
|
||||
|
||||
**Docs changes needed:**
|
||||
- Add a note in [Testing-Requirements.md](Testing-Requirements.md) explaining the ban pipeline timing expectations and why a sleep is needed in this test.
|
||||
- Document the `manual-Jail` maxretry value and log path in [CONFIGURATION.md](CONFIGURATION.md) so it is clear what the E2E test depends on.
|
||||
|
||||
**Doc references:**
|
||||
- [CONFIGURATION.md](CONFIGURATION.md)
|
||||
- [Testing-Requirements.md](Testing-Requirements.md)
|
||||
- `Docker/simulate_failed_logins.sh`
|
||||
- `Docker/check_ban_status.sh`
|
||||
- `Docker/fail2ban-dev-config/` — jail configuration
|
||||
|
||||
---
|
||||
|
||||
## [E2E-4] Blocklist import executes and is reflected in the UI
|
||||
|
||||
**Where found:**
|
||||
The blocklist import endpoint (`POST /api/blocklists/import`) is implemented in `backend/app/routers/blocklist.py` and has unit tests in `backend/tests/test_routers/test_blocklist.py` and `backend/tests/test_tasks/test_blocklist_import.py`. The `/blocklists` frontend page exists but there is no E2E test verifying the manual import button works end-to-end.
|
||||
|
||||
**Why this is needed:**
|
||||
The import flow is asynchronous and involves DNS validation, an external HTTP fetch, and a database write. Unit tests mock all external calls. An E2E test is the only way to verify that the full import pipeline — including the network call to the external source — completes and updates the UI.
|
||||
|
||||
**Goal:**
|
||||
Clicking the manual import button on the `/blocklists` page triggers an import run, the UI reflects completion (no error banner), and the import log table shows a new entry.
|
||||
|
||||
**What to do:**
|
||||
1. Create `e2e/tests/03_blocklist_import.robot`.
|
||||
2. Suite Setup: `Login As Admin`.
|
||||
3. Pre-condition: at least one blocklist source must be configured. Add a keyword `Ensure Blocklist Source Exists` that:
|
||||
- Calls `GET /api/blocklists` to check if any sources are defined.
|
||||
- If none: calls `POST /api/blocklists` to add a known-good source (e.g., a small, stable public list).
|
||||
4. Test case:
|
||||
```robot
|
||||
*** Test Cases ***
|
||||
Manual Blocklist Import Completes Without Error
|
||||
Ensure Blocklist Source Exists
|
||||
Go To ${FRONTEND_URL}/blocklists
|
||||
Wait For Elements State css=[aria-label*="Import"],button visible timeout=15s
|
||||
# record the current log entry count
|
||||
${resp_before}= GET ${BACKEND_URL}/api/blocklists/log expected_status=200
|
||||
# trigger the import
|
||||
Click css=[aria-label*="Import"],button
|
||||
# wait for import to finish (spinner gone or success toast)
|
||||
Wait For Elements State css=[aria-label*="Import"],button enabled timeout=45s
|
||||
Get Text body not contains error
|
||||
# verify the log has a new entry
|
||||
${resp_after}= GET ${BACKEND_URL}/api/blocklists/log expected_status=200
|
||||
Should Not Be Equal ${resp_before.text} ${resp_after.text}
|
||||
```
|
||||
5. If the environment has no internet access, mock the external fetch via a local HTTP server (use Python's `http.server` in a `Run Process` background task and point the source URL at `http://localhost:<port>/test.txt`).
|
||||
|
||||
**Possible traps and issues:**
|
||||
- The import endpoint has a rate limit (`RATE_LIMIT_BLOCKLIST_IMPORT_REQUESTS`). Running the suite more than once in the same hour may result in a 429. Either reset the rate limiter between runs or use a unique client IP via a custom `X-Forwarded-For` header.
|
||||
- The external network may be unavailable in CI. The test must either skip gracefully (`Skip If ${no_internet}`) or use a local mock server.
|
||||
- The import button selector is unknown until inspected in a running browser. The selector `css=[aria-label*="Import"],button` is a best guess — it must be verified against the actual rendered DOM and updated if wrong.
|
||||
- If a blocklist source URL returns an invalid or empty file, the import will complete but with 0 bans added. The test must distinguish "import ran successfully" from "bans were added" — these are separate assertions.
|
||||
- The `POST /api/blocklists/import` can take several seconds per source. The 45 s timeout may be insufficient for large lists.
|
||||
|
||||
**Docs changes needed:**
|
||||
- Add the rate limit value and reset mechanism to [CONFIGURATION.md](CONFIGURATION.md).
|
||||
- Document the E2E dependency on network access (or local mock) in [Testing-Requirements.md](Testing-Requirements.md).
|
||||
|
||||
**Doc references:**
|
||||
- [CONFIGURATION.md](CONFIGURATION.md)
|
||||
- [Testing-Requirements.md](Testing-Requirements.md)
|
||||
- [Features.md](Features.md) — blocklist feature description
|
||||
- `backend/app/routers/blocklist.py` — endpoint and rate limit implementation
|
||||
- `backend/tests/test_tasks/test_blocklist_import.py`
|
||||
|
||||
---
|
||||
|
||||
## [E2E-5] Config edit saves and persists after page reload
|
||||
|
||||
**Where found:**
|
||||
|
||||
Reference in New Issue
Block a user