Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f4fc4bd

Browse files
Merge branch 'issue-179' into 'master'
fix: quote username provided in create clone with restricted flag (joe#178) See merge request postgres-ai/database-lab!288
2 parents d6df4dd + e1fa894 commit f4fc4bd

File tree

2 files changed

+72
-16
lines changed

2 files changed

+72
-16
lines changed

‎pkg/services/provision/databases/postgres/postgres_mgmt.go‎

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"strings"
1010

11+
"github.com/lib/pq"
1112
"github.com/pkg/errors"
1213

1314
"gitlab.com/postgres-ai/database-lab/v2/pkg/log"
@@ -95,23 +96,23 @@ func CreateUser(c *resources.AppConfig, user resources.EphemeralUser) error {
9596
}
9697

9798
func superuserQuery(username, password string) string {
98-
return fmt.Sprintf(`create user "%s" with password '%s' login superuser;`, username, password)
99+
return fmt.Sprintf(`create user %s with password %s login superuser;`, pq.QuoteIdentifier(username), pq.QuoteLiteral(password))
99100
}
100101

101102
const restrictionTemplate = `
102103
-- create a new user
103-
create user %[1]s with password '%s' login;
104+
create user @username with password @password login;
104105
105106
-- change a database owner
106-
alter database %s owner to %[1]s;
107+
alter database @database owner to @username;
107108
108109
do $$
109110
declare
110111
new_owner text;
111112
object_type record;
112113
r record;
113114
begin
114-
new_owner := '%[1]s';
115+
new_owner := @usernameStr;
115116
116117
-- c: composite type
117118
-- p: partitioned table
@@ -133,16 +134,16 @@ begin
133134
join pg_namespace n on
134135
n.oid = c.relnamespace
135136
and not n.nspname in ('pg_catalog', 'information_schema')
136-
and c.relkind = %%L
137+
and c.relkind = %L
137138
order by c.relname
138139
$sql,ドル
139140
object_type.code
140141
)
141142
loop
142-
raise debug 'Changing ownership of %% %%.%% to %%',
143+
raise debug 'Changing ownership of % %.% to %',
143144
object_type.type_name, r.nspname, r.relname, new_owner;
144145
execute format(
145-
'alter %%s %%I.%%I owner to %%I;',
146+
'alter %s %I.%I owner to %I;',
146147
object_type.type_name,
147148
r.nspname,
148149
r.relname,
@@ -160,12 +161,12 @@ begin
160161
from pg_catalog.pg_namespace as n
161162
join pg_catalog.pg_proc as p on p.pronamespace = n.oid
162163
where not n.nspname in ('pg_catalog', 'information_schema')
163-
and p.proname not ilike 'dblink%%' -- We do not want dblink to be involved (exclusion)
164+
and p.proname not ilike 'dblink%' -- We do not want dblink to be involved (exclusion)
164165
loop
165-
raise debug 'Changing ownership of function %%.%%(%%) to %%',
166+
raise debug 'Changing ownership of function %.%(%) to %',
166167
r.nspname, r.proname, r.args, new_owner;
167168
execute format(
168-
'alter function %%I.%%I(%%s) owner to %%I', -- todo: check support CamelStyle r.args
169+
'alter function %I.%I(%s) owner to %I', -- todo: check support CamelStyle r.args
169170
r.nspname,
170171
r.proname,
171172
r.args,
@@ -181,10 +182,10 @@ begin
181182
join pg_catalog.pg_ts_dict d on d.dictnamespace = n.oid
182183
where not n.nspname in ('pg_catalog', 'information_schema')
183184
loop
184-
raise debug 'Changing ownership of text search dictionary %%.%% to %%',
185+
raise debug 'Changing ownership of text search dictionary %.% to %',
185186
r.nspname, r.dictname, new_owner;
186187
execute format(
187-
'alter text search dictionary %%I.%%I owner to %%I',
188+
'alter text search dictionary %I.%I owner to %I',
188189
r.nspname,
189190
r.dictname,
190191
new_owner
@@ -198,22 +199,29 @@ begin
198199
join pg_catalog.pg_namespace on pg_namespace.oid = pg_type.typnamespace
199200
where typtype = 'd' and not nspname in ('pg_catalog', 'information_schema')
200201
loop
201-
raise debug 'Changing ownership of domain %%.%% to %%',
202+
raise debug 'Changing ownership of domain %.% to %',
202203
r.nspname, r.typname, new_owner;
203204
execute format(
204-
'alter domain %%I.%%I owner to %%I',
205+
'alter domain %I.%I owner to %I',
205206
r.nspname,
206207
r.typname,
207208
new_owner
208209
);
209210
end loop;
210211
211-
grant select on pg_stat_activity to %[1]s;
212+
grant select on pg_stat_activity to @username;
212213
213214
end
214215
$$;
215216
`
216217

217218
func restrictedUserQuery(username, password, database string) string {
218-
return fmt.Sprintf(restrictionTemplate, username, password, database)
219+
repl := strings.NewReplacer(
220+
"@usernameStr", pq.QuoteLiteral(username),
221+
"@username", pq.QuoteIdentifier(username),
222+
"@password", pq.QuoteLiteral(password),
223+
"@database", pq.QuoteIdentifier(database),
224+
)
225+
226+
return repl.Replace(restrictionTemplate)
219227
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
2021 © Postgres.ai
3+
*/
4+
5+
package postgres
6+
7+
import (
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestSuperuserQuery(t *testing.T) {
14+
t.Run("username and password must be quoted", func(t *testing.T) {
15+
user := "user1"
16+
pwd := "pwd"
17+
assert.Equal(t, `create user "user1" with password 'pwd' login superuser;`, superuserQuery(user, pwd))
18+
})
19+
20+
t.Run("special chars must be quoted", func(t *testing.T) {
21+
user := "user.test\""
22+
pwd := "pwd\\'--"
23+
assert.Equal(t, `create user "user.test""" with password E'pwd\\''--' login superuser;`, superuserQuery(user, pwd))
24+
})
25+
}
26+
27+
func TestRestrictedUserQuery(t *testing.T) {
28+
t.Run("username and password must be quoted", func(t *testing.T) {
29+
user := "user1"
30+
pwd := "pwd"
31+
db := "postgres"
32+
query := restrictedUserQuery(user, pwd, db)
33+
34+
assert.Contains(t, query, `create user "user1" with password 'pwd' login;`)
35+
assert.Contains(t, query, `new_owner := 'user1'`)
36+
37+
})
38+
39+
t.Run("special chars must be quoted", func(t *testing.T) {
40+
user := "user.test\""
41+
pwd := "pwd\\'--"
42+
db := "postgres"
43+
query := restrictedUserQuery(user, pwd, db)
44+
45+
assert.Contains(t, query, `create user "user.test""" with password E'pwd\\''--' login;`)
46+
assert.Contains(t, query, `new_owner := 'user.test"'`)
47+
})
48+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /