comparison pkg/middleware/modifyquery.go @ 419:6627c48363a0

First attempt for user injection of proxy for using GeoServer with role based security.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 16 Aug 2018 13:39:13 +0200
parents
children ffdb507d5b42
comparison
equal deleted inserted replaced
418:c70ddc6eb168 419:6627c48363a0
1 package middleware
2
3 import (
4 "log"
5 "net/http"
6 "net/url"
7 "strings"
8
9 "gemma.intevation.de/gemma/pkg/auth"
10 )
11
12 // ParseQuery is a modified version of the internal query
13 // parser of the url.parseQuery of the standard library.
14 func ParseQuery(
15 m url.Values,
16 query string,
17 keySep, valueSep string,
18 unescape func(string) (string, error),
19 ) error {
20 if unescape == nil {
21 unescape = url.QueryUnescape
22 }
23 for query != "" {
24 key := query
25 if i := strings.Index(key, keySep); i >= 0 {
26 key, query = key[:i], key[i+1:]
27
28 } else {
29 query = ""
30 }
31 if key == "" {
32 continue
33 }
34 value := ""
35 if i := strings.Index(key, valueSep); i >= 0 {
36 key, value = key[:i], key[i+1:]
37 }
38 key, err := unescape(key)
39 if err != nil {
40 return err
41 }
42 value, err = unescape(value)
43 if err != nil {
44 return err
45 }
46 m[key] = append(m[key], value)
47 }
48 return nil
49 }
50
51 func ModifyQuery(next http.Handler, modify func(*http.Request, url.Values) error) http.Handler {
52
53 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
54
55 // GeoServer query parameters contain ';' as sub key separators.
56 // If we would use req.URL.Query() this would be split
57 // at the wrong level resulting in broken key/value pairs.
58 // So we do the splitting ourselves.
59
60 parameters := make(url.Values)
61
62 if err := ParseQuery(parameters, req.URL.RawQuery, "&", "=", nil); err != nil {
63 log.Printf("parsing query failed: %v\n", err)
64 http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
65 return
66 }
67
68 if err := modify(req, parameters); err != nil {
69 log.Printf("modifying query parameters failed: %v\n", err)
70 http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
71 }
72
73 req.URL.RawQuery = parameters.Encode()
74
75 next.ServeHTTP(rw, req)
76 })
77 }
78
79 func InjectUser(req *http.Request, parameters url.Values) error {
80 // To prevent SQL injections
81 parameters.Del("env")
82
83 session, ok := auth.GetSession(req)
84 if ok && !strings.ContainsAny(session.User, `\"':;`) {
85 log.Printf("Injecting user %s\n", session.User)
86 parameters.Set("env", "user:"+session.User)
87 }
88 return nil
89 }