depot/web/fup/fuphttp/auth.go

48 lines
1,009 B
Go
Raw Normal View History

package fuphttp
import (
"crypto/subtle"
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func TokenAuthMiddleware(token, realm string) mux.MiddlewareFunc {
return func(next http.Handler) http.Handler {
if token == "" {
return next
}
tokenBytes := []byte(token)
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !IsMutate(ctx) {
// Allow all access to public pages.
next.ServeHTTP(rw, r)
return
}
requestAuth := func(s string) {
rw.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q, charset=\"UTF-8\"", realm))
http.Error(rw, s, http.StatusUnauthorized)
}
// Check for basic auth, first.
_, pw, ok := r.BasicAuth()
switch {
case !ok:
requestAuth("unparsable or no credentials")
return
case subtle.ConstantTimeCompare([]byte(pw), tokenBytes) != 1:
requestAuth("bad credentials")
return
}
// Auth check passed, let's go.
next.ServeHTTP(rw, r)
return
})
}
}