Add delete token UI for info page

This commit is contained in:
2026-09-13 00:32:51 +02:00
parent ca34f1506d
commit 74bfdbfd8a
9 changed files with 293 additions and 25 deletions
+25 -3
View File
@@ -27,12 +27,23 @@ func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request) {
}
presented := s.deleteCredentials(w, r)
from := r.PostFormValue("from")
if len(presented) == 0 {
s.fail(w, r, http.StatusUnauthorized, "A delete token or an owning token is required.")
s.refuse(w, r, m, from, http.StatusUnauthorized,
"A delete token or an owning token is required.")
return
}
if !s.authorised(m, presented) {
s.fail(w, r, http.StatusForbidden, "That token cannot delete this file.")
// Only failures are throttled, so a correct token is never delayed.
// The info page is publicly shareable and now carries a credential
// field, which is reason enough not to let it be hammered freely.
if !s.deleteLimiter.allow(clientIP(r, s.cfg), s.now()) {
s.refuse(w, r, m, from, http.StatusTooManyRequests,
"Too many failed attempts; try again shortly.")
return
}
s.refuse(w, r, m, from, http.StatusForbidden, "That delete token is not correct.")
return
}
@@ -50,7 +61,7 @@ func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request) {
// Deleting from the administration table goes back to it. The destination
// is built from configuration, never from the request, so this cannot be
// turned into an open redirect.
if r.PostFormValue("from") == "admin" {
if from == "admin" {
http.Redirect(w, r, s.cfg.BasePath+"admin", http.StatusSeeOther)
return
}
@@ -61,6 +72,17 @@ func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request) {
})
}
// refuse reports a rejected deletion. A failed attempt from the file's own page
// lands back on that page with the reason, rather than on a generic error page
// that has thrown away what the reader typed.
func (s *Server) refuse(w http.ResponseWriter, r *http.Request, m *store.Meta, from string, status int, msg string) {
if from == "info" && !wantsJSON(r) {
s.renderInfo(w, r, m, status, msg)
return
}
s.fail(w, r, status, msg)
}
// deleteCredentials collects every secret the request carries.
//
// Three can legitimately arrive at once — the object's delete token in the