From 39a926cd521806aedc298ddd671d1a118794fcec Mon Sep 17 00:00:00 2001 From: Leonardo Bishop Date: Wed, 17 Sep 2025 18:13:30 +0100 Subject: Add endpoints for web extension --- api/middleware/auth.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ api/middleware/cors.go | 12 +++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 api/middleware/auth.go (limited to 'api/middleware') diff --git a/api/middleware/auth.go b/api/middleware/auth.go new file mode 100644 index 0000000..f6e5c4b --- /dev/null +++ b/api/middleware/auth.go @@ -0,0 +1,51 @@ +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 +} diff --git a/api/middleware/cors.go b/api/middleware/cors.go index 926c1ed..1fbd850 100644 --- a/api/middleware/cors.go +++ b/api/middleware/cors.go @@ -2,11 +2,13 @@ package middleware import "net/http" -func Cors(next http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") +func PermissiveCors() func(http.HandlerFunc) http.HandlerFunc { + return func(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") - next(w, r) + next(w, r) + } } } -- cgit v1.2.3-70-g09d2