Sign-in page redesign and Portal roles Super Admin / Admin / Viewer
Sign-in: brand panel, show / hide password, Caps Lock warning, moving background, tab icon. Roles: Super Admin manages Admins and Viewers, Admin manages Viewers only (and can Start / Stop, see Sign-ins), Viewer sees claims and Runs only. create_tables.sql moves an old table. 71 test files, 1220 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
120fd6808a
commit
ce9bdbd974
11 files changed
+408
-99
No files matched your search
+14
-9
@@ -54,8 +54,9 @@ from ecw_bot.core.run_events import run_id_of # noqa: E402
|
||||
from .repo import SqlResultsRepo # noqa: E402
|
||||
from . import run_status # noqa: E402
|
||||
from . import runs as run_view # noqa: E402
|
||||
from .users import (Accounts, CAN_RUN, ROLES, Sessions, # noqa: E402
|
||||
SqlUserStore, UserError)
|
||||
from .users import (Accounts, CAN_ADMIN, CAN_RUN, # noqa: E402
|
||||
IDLE_MINUTES, LOCK_AFTER, LOCK_MINUTES, MANAGES,
|
||||
Sessions, SqlUserStore, UserError)
|
||||
from .bot_runner import (AlreadyRunning, BotRunner, # noqa: E402
|
||||
NotRunning, StopFailed)
|
||||
|
||||
@@ -379,7 +380,7 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
|
||||
"run_token": app.state.run_token, "crumbs": crumbs,
|
||||
"categories": CATEGORIES, "user": user,
|
||||
"can_run": bool(user and user["role"] in CAN_RUN),
|
||||
"is_admin": bool(user and user["role"] == "Admin"),
|
||||
"is_admin": bool(user and user["role"] in CAN_ADMIN),
|
||||
**context})
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
@@ -548,7 +549,9 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
|
||||
def _signin_page(request, error="", next_url="/", status_code=200):
|
||||
page = _page(request, "signin.html", [["Sign in", None]],
|
||||
error=error, next_url=_safe_next(next_url),
|
||||
no_users=not _db(store.list))
|
||||
no_users=not _db(store.list),
|
||||
idle_minutes=IDLE_MINUTES, lock_after=LOCK_AFTER,
|
||||
lock_minutes=LOCK_MINUTES)
|
||||
page.status_code = status_code
|
||||
return page
|
||||
|
||||
@@ -611,26 +614,28 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
|
||||
sessions.refresh_user(updated)
|
||||
return RedirectResponse("/", status_code=303)
|
||||
|
||||
# ── Portal Users (Admin) ─────────────────────────────────────────────
|
||||
# ── Portal Users (Super Admin, Admin) ────────────────────────────────
|
||||
|
||||
def _users_page(request, error="", message="", status_code=200):
|
||||
page = _page(request, "users.html",
|
||||
[["Dashboard", "/"], ["Portal Users", None]],
|
||||
users=_db(store.list), roles=ROLES, error=error,
|
||||
users=_db(store.list),
|
||||
roles=MANAGES.get(request.state.user["role"], ()),
|
||||
error=error,
|
||||
message=message)
|
||||
page.status_code = status_code
|
||||
return page
|
||||
|
||||
@app.get("/admin/users", response_class=HTMLResponse)
|
||||
def users_page(request: Request, msg: str = ""):
|
||||
_need(request, ("Admin",))
|
||||
_need(request, CAN_ADMIN)
|
||||
return _users_page(request, message=msg[:200])
|
||||
|
||||
def _admin_change(request, token, done, fn, *args):
|
||||
"""One Admin change: checked, made, then back to the list with
|
||||
`done` said — or the list again with the problem."""
|
||||
_check_token(request, token)
|
||||
me = _need(request, ("Admin",))["username"]
|
||||
me = _need(request, CAN_ADMIN)["username"]
|
||||
try:
|
||||
_db(fn, *args, by=me)
|
||||
except UserError as exc:
|
||||
@@ -686,7 +691,7 @@ def create_app(repo, allowed_hosts=ALLOWED_HOSTS, runner=None,
|
||||
|
||||
@app.get("/admin/signins", response_class=HTMLResponse)
|
||||
def signins_page(request: Request):
|
||||
_need(request, ("Admin",))
|
||||
_need(request, CAN_ADMIN)
|
||||
return _page(request, "signins.html",
|
||||
[["Dashboard", "/"], ["Sign-in history", None]],
|
||||
events=_db(store.history))
|
||||
|
||||
Reference in new issue
Block a user