Tell non-admins why the console is off-limits instead of bouncing them to the dashboard
coordinator / test (push) Waiting to run
python / test (push) Waiting to run
release / binaries (amd64, darwin) (push) Waiting to run
release / binaries (amd64, linux) (push) Waiting to run
release / binaries (amd64, windows) (push) Waiting to run
release / binaries (arm64, darwin) (push) Waiting to run
release / binaries (arm64, linux) (push) Waiting to run
release / binaries (arm64, windows) (push) Waiting to run
release / release (push) Blocked by required conditions
release / image (push) Waiting to run
users / test (push) Waiting to run

This commit is contained in:
Emil
2026-08-03 01:34:22 +03:00
parent 82eaec4c55
commit 7c1d0dc568
4 changed files with 10 additions and 8 deletions
@@ -26,12 +26,14 @@ var adminUserActions = map[string]bool{
}
// requireAdmin gates a route on the session caller being an admin. It runs
// inside withUISession, which has already stamped the requester. A non-admin is
// sent back to the dashboard rather than shown the panel.
// inside withUISession, which has already stamped the requester. A signed-in
// non-admin is told why (and bounced to the login with the message); an
// unauthenticated caller never gets here — the gate has already sent them to
// the login page with the intended destination.
func requireAdmin(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if req, ok := authctx.From(r.Context()); !ok || !req.IsAdmin() {
http.Redirect(w, r, "/ui", http.StatusSeeOther)
http.Redirect(w, r, "/ui/login?error=admin+role+required", http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
@@ -30,15 +30,15 @@ func TestRequireAdminAllowsAdminOnly(t *testing.T) {
t.Error("admin must reach the handler")
}
// Plain user is redirected to the dashboard.
// Plain user is redirected to the login with the reason.
reached = false
rec := httptest.NewRecorder()
h.ServeHTTP(rec, adminReq(t, "user"))
if reached {
t.Error("non-admin must not reach the handler")
}
if rec.Code != http.StatusSeeOther || rec.Header().Get("Location") != "/ui" {
t.Errorf("non-admin got %d -> %q, want 303 -> /ui", rec.Code, rec.Header().Get("Location"))
if rec.Code != http.StatusSeeOther || rec.Header().Get("Location") != "/ui/login?error=admin+role+required" {
t.Errorf("non-admin got %d -> %q, want 303 -> login with the admin-required error", rec.Code, rec.Header().Get("Location"))
}
}
+1 -1
View File
@@ -65,7 +65,7 @@ Write-Host "SciMesh $Component installed: $Target"
Write-Host ""
if ($Component -eq "coordinator") {
if ($AutoStart -eq "1") {
Write-Host "Starting the platform and opening the control room in your browser..."
Write-Host "Starting the platform and opening the admin console in your browser..."
Write-Host "(stop it with Ctrl-C; it keeps your data in ~\.scimesh)"
Write-Host ""
& $Target serve --open
+1 -1
View File
@@ -78,7 +78,7 @@ fi
if [ "$COMPONENT" = "coordinator" ]; then
if [ "$AUTO_START" = "1" ]; then
echo
echo "Starting the platform and opening the control room in your browser..."
echo "Starting the platform and opening the admin console in your browser..."
echo "(stop it with Ctrl-C; it keeps your data in ~/.scimesh)"
echo
exec "$TARGET" serve --open