diff options
| author | Leonardo Bishop <me@leonardobishop.net> | 2025-09-17 18:13:30 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.net> | 2025-09-17 18:13:30 +0100 |
| commit | 39a926cd521806aedc298ddd671d1a118794fcec (patch) | |
| tree | a38908af8c91e01b2acec112b871c951e1bf6c1b /api/middleware/auth.go | |
| parent | 1b7c07d9bbfb7984536a3aeade0f543251f1a666 (diff) | |
Add endpoints for web extension
Diffstat (limited to 'api/middleware/auth.go')
| -rw-r--r-- | api/middleware/auth.go | 51 |
1 files changed, 51 insertions, 0 deletions
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 +} |
