Mercurial > gemma
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/middleware/modifyquery.go Thu Aug 16 13:39:13 2018 +0200 @@ -0,0 +1,89 @@ +package middleware + +import ( + "log" + "net/http" + "net/url" + "strings" + + "gemma.intevation.de/gemma/pkg/auth" +) + +// ParseQuery is a modified version of the internal query +// parser of the url.parseQuery of the standard library. +func ParseQuery( + m url.Values, + query string, + keySep, valueSep string, + unescape func(string) (string, error), +) error { + if unescape == nil { + unescape = url.QueryUnescape + } + for query != "" { + key := query + if i := strings.Index(key, keySep); i >= 0 { + key, query = key[:i], key[i+1:] + + } else { + query = "" + } + if key == "" { + continue + } + value := "" + if i := strings.Index(key, valueSep); i >= 0 { + key, value = key[:i], key[i+1:] + } + key, err := unescape(key) + if err != nil { + return err + } + value, err = unescape(value) + if err != nil { + return err + } + m[key] = append(m[key], value) + } + return nil +} + +func ModifyQuery(next http.Handler, modify func(*http.Request, url.Values) error) http.Handler { + + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + + // GeoServer query parameters contain ';' as sub key separators. + // If we would use req.URL.Query() this would be split + // at the wrong level resulting in broken key/value pairs. + // So we do the splitting ourselves. + + parameters := make(url.Values) + + if err := ParseQuery(parameters, req.URL.RawQuery, "&", "=", nil); err != nil { + log.Printf("parsing query failed: %v\n", err) + http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + + if err := modify(req, parameters); err != nil { + log.Printf("modifying query parameters failed: %v\n", err) + http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + } + + req.URL.RawQuery = parameters.Encode() + + next.ServeHTTP(rw, req) + }) +} + +func InjectUser(req *http.Request, parameters url.Values) error { + // To prevent SQL injections + parameters.Del("env") + + session, ok := auth.GetSession(req) + if ok && !strings.ContainsAny(session.User, `\"':;`) { + log.Printf("Injecting user %s\n", session.User) + parameters.Set("env", "user:"+session.User) + } + return nil +}