mirror of
https://github.com/ipnet-mesh/meshcore-hub.git
synced 2026-08-10 02:42:45 +02:00
feat(routes): allow operators to manage routes
Operators can now create, edit, and delete routes (previously admin-only). A user may never scope a route above their own role tier: an operator creating/editing an admin-visibility route is rejected (403 on the visibility value, 404 on touching an existing higher-visibility route), preventing them from creating routes they could then never see or modify. - routes.py: RequireAdmin -> RequireOperatorOrAdmin on create/update/delete; add visibility-cap enforcement helpers reusing the existing resolve_user_role / VISIBILITY_LEVELS ladder - web/app.py: proxy access map admits operator for routes POST/PUT/DELETE - Routes.tsx: canManage gate (admin||operator) on Add/Edit/Delete; visibility <select> filters options by caller tier so operators never see 'admin' - tests: operator-tier coverage (create/update/delete at/below/above level), proxy access-map assertion, vitest role-gating + filtered select - e2e: mint operator session + routes-operator spec - docs: routes.md + auth.md operator/visibility-cap notes
This commit is contained in:
+6
-2
@@ -21,7 +21,7 @@ User roles are read from the OIDC token's `roles` claim (configurable via `OIDC_
|
||||
| Role | Config Variable | Default | Description |
|
||||
|------|----------------|---------|-------------|
|
||||
| Admin | `OIDC_ROLE_ADMIN` | `admin` | Full write access to all API endpoints through the proxy |
|
||||
| Operator | `OIDC_ROLE_OPERATOR` | `operator` | Reserved for future use — no endpoint assignments yet |
|
||||
| Operator | `OIDC_ROLE_OPERATOR` | `operator` | Manage nodes, node tags, adoptions, and routes (create/edit/delete, scoped to the operator visibility tier) |
|
||||
| Member | `OIDC_ROLE_MEMBER` | `member` | Read-only access (no endpoint assignments) |
|
||||
|
||||
The role names are configurable to match your IdP's role naming convention. For example, if your IdP uses `superuser` instead of `admin`, set `OIDC_ROLE_ADMIN=superuser`.
|
||||
@@ -36,17 +36,21 @@ The proxy uses a hardcoded per-endpoint, per-method mapping in `src/meshcore_hub
|
||||
|-------------|--------|--------|
|
||||
| `v1/nodes` | GET | Open |
|
||||
| `v1/nodes/` | GET | Open |
|
||||
| `v1/nodes/` | POST, PUT, DELETE | `admin` |
|
||||
| `v1/nodes/` | POST, PUT, DELETE | `admin`, `operator` |
|
||||
| `v1/members` | GET | Open |
|
||||
| `v1/members` | POST, PUT, DELETE | `admin` |
|
||||
| `v1/messages` | GET | Open |
|
||||
| `v1/advertisements` | GET | Open |
|
||||
| `v1/adoptions` | POST, DELETE | `admin`, `operator` |
|
||||
| `v1/routes` | POST | `admin`, `operator` |
|
||||
| `v1/routes/` | PUT, DELETE | `admin`, `operator` |
|
||||
| `v1/dashboard` | GET | Open |
|
||||
| `v1/trace-paths` | GET | Open |
|
||||
| `v1/telemetry` | GET | Open |
|
||||
|
||||
- **Open** = no authentication required (anonymous OK, works with or without OIDC)
|
||||
- **`admin`** = requires OIDC enabled + user has the `admin` role
|
||||
- **`admin`, `operator`** = requires OIDC enabled + user has the `admin` *or* `operator` role
|
||||
- Method not listed for a matched prefix = denied
|
||||
- No prefix match = denied
|
||||
|
||||
|
||||
+4
-2
@@ -44,11 +44,13 @@ The collector runs a background thread that re-evaluates every enabled route on
|
||||
|
||||
Routes carry the same role-based visibility levels as channels — `community`, `member`, `operator`, `admin`. A user only sees routes whose visibility is at or below their role's maximum level. Seeded routes default to `community` (visible to everyone); set a higher level to restrict a route to operators/admins only. Visibility is enforced on both the list and detail endpoints, so a hidden route's existence is not leaked.
|
||||
|
||||
Both operators and admins can create, edit, and delete routes. A user may never scope a route above their own role (e.g. an operator cannot create an `admin`-visibility route) — this is enforced on the write endpoints and prevents a user from creating a route they could then never see or modify. Operators can only edit/delete routes whose visibility is at or below the operator tier; attempting to modify a higher-visibility route returns `404`.
|
||||
|
||||
## Defining routes
|
||||
|
||||
Routes are keyed by their `from`/`to` endpoint labels and upserted by that pair. There are two ways to create them:
|
||||
|
||||
- **Seed YAML** — add a `routes.yaml` to your `SEED_HOME` and run the seed process. See [seeding.md → Routes](seeding.md#routes) for the format and rules (path nodes must already exist in the database; the `(from, to)` pair must be unique).
|
||||
- **API** — `POST /api/v1/routes` (admin only) creates a route, with a `/preview` endpoint that dry-runs matching against an unsaved configuration so you can tune thresholds before committing. See `SCHEMAS.md` for the request/response shapes.
|
||||
- **API** — `POST /api/v1/routes` (operator or admin) creates a route, with a `/preview` endpoint that dry-runs matching against an unsaved configuration so you can tune thresholds before committing. See `SCHEMAS.md` for the request/response shapes.
|
||||
|
||||
The `/routes` page renders the live status card, the per-day history strip, recent matching transmissions (with observer attribution), and — for admins — inline edit/delete controls.
|
||||
The `/routes` page renders the live status card, the per-day history strip, recent matching transmissions (with observer attribution), and — for operators and admins — inline edit/delete controls.
|
||||
|
||||
Reference in New Issue
Block a user