package middleware import ( "crypto/subtle" "fmt" "net/http" "strings" "git.leonardobishop.net/stash/api/dto" ) func MustAuthenticate(token string) func(http.HandlerFunc) http.HandlerFunc { return func(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { authHeader := r.Header.Get("Authorization") givenToken, err := extractBearerToken(authHeader) if err != nil { dto.WriteDto(w, r, &dto.ErrorResponse{ Code: http.StatusUnauthorized, Message: "Unauthorized", }) return } if subtle.ConstantTimeCompare([]byte(token), []byte(givenToken)) != 1 { dto.WriteDto(w, r, &dto.ErrorResponse{ Code: http.StatusForbidden, Message: "Forbidden", }) return } next(w, r) } } } func extractBearerToken(header string) (string, error) { const prefix = "Bearer " if header == "" { return "", fmt.Errorf("authorization header missing") } if !strings.HasPrefix(header, prefix) { return "", fmt.Errorf("invalid authorization scheme") } token := strings.TrimSpace(header[len(prefix):]) if token == "" { return "", fmt.Errorf("token is empty") } return token, nil }