Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Add one Admin page with status, accounts, and the audit log

43e681d8a5d94567aa9530d32b2c89223c1a17f9 · Keenan Nemetz · 5d ago · parent af018ce8

Add one Admin page with status, accounts, and the audit log

Instance administration was split between the Status and Accounts pages,
and the audit log had no browser view at all. The new /admin page gathers
the status tabs, the account roster, and a read-only audit viewer into one
place with a tab for each, and /status, /runners, and /users redirect to
the tab they named so old links keep working.

The audit reader walks the file backwards a chunk at a time, returns the
newest records first, and shows one extra record to know whether an older
page exists. It skips a line it cannot parse rather than failing the page
and refuses a symlink or a non-regular file, as startup already does.

Refs #198 (01M6MK0NNZ2XR1D5TQKNWYT4HN).

server/web/auth.go +9−2

@@ -186,14 +186,14 @@ func (w *Web) Middleware(next http.Handler) http.Handler {
186 186 }
187 187
188 188 // recordPageView counts a successfully rendered HTML page. Static files, Git
189 // traffic, redirects, HTMX fragments and the status page itself are excluded, so
189 // traffic, redirects, HTMX fragments and the admin surface itself are excluded, so
190 190 // the metric follows reading rather than polling or asset loads. It is
191 191 // best-effort: analytics must never turn a page into an error.
192 192 func (w *Web) recordPageView(r *http.Request, sw *statusWriter) {
193 193 if w.PageViews == nil || r.Method != http.MethodGet || sw.status != http.StatusOK {
194 194 return
195 195 }
196 if r.Header.Get("HX-Request") == "true" || r.URL.Path == "/status" {
196 if r.Header.Get("HX-Request") == "true" || adminPath(r.URL.Path) {
197 197 return
198 198 }
199 199 if !strings.HasPrefix(sw.Header().Get("Content-Type"), "text/html") {
@@ -208,6 +208,13 @@ func (w *Web) recordPageView(r *http.Request, sw *statusWriter) {
208 208 }
209 209 }
210 210
211 // adminPath reports whether a path belongs to the instance-admin surface. Those
212 // pages are read by the same few people watching the instance, so counting them
213 // would measure administration rather than readership.
214 func adminPath(path string) bool {
215 return path == "/admin" || path == "/status" || path == "/users" || strings.HasPrefix(path, "/users/")
216 }
217
211 218 // sessionFromCookie returns the first valid session cookie and the name it came
212 219 // from. The dev cookie is only considered when dev login is enabled, so a stray
213 220 // cookie on a normal instance is never a credential.