Mercurial > gemma
comparison pkg/auth/opendb.go @ 1341:a0892b578553
Added comments how to use the impersonating database connections from the session middleware.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 26 Nov 2018 10:45:51 +0100 |
parents | cabf4789e02b |
children | 7cccf7fef3e8 |
comparison
equal
deleted
inserted
replaced
1340:97430d442909 | 1341:a0892b578553 |
---|---|
25 | 25 |
26 "gemma.intevation.de/gemma/pkg/config" | 26 "gemma.intevation.de/gemma/pkg/config" |
27 ) | 27 ) |
28 | 28 |
29 var ( | 29 var ( |
30 // ErrNoMetamorphUser is returned if no metamorphic user is configured. | |
30 ErrNoMetamorphUser = errors.New("No metamorphic user configured") | 31 ErrNoMetamorphUser = errors.New("No metamorphic user configured") |
31 ErrNotLoggedIn = errors.New("Not logged in") | 32 // ErrNotLoggedIn is returned if there is the user is not logged in. |
33 ErrNotLoggedIn = errors.New("Not logged in") | |
32 ) | 34 ) |
33 | 35 |
36 // OpenDB opens up a database connection with a given username and password. | |
37 // The other credentials are taken from the configuration. | |
34 func OpenDB(user, password string) (*sql.DB, error) { | 38 func OpenDB(user, password string) (*sql.DB, error) { |
35 | 39 |
36 // To ease SSL config ride a bit on parsing. | 40 // To ease SSL config ride a bit on parsing. |
37 cc, err := pgx.ParseConnectionString("sslmode=" + config.DBSSLMode()) | 41 cc, err := pgx.ParseConnectionString("sslmode=" + config.DBSSLMode()) |
38 if err != nil { | 42 if err != nil { |
72 } | 76 } |
73 m.db = db | 77 m.db = db |
74 return db, nil | 78 return db, nil |
75 } | 79 } |
76 | 80 |
77 func MetamorphConn(ctx context.Context, user string) (*sql.Conn, error) { | 81 func metamorphConn(ctx context.Context, user string) (*sql.Conn, error) { |
78 db, err := mm.open() | 82 db, err := mm.open() |
79 if err != nil { | 83 if err != nil { |
80 return nil, err | 84 return nil, err |
81 } | 85 } |
82 conn, err := db.Conn(ctx) | 86 conn, err := db.Conn(ctx) |
100 ) | 104 ) |
101 SELECT rolname FROM pg_roles | 105 SELECT rolname FROM pg_roles |
102 WHERE oid IN (SELECT oid FROM cte) AND rolname <> current_user | 106 WHERE oid IN (SELECT oid FROM cte) AND rolname <> current_user |
103 AND EXISTS (SELECT 1 FROM users.list_users WHERE username = current_user)` | 107 AND EXISTS (SELECT 1 FROM users.list_users WHERE username = current_user)` |
104 | 108 |
109 // AllOtherRoles loggs in as user with password and returns a list | |
110 // of all roles the logged in user has in the system. | |
105 func AllOtherRoles(user, password string) (Roles, error) { | 111 func AllOtherRoles(user, password string) (Roles, error) { |
106 db, err := OpenDB(user, password) | 112 db, err := OpenDB(user, password) |
107 if err != nil { | 113 if err != nil { |
108 return nil, err | 114 return nil, err |
109 } | 115 } |
124 roles = append(roles, role) | 130 roles = append(roles, role) |
125 } | 131 } |
126 return roles, rows.Err() | 132 return roles, rows.Err() |
127 } | 133 } |
128 | 134 |
135 // RunAs runs a given function fn with a database connection impersonated | |
136 // as the given role. | |
137 // To make this work a metamorphic user has to be configured in | |
138 // the system configuration. | |
129 func RunAs(ctx context.Context, role string, fn func(*sql.Conn) error) error { | 139 func RunAs(ctx context.Context, role string, fn func(*sql.Conn) error) error { |
130 conn, err := MetamorphConn(ctx, role) | 140 conn, err := metamorphConn(ctx, role) |
131 if err != nil { | 141 if err != nil { |
132 return err | 142 return err |
133 } | 143 } |
134 defer conn.Close() | 144 defer conn.Close() |
135 return fn(conn) | 145 return fn(conn) |
136 } | 146 } |
137 | 147 |
148 // RunAsSessionUser is a convinience wrapper araound which extracts | |
149 // the logged in user from a session and calls RunAs with it. | |
138 func RunAsSessionUser(req *http.Request, fn func(*sql.Conn) error) error { | 150 func RunAsSessionUser(req *http.Request, fn func(*sql.Conn) error) error { |
139 token, ok := GetToken(req) | 151 token, ok := GetToken(req) |
140 if !ok { | 152 if !ok { |
141 return ErrNotLoggedIn | 153 return ErrNotLoggedIn |
142 } | 154 } |