feat: initial WireGUI implementation — full VPN management platform
Complete Python/NiceGUI rewrite of the Wirezone (Elixir/Phoenix) VPN management platform. All 10 implementation phases delivered. Core stack: - NiceGUI reactive UI with SQLModel ORM on PostgreSQL (asyncpg) - Alembic migrations, Valkey/Redis cache, pydantic-settings config - WireGuard management via subprocess (wg/ip/nft CLIs) - 164 tests passing, 35% code coverage Features: - User/device/rule CRUD with admin and unprivileged roles - Full device config form with per-device WG overrides - WireGuard client config generation with QR codes - REST API (v0) with Bearer token auth for all resources - TOTP MFA with QR registration and challenge flow - OIDC SSO with authlib (provider registry, auto-create users) - Magic link passwordless sign-in via email - SAML SP-initiated SSO with IdP metadata parsing - WebAuthn/FIDO2 security key registration - nftables firewall with per-user chains and masquerade - Background tasks: WG stats polling, VPN session expiry, OIDC token refresh, WAN connectivity checks - Startup reconciliation (DB ↔ WireGuard state sync) - In-memory notification system with header badge - Admin UI: users, devices, rules, settings (3 tabs), diagnostics - Loguru logging with optional timestamped file output Deployment: - Multi-stage Dockerfile (python:3.13-slim) - Docker Compose prod stack (bridge networking, NET_ADMIN, nftables) - Forgejo CI: tests → semantic versioning → Docker registry push - Health endpoint at /api/health
This commit is contained in:
commit
0546b44507
109 changed files with 11793 additions and 0 deletions
124
CLAUDE.md
Normal file
124
CLAUDE.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
# WireGUI
|
||||
|
||||
## Project Overview
|
||||
WireGUI is a Python rewrite of the Wirezone VPN management platform (Elixir/Phoenix).
|
||||
Original source: `/home/stefanob/PycharmProjects/personal/wirezone`
|
||||
|
||||
## Tech Stack
|
||||
- **UI Framework**: NiceGUI (reactive server-side UI over WebSocket)
|
||||
- **ORM/Models**: SQLModel (SQLAlchemy + Pydantic)
|
||||
- **Database**: PostgreSQL (via asyncpg)
|
||||
- **Cache/Sessions**: Valkey (Redis-compatible)
|
||||
- **Migrations**: Alembic
|
||||
- **REST API**: FastAPI (built into NiceGUI)
|
||||
- **Auth**: authlib (OIDC), python-jose (JWT), pyotp (TOTP), webauthn, bcrypt
|
||||
- **VPN**: subprocess calls to `wg` and `ip` commands
|
||||
- **Firewall**: python-nftables or subprocess `nft`
|
||||
- **Python**: 3.13
|
||||
- **Package Manager**: uv
|
||||
|
||||
## Development Setup
|
||||
```bash
|
||||
uv sync # Install dependencies
|
||||
docker compose up -d # Start PostgreSQL and Valkey
|
||||
alembic upgrade head # Run migrations
|
||||
uv run python -m wiregui.main # Start the application
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
wiregui/
|
||||
├── main.py # NiceGUI entrypoint, mounts FastAPI, starts background tasks
|
||||
├── config.py # pydantic-settings: Settings class
|
||||
├── db.py # async SQLAlchemy engine + sessionmaker
|
||||
├── redis.py # Valkey connection pool
|
||||
├── models/ # SQLModel table definitions
|
||||
│ ├── user.py
|
||||
│ ├── device.py
|
||||
│ ├── rule.py
|
||||
│ ├── mfa_method.py
|
||||
│ ├── oidc_connection.py
|
||||
│ ├── api_token.py
|
||||
│ ├── connectivity_check.py
|
||||
│ └── configuration.py
|
||||
├── schemas/ # Pydantic request/response schemas (non-table)
|
||||
├── auth/ # Authentication modules
|
||||
│ ├── passwords.py # bcrypt hashing
|
||||
│ ├── jwt.py # JWT create/verify
|
||||
│ ├── session.py # NiceGUI session middleware
|
||||
│ ├── oidc.py # authlib OIDC
|
||||
│ ├── saml.py # python3-saml
|
||||
│ ├── mfa.py # TOTP + WebAuthn
|
||||
│ └── api_token.py # API token auth
|
||||
├── api/v0/ # REST API routers
|
||||
│ ├── users.py
|
||||
│ ├── devices.py
|
||||
│ ├── rules.py
|
||||
│ └── configuration.py
|
||||
├── pages/ # NiceGUI page definitions
|
||||
│ ├── layout.py # shared sidebar/header
|
||||
│ ├── login.py
|
||||
│ ├── devices.py # user device CRUD
|
||||
│ ├── account.py # user account/MFA
|
||||
│ ├── mfa_challenge.py
|
||||
│ └── admin/ # admin pages
|
||||
│ ├── users.py
|
||||
│ ├── devices.py
|
||||
│ ├── rules.py
|
||||
│ ├── settings.py
|
||||
│ └── diagnostics.py
|
||||
├── services/ # Core services
|
||||
│ ├── wireguard.py # WG interface management
|
||||
│ ├── firewall.py # nftables rule management
|
||||
│ ├── events.py # DB → WG/firewall bridge
|
||||
│ ├── notifications.py # in-memory notification queue
|
||||
│ └── email.py # aiosmtplib
|
||||
├── tasks/ # Background tasks
|
||||
│ ├── vpn_session.py # expire VPN sessions
|
||||
│ ├── stats.py # poll WG stats
|
||||
│ ├── connectivity.py # WAN connectivity checks
|
||||
│ └── oidc_refresh.py # refresh OIDC tokens
|
||||
└── utils/ # Utilities
|
||||
├── crypto.py # keypair gen, Fernet encrypt/decrypt
|
||||
├── network.py # IP allocation, CIDR validation
|
||||
└── validators.py # shared validators
|
||||
alembic/
|
||||
├── env.py
|
||||
├── script.py.mako
|
||||
└── versions/
|
||||
```
|
||||
|
||||
## Commands
|
||||
- `uv sync` — install/update dependencies
|
||||
- `uv run python -m wiregui.main` — run the app
|
||||
- `alembic revision --autogenerate -m "description"` — create migration
|
||||
- `alembic upgrade head` — apply all migrations
|
||||
- `alembic downgrade -1` — rollback last migration
|
||||
- `docker compose up -d` — start local Postgres + Valkey
|
||||
- `docker compose down` — stop local services
|
||||
- `pytest` — run tests
|
||||
|
||||
## Conventions
|
||||
- Use SQLModel for all database models (combines SQLAlchemy table + Pydantic validation)
|
||||
- Use async database sessions with asyncpg
|
||||
- Place all NiceGUI pages in `wiregui/pages/`
|
||||
- Place all SQLModel table models in `wiregui/models/`
|
||||
- Place Pydantic request/response schemas in `wiregui/schemas/`
|
||||
- Use Alembic autogenerate for migrations
|
||||
- Background tasks use asyncio (create_task + while/sleep pattern)
|
||||
- WireGuard/nftables managed via subprocess (asyncio.create_subprocess_exec)
|
||||
- DB is source of truth; WG/firewall state is reconciled on startup
|
||||
|
||||
## Logging — MANDATORY
|
||||
- **Use loguru for ALL logging and messages. No `print()` statements allowed anywhere in this project.**
|
||||
- Import: `from loguru import logger`
|
||||
- Use `logger.info()`, `logger.warning()`, `logger.error()`, `logger.debug()`, etc.
|
||||
- Loguru is configured in `wiregui/logging.py` via `setup_logging()`
|
||||
- When `WG_LOG_TO_FILE=true` (default), timestamped log files are written to `logs/` in the project root
|
||||
- The `logs/` directory is gitignored
|
||||
|
||||
## Testing
|
||||
- Tests live in `tests/` mirroring the `wiregui/` structure
|
||||
- Run with `uv run pytest`
|
||||
- Use `pytest-asyncio` for async tests
|
||||
- Test database: uses same Postgres instance, separate `wiregui_test` database
|
||||
Loading…
Add table
Add a link
Reference in a new issue