annotate pkg/auth/middleware.go @ 5591:0011f50cf216 surveysperbottleneckid

Removed no longer used alternative api for surveys/ endpoint. As bottlenecks in the summary for SR imports are now identified by their id and no longer by the (not guarantied to be unique!) name, there is no longer the need to request survey data by the name+date tuple (which isn't reliable anyway). So the workaround was now reversed.
author Sascha Wilde <wilde@sha-bang.de>
date Wed, 06 Apr 2022 13:30:29 +0200
parents 97430d442909
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1017
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
1 // This is Free Software under GNU Affero General Public License v >= 3.0
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
2 // without warranty, see README.md and license for details.
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
3 //
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
4 // SPDX-License-Identifier: AGPL-3.0-or-later
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
5 // License-Filename: LICENSES/AGPL-3.0.txt
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
6 //
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
7 // Copyright (C) 2018 by via donau
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
8 // – Österreichische Wasserstraßen-Gesellschaft mbH
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
9 // Software engineering by Intevation GmbH
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
10 //
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
11 // Author(s):
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de>
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 493
diff changeset
13
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
14 package auth
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
15
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
16 import (
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
17 "context"
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
18 "net/http"
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
19 "strings"
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
20 )
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
21
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
22 type contextType int
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
23
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
24 const (
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
25 sessionKey contextType = iota
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
26 tokenKey
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
27 )
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
28
1340
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
29 // GetSession returns the session stored in the context of the request.
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
30 func GetSession(req *http.Request) (*Session, bool) {
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
31 session, ok := req.Context().Value(sessionKey).(*Session)
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
32 return session, ok
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
33 }
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
34
1340
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
35 // GetToken returns the session token associated with given request.
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
36 func GetToken(req *http.Request) (string, bool) {
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
37 token, ok := req.Context().Value(tokenKey).(string)
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
38 return token, ok
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
39 }
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
40
1340
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
41 // SessionMiddleware constructs a middleware to enforce the existence
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
42 // of the header X-Gemma-Auth in the incoming request and checks
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
43 // if a session is bound to it.
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
44 // Ihe the checks fail the constructed handler issues an http.StatusUnauthorized
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
45 // back to the invokation stacks and prevents the execution of the
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
46 // nested http.Handler next.
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
47 // Inside the http.Handler next calls to GetSession and GetToken are valid
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
48 // to fetch the respective information.
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
49 func SessionMiddleware(next http.Handler) http.Handler {
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
50
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
51 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
52
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
53 auth := req.Header.Get("X-Gemma-Auth")
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
54
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
55 token := strings.TrimSpace(auth)
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
56 if token == "" {
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
57 http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
58 return
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
59 }
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
60
493
8a0737aa6ab6 The connection pool is now only a session store.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 447
diff changeset
61 session := Sessions.Session(token)
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
62 if session == nil {
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
63 http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
64 return
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
65 }
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
66
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
67 ctx := req.Context()
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
68 ctx = context.WithValue(ctx, sessionKey, session)
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
69 ctx = context.WithValue(ctx, tokenKey, token)
119
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
70 req = req.WithContext(ctx)
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
71
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
72 next.ServeHTTP(rw, req)
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
73 })
29e56c342c9f Added first middleware for JWT token extraction. TODO: Add second one to check against logged in users.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
74 }
128
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
75
1340
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
76 // SessionChecker constructs a middleware to check invariants about a session
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
77 // before calling the nested http.Handler next.
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
78 // This is useful when creating specialized middleware e.g. to enforce
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
79 // a role system.
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
80 func SessionChecker(next http.Handler, check func(*Session) bool) http.Handler {
128
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
81 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
1319
450f5d0f5fe7 Cosmetics.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1017
diff changeset
82 if claims, ok := GetSession(req); !ok || !check(claims) {
128
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
83 http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
84 return
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
85 }
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
86 next.ServeHTTP(rw, req)
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
87 })
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
88 }
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
89
1340
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
90 // HasRole is a checker function fitting into SessionChecker to check
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
91 // if the user is logged in with at least one of list of given roles.
134
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
92 func HasRole(roles ...string) func(*Session) bool {
0c56c56a1c44 Removed the JWT layer from the session management.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 128
diff changeset
93 return func(session *Session) bool {
447
62c909dd3098 Only allow log in if user has at least one of the roles 'sys_admin', 'waterway_admin', 'waterway_user'.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
94 return session.Roles.HasAny(roles...)
128
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
95 }
441a8ee637c5 Added claims checker + example.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 119
diff changeset
96 }
226
63dd5216eee4 Refactored gemma server to be more REST-like.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 134
diff changeset
97
1340
97430d442909 Added comments to auth middleware.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 1319
diff changeset
98 // EnsureRole is a macro function to stitch SessionChecker and HasRole together.
237
3771788d3dae Reduce boilerplate code when writing JSON parsing/generating endpoints.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 230
diff changeset
99 func EnsureRole(roles ...string) func(http.Handler) http.Handler {
3771788d3dae Reduce boilerplate code when writing JSON parsing/generating endpoints.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 230
diff changeset
100 return func(handler http.Handler) http.Handler {
3771788d3dae Reduce boilerplate code when writing JSON parsing/generating endpoints.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 230
diff changeset
101 return SessionMiddleware(SessionChecker(handler, HasRole(roles...)))
226
63dd5216eee4 Refactored gemma server to be more REST-like.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 134
diff changeset
102 }
63dd5216eee4 Refactored gemma server to be more REST-like.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 134
diff changeset
103 }