Move user administration to its own page; add Project Super User
User accounts lived in the Admin Console, which is admins-only. Project admins
need to create the accounts on their own jobs without an app admin on the phone,
so accounts move to a new User Directory page and a new role carries the right.
server/auth.py, server/app.py
New permissions role `project_super_user`, between admin and project_admin:
everything a project admin may do, plus user administration SCOPED to the
projects they hold the role on. Four limits make it safe to hand out, all
enforced server-side:
* Scope comes from projects, not the job title. It resolves per membership
(managed_project_ids), so an ordinary account can hold it on one job via
ProjectMember.role, and a super user demoted on one job administers
nobody there. No projects, no authority.
* Account-level changes (password, disable, rename, permissions, delete)
require EXCLUSIVE scope: refused when the target is also on a project the
caller does not administer, because those changes are global. The
directory renders such rows read-only with the reason.
* No admin or super-user targets, and neither role can be granted by a
super user -- that is the line that stops it becoming app-wide control.
* PUT .../projects rebuilds only the caller's own slice; memberships on
projects they do not administer are left untouched. A payload that simply
omits them must not cut someone off a job the caller cannot see.
Creating requires naming at least one of your own projects: an account with
none would be one the creator instantly cannot manage.
/api/auth/users is now scoped rather than admin-only, and carries a per-row
`manageable` verdict plus the reason. Non-managers get a contact card only --
a project user has no business reading colleagues' login history. New
/api/auth/user-scope tells the page what it may offer. Administrative
password resets are now audited; they were the one account change that left
no trace. Settings, feature flags and the auto-add rule stay admin-only.
While here: one definition of "is a user manager", derived from the managed
set. An account-role-only version disagreed with the scoped one and locked
per-project super users out of routes they were entitled to.
html/users.html, html/users.js
The directory: three renderings from one page -- admin (everything), super
user (controls per row, read-only where scope is shared), everyone else (a
read-only directory of the people on their own projects).
html/console.css, html/console-util.js
Extracted from admin.html/admin.js so both console pages share them. A
divergent jsq() is an XSS and a divergent role list offers permissions the
server refuses, so neither may exist twice.
html/wp-sidenav.{js,css}
Global nav drawer, role-gated, carrying ?project= across links. Mounted on
the field view (which had no way to anywhere) plus both console pages.
No migration: users.role is already String(20) and the new value fits.
Verified: 93 scope/gate tests, 29 live HTTP tests through the real dependency
stack, 33 static JS checks. Not verified in a browser -- no JS engine on this
machine -- so users.html and field.html want one manual load.
server/smoketest.py still fails with 401s. Pre-existing: it has no login code,
so auth_gate refuses it. Confirmed unchanged by stashing this work.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -195,12 +195,18 @@ good deploy look broken.
|
||||
Sanity checks — all four should take under a minute:
|
||||
|
||||
1. Log in. The home page offers to select or create a project.
|
||||
2. Open **Admin Console** (the link is on the home page; you need an admin account).
|
||||
The user table should read as **one line per user** — if rows are three lines tall
|
||||
and the table spills outside its white card, you are still on the old cached
|
||||
2. Open **User Directory** (the `Users` link in the top-right menu, or the tile on the
|
||||
home page). The table should read as **one line per user** — if rows are three lines
|
||||
tall and the table spills outside its white card, you are still on the old cached
|
||||
files: hard-reload again.
|
||||
3. Two new cards are present and load: **Projects**, and **Default members on new
|
||||
projects**. Both should list rows, not an error.
|
||||
|
||||
> Changed since this runbook was written: user accounts moved out of the Admin
|
||||
> Console into `users.html` when the **Project Super User** role was added, so that
|
||||
> a project admin can create accounts on their own job. If you are deploying a build
|
||||
> from before that change, read this step as "Admin Console → the user table".
|
||||
3. Open **Admin Console** (admin account required). Two new cards are present and
|
||||
load: **Projects**, and **Default members on new projects**. Both should list rows,
|
||||
not an error.
|
||||
4. In the **Projects** card, click **Archive** on a project you don't mind hiding
|
||||
(a `DEMO-` one if there is one), confirm the prompt, then tick **Show archived** —
|
||||
it should reappear marked `archived`. Click **Unarchive** to put it back. That
|
||||
|
||||
Reference in New Issue
Block a user