@@ -70,6 +70,9 @@ func ResetAllPasswords(c *resources.AppConfig, whitelistUsers []string) error {
70
70
return nil
71
71
}
72
72
73
+ // selectAllDatabases provides a query to list available databases.
74
+ const selectAllDatabases = "select datname from pg_catalog.pg_database where not datistemplate"
75
+
73
76
// CreateUser defines a method for creation of Postgres user.
74
77
func CreateUser (c * resources.AppConfig , user resources.EphemeralUser ) error {
75
78
var query string
@@ -80,17 +83,43 @@ func CreateUser(c *resources.AppConfig, user resources.EphemeralUser) error {
80
83
}
81
84
82
85
if user .Restricted {
83
- query = restrictedUserQuery (user .Name , user .Password , dbName )
86
+ // create restricted user
87
+ query = restrictedUserQuery (user .Name , user .Password )
88
+ out , err := runSimpleSQL (query , getPgConnStr (c .Host , dbName , c .DB .Username , c .Port ))
89
+
90
+ if err != nil {
91
+ return fmt .Errorf ("failed to create restricted user: %w" , err )
92
+ }
93
+
94
+ log .Dbg ("Restricted user has been created: " , out )
95
+
96
+ // set restricted user as owner for database objects
97
+ databaseList , err := runSQLSelectQuery (selectAllDatabases , getPgConnStr (c .Host , dbName , c .DB .Username , c .Port ))
98
+
99
+ if err != nil {
100
+ return fmt .Errorf ("failed list all databases: %w" , err )
101
+ }
102
+
103
+ for _ , database := range databaseList {
104
+ query = restrictedObjectsQuery (user .Name )
105
+ out , err = runSimpleSQL (query , getPgConnStr (c .Host , database , c .DB .Username , c .Port ))
106
+
107
+ if err != nil {
108
+ return fmt .Errorf ("failed to run objects restrict query: %w" , err )
109
+ }
110
+
111
+ log .Dbg ("Objects restriction applied" , database , out )
112
+ }
84
113
} else {
85
114
query = superuserQuery (user .Name , user .Password )
86
- }
87
115
88
- out , err := runSimpleSQL (query , getPgConnStr (c .Host , dbName , c .DB .Username , c .Port ))
89
- if err != nil {
90
- return errors . Wrap ( err , "failed to run psql" )
91
- }
116
+ out , err := runSimpleSQL (query , getPgConnStr (c .Host , dbName , c .DB .Username , c .Port ))
117
+ if err != nil {
118
+ return fmt . Errorf ( "failed to create superuser: %w" , err )
119
+ }
92
120
93
- log .Dbg ("AddUser:" , out )
121
+ log .Dbg ("Super user has been created: " , out )
122
+ }
94
123
95
124
return nil
96
125
}
@@ -99,13 +128,31 @@ func superuserQuery(username, password string) string {
99
128
return fmt .Sprintf (`create user %s with password %s login superuser;` , pq .QuoteIdentifier (username ), pq .QuoteLiteral (password ))
100
129
}
101
130
102
- const restrictionTemplate = `
131
+ const restrictionUserCreationTemplate = `
103
132
-- create a new user
104
133
create user @username with password @password login;
134
+ do $$
135
+ declare
136
+ new_owner text;
137
+ object_type record;
138
+ r record;
139
+ begin
140
+ new_owner := @usernameStr;
105
141
106
- -- change a database owner
107
- alter database @database owner to @username;
142
+ -- Changing owner of all databases
143
+ for r in select datname from pg_catalog.pg_database where not datistemplate loop
144
+ raise debug 'Changing owner of %', r.datname;
145
+ execute format(
146
+ 'alter database %s owner to %s;',
147
+ r.datname,
148
+ new_owner
149
+ );
150
+ end loop;
151
+ end
152
+ $$;
153
+ `
108
154
155
+ const restrictionTemplate = `
109
156
do $$
110
157
declare
111
158
new_owner text;
@@ -260,12 +307,20 @@ end
260
307
$$;
261
308
`
262
309
263
- func restrictedUserQuery (username , password , database string ) string {
310
+ func restrictedUserQuery (username , password string ) string {
264
311
repl := strings .NewReplacer (
265
312
"@usernameStr" , pq .QuoteLiteral (username ),
266
313
"@username" , pq .QuoteIdentifier (username ),
267
314
"@password" , pq .QuoteLiteral (password ),
268
- "@database" , pq .QuoteIdentifier (database ),
315
+ )
316
+
317
+ return repl .Replace (restrictionUserCreationTemplate )
318
+ }
319
+
320
+ func restrictedObjectsQuery (username string ) string {
321
+ repl := strings .NewReplacer (
322
+ "@usernameStr" , pq .QuoteLiteral (username ),
323
+ "@username" , pq .QuoteIdentifier (username ),
269
324
)
270
325
271
326
return repl .Replace (restrictionTemplate )
0 commit comments