@@ -70,6 +70,9 @@ func ResetAllPasswords(c *resources.AppConfig, whitelistUsers []string) error {
7070 return nil
7171}
7272
73+ // selectAllDatabases provides a query to list available databases.
74+ const selectAllDatabases = "select datname from pg_catalog.pg_database where not datistemplate"
75+
7376// CreateUser defines a method for creation of Postgres user.
7477func CreateUser (c * resources.AppConfig , user resources.EphemeralUser ) error {
7578 var query string
@@ -80,17 +83,43 @@ func CreateUser(c *resources.AppConfig, user resources.EphemeralUser) error {
8083 }
8184
8285 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+ }
84113 } else {
85114 query = superuserQuery (user .Name , user .Password )
86- }
87115
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+ }
92120
93- log .Dbg ("AddUser:" , out )
121+ log .Dbg ("Super user has been created: " , out )
122+ }
94123
95124 return nil
96125}
@@ -99,13 +128,31 @@ func superuserQuery(username, password string) string {
99128 return fmt .Sprintf (`create user %s with password %s login superuser;` , pq .QuoteIdentifier (username ), pq .QuoteLiteral (password ))
100129}
101130
102- const restrictionTemplate = `
131+ const restrictionUserCreationTemplate = `
103132-- create a new user
104133create 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;
105141
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+ `
108154
155+ const restrictionTemplate = `
109156do $$
110157declare
111158 new_owner text;
@@ -260,12 +307,20 @@ end
260307$$;
261308`
262309
263- func restrictedUserQuery (username , password , database string ) string {
310+ func restrictedUserQuery (username , password string ) string {
264311 repl := strings .NewReplacer (
265312 "@usernameStr" , pq .QuoteLiteral (username ),
266313 "@username" , pq .QuoteIdentifier (username ),
267314 "@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 ),
269324 )
270325
271326 return repl .Replace (restrictionTemplate )
0 commit comments