changeset 438:ffdb507d5b42

Removed db service user. Use an impersonated metamorph user instead.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 21 Aug 2018 11:33:19 +0200
parents b8366b24dc55
children 1504f8eff12e
files pkg/auth/opendb.go pkg/config/config.go pkg/controllers/pwreset.go pkg/controllers/types.go pkg/middleware/modifyquery.go
diffstat 5 files changed, 31 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/auth/opendb.go	Mon Aug 20 18:10:55 2018 +0200
+++ b/pkg/auth/opendb.go	Tue Aug 21 11:33:19 2018 +0200
@@ -2,6 +2,8 @@
 
 import (
 	"database/sql"
+	"errors"
+	"strings"
 
 	"github.com/jackc/pgx"
 	"github.com/jackc/pgx/stdlib"
@@ -38,6 +40,10 @@
 SELECT rolname FROM pg_roles
 WHERE oid IN (SELECT oid FROM cte) AND rolname <> current_user`
 
+const InvalidRoleCharacters = `\"':;`
+
+var ErrInvalidRoleCharacters = errors.New("rolename contains invalid character")
+
 func AllOtherRoles(user, password string) ([]string, error) {
 	db, err := OpenDB(user, password)
 	if err != nil {
@@ -61,3 +67,18 @@
 	}
 	return roles, rows.Err()
 }
+
+func RunAs(role string, fn func(*sql.DB) error) error {
+	if strings.Contains(role, InvalidRoleCharacters) {
+		return ErrInvalidRoleCharacters
+	}
+	db, err := OpenDB(config.MetamorphDBUser(), config.MetamorhpDBPassword())
+	if err != nil {
+		return nil
+	}
+	defer db.Close()
+	if _, err := db.Exec(`SET ROLE "` + role + `"`); err != nil {
+		return err
+	}
+	return fn(db)
+}
--- a/pkg/config/config.go	Mon Aug 20 18:10:55 2018 +0200
+++ b/pkg/config/config.go	Tue Aug 21 11:33:19 2018 +0200
@@ -27,9 +27,6 @@
 func WebHost() string      { return viper.GetString("host") }
 func WebPort() uint        { return uint(viper.GetInt32("port")) }
 
-func ServiceUser() string     { return viper.GetString("service-user") }
-func ServicePassword() string { return viper.GetString("service-password") }
-
 func MetamorphDBUser() string     { return viper.GetString("metamorph-db-user") }
 func MetamorhpDBPassword() string { return viper.GetString("metamorph-db-password") }
 
@@ -135,9 +132,6 @@
 	strP("host", "o", "localhost", "host of the web app")
 	uiP("port", "p", 8000, "port of the web app")
 
-	str("service-user", "postgres", "user to do service tasks")
-	str("service-password", "", "password of user to do service tasks")
-
 	str("mail-host", "localhost", "server to send mail with")
 	ui("mail-port", 465, "port of server to send mail with")
 	str("mail-user", "gemma", "user to send mail with")
--- a/pkg/controllers/pwreset.go	Mon Aug 20 18:10:55 2018 +0200
+++ b/pkg/controllers/pwreset.go	Tue Aug 21 11:33:19 2018 +0200
@@ -15,7 +15,6 @@
 
 	"gemma.intevation.de/gemma/pkg/auth"
 	"gemma.intevation.de/gemma/pkg/common"
-	"gemma.intevation.de/gemma/pkg/config"
 	"gemma.intevation.de/gemma/pkg/misc"
 )
 
@@ -55,6 +54,8 @@
 	cleanupPause               = 15 * time.Minute
 )
 
+const pwResetRole = "pw_reset"
+
 var (
 	passwordResetRequestMailTmpl = template.Must(
 		template.New("request").Parse(`You have requested a password change
@@ -83,15 +84,6 @@
     Your service team`))
 )
 
-func asServiceUser(fn func(*sql.DB) error) error {
-	db, err := auth.OpenDB(config.ServiceUser(), config.ServicePassword())
-	if err == nil {
-		defer db.Close()
-		err = fn(db)
-	}
-	return err
-}
-
 func init() {
 	go removeOutdated()
 }
@@ -99,7 +91,7 @@
 func removeOutdated() {
 	for {
 		time.Sleep(cleanupPause)
-		err := asServiceUser(func(db *sql.DB) error {
+		err := auth.RunAs(pwResetRole, func(db *sql.DB) error {
 			good := time.Now().Add(-passwordResetValid)
 			_, err := db.Exec(cleanupRequestsSQL, good)
 			return err
@@ -184,7 +176,7 @@
 
 	var hash, email string
 
-	if err = asServiceUser(func(db *sql.DB) error {
+	if err = auth.RunAs(pwResetRole, func(db *sql.DB) error {
 
 		var count int64
 		if err := db.QueryRow(countRequestsSQL).Scan(&count); err != nil {
@@ -249,7 +241,7 @@
 
 	var email, user, password string
 
-	if err = asServiceUser(func(db *sql.DB) error {
+	if err = auth.RunAs(pwResetRole, func(db *sql.DB) error {
 		err := db.QueryRow(findRequestSQL, hash).Scan(&email, &user)
 		switch {
 		case err == sql.ErrNoRows:
--- a/pkg/controllers/types.go	Mon Aug 20 18:10:55 2018 +0200
+++ b/pkg/controllers/types.go	Tue Aug 21 11:33:19 2018 +0200
@@ -6,6 +6,8 @@
 	"errors"
 	"regexp"
 	"strings"
+
+	"gemma.intevation.de/gemma/pkg/auth"
 )
 
 type (
@@ -80,7 +82,8 @@
 var errNoValidUser = errors.New("Not a valid user")
 
 func (u UserName) isValid() bool {
-	return u != "" && !strings.ContainsAny(string(u), `\"':;`)
+	return u != "" &&
+		!strings.ContainsAny(string(u), auth.InvalidRoleCharacters)
 }
 
 func (u *UserName) UnmarshalJSON(data []byte) error {
--- a/pkg/middleware/modifyquery.go	Mon Aug 20 18:10:55 2018 +0200
+++ b/pkg/middleware/modifyquery.go	Tue Aug 21 11:33:19 2018 +0200
@@ -81,7 +81,7 @@
 	parameters.Del("env")
 
 	session, ok := auth.GetSession(req)
-	if ok && !strings.ContainsAny(session.User, `\"':;`) {
+	if ok && !strings.ContainsAny(session.User, auth.InvalidRoleCharacters) {
 		log.Printf("Injecting user %s\n", session.User)
 		parameters.Set("env", "user:"+session.User)
 	}