docs(e2e): add debugging notes and fix incorrect login example
Document lessons learned from debugging blocklist import tests: - RequestsLibrary vs Browser library auth isolation - CSRF header requirement - Robot variable type rules - network_mode: host implications - SSRF protection behavior - API response key discrepancies Also fix API login example: backend accepts plaintext passwords, not SHA256-hashed as previously documented. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -257,18 +257,71 @@ Backend: `http://127.0.0.1:8000` · Frontend (Vite proxy): `http://127.0.0.1:517
|
||||
|
||||
### API login (dev)
|
||||
|
||||
The frontend SHA256-hashes the password before sending it to the API.
|
||||
The initial setup password must be at least 8 characters long and include one uppercase letter, one number, and one special character from `!@#$%^&*()`.
|
||||
The backend accepts **plaintext** passwords (no frontend hashing).
|
||||
The session cookie is named `bangui_session`.
|
||||
|
||||
```bash
|
||||
# Dev master password: Hallo123!
|
||||
HASHED=$(echo -n "Hallo123!" | sha256sum | awk '{print $1}')
|
||||
TOKEN=$(curl -s -X POST http://127.0.0.1:8000/api/v1/auth/login \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"password\":\"$HASHED\"}" \
|
||||
| python3 -c 'import sys,json; print(json.load(sys.stdin)["token"])')
|
||||
|
||||
# Use token in subsequent requests:
|
||||
curl -H "Cookie: bangui_session=$TOKEN" http://127.0.0.1:8000/api/v1/dashboard/status
|
||||
-d '{"password":"Hallo123!"}' \
|
||||
| python3 -c 'import sys,json; print(json.load(sys.stdin)["expires_at"])')
|
||||
# Login sets bangui_session cookie automatically.
|
||||
# Use the cookie in subsequent requests:
|
||||
curl -b "bangui_session=$(cat ~/.bangui_session)" http://127.0.0.1:8000/api/v1/dashboard/status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## E2E Testing Notes
|
||||
|
||||
Debugging failures: open `results/log.html` (not output.xml) for full request/response traces.
|
||||
|
||||
### Auth (RequestsLibrary vs Browser)
|
||||
|
||||
`Login As Admin` uses browser JavaScript (`Evaluate JavaScript`) — session cookie lives in the **browser context only**.
|
||||
Any `RequestsLibrary` keyword (GET/POST to API) in the same test needs its own auth session.
|
||||
Use `Login Via HTTP` from `auth.resource` to get a session cookie for RequestsLibrary calls.
|
||||
RequestsLibrary and Browser library share no state.
|
||||
|
||||
### CSRF Protection
|
||||
|
||||
Backend enforces CSRF on all POST/PUT/DELETE via `X-BanGUI-Request: 1` header.
|
||||
RequestsLibrary sessions must include this header on creation:
|
||||
```
|
||||
Create Session bangsess ${BACKEND_URL} headers=${headers} # headers = {X-BanGUI-Request: 1}
|
||||
```
|
||||
Then all requests on that session inherit it.
|
||||
|
||||
### Robot Variable Type Rules
|
||||
|
||||
Bare values in `Create Dictionary` are **strings**, not Python types:
|
||||
- `enabled=true` → `"true"` (string) — backend Pydantic expects boolean → validation fails
|
||||
- Fix: `enabled=${TRUE}` for booleans, `${60}` for integers
|
||||
- `${NONE}` is Robot's null/None equivalent
|
||||
- `${len(sources)}` is invalid — use `Get Length ${sources}` keyword instead
|
||||
|
||||
### Network Mode (podman-compose)
|
||||
|
||||
With `network_mode: host`, containers share the host network namespace.
|
||||
- Backend can reach host's `127.0.0.1:PORT` — needed for mock HTTP servers
|
||||
- Frontend must set `VITE_BACKEND_URL=http://localhost:8000` since `localhost` now resolves to host
|
||||
- Vite proxy works when frontend also uses `network_mode: host` (same namespace)
|
||||
|
||||
### SSRF Protection
|
||||
|
||||
Blocklist source URLs are validated: hostname must resolve to a **public** IP.
|
||||
- `127.0.0.1` and other loopback addresses are rejected
|
||||
- In dev mode (`BANGUI_LOG_LEVEL=debug`), loopback is allowed for e2e testing
|
||||
- For real e2e tests, use a public blocklist URL or ensure mock server is reachable
|
||||
|
||||
### API Response Keys
|
||||
|
||||
Always verify response shape in `results/log.html` — field names differ from expectations:
|
||||
- Blocklist import log: `items` not `entries`
|
||||
- Error responses: `{"code": "...", "detail": "..."}`
|
||||
|
||||
### Process Library Teardown
|
||||
|
||||
`Terminate Process` fails if the process alias doesn't exist (mock server not started).
|
||||
Wrap in `Run Keyword And Return Status` to avoid teardown cascading failures.
|
||||
|
||||
Reference in New Issue
Block a user