view pkg/middleware/dbconn.go @ 5490:5f47eeea988d logging

Use own logging package.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 Sep 2021 17:45:39 +0200
parents 6f9d00c8cc38
children
line wrap: on
line source

// 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 <sascha.teichmann@intevation.de>

package middleware

import (
	"context"
	"database/sql"
	"fmt"
	"net/http"

	"gemma.intevation.de/gemma/pkg/auth"
	"gemma.intevation.de/gemma/pkg/log"
)

type wrapDBKeyType int

const wrapDBKey wrapDBKeyType = 0

// GetDBConn fetches a *sql.Conn from the context of the request.
// Returns nil if no such connection exists.
func GetDBConn(req *http.Request) *sql.Conn {
	if conn, ok := req.Context().Value(wrapDBKey).(*sql.Conn); ok {
		return conn
	}
	return nil
}

// DBConn is a middleware that stores a *sql.Conn in the context
// of the incoming request if the user is authorized and
// has a valid session.
// The handler will return with an http.StatusUnauthorized else
// w/o calling the cascaded next handler.
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.Errorf("%v\n", err)
			http.Error(rw, fmt.Sprintf("error: %v", err), http.StatusInternalServerError)
		}
	})
}