All checks were successful
gitea-deepak/gogmagog/pipeline/head This commit looks good
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
package tokens
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type contextKey struct {
|
|
name string
|
|
}
|
|
|
|
var userIDCtxKey = &contextKey{"UserID"}
|
|
|
|
func unauthorized(w http.ResponseWriter, r *http.Request) {
|
|
code := http.StatusUnauthorized
|
|
http.Error(w, http.StatusText(code), code)
|
|
}
|
|
|
|
// TokenFromHeader tries to retreive the token string from the
|
|
// "Authorization" reqeust header: "Authorization: BEARER T".
|
|
func TokenFromHeader(r *http.Request) string {
|
|
// Get token from authorization header.
|
|
bearer := r.Header.Get("Authorization")
|
|
if len(bearer) > 7 && strings.ToUpper(bearer[0:6]) == "BEARER" {
|
|
return bearer[7:]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (tok *jwtToker) Authenticator(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
tokenString := TokenFromHeader(r)
|
|
if tokenString == "" {
|
|
log.Print("No valid token found")
|
|
unauthorized(w, r)
|
|
return
|
|
}
|
|
|
|
userID, err := tok.DecodeTokenString(tokenString)
|
|
if err != nil {
|
|
log.Printf("Error while verifying token: %s", err)
|
|
unauthorized(w, r)
|
|
return
|
|
}
|
|
|
|
log.Printf("Got user with ID: [%d]", userID)
|
|
ctx := context.WithValue(r.Context(), userIDCtxKey, userID)
|
|
// Authenticated
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
// GetUserID is a convenience method that gets the user ID from the context.
|
|
// I hate the fact that we're passing user ID on the context, but it is more
|
|
// idiomatic Go than any type shenanigans.
|
|
func GetUserID(ctx context.Context) (int, error) {
|
|
userID, ok := ctx.Value(userIDCtxKey).(int64)
|
|
if !ok {
|
|
return -1, fmt.Errorf("Could not parse user ID [%s] from context", ctx.Value(userIDCtxKey))
|
|
|
|
}
|
|
return int(userID), nil
|
|
}
|
|
|
|
// GetContextForUserID is a test helper method that creates a context with user ID set.
|
|
func GetContextForUserID(userID int) context.Context {
|
|
return context.WithValue(context.Background(), userIDCtxKey, int64(userID))
|
|
}
|