91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
// 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))
|
|
})
|
|
}
|