view pkg/auth/middleware.go @ 935:430d52c2f6ef

client: move layer isolines to be drawn at the top * Move layer isolones to be drawn last (and thus being "on top") so that the bottleneck (position) layer will not interfere that much with the colours. It also allows to set a white background with high opacity on the bottleneck polygon in order to get highly visible isolines.
author Bernhard Reiter <bernhard@intevation.de>
date Mon, 08 Oct 2018 17:20:42 +0200
parents 8a0737aa6ab6
children a244b18cb916
line wrap: on
line source

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 := Sessions.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 {
		return session.Roles.HasAny(roles...)
	}
}

func EnsureRole(roles ...string) func(http.Handler) http.Handler {
	return func(handler http.Handler) http.Handler {
		return SessionMiddleware(SessionChecker(handler, HasRole(roles...)))
	}
}