gpaste/middleware.go

88 lines
2.0 KiB
Go
Raw Normal View History

2022-01-19 02:23:54 +00:00
package gpaste
import (
2022-01-20 00:04:44 +00:00
"context"
"fmt"
2022-01-19 02:23:54 +00:00
"net/http"
2022-01-20 00:04:44 +00:00
"strings"
2022-01-19 02:23:54 +00:00
"time"
"github.com/go-chi/chi/v5/middleware"
)
2022-01-20 00:04:44 +00:00
type authCtxKey int
const (
authCtxUsername authCtxKey = iota
)
2022-01-19 02:23:54 +00:00
func (s *HTTPServer) MiddlewareAccessLogger(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
t1 := time.Now()
reqID := middleware.GetReqID(r.Context())
defer func() {
s.AccessLogger.Infow(r.Method,
"path", r.URL.Path,
"status", ww.Status(),
"written", ww.BytesWritten(),
"remote_addr", r.RemoteAddr,
"processing_time_ms", time.Since(t1).Milliseconds(),
"req_id", reqID)
}()
next.ServeHTTP(ww, r)
}
return http.HandlerFunc(fn)
}
2022-01-20 00:04:44 +00:00
func (s *HTTPServer) MiddlewareAuthentication(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
reqID := middleware.GetReqID(r.Context())
header := r.Header.Get("Authorization")
if header == "" {
s.Logger.Debugw("Request has no auth header.", "req_id", reqID)
next.ServeHTTP(w, r)
return
}
splitHeader := strings.Split(header, "Bearer ")
if len(splitHeader) != 2 {
s.Logger.Debugw("Request has invalid token.", "req_id", reqID)
next.ServeHTTP(w, r)
return
}
token := splitHeader[1]
claims, err := s.Auth.ValidateToken(token)
if err != nil {
s.Logger.Debugw("Request has invalid token.", "req_id", reqID)
next.ServeHTTP(w, r)
return
}
ctx := context.WithValue(r.Context(), authCtxUsername, claims.Subject)
withCtx := r.WithContext(ctx)
s.Logger.Debugw("Request is authenticated.", "req_id", reqID, "username", claims.Subject)
next.ServeHTTP(w, withCtx)
}
return http.HandlerFunc(fn)
}
func UsernameFromRequest(r *http.Request) (string, error) {
rawUsername := r.Context().Value(authCtxUsername)
if rawUsername == nil {
return "", fmt.Errorf("no username")
}
username, ok := rawUsername.(string)
if !ok {
return "", fmt.Errorf("no username")
}
return username, nil
}