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
5.2 KiB
5.2 KiB
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
wgandipcommands - Firewall: python-nftables or subprocess
nft - Python: 3.13
- Package Manager: uv
Development Setup
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 dependenciesuv run python -m wiregui.main— run the appalembic revision --autogenerate -m "description"— create migrationalembic upgrade head— apply all migrationsalembic downgrade -1— rollback last migrationdocker compose up -d— start local Postgres + Valkeydocker compose down— stop local servicespytest— 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.pyviasetup_logging() - When
WG_LOG_TO_FILE=true(default), timestamped log files are written tologs/in the project root - The
logs/directory is gitignored
Testing
- Tests live in
tests/mirroring thewiregui/structure - Run with
uv run pytest - Use
pytest-asynciofor async tests - Test database: uses same Postgres instance, separate
wiregui_testdatabase