Add a read-only Settings page for the loaded configuration (closes #402)
check / check (push) Waiting to run
check / check (push) Waiting to run
A new page at /settings, linked from the navigation bar and behind the login, lists every configuration field the server loaded at startup: its environment variable, the README table's description, and the value in effect. METRICS_PASSWORD and SENTRY_DSN show only as set or not set; their values are replaced before rendering and never reach the template. The route is GET only and its group is built like the other admin page groups. Tests set the credentials one at a time so each value shown is checked against its own field and a set secret never appears in the page. Model: opus-5-5
This commit was merged in pull request #409.
This commit is contained in:
@@ -14,10 +14,11 @@ import (
|
||||
// bytes) for form POST endpoints. 1 MB is generous for any form
|
||||
// submission while preventing abuse from oversized payloads.
|
||||
//
|
||||
// The four admin page route groups below (/pages, /user/{username},
|
||||
// /hooks and /hook/{sourceID}) install MaxBodySize(maxFormBodySize)
|
||||
// right after their recoverer and error reporting, ahead of both CSRF
|
||||
// and RequireAuth. Both orderings are deliberate.
|
||||
// The five admin page route groups below (/pages, /user/{username},
|
||||
// /settings, /hooks and /hook/{sourceID}) install
|
||||
// MaxBodySize(maxFormBodySize) right after their recoverer and error
|
||||
// reporting, ahead of both CSRF and RequireAuth. Both orderings are
|
||||
// deliberate.
|
||||
//
|
||||
// Ahead of CSRF because gorilla/csrf parses the form. The cap has to
|
||||
// be installed before anything reads the body, or the parse runs
|
||||
@@ -154,6 +155,7 @@ func (s *Server) setupRoutes() {
|
||||
|
||||
s.setupPageRoutes()
|
||||
s.setupUserRoutes()
|
||||
s.setupSettingsRoutes()
|
||||
s.setupSourceRoutes()
|
||||
s.setupWebhookRoutes()
|
||||
}
|
||||
@@ -201,6 +203,24 @@ func (s *Server) setupUserRoutes() {
|
||||
})
|
||||
}
|
||||
|
||||
// setupSettingsRoutes serves the Settings page. It is GET only:
|
||||
// configuration comes from the environment and nothing here changes
|
||||
// it.
|
||||
func (s *Server) setupSettingsRoutes() {
|
||||
s.router.Route("/settings", func(r chi.Router) {
|
||||
s.recoverPanics(
|
||||
r, s.h.HandleErrorPage(http.StatusInternalServerError),
|
||||
)
|
||||
// MaxBodySize precedes CSRF and RequireAuth deliberately;
|
||||
// see maxFormBodySize for why, and for what it costs.
|
||||
r.Use(s.mw.MaxBodySize(maxFormBodySize))
|
||||
r.Use(s.mw.CSRF(s.h.HandleErrorPage(http.StatusForbidden)))
|
||||
r.Use(s.mw.NoCache())
|
||||
r.Use(s.mw.RequireAuth())
|
||||
r.Get("/", s.h.HandleSettings())
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) setupSourceRoutes() {
|
||||
s.router.Route("/hooks", func(r chi.Router) {
|
||||
s.recoverPanics(
|
||||
|
||||
Reference in New Issue
Block a user