90 lines
1.7 KiB
Go
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
|
|
}
|