# HG changeset patch # User Sascha L. Teichmann # Date 1552664734 -3600 # Node ID ef59a4255670d8dacbb9da1af079a751b534bb9b # Parent 8f919fe629f965c0f283c011b147b3a0a4245ac1 Added http middlewares to connect to db and parse input as JSON. This complements the JSONHandler which is for JSON in to JSON out. The new middlewares are for JSON in to abitrary out. diff -r 8f919fe629f9 -r ef59a4255670 pkg/middleware/dbconn.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/middleware/dbconn.go Fri Mar 15 16:45:34 2019 +0100 @@ -0,0 +1,61 @@ +// This is Free Software under GNU Affero General Public License v >= 3.0 +// without warranty, see README.md and license for details. +// +// SPDX-License-Identifier: AGPL-3.0-or-later +// License-Filename: LICENSES/AGPL-3.0.txt +// +// Copyright (C) 2019 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha L. Teichmann + +package middleware + +import ( + "context" + "database/sql" + "fmt" + "log" + "net/http" + + "gemma.intevation.de/gemma/pkg/auth" +) + +type wrapDBKeyType int + +const wrapDBKey wrapDBKeyType = 0 + +func GetDBConn(req *http.Request) *sql.Conn { + if conn, ok := req.Context().Value(wrapDBKey).(*sql.Conn); ok { + return conn + } + return nil +} + +func DBConn(next http.Handler) http.Handler { + + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + token, ok := auth.GetToken(req) + if !ok { + http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + session := auth.Sessions.Session(token) + if session == nil { + http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + parent := req.Context() + if err := auth.RunAs(parent, session.User, func(conn *sql.Conn) error { + ctx := context.WithValue(parent, wrapDBKey, conn) + req = req.WithContext(ctx) + next.ServeHTTP(rw, req) + return nil + }); err != nil { + log.Printf("error: %v\n", err) + http.Error(rw, fmt.Sprintf("error: %v", err), http.StatusInternalServerError) + } + }) +} diff -r 8f919fe629f9 -r ef59a4255670 pkg/middleware/json.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/middleware/json.go Fri Mar 15 16:45:34 2019 +0100 @@ -0,0 +1,56 @@ +// This is Free Software under GNU Affero General Public License v >= 3.0 +// without warranty, see README.md and license for details. +// +// SPDX-License-Identifier: AGPL-3.0-or-later +// License-Filename: LICENSES/AGPL-3.0.txt +// +// Copyright (C) 2019 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha L. Teichmann + +package middleware + +import ( + "context" + "encoding/json" + "io" + "net/http" +) + +type jsonInputKeyType int + +const jsonInputKey jsonInputKeyType = 0 + +const DefaultLimit = 2048 + +func GetJSONInput(req *http.Request) interface{} { + return req.Context().Value(jsonInputKey) +} + +func JSONInput(next http.Handler, input func(*http.Request) interface{}, limit int64) http.Handler { + + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + dst := input(req) + defer req.Body.Close() + var r io.Reader + switch { + case limit == 0: + r = io.LimitReader(req.Body, DefaultLimit) + case limit > 0: + r = io.LimitReader(req.Body, limit) + default: + r = req.Body + } + if err := json.NewDecoder(r).Decode(dst); err != nil { + http.Error(rw, "error: "+err.Error(), http.StatusBadRequest) + return + } + parent := req.Context() + ctx := context.WithValue(parent, jsonInputKey, input) + req = req.WithContext(ctx) + next.ServeHTTP(rw, req) + }) +}