mirror of
https://github.com/ipnet-mesh/meshcore-hub.git
synced 2026-10-31 04:02:03 +01:00
Add user profiles with node adoption via /v1/adoptions endpoint
Move adopt/release from profile routes to dedicated /v1/adoptions endpoint. Node API now returns adopted_by field. Profile page shows read-only adopted nodes. Node detail page has adopt/release buttons (operator adopts, admin can release any). Admin release bypasses ownership check.
This commit is contained in:
1 parent
6a5a23845f
commit
31418e6847
39 files changed
+1849
-174
No files matched your search
+88
-4
@@ -4,7 +4,7 @@ This guide covers upgrading from a previous MeshCore Hub release to the current
|
||||
|
||||
## v0.10.0
|
||||
|
||||
This release includes **breaking changes** to the admin authentication model.
|
||||
This release includes **breaking changes** to the admin authentication model, OIDC role configuration, and adds user profiles with node adoption.
|
||||
|
||||
### Overview of Changes
|
||||
|
||||
@@ -12,9 +12,18 @@ This release includes **breaking changes** to the admin authentication model.
|
||||
|------|--------|-------|
|
||||
| Admin auth | `WEB_ADMIN_ENABLED=true` (open access) | OIDC/OAuth2 authentication via identity provider |
|
||||
| Auth library | None | Authlib (`authlib>=1.3.0`) |
|
||||
| Admin access | Anyone with the URL | Authenticated users with `admin` role from IdP |
|
||||
| Admin access | Anyone with the URL | Authenticated users with roles from IdP |
|
||||
| Session mgmt | None | Starlette `SessionMiddleware` (signed cookies) |
|
||||
| Write gating | None (API proxy open) | POST/PUT/DELETE/PATCH require admin session when OIDC enabled |
|
||||
| Proxy gating | None (API proxy open) | Per-endpoint, per-method role-based access mapping |
|
||||
| Role config | None | `OIDC_ROLE_ADMIN`, `OIDC_ROLE_OPERATOR`, `OIDC_ROLE_MEMBER` env vars |
|
||||
| SPA config | `is_admin: bool`, `is_member: bool` | `roles: ["admin", "member"]` array + `role_names` mapping |
|
||||
| Client-side | `config.is_admin` checks | `hasRole("admin")` helper |
|
||||
| OIDC disabled | All proxy access open | Only read access to known endpoints; writes blocked |
|
||||
| User profiles | None | `user_profiles` table (auto-created on first access) |
|
||||
| Node adoption | None | `user_profile_nodes` join table (operator role required) |
|
||||
| Node cleanup | 7 days default | 30 days default |
|
||||
| API proxy | No user identity forwarding | Injects `X-User-Id` and `X-User-Roles` headers |
|
||||
| Profile page | None | `/profile` SPA page linked from auth dropdown |
|
||||
|
||||
### Migration Steps
|
||||
|
||||
@@ -28,7 +37,15 @@ This release includes **breaking changes** to the admin authentication model.
|
||||
OIDC_SESSION_SECRET=$(openssl rand -hex 32)
|
||||
```
|
||||
3. **Remove `WEB_ADMIN_ENABLED`** from your `.env` (no longer used)
|
||||
4. **Configure roles** in your IdP: assign `admin` and/or `member` roles to users
|
||||
4. **Remove `OIDC_ADMIN_ROLE` and `OIDC_MEMBER_ROLE`** from your `.env` if present (renamed, see below)
|
||||
5. **Configure roles** in your IdP and set the role name env vars to match:
|
||||
```bash
|
||||
# These defaults match common IdP setups — only change if your IdP uses different role names
|
||||
OIDC_ROLE_ADMIN=admin
|
||||
OIDC_ROLE_OPERATOR=operator
|
||||
OIDC_ROLE_MEMBER=member
|
||||
```
|
||||
6. **Test admin access** — confirm that admin users can access `/admin/` and perform write operations
|
||||
|
||||
### Removed Variables
|
||||
|
||||
@@ -36,12 +53,79 @@ This release includes **breaking changes** to the admin authentication model.
|
||||
|----------|--------|
|
||||
| `WEB_ADMIN_ENABLED` | Replaced by `OIDC_ENABLED` |
|
||||
|
||||
### Renamed Variables
|
||||
|
||||
| Old Variable | New Variable | Notes |
|
||||
|--------------|-------------|-------|
|
||||
| `OIDC_ADMIN_ROLE` | `OIDC_ROLE_ADMIN` | New naming convention (`OIDC_ROLE_<NAME>`) |
|
||||
| `OIDC_MEMBER_ROLE` | `OIDC_ROLE_MEMBER` | New naming convention |
|
||||
|
||||
### New Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `OIDC_ROLE_ADMIN` | `admin` | IdP role name granting admin access |
|
||||
| `OIDC_ROLE_OPERATOR` | `operator` | IdP role name for operator access (future use) |
|
||||
| `OIDC_ROLE_MEMBER` | `member` | IdP role name for member access |
|
||||
|
||||
See the OIDC section in `.env.example` for the full list of environment variables.
|
||||
|
||||
### Behavior Change: OIDC Disabled
|
||||
|
||||
When OIDC is disabled, the web proxy now only allows GET access to known API endpoints. Write operations (POST/PUT/DELETE) are blocked, even without OIDC. If you relied on open write access through the web proxy without OIDC, use the CLI or direct API access with Bearer tokens instead.
|
||||
|
||||
**Important for LogTo users:** You must pass `client_id` in the logout request for the post-logout redirect to work. This is handled automatically by the application. You also need to register your app's URL as a **Sign-out redirect URI** in the LogTo admin console (e.g. `https://ipnt.uk`). If the redirect still doesn't work after updating, set `OIDC_POST_LOGOUT_REDIRECT_URI` explicitly to match your registered URI.
|
||||
|
||||
### User Profiles and Node Adoption
|
||||
|
||||
Authenticated OIDC users now have a profile page at `/profile` (linked from the avatar dropdown menu). Profiles are auto-created on first access with blank name and callsign fields.
|
||||
|
||||
Users with the **operator** role can adopt (claim) mesh network nodes from the node detail page. Users with the **admin** role can release any adopted node. Adopted nodes are shown as a read-only list on the profile page and display the adopting user's name on the node detail page.
|
||||
|
||||
### New API Endpoints
|
||||
|
||||
| Endpoint | Method | Auth | Description |
|
||||
|----------|--------|------|-------------|
|
||||
| `/api/v1/user/profile/{user_id}` | GET | Any OIDC user (own profile only) | Get-or-create profile with adopted nodes |
|
||||
| `/api/v1/user/profile/{user_id}` | PUT | Any OIDC user (own profile only) | Update name/callsign |
|
||||
| `/api/v1/adoptions` | POST | Operator or Admin | Adopt a node (auto-creates profile if needed) |
|
||||
| `/api/v1/adoptions/{public_key}` | DELETE | Operator (own node) or Admin (any) | Release a node |
|
||||
|
||||
The `NodeRead` schema now includes an `adopted_by` field with the adopting user's `user_id`, `name`, and `callsign` (or `null` if not adopted).
|
||||
|
||||
The web proxy injects `X-User-Id` and `X-User-Roles` headers when forwarding API requests for authenticated users, enabling the API layer to enforce per-user access control.
|
||||
|
||||
### New Database Tables
|
||||
|
||||
The database migration creates two new tables:
|
||||
|
||||
**`user_profiles`**: Stores OIDC user profile data (auto-created on first access).
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | VARCHAR(36) PK | UUID |
|
||||
| `user_id` | VARCHAR(255) UNIQUE | OIDC `sub` claim |
|
||||
| `name` | VARCHAR(255) | Display name (blank initially) |
|
||||
| `callsign` | VARCHAR(20) | Radio callsign (blank initially) |
|
||||
| `created_at` | DATETIME | Auto |
|
||||
| `updated_at` | DATETIME | Auto |
|
||||
|
||||
**`user_profile_nodes`**: Join table linking users to adopted nodes. Foreign keys have `ON DELETE CASCADE` so node cleanup automatically removes stale adoption records.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `user_profile_id` | VARCHAR(36) FK PK | References `user_profiles.id` (CASCADE) |
|
||||
| `node_id` | VARCHAR(36) FK PK UNIQUE | References `nodes.id` (CASCADE) |
|
||||
| `adopted_at` | DATETIME | When the adoption occurred |
|
||||
|
||||
### Default Change: Node Cleanup
|
||||
|
||||
The default value for `NODE_CLEANUP_DAYS` has changed from **7 days** to **30 days**. If you previously relied on the 7-day default, set it explicitly in your `.env`:
|
||||
|
||||
```bash
|
||||
NODE_CLEANUP_DAYS=7
|
||||
```
|
||||
|
||||
## v0.9.0
|
||||
|
||||
This release includes **breaking changes** to the MQTT broker, packet capture service, data ingestion pipeline, and public key handling.
|
||||
|
||||
Reference in new issue
Block a user