pegasus/backend/middleware.go

91 lines
2.5 KiB
Go
Raw Permalink Normal View History

2026-04-11 00:02:59 -03:00
// backend/middleware.go
package main
import (
"net/http"
"strings"
"time"
"github.com/tus/tusd/pkg/handler"
"scm.bstein.dev/bstein/Pegasus/backend/internal"
)
type loggingRW struct {
http.ResponseWriter
status int
}
func (l *loggingRW) WriteHeader(code int) {
l.status = code
l.ResponseWriter.WriteHeader(code)
}
func sessionRequired(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if _, err := internal.CurrentUser(r); err != nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func corsForTus(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if origin := r.Header.Get("Origin"); origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Vary", "Origin")
}
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Methods", "GET,POST,HEAD,PATCH,DELETE,OPTIONS")
w.Header().Set("Access-Control-Max-Age", "86400")
w.Header().Set(
"Access-Control-Allow-Headers",
"Content-Type, Tus-Resumable, Upload-Length, Upload-Defer-Length, Upload-Metadata, Upload-Offset, Upload-Concat, Upload-Checksum, X-Requested-With",
)
w.Header().Set("Access-Control-Expose-Headers", "Location, Upload-Offset, Upload-Length, Tus-Resumable, Upload-Checksum")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return
}
next.ServeHTTP(w, r)
})
}
func claimsFromHook(ev handler.HookEvent) (internal.Claims, error) {
req := ev.HTTPRequest
if req.Header == nil {
return internal.Claims{}, http.ErrNoCookie
}
r := http.Request{Header: http.Header(req.Header)}
return internal.CurrentUser(&r)
}
func redactHeaders(h http.Header) http.Header {
cp := http.Header{}
for k, v := range h {
kk := strings.ToLower(k)
if kk == "cookie" || strings.HasPrefix(kk, "authorization") || strings.Contains(kk, "token") {
cp[k] = []string{"<redacted>"}
continue
}
cp[k] = append([]string(nil), v...)
}
return cp
}
func debugHandler(next http.Handler) http.Handler {
if !internal.Debug {
return next
}
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
id := time.Now().UnixNano()
internal.Logf(">> %d %s %s %v", id, req.Method, req.URL.Path, redactHeaders(req.Header))
rw := &loggingRW{ResponseWriter: w, status: http.StatusOK}
start := time.Now()
next.ServeHTTP(rw, req)
internal.Logf("<< %d %s %s %d %s", id, req.Method, req.URL.Path, rw.status, time.Since(start))
})
}