Add WG_IDP_CONFIG_FILE env var to seed OIDC/SAML identity providers from a YAML file at startup, enabling GitOps and IaC workflows. Providers are upserted by id (merge strategy preserves manual additions). Convert all e2e tests from NiceGUI User fixture to Playwright async API with --headed and --slowmo flags for visual debugging. Add full OIDC login flow test against the mock-oidc service.
135 lines
7 KiB
Markdown
135 lines
7 KiB
Markdown
# WireGUI Implementation TODO
|
|
|
|
Migration of Wirezone (Elixir/Phoenix) to Python/NiceGUI.
|
|
Source: `/home/stefanob/PycharmProjects/personal/wirezone`
|
|
|
|
**Test count: 199 (164 unit + 35 E2E) | Coverage: 35%**
|
|
**Run:** `uv run pytest` (unit) / `uv run pytest tests/e2e/` (E2E via Playwright)
|
|
|
|
|
|
## Phase 7: Admin UI ✅
|
|
|
|
- [ ] **TODO:** SAML provider management in Authentication tab
|
|
|
|
## Phase 10: Polish, Testing & Deployment
|
|
|
|
### Testing (partially done)
|
|
- [ ] HTTP-level integration tests (OIDC redirect/callback flow with respx mocking)
|
|
|
|
### Coverage gaps (35% overall — run `uv run pytest --cov=wiregui --cov-report=term-missing --cov-branch`)
|
|
|
|
**100% covered:** models, schemas, config, auth/passwords, auth/jwt, auth/mfa, auth/api_token, utils/crypto, utils/time, services/notifications
|
|
|
|
**API routes (32-84% — partially covered via httpx TestClient):**
|
|
- [x] `wiregui/api/v0/users.py` (84%) — list/get/create/update/delete
|
|
- [x] `wiregui/api/v0/rules.py` (71%) — CRUD
|
|
- [x] `wiregui/api/v0/devices.py` (67%) — CRUD, permissions
|
|
- [x] `wiregui/api/v0/configuration.py` (61%) — get/update, auto-create
|
|
- [ ] `wiregui/api/deps.py` (32%) — test get_current_api_user with real Bearer header parsing, require_admin rejection
|
|
|
|
**Services (62-89% covered):**
|
|
- [x] `wiregui/services/wireguard.py` (62%) — add/remove/get peers mocked
|
|
- [x] `wiregui/services/firewall.py` (73%) — base tables, chains, rules, rebuild mocked
|
|
- [x] `wiregui/services/events.py` (80%) — device + rule events, rebuild chain
|
|
- [x] `wiregui/services/email.py` (89%) — send_email, magic link, no-smtp fallback
|
|
- [ ] `wiregui/services/wireguard.py` — test ensure_interface, set_private_key, set_listen_port
|
|
- [ ] `wiregui/services/firewall.py` — test _nft/_nft_batch error handling, add_device_jump_rule with only ipv4/ipv6
|
|
|
|
**Tasks (40-84% covered):**
|
|
- [x] `wiregui/tasks/stats.py` (77%) — update from peers, no-op, unmatched peer
|
|
- [x] `wiregui/tasks/reconcile.py` (84%) — add missing, remove orphaned, in-sync
|
|
- [x] `wiregui/tasks/oidc_refresh.py` (40%) — no connections, skip unknown provider
|
|
- [ ] `wiregui/tasks/oidc_refresh.py` — test successful refresh, failure with notification, disable_vpn_on_oidc_error
|
|
|
|
**Auth modules (85-92% covered):**
|
|
- [x] `wiregui/auth/oidc.py` (87%) — register providers, get_client, load from config
|
|
- [x] `wiregui/auth/webauthn.py` (85%) — registration/authentication options
|
|
- [x] `wiregui/auth/session.py` (90%) — no-password, disabled, nonexistent user
|
|
- [ ] `wiregui/auth/saml.py` (0%) — needs mock SAML IdP metadata + response parsing
|
|
- [ ] `wiregui/auth/webauthn.py` — test verify_registration, verify_authentication with mock credential data
|
|
|
|
**E2E page tests (Playwright async API in `tests/e2e/`):**
|
|
- [x] `tests/e2e/test_login.py` (6 tests) — valid login, invalid password, nonexistent email, disabled user, logout, unauthenticated redirect
|
|
- [x] `tests/e2e/test_devices.py` (2 tests) — add device full flow, name validation
|
|
- [x] `tests/e2e/test_account.py` (8 tests) — change password (success/wrong/mismatch/short), create API token, TOTP registration + invalid code, account deletion
|
|
- [x] `tests/e2e/test_admin_users.py` (10 tests) — page renders, create user, duplicate email, edit role/password, disable/enable, delete, cascade delete, self-delete guard
|
|
- [x] `tests/e2e/test_idp_seed.py` (9 tests) — IdP YAML seeding (noop/missing/invalid, OIDC/SAML add, upsert, preserve), OIDC button visible, full OIDC login flow via mock-oidc
|
|
|
|
**E2E tests still needed:**
|
|
|
|
`tests/e2e/test_login.py` — Login & Auth flows (remaining):
|
|
- [ ] Login with MFA → redirects to /mfa challenge page
|
|
- [ ] MFA challenge: valid TOTP code → completes login
|
|
- [ ] MFA challenge: invalid code → shows error, stays on /mfa
|
|
- [ ] MFA challenge: cancel → returns to /login
|
|
- [ ] Magic link request page renders, shows success on submit
|
|
|
|
`tests/e2e/test_admin_devices.py` — Admin Device Management:
|
|
- [ ] List all devices across users
|
|
- [ ] Filter by user → shows only that user's devices
|
|
- [ ] Create device with full config overrides (DNS, endpoint, MTU, keepalive, allowed IPs)
|
|
- [ ] Create device with defaults → use_default flags all True
|
|
- [ ] Edit device name and description → persists
|
|
- [ ] Edit device config overrides (toggle use_default off, set custom values)
|
|
- [ ] Delete device → removed from table
|
|
- [ ] Config dialog shows valid WireGuard config with real server public key
|
|
- [ ] QR code renders in config dialog
|
|
|
|
`tests/e2e/test_admin_rules.py` — Admin Firewall Rules:
|
|
- [ ] List rules → table shows action, destination, protocol, port, user
|
|
- [ ] Create accept rule with CIDR → appears in table
|
|
- [ ] Create drop rule with TCP port range → appears correctly
|
|
- [ ] Create global rule (no user) → shows "Global"
|
|
- [ ] Edit rule action (accept → drop) → persists
|
|
- [ ] Edit rule destination → persists
|
|
- [ ] Delete rule → removed from table
|
|
|
|
`tests/e2e/test_admin_settings.py` — Admin Settings:
|
|
- [ ] Client defaults: save endpoint, DNS, MTU, keepalive, allowed IPs → persists in DB
|
|
- [ ] Client defaults: saved values reflected on page reload
|
|
- [ ] Security: toggle local auth → persists
|
|
- [ ] Security: change VPN session duration → persists
|
|
- [ ] Security: toggle unprivileged device management/configuration → persists
|
|
- [ ] OIDC: add provider → appears in table
|
|
- [ ] OIDC: delete provider → removed from table
|
|
- [ ] SAML: add provider → appears in table
|
|
- [ ] SAML: delete provider → removed from table
|
|
|
|
`tests/e2e/test_admin_diagnostics.py` — Admin Diagnostics:
|
|
- [ ] Page renders WireGuard interface status
|
|
- [ ] Active peers table shows devices with handshakes
|
|
- [ ] Connectivity checks table shows recent results
|
|
- [ ] Notifications list shows system notifications
|
|
- [ ] Clear single notification → removed
|
|
- [ ] Clear all notifications → list empty
|
|
|
|
`tests/e2e/test_devices_user.py` — User Device Pages:
|
|
- [ ] Device list shows only own devices (not other users')
|
|
- [ ] Create device → shows in table with allocated IPs
|
|
- [ ] Device detail page shows public key, IPs, stats, active config
|
|
- [ ] Device detail: edit name → persists
|
|
- [ ] Device detail: toggle config overrides → custom values saved
|
|
- [ ] Device detail: delete with confirmation → redirects to /devices
|
|
- [ ] Auto-refresh: stats labels update after timer fires (mock timer)
|
|
|
|
`tests/e2e/test_account_extended.py` — Account Page (additional):
|
|
- [ ] SSO providers section shows connected providers
|
|
- [ ] SSO providers section shows "No SSO providers" when empty
|
|
- [ ] MFA: add security key (WebAuthn) → method appears in table (mock navigator.credentials)
|
|
- [ ] MFA: delete method with confirmation → removed from table
|
|
- [ ] API tokens: expired token shows "Expired" badge
|
|
- [ ] API tokens: delete token → removed from table
|
|
- [ ] API tokens: copy button calls clipboard API
|
|
- [ ] Danger zone: disabled when only admin
|
|
- [ ] Danger zone: wrong email in confirmation → shows error
|
|
|
|
|
|
### Deployment ✅
|
|
|
|
- [ ] First-run CLI setup command
|
|
|
|
---
|
|
|
|
### Remaining
|
|
- [ ] SSO Providers: add Status column, "Disconnect" action
|
|
- [ ] Admin pages (users, devices, rules): apply same card-based styling
|