package main import ( "net/http" "net/url" "strings" ) type tokensData struct { Tokens []Token Audit []AuditEntry URL string // the endpoint, for the example Secret string // a token made just now: shown once Name string HasDoc bool } func (a *app) tokensData(r *http.Request) tokensData { return tokensData{Tokens: a.tokens.List(), Audit: a.sys.RecentAudit(30), URL: "https://" + r.Host + "/mcp", HasDoc: a.optionsFile != ""} } func (a *app) tokensPage(w http.ResponseWriter, r *http.Request, sess session) { a.render(w, "tokens", page{Title: "API access", CSRF: sess.csrf, LoggedIn: true, Flash: r.URL.Query().Get("msg"), Data: a.tokensData(r)}) } func (a *app) tokenCreate(w http.ResponseWriter, r *http.Request, sess session) { tok, secret, err := a.tokens.Create(r.PostFormValue("name"), r.PostFormValue("scope")) p := page{Title: "API access", CSRF: sess.csrf, LoggedIn: true} d := a.tokensData(r) if err != nil { p.Error = err.Error() w.WriteHeader(http.StatusUnprocessableEntity) } else { d.Secret, d.Name = secret, tok.Name p.Flash = "Token " + tok.Name + " created. Copy it now: it is not shown again." } p.Data = d a.render(w, "tokens", p) } func (a *app) tokenRevoke(w http.ResponseWriter, r *http.Request, _ session) { msg := "Token revoked." if err := a.tokens.Revoke(strings.TrimSpace(r.PostFormValue("id"))); err != nil { msg = "Could not revoke: " + err.Error() } http.Redirect(w, r, "/tokens?msg="+url.QueryEscape(msg), http.StatusSeeOther) } // changesPage shows what differs between the confirmed settings and the saved // ones, for a person to review before applying. func (a *app) changesPage(w http.ResponseWriter, r *http.Request, sess session) { a.render(w, "changes", page{Title: "Changes", CSRF: sess.csrf, LoggedIn: true, Data: map[string]any{ "Diff": a.sys.pendingChanges(), "Unapplied": a.sys.Status().Unapplied, }}) }