Make source-health page public with a trimmed reader view
/status was admin-only (404 for everyone else). Serve it to all: a reader view with per-feed live/idle/delayed status and last-update time, while admins additionally get poll cadence, item/story counts, paywall rates, posting times, and raw fetch errors. Error strings are stripped server-side for non-admins so feed-specific workarounds and upstream URLs never reach the public payload. Nav status link now shows for everyone.
This commit is contained in:
@@ -13,26 +13,47 @@ func TestStatusTemplateExecutes(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
data := statusPage{
|
||||
pageData: pageData{SiteTitle: "Pete", Channels: channels},
|
||||
DegradedCnt: 1,
|
||||
Sources: []sourceStatus{
|
||||
{Name: "Broken Feed", Channel: "tech", Failures: 3, LastError: "dial tcp: timeout",
|
||||
LastPollAt: time.Now(), NeverRun: false, Healthy: false, Total: 4, Paywalled: 2, PaywallRate: 50},
|
||||
{Name: "Good Feed", Channel: "eu", Healthy: true, LastPollAt: time.Now(),
|
||||
LastSuccessAt: time.Now(), LastItemCount: 12, Total: 30, Classified: 28,
|
||||
LastSeenAt: time.Now(), LastPostedAt: time.Now()},
|
||||
{Name: "Idle Feed", Channel: "music", NeverRun: true},
|
||||
},
|
||||
sources := []sourceStatus{
|
||||
{Name: "Broken Feed", Channel: "tech", Failures: 3, LastError: "dial tcp: timeout",
|
||||
LastPollAt: time.Now(), NeverRun: false, Healthy: false, Total: 4, Paywalled: 2, PaywallRate: 50},
|
||||
{Name: "Good Feed", Channel: "eu", Healthy: true, LastPollAt: time.Now(),
|
||||
LastSuccessAt: time.Now(), LastItemCount: 12, Total: 30, Classified: 28,
|
||||
LastSeenAt: time.Now(), LastPostedAt: time.Now()},
|
||||
{Name: "Idle Feed", Channel: "music", NeverRun: true},
|
||||
}
|
||||
var b strings.Builder
|
||||
if err := s.tpls["status"].ExecuteTemplate(&b, "layout", data); err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
render := func(admin bool) string {
|
||||
data := statusPage{
|
||||
pageData: pageData{SiteTitle: "Pete", Channels: channels},
|
||||
DegradedCnt: 1,
|
||||
Admin: admin,
|
||||
Sources: sources,
|
||||
}
|
||||
var b strings.Builder
|
||||
if err := s.tpls["status"].ExecuteTemplate(&b, "layout", data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
out := b.String()
|
||||
|
||||
// Admin view: every feed plus the operator diagnostics and raw errors.
|
||||
admin := render(true)
|
||||
for _, want := range []string{"Broken Feed", "Good Feed", "dial tcp: timeout", "1 degraded", "Source health"} {
|
||||
if !strings.Contains(out, want) {
|
||||
t.Errorf("rendered status page missing %q", want)
|
||||
if !strings.Contains(admin, want) {
|
||||
t.Errorf("admin status page missing %q", want)
|
||||
}
|
||||
}
|
||||
|
||||
// Public view: same feeds and states, but no error strings or ops columns.
|
||||
pub := render(false)
|
||||
for _, want := range []string{"Broken Feed", "Good Feed", "Idle Feed", "delayed", "Source health"} {
|
||||
if !strings.Contains(pub, want) {
|
||||
t.Errorf("public status page missing %q", want)
|
||||
}
|
||||
}
|
||||
for _, leak := range []string{"dial tcp: timeout", "degraded", "Last posted", "Paywall"} {
|
||||
if strings.Contains(pub, leak) {
|
||||
t.Errorf("public status page leaked operator detail %q", leak)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user