Mercurial > gemma
comparison pkg/auth/middleware.go @ 1340:97430d442909
Added comments to auth middleware.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 26 Nov 2018 10:32:37 +0100 |
parents | 450f5d0f5fe7 |
children |
comparison
equal
deleted
inserted
replaced
1339:1d1fc92fc3ea | 1340:97430d442909 |
---|---|
24 const ( | 24 const ( |
25 sessionKey contextType = iota | 25 sessionKey contextType = iota |
26 tokenKey | 26 tokenKey |
27 ) | 27 ) |
28 | 28 |
29 // GetSession returns the session stored in the context of the request. | |
29 func GetSession(req *http.Request) (*Session, bool) { | 30 func GetSession(req *http.Request) (*Session, bool) { |
30 session, ok := req.Context().Value(sessionKey).(*Session) | 31 session, ok := req.Context().Value(sessionKey).(*Session) |
31 return session, ok | 32 return session, ok |
32 } | 33 } |
33 | 34 |
35 // GetToken returns the session token associated with given request. | |
34 func GetToken(req *http.Request) (string, bool) { | 36 func GetToken(req *http.Request) (string, bool) { |
35 token, ok := req.Context().Value(tokenKey).(string) | 37 token, ok := req.Context().Value(tokenKey).(string) |
36 return token, ok | 38 return token, ok |
37 } | 39 } |
38 | 40 |
41 // SessionMiddleware constructs a middleware to enforce the existence | |
42 // of the header X-Gemma-Auth in the incoming request and checks | |
43 // if a session is bound to it. | |
44 // Ihe the checks fail the constructed handler issues an http.StatusUnauthorized | |
45 // back to the invokation stacks and prevents the execution of the | |
46 // nested http.Handler next. | |
47 // Inside the http.Handler next calls to GetSession and GetToken are valid | |
48 // to fetch the respective information. | |
39 func SessionMiddleware(next http.Handler) http.Handler { | 49 func SessionMiddleware(next http.Handler) http.Handler { |
40 | 50 |
41 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { | 51 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { |
42 | 52 |
43 auth := req.Header.Get("X-Gemma-Auth") | 53 auth := req.Header.Get("X-Gemma-Auth") |
61 | 71 |
62 next.ServeHTTP(rw, req) | 72 next.ServeHTTP(rw, req) |
63 }) | 73 }) |
64 } | 74 } |
65 | 75 |
76 // SessionChecker constructs a middleware to check invariants about a session | |
77 // before calling the nested http.Handler next. | |
78 // This is useful when creating specialized middleware e.g. to enforce | |
79 // a role system. | |
66 func SessionChecker(next http.Handler, check func(*Session) bool) http.Handler { | 80 func SessionChecker(next http.Handler, check func(*Session) bool) http.Handler { |
67 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { | 81 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { |
68 if claims, ok := GetSession(req); !ok || !check(claims) { | 82 if claims, ok := GetSession(req); !ok || !check(claims) { |
69 http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) | 83 http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) |
70 return | 84 return |
71 } | 85 } |
72 next.ServeHTTP(rw, req) | 86 next.ServeHTTP(rw, req) |
73 }) | 87 }) |
74 } | 88 } |
75 | 89 |
90 // HasRole is a checker function fitting into SessionChecker to check | |
91 // if the user is logged in with at least one of list of given roles. | |
76 func HasRole(roles ...string) func(*Session) bool { | 92 func HasRole(roles ...string) func(*Session) bool { |
77 return func(session *Session) bool { | 93 return func(session *Session) bool { |
78 return session.Roles.HasAny(roles...) | 94 return session.Roles.HasAny(roles...) |
79 } | 95 } |
80 } | 96 } |
81 | 97 |
98 // EnsureRole is a macro function to stitch SessionChecker and HasRole together. | |
82 func EnsureRole(roles ...string) func(http.Handler) http.Handler { | 99 func EnsureRole(roles ...string) func(http.Handler) http.Handler { |
83 return func(handler http.Handler) http.Handler { | 100 return func(handler http.Handler) http.Handler { |
84 return SessionMiddleware(SessionChecker(handler, HasRole(roles...))) | 101 return SessionMiddleware(SessionChecker(handler, HasRole(roles...))) |
85 } | 102 } |
86 } | 103 } |