Mercurial > gemma
view pkg/auth/opendb.go @ 453:a7dc68d8e22f
Only let users in which are listed in users.list_users.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 22 Aug 2018 11:05:59 +0200 |
parents | 62c909dd3098 |
children | 685b886002b8 |
line wrap: on
line source
package auth import ( "database/sql" "errors" "strings" "github.com/jackc/pgx" "github.com/jackc/pgx/stdlib" "gemma.intevation.de/gemma/pkg/config" ) func OpenDB(user, password string) (*sql.DB, error) { // To ease SSL config ride a bit on parsing. cc, err := pgx.ParseConnectionString("sslmode=" + config.DBSSLMode()) if err != nil { return nil, err } // Do the rest manually to allow whitespace in user/password. cc.Host = config.DBHost() cc.Port = uint16(config.DBPort()) cc.User = user cc.Password = password cc.Database = config.DBName() return stdlib.OpenDB(cc), nil } const allRoles = ` WITH RECURSIVE cte AS ( SELECT oid FROM pg_roles WHERE rolname = current_user UNION ALL SELECT m.roleid FROM cte JOIN pg_auth_members m ON m.member = cte.oid ) SELECT rolname FROM pg_roles WHERE oid IN (SELECT oid FROM cte) AND rolname <> current_user AND EXISTS (SELECT 1 FROM users.list_users WHERE username = current_user)` const InvalidRoleCharacters = `\"':;` var ErrInvalidRoleCharacters = errors.New("rolename contains invalid character") func AllOtherRoles(user, password string) (Roles, error) { db, err := OpenDB(user, password) if err != nil { return nil, err } defer db.Close() rows, err := db.Query(allRoles) if err != nil { return nil, err } defer rows.Close() roles := Roles{} // explicit empty by intention. for rows.Next() { var role string if err := rows.Scan(&role); err != nil { return nil, err } roles = append(roles, role) } 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) }