super-graph/serv/auth.go
2020-02-03 01:21:07 -05:00

90 lines
1.7 KiB
Go

package serv
import (
"context"
"net/http"
)
type ctxkey int
const (
userIDProviderKey ctxkey = iota
userIDKey
userRoleKey
)
func headerAuth(authc configAuth, next http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
userIDProvider := r.Header.Get("X-User-ID-Provider")
if len(userIDProvider) != 0 {
ctx = context.WithValue(ctx, userIDProviderKey, userIDProvider)
}
userID := r.Header.Get("X-User-ID")
if len(userID) != 0 {
ctx = context.WithValue(ctx, userIDKey, userID)
}
userRole := r.Header.Get("X-User-Role")
if len(userRole) != 0 {
ctx = context.WithValue(ctx, userRoleKey, userRole)
}
next.ServeHTTP(w, r.WithContext(ctx))
}
}
func headerHandler(authc configAuth, next http.Handler) http.HandlerFunc {
hdr := authc.Header
if len(hdr.Name) == 0 {
errlog.Fatal().Str("auth", authc.Name).Msg("no header.name defined")
}
if !hdr.Exists && len(hdr.Value) == 0 {
errlog.Fatal().Str("auth", authc.Name).Msg("no header.value defined")
}
return func(w http.ResponseWriter, r *http.Request) {
var fo1 bool
value := r.Header.Get(hdr.Name)
switch {
case hdr.Exists:
fo1 = (len(value) == 0)
default:
fo1 = (value != hdr.Value)
}
if fo1 {
http.Error(w, "401 unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
}
}
func withAuth(next http.Handler, authc configAuth) http.Handler {
if authc.CredsInHeader {
next = headerAuth(authc, next)
}
switch authc.Type {
case "rails":
return railsHandler(authc, next)
case "jwt":
return jwtHandler(authc, next)
case "header":
return headerHandler(authc, next)
}
return next
}