diff pkg/auth/middleware.go @ 414:c1047fd04a3a

Moved project specific Go packages to new pkg folder.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 15 Aug 2018 17:30:50 +0200
parents auth/middleware.go@a7b2db8b3d18
children 62c909dd3098
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/auth/middleware.go	Wed Aug 15 17:30:50 2018 +0200
@@ -0,0 +1,79 @@
+package auth
+
+import (
+	"context"
+	"net/http"
+	"strings"
+)
+
+type contextType int
+
+const (
+	sessionKey contextType = iota
+	tokenKey
+)
+
+func GetSession(req *http.Request) (*Session, bool) {
+	session, ok := req.Context().Value(sessionKey).(*Session)
+	return session, ok
+}
+
+func GetToken(req *http.Request) (string, bool) {
+	token, ok := req.Context().Value(tokenKey).(string)
+	return token, ok
+}
+
+func SessionMiddleware(next http.Handler) http.Handler {
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+
+		auth := req.Header.Get("X-Gemma-Auth")
+
+		token := strings.TrimSpace(auth)
+		if token == "" {
+			http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+			return
+		}
+
+		session := ConnPool.Session(token)
+		if session == nil {
+			http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+			return
+		}
+
+		ctx := req.Context()
+		ctx = context.WithValue(ctx, sessionKey, session)
+		ctx = context.WithValue(ctx, tokenKey, token)
+		req = req.WithContext(ctx)
+
+		next.ServeHTTP(rw, req)
+	})
+}
+
+func SessionChecker(next http.Handler, check func(*Session) bool) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		claims, ok := GetSession(req)
+		if !ok || !check(claims) {
+			http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+			return
+		}
+		next.ServeHTTP(rw, req)
+	})
+}
+
+func HasRole(roles ...string) func(*Session) bool {
+	return func(session *Session) bool {
+		for _, r1 := range roles {
+			if session.Roles.Has(r1) {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+func EnsureRole(roles ...string) func(http.Handler) http.Handler {
+	return func(handler http.Handler) http.Handler {
+		return SessionMiddleware(SessionChecker(handler, HasRole(roles...)))
+	}
+}