Add admin invites and user workspace management tools.

Implement invite-token registration with optional email delivery, add admin UI actions for creating invites and opening user workspaces, and support superuser workspace override while preserving per-user code isolation with shared read-only lib.

Made-with: Cursor
This commit is contained in:
2026-05-01 21:13:13 +12:00
parent e4c811f51d
commit 7d682cce8d
15 changed files with 683 additions and 71 deletions

View File

@@ -1,6 +1,6 @@
# python-editor
Browser-based Python editing: **FastAPI** serves static assets, stores workspace files, and optional **API key auth**. **Pyodide** runs your scripts and **Jedi** (inside Pyodide) powers completions — no server-side Python execution or Jedi.
Browser-based Python editing: **FastAPI** serves static assets, stores workspace files, and optional **API key auth**. **Pyodide** runs your scripts and **Jedi** (inside Pyodide) powers completions and syntax diagnostics — no server-side Python execution or LSP process.
## Run
@@ -48,6 +48,13 @@ If nothing is listening, the smoke test **skips** with a short message instead o
Open [http://localhost:8080](http://localhost:8080).
### Editor runtime controls
- `Run Python` runs the active open `.py` tab.
- Enable `Run main.py` to always run `code/main.py` instead.
- Pressing `Run Python` while a script is running will stop and restart with the selected target.
- `LSP` badge in the header shows in-browser Jedi syntax status (`n/a`, `checking...`, `OK`, or issue count).
## Deploy with Docker
Build and run with Docker Compose:
@@ -68,6 +75,17 @@ Notes:
**User accounts** — Set `AUTH_ENABLED=true` in `.env` to require sign-in for workspace APIs. Users live in a SQLite file (`AUTH_DATABASE_PATH`, default `./data/editor.db`). Use `/register` (if `AUTH_REGISTER_OPEN=true`) or `BOOTSTRAP_ADMIN_USERNAME` / `BOOTSTRAP_ADMIN_PASSWORD` for the first superuser. Superusers can **GET/POST/DELETE `/api/users`** to list, create, or remove accounts.
Email invite signup:
- Superusers can create invites via `POST /api/users/invites` with `{ "email": "...", "expires_days": 7 }`.
- Response includes `invite_url`; if SMTP is configured the invite email is sent automatically.
- Set `AUTH_INVITE_ONLY=true` to require invite tokens for all registrations.
- Registration page accepts invite links like `/register?invite=<token>`.
When auth is enabled, file APIs use a per-user workspace under `WORKSPACE_ROOT/users/<username-id>/` for **isolated `code/`**. The `lib/` tree is shared and read-only for all users. When auth is disabled, the shared workspace root is used for everything.
Admins can open another user's workspace from the home page user management panel (links to `/editor?workspace_user_id=<id>`). Only superusers may use this override.
**API key** — If `EDITOR_API_KEY` is set, requests may use `Authorization: Bearer …` instead of a session (useful for automation). When `AUTH_ENABLED=true`, a valid session *or* API key is accepted.
The home page can store the API key in `sessionStorage` when you are not using cookie login, or use `?api_key=` on `/editor`.
@@ -95,7 +113,16 @@ np[0] = (255, 0, 0)
np.write()
```
`write()` updates the NeoPixel simulator window so you can verify behavior visually.
`write()` updates the NeoPixel simulator so you can verify behavior visually.
Simulator modes:
- Default: in-app LED strip/panel section under the editor.
- `16x16 panel` checkbox: opens a dedicated popup with 16x16 serpentine mapping:
- first LED at top-right
- first row goes right -> left
- rows zig-zag left/right.
- The 16x16 popup closes automatically on **Stop** or when script execution finishes.
Tutorial files: