Mercurial > gemma
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...))) + } +}