@pgpmjs/core 3.0.8 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/roles/index.js ADDED
@@ -0,0 +1,497 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCreateBaseRolesSQL = generateCreateBaseRolesSQL;
4
+ exports.generateCreateUserSQL = generateCreateUserSQL;
5
+ exports.generateCreateTestUsersSQL = generateCreateTestUsersSQL;
6
+ exports.generateGrantRoleSQL = generateGrantRoleSQL;
7
+ exports.generateRemoveUserSQL = generateRemoveUserSQL;
8
+ exports.generateCreateUserWithGrantsSQL = generateCreateUserWithGrantsSQL;
9
+ /**
10
+ * Safely escape a string for use as a SQL string literal.
11
+ * Doubles single quotes and wraps in single quotes.
12
+ */
13
+ function sqlLiteral(value) {
14
+ return `'${value.replace(/'/g, "''")}'`;
15
+ }
16
+ /**
17
+ * Generate SQL to create base roles (anonymous, authenticated, administrator).
18
+ * Callers should use getConnEnvOptions() from @pgpmjs/env to get merged values.
19
+ * @param roles - Role mapping from getConnEnvOptions().roles!
20
+ */
21
+ function generateCreateBaseRolesSQL(roles) {
22
+ const r = {
23
+ anonymous: roles.anonymous,
24
+ authenticated: roles.authenticated,
25
+ administrator: roles.administrator
26
+ };
27
+ return `
28
+ BEGIN;
29
+ DO $do$
30
+ DECLARE
31
+ v_anonymous text := ${sqlLiteral(r.anonymous)};
32
+ v_authenticated text := ${sqlLiteral(r.authenticated)};
33
+ v_administrator text := ${sqlLiteral(r.administrator)};
34
+ BEGIN
35
+ -- Create anonymous role: pre-check + exception handling for TOCTOU safety
36
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_anonymous) THEN
37
+ BEGIN
38
+ EXECUTE format('CREATE ROLE %I', v_anonymous);
39
+ EXCEPTION
40
+ WHEN duplicate_object THEN
41
+ -- 42710: Role already exists (race condition); safe to ignore
42
+ NULL;
43
+ WHEN unique_violation THEN
44
+ -- 23505: Concurrent CREATE ROLE hit unique index; safe to ignore
45
+ NULL;
46
+ WHEN insufficient_privilege THEN
47
+ -- 42501: Must surface this error - caller lacks permission
48
+ RAISE;
49
+ END;
50
+ END IF;
51
+
52
+ -- Create authenticated role: pre-check + exception handling for TOCTOU safety
53
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_authenticated) THEN
54
+ BEGIN
55
+ EXECUTE format('CREATE ROLE %I', v_authenticated);
56
+ EXCEPTION
57
+ WHEN duplicate_object THEN
58
+ -- 42710: Role already exists (race condition); safe to ignore
59
+ NULL;
60
+ WHEN unique_violation THEN
61
+ -- 23505: Concurrent CREATE ROLE hit unique index; safe to ignore
62
+ NULL;
63
+ WHEN insufficient_privilege THEN
64
+ -- 42501: Must surface this error - caller lacks permission
65
+ RAISE;
66
+ END;
67
+ END IF;
68
+
69
+ -- Create administrator role: pre-check + exception handling for TOCTOU safety
70
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_administrator) THEN
71
+ BEGIN
72
+ EXECUTE format('CREATE ROLE %I', v_administrator);
73
+ EXCEPTION
74
+ WHEN duplicate_object THEN
75
+ -- 42710: Role already exists (race condition); safe to ignore
76
+ NULL;
77
+ WHEN unique_violation THEN
78
+ -- 23505: Concurrent CREATE ROLE hit unique index; safe to ignore
79
+ NULL;
80
+ WHEN insufficient_privilege THEN
81
+ -- 42501: Must surface this error - caller lacks permission
82
+ RAISE;
83
+ END;
84
+ END IF;
85
+
86
+ -- Set role attributes (safe to run even if role already exists)
87
+ EXECUTE format('ALTER ROLE %I WITH NOCREATEDB NOSUPERUSER NOCREATEROLE NOLOGIN NOREPLICATION NOBYPASSRLS', v_anonymous);
88
+ EXECUTE format('ALTER ROLE %I WITH NOCREATEDB NOSUPERUSER NOCREATEROLE NOLOGIN NOREPLICATION NOBYPASSRLS', v_authenticated);
89
+ EXECUTE format('ALTER ROLE %I WITH NOCREATEDB NOSUPERUSER NOCREATEROLE NOLOGIN NOREPLICATION BYPASSRLS', v_administrator);
90
+ END
91
+ $do$;
92
+ COMMIT;
93
+ `;
94
+ }
95
+ /**
96
+ * Generate SQL to create a user with password and grant base roles.
97
+ * Callers should use getConnEnvOptions() from @pgpmjs/env to get merged values.
98
+ * @param roles - Role mapping from getConnEnvOptions().roles!
99
+ * @param useLocksForRoles - Whether to use advisory locks (from getConnEnvOptions().useLocksForRoles)
100
+ */
101
+ function generateCreateUserSQL(username, password, roles, useLocksForRoles = false) {
102
+ const r = {
103
+ anonymous: roles.anonymous,
104
+ authenticated: roles.authenticated
105
+ };
106
+ const lockStatement = useLocksForRoles
107
+ ? `PERFORM pg_advisory_xact_lock(42, hashtext(v_username));`
108
+ : '';
109
+ return `
110
+ BEGIN;
111
+ DO $do$
112
+ DECLARE
113
+ v_username text := ${sqlLiteral(username)};
114
+ v_password text := ${sqlLiteral(password)};
115
+ v_anonymous text := ${sqlLiteral(r.anonymous)};
116
+ v_authenticated text := ${sqlLiteral(r.authenticated)};
117
+ BEGIN
118
+ ${lockStatement}
119
+ -- Pre-check + exception handling for TOCTOU safety
120
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_username) THEN
121
+ BEGIN
122
+ EXECUTE format('CREATE ROLE %I LOGIN PASSWORD %L', v_username, v_password);
123
+ EXCEPTION
124
+ WHEN duplicate_object THEN
125
+ -- 42710: Role already exists (race condition); safe to ignore
126
+ NULL;
127
+ WHEN unique_violation THEN
128
+ -- 23505: Concurrent CREATE ROLE hit unique index; safe to ignore
129
+ NULL;
130
+ WHEN insufficient_privilege THEN
131
+ -- 42501: Must surface this error - caller lacks permission
132
+ RAISE;
133
+ END;
134
+ END IF;
135
+
136
+ -- Grant anonymous to user
137
+ IF NOT EXISTS (
138
+ SELECT 1 FROM pg_auth_members am
139
+ JOIN pg_roles r1 ON am.roleid = r1.oid
140
+ JOIN pg_roles r2 ON am.member = r2.oid
141
+ WHERE r1.rolname = v_anonymous AND r2.rolname = v_username
142
+ ) THEN
143
+ BEGIN
144
+ EXECUTE format('GRANT %I TO %I', v_anonymous, v_username);
145
+ EXCEPTION
146
+ WHEN unique_violation THEN
147
+ -- 23505: Membership was granted concurrently; safe to ignore
148
+ NULL;
149
+ WHEN undefined_object THEN
150
+ -- 42704: One of the roles doesn't exist; log notice and continue
151
+ RAISE NOTICE 'Missing role when granting % to %', v_anonymous, v_username;
152
+ WHEN insufficient_privilege THEN
153
+ -- 42501: Must surface this error - caller lacks permission
154
+ RAISE;
155
+ WHEN invalid_grant_operation THEN
156
+ -- 0LP01: Must surface this error - invalid grant operation
157
+ RAISE;
158
+ END;
159
+ END IF;
160
+
161
+ -- Grant authenticated to user
162
+ IF NOT EXISTS (
163
+ SELECT 1 FROM pg_auth_members am
164
+ JOIN pg_roles r1 ON am.roleid = r1.oid
165
+ JOIN pg_roles r2 ON am.member = r2.oid
166
+ WHERE r1.rolname = v_authenticated AND r2.rolname = v_username
167
+ ) THEN
168
+ BEGIN
169
+ EXECUTE format('GRANT %I TO %I', v_authenticated, v_username);
170
+ EXCEPTION
171
+ WHEN unique_violation THEN
172
+ -- 23505: Membership was granted concurrently; safe to ignore
173
+ NULL;
174
+ WHEN undefined_object THEN
175
+ -- 42704: One of the roles doesn't exist; log notice and continue
176
+ RAISE NOTICE 'Missing role when granting % to %', v_authenticated, v_username;
177
+ WHEN insufficient_privilege THEN
178
+ -- 42501: Must surface this error - caller lacks permission
179
+ RAISE;
180
+ WHEN invalid_grant_operation THEN
181
+ -- 0LP01: Must surface this error - invalid grant operation
182
+ RAISE;
183
+ END;
184
+ END IF;
185
+ END
186
+ $do$;
187
+ COMMIT;
188
+ `;
189
+ }
190
+ /**
191
+ * Generate SQL to create test users with grants to base roles.
192
+ * Callers should use getConnEnvOptions() from @pgpmjs/env to get merged values.
193
+ * @param roles - Role mapping from getConnEnvOptions().roles!
194
+ * @param connections - Test user credentials from getConnEnvOptions().connections!
195
+ */
196
+ function generateCreateTestUsersSQL(roles, connections) {
197
+ const r = {
198
+ anonymous: roles.anonymous,
199
+ authenticated: roles.authenticated,
200
+ administrator: roles.administrator
201
+ };
202
+ const users = {
203
+ app: { user: connections.app.user, password: connections.app.password },
204
+ admin: { user: connections.admin.user, password: connections.admin.password }
205
+ };
206
+ return `
207
+ BEGIN;
208
+ DO $do$
209
+ DECLARE
210
+ v_app_user text := ${sqlLiteral(users.app.user)};
211
+ v_app_user_password text := ${sqlLiteral(users.app.password)};
212
+ v_app_admin text := ${sqlLiteral(users.admin.user)};
213
+ v_app_admin_password text := ${sqlLiteral(users.admin.password)};
214
+ v_anonymous text := ${sqlLiteral(r.anonymous)};
215
+ v_authenticated text := ${sqlLiteral(r.authenticated)};
216
+ v_administrator text := ${sqlLiteral(r.administrator)};
217
+ BEGIN
218
+ -- Create app_user: pre-check + exception handling for TOCTOU safety
219
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_app_user) THEN
220
+ BEGIN
221
+ EXECUTE format('CREATE ROLE %I LOGIN PASSWORD %L', v_app_user, v_app_user_password);
222
+ EXCEPTION
223
+ WHEN duplicate_object THEN NULL;
224
+ WHEN unique_violation THEN NULL;
225
+ WHEN insufficient_privilege THEN RAISE;
226
+ END;
227
+ END IF;
228
+
229
+ -- Create app_admin: pre-check + exception handling for TOCTOU safety
230
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_app_admin) THEN
231
+ BEGIN
232
+ EXECUTE format('CREATE ROLE %I LOGIN PASSWORD %L', v_app_admin, v_app_admin_password);
233
+ EXCEPTION
234
+ WHEN duplicate_object THEN NULL;
235
+ WHEN unique_violation THEN NULL;
236
+ WHEN insufficient_privilege THEN RAISE;
237
+ END;
238
+ END IF;
239
+
240
+ -- Grant anonymous to app_user
241
+ IF NOT EXISTS (
242
+ SELECT 1 FROM pg_auth_members am
243
+ JOIN pg_roles r1 ON am.roleid = r1.oid
244
+ JOIN pg_roles r2 ON am.member = r2.oid
245
+ WHERE r1.rolname = v_anonymous AND r2.rolname = v_app_user
246
+ ) THEN
247
+ BEGIN
248
+ EXECUTE format('GRANT %I TO %I', v_anonymous, v_app_user);
249
+ EXCEPTION
250
+ WHEN unique_violation THEN NULL;
251
+ WHEN undefined_object THEN RAISE NOTICE 'Missing role when granting % to %', v_anonymous, v_app_user;
252
+ WHEN insufficient_privilege THEN RAISE;
253
+ WHEN invalid_grant_operation THEN RAISE;
254
+ END;
255
+ END IF;
256
+
257
+ -- Grant authenticated to app_user
258
+ IF NOT EXISTS (
259
+ SELECT 1 FROM pg_auth_members am
260
+ JOIN pg_roles r1 ON am.roleid = r1.oid
261
+ JOIN pg_roles r2 ON am.member = r2.oid
262
+ WHERE r1.rolname = v_authenticated AND r2.rolname = v_app_user
263
+ ) THEN
264
+ BEGIN
265
+ EXECUTE format('GRANT %I TO %I', v_authenticated, v_app_user);
266
+ EXCEPTION
267
+ WHEN unique_violation THEN NULL;
268
+ WHEN undefined_object THEN RAISE NOTICE 'Missing role when granting % to %', v_authenticated, v_app_user;
269
+ WHEN insufficient_privilege THEN RAISE;
270
+ WHEN invalid_grant_operation THEN RAISE;
271
+ END;
272
+ END IF;
273
+
274
+ -- Grant anonymous to administrator
275
+ IF NOT EXISTS (
276
+ SELECT 1 FROM pg_auth_members am
277
+ JOIN pg_roles r1 ON am.roleid = r1.oid
278
+ JOIN pg_roles r2 ON am.member = r2.oid
279
+ WHERE r1.rolname = v_anonymous AND r2.rolname = v_administrator
280
+ ) THEN
281
+ BEGIN
282
+ EXECUTE format('GRANT %I TO %I', v_anonymous, v_administrator);
283
+ EXCEPTION
284
+ WHEN unique_violation THEN NULL;
285
+ WHEN undefined_object THEN RAISE NOTICE 'Missing role when granting % to %', v_anonymous, v_administrator;
286
+ WHEN insufficient_privilege THEN RAISE;
287
+ WHEN invalid_grant_operation THEN RAISE;
288
+ END;
289
+ END IF;
290
+
291
+ -- Grant authenticated to administrator
292
+ IF NOT EXISTS (
293
+ SELECT 1 FROM pg_auth_members am
294
+ JOIN pg_roles r1 ON am.roleid = r1.oid
295
+ JOIN pg_roles r2 ON am.member = r2.oid
296
+ WHERE r1.rolname = v_authenticated AND r2.rolname = v_administrator
297
+ ) THEN
298
+ BEGIN
299
+ EXECUTE format('GRANT %I TO %I', v_authenticated, v_administrator);
300
+ EXCEPTION
301
+ WHEN unique_violation THEN NULL;
302
+ WHEN undefined_object THEN RAISE NOTICE 'Missing role when granting % to %', v_authenticated, v_administrator;
303
+ WHEN insufficient_privilege THEN RAISE;
304
+ WHEN invalid_grant_operation THEN RAISE;
305
+ END;
306
+ END IF;
307
+
308
+ -- Grant administrator to app_admin
309
+ IF NOT EXISTS (
310
+ SELECT 1 FROM pg_auth_members am
311
+ JOIN pg_roles r1 ON am.roleid = r1.oid
312
+ JOIN pg_roles r2 ON am.member = r2.oid
313
+ WHERE r1.rolname = v_administrator AND r2.rolname = v_app_admin
314
+ ) THEN
315
+ BEGIN
316
+ EXECUTE format('GRANT %I TO %I', v_administrator, v_app_admin);
317
+ EXCEPTION
318
+ WHEN unique_violation THEN NULL;
319
+ WHEN undefined_object THEN RAISE NOTICE 'Missing role when granting % to %', v_administrator, v_app_admin;
320
+ WHEN insufficient_privilege THEN RAISE;
321
+ WHEN invalid_grant_operation THEN RAISE;
322
+ END;
323
+ END IF;
324
+ END
325
+ $do$;
326
+ COMMIT;
327
+ `;
328
+ }
329
+ /**
330
+ * Generate SQL to grant a role to a user
331
+ */
332
+ function generateGrantRoleSQL(role, user) {
333
+ return `
334
+ DO $$
335
+ DECLARE
336
+ v_user text := ${sqlLiteral(user)};
337
+ v_role text := ${sqlLiteral(role)};
338
+ BEGIN
339
+ -- Pre-check to avoid unnecessary GRANTs; still catch TOCTOU under concurrency
340
+ IF NOT EXISTS (
341
+ SELECT 1 FROM pg_auth_members am
342
+ JOIN pg_roles r1 ON am.roleid = r1.oid
343
+ JOIN pg_roles r2 ON am.member = r2.oid
344
+ WHERE r1.rolname = v_role AND r2.rolname = v_user
345
+ ) THEN
346
+ BEGIN
347
+ EXECUTE format('GRANT %I TO %I', v_role, v_user);
348
+ EXCEPTION
349
+ WHEN unique_violation THEN
350
+ -- 23505: Concurrent membership grant; safe to ignore
351
+ NULL;
352
+ WHEN undefined_object THEN
353
+ -- 42704: Role or user missing; emit notice and continue
354
+ RAISE NOTICE 'Missing role when granting % to %', v_role, v_user;
355
+ WHEN insufficient_privilege THEN
356
+ -- 42501: Must surface this error - caller lacks permission
357
+ RAISE;
358
+ WHEN invalid_grant_operation THEN
359
+ -- 0LP01: Must surface this error - invalid grant operation
360
+ RAISE;
361
+ END;
362
+ END IF;
363
+ END
364
+ $$;
365
+ `;
366
+ }
367
+ /**
368
+ * Generate SQL to remove a user and revoke grants.
369
+ * Callers should use getConnEnvOptions() from @pgpmjs/env to get merged values.
370
+ * @param roles - Role mapping from getConnEnvOptions().roles!
371
+ * @param useLocksForRoles - Whether to use advisory locks (from getConnEnvOptions().useLocksForRoles)
372
+ */
373
+ function generateRemoveUserSQL(username, roles, useLocksForRoles = false) {
374
+ const r = {
375
+ anonymous: roles.anonymous,
376
+ authenticated: roles.authenticated
377
+ };
378
+ const lockStatement = useLocksForRoles
379
+ ? `PERFORM pg_advisory_xact_lock(42, hashtext(v_username));`
380
+ : '';
381
+ return `
382
+ BEGIN;
383
+ DO $do$
384
+ DECLARE
385
+ v_username text := ${sqlLiteral(username)};
386
+ v_anonymous text := ${sqlLiteral(r.anonymous)};
387
+ v_authenticated text := ${sqlLiteral(r.authenticated)};
388
+ BEGIN
389
+ ${lockStatement}
390
+ IF EXISTS (
391
+ SELECT 1
392
+ FROM pg_catalog.pg_roles
393
+ WHERE rolname = v_username
394
+ ) THEN
395
+ -- REVOKE anonymous membership
396
+ BEGIN
397
+ EXECUTE format('REVOKE %I FROM %I', v_anonymous, v_username);
398
+ EXCEPTION
399
+ WHEN undefined_object THEN
400
+ -- 42704: Role doesn't exist; safe to ignore
401
+ NULL;
402
+ WHEN insufficient_privilege THEN
403
+ -- 42501: Must surface this error - caller lacks permission
404
+ RAISE;
405
+ END;
406
+
407
+ -- REVOKE authenticated membership
408
+ BEGIN
409
+ EXECUTE format('REVOKE %I FROM %I', v_authenticated, v_username);
410
+ EXCEPTION
411
+ WHEN undefined_object THEN
412
+ -- 42704: Role doesn't exist; safe to ignore
413
+ NULL;
414
+ WHEN insufficient_privilege THEN
415
+ -- 42501: Must surface this error - caller lacks permission
416
+ RAISE;
417
+ END;
418
+
419
+ -- DROP ROLE
420
+ BEGIN
421
+ EXECUTE format('DROP ROLE %I', v_username);
422
+ EXCEPTION
423
+ WHEN undefined_object THEN
424
+ -- 42704: Role doesn't exist; safe to ignore
425
+ NULL;
426
+ WHEN dependent_objects_still_exist THEN
427
+ -- 2BP01: Must surface this error - role has dependent objects
428
+ RAISE;
429
+ WHEN object_in_use THEN
430
+ -- 55006: Must surface this error - role is in use
431
+ RAISE;
432
+ WHEN insufficient_privilege THEN
433
+ -- 42501: Must surface this error - caller lacks permission
434
+ RAISE;
435
+ END;
436
+ END IF;
437
+ END
438
+ $do$;
439
+ COMMIT;
440
+ `;
441
+ }
442
+ /**
443
+ * Generate SQL to create a user with grants to specified roles (for test harness)
444
+ * @param useLocksForRoles - Whether to use advisory locks (from getConnEnvOptions().useLocksForRoles)
445
+ */
446
+ function generateCreateUserWithGrantsSQL(username, password, rolesToGrant, useLocksForRoles = false) {
447
+ const lockStatement = useLocksForRoles
448
+ ? `PERFORM pg_advisory_xact_lock(42, hashtext(v_user));`
449
+ : '';
450
+ // Generate variable declarations for all roles
451
+ const roleVarDeclarations = rolesToGrant.map((role, i) => ` v_role_${i} text := ${sqlLiteral(role)};`).join('\n');
452
+ // Generate grant blocks using the variables
453
+ const grantBlocks = rolesToGrant.map((_, i) => `
454
+ -- Grant role ${i}
455
+ IF NOT EXISTS (
456
+ SELECT 1 FROM pg_auth_members am
457
+ JOIN pg_roles r1 ON am.roleid = r1.oid
458
+ JOIN pg_roles r2 ON am.member = r2.oid
459
+ WHERE r1.rolname = v_role_${i} AND r2.rolname = v_user
460
+ ) THEN
461
+ BEGIN
462
+ EXECUTE format('GRANT %I TO %I', v_role_${i}, v_user);
463
+ EXCEPTION
464
+ WHEN unique_violation THEN NULL;
465
+ WHEN undefined_object THEN RAISE NOTICE 'Missing role when granting % to %', v_role_${i}, v_user;
466
+ WHEN insufficient_privilege THEN RAISE;
467
+ WHEN invalid_grant_operation THEN RAISE;
468
+ END;
469
+ END IF;`).join('\n');
470
+ return `
471
+ DO $$
472
+ DECLARE
473
+ v_user text := ${sqlLiteral(username)};
474
+ v_password text := ${sqlLiteral(password)};
475
+ ${roleVarDeclarations}
476
+ BEGIN
477
+ ${lockStatement}
478
+ -- Create role: pre-check + exception handling for TOCTOU safety
479
+ IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = v_user) THEN
480
+ BEGIN
481
+ EXECUTE format('CREATE ROLE %I LOGIN PASSWORD %L', v_user, v_password);
482
+ EXCEPTION
483
+ WHEN duplicate_object THEN
484
+ -- 42710: Role already exists (race condition); safe to ignore
485
+ NULL;
486
+ WHEN unique_violation THEN
487
+ -- 23505: Concurrent CREATE ROLE hit unique index; safe to ignore
488
+ NULL;
489
+ WHEN insufficient_privilege THEN
490
+ -- 42501: Must surface this error - caller lacks permission
491
+ RAISE;
492
+ END;
493
+ END IF;
494
+ ${grantBlocks}
495
+ END $$;
496
+ `;
497
+ }
@@ -1,55 +0,0 @@
1
- BEGIN;
2
- DO $do$
3
- BEGIN
4
- -- anonymous
5
- BEGIN
6
- EXECUTE format('CREATE ROLE %I', 'anonymous');
7
- EXCEPTION
8
- WHEN duplicate_object THEN
9
- -- Role already exists; optionally sync attributes here with ALTER ROLE
10
- NULL;
11
- END;
12
-
13
- -- authenticated
14
- BEGIN
15
- EXECUTE format('CREATE ROLE %I', 'authenticated');
16
- EXCEPTION
17
- WHEN duplicate_object THEN
18
- -- Role already exists; optionally sync attributes here with ALTER ROLE
19
- NULL;
20
- END;
21
-
22
- -- administrator
23
- BEGIN
24
- EXECUTE format('CREATE ROLE %I', 'administrator');
25
- EXCEPTION
26
- WHEN duplicate_object THEN
27
- -- Role already exists; optionally sync attributes here with ALTER ROLE
28
- NULL;
29
- END;
30
- END
31
- $do$;
32
-
33
- -- Set role attributes (safe to run even if role already exists)
34
- ALTER USER anonymous WITH NOCREATEDB;
35
- ALTER USER anonymous WITH NOSUPERUSER;
36
- ALTER USER anonymous WITH NOCREATEROLE;
37
- ALTER USER anonymous WITH NOLOGIN;
38
- ALTER USER anonymous WITH NOREPLICATION;
39
- ALTER USER anonymous WITH NOBYPASSRLS;
40
-
41
- ALTER USER authenticated WITH NOCREATEDB;
42
- ALTER USER authenticated WITH NOSUPERUSER;
43
- ALTER USER authenticated WITH NOCREATEROLE;
44
- ALTER USER authenticated WITH NOLOGIN;
45
- ALTER USER authenticated WITH NOREPLICATION;
46
- ALTER USER authenticated WITH NOBYPASSRLS;
47
-
48
- ALTER USER administrator WITH NOCREATEDB;
49
- ALTER USER administrator WITH NOSUPERUSER;
50
- ALTER USER administrator WITH NOCREATEROLE;
51
- ALTER USER administrator WITH NOLOGIN;
52
- ALTER USER administrator WITH NOREPLICATION;
53
- -- they CAN bypass RLS
54
- ALTER USER administrator WITH BYPASSRLS;
55
- COMMIT;
@@ -1,72 +0,0 @@
1
- BEGIN;
2
- DO $do$
3
- BEGIN
4
- BEGIN
5
- EXECUTE format('CREATE ROLE %I LOGIN PASSWORD %L', 'app_user', 'app_password');
6
- EXCEPTION
7
- WHEN duplicate_object THEN
8
- -- Role already exists; optionally sync attributes here with ALTER ROLE
9
- NULL;
10
- END;
11
-
12
- BEGIN
13
- EXECUTE format('CREATE ROLE %I LOGIN PASSWORD %L', 'app_admin', 'admin_password');
14
- EXCEPTION
15
- WHEN duplicate_object THEN
16
- -- Role already exists; optionally sync attributes here with ALTER ROLE
17
- NULL;
18
- END;
19
- END
20
- $do$;
21
-
22
- DO $do$
23
- BEGIN
24
- BEGIN
25
- EXECUTE format('GRANT %I TO %I', 'anonymous', 'app_user');
26
- EXCEPTION
27
- WHEN unique_violation THEN
28
- -- Membership was granted concurrently; ignore.
29
- NULL;
30
- WHEN undefined_object THEN
31
- -- One of the roles doesn't exist yet; order operations as needed.
32
- RAISE NOTICE 'Missing role when granting % to %', 'anonymous', 'app_user';
33
- END;
34
-
35
- BEGIN
36
- EXECUTE format('GRANT %I TO %I', 'authenticated', 'app_user');
37
- EXCEPTION
38
- WHEN unique_violation THEN
39
- NULL;
40
- WHEN undefined_object THEN
41
- RAISE NOTICE 'Missing role when granting % to %', 'authenticated', 'app_user';
42
- END;
43
-
44
- BEGIN
45
- EXECUTE format('GRANT %I TO %I', 'anonymous', 'administrator');
46
- EXCEPTION
47
- WHEN unique_violation THEN
48
- NULL;
49
- WHEN undefined_object THEN
50
- RAISE NOTICE 'Missing role when granting % to %', 'anonymous', 'administrator';
51
- END;
52
-
53
- BEGIN
54
- EXECUTE format('GRANT %I TO %I', 'authenticated', 'administrator');
55
- EXCEPTION
56
- WHEN unique_violation THEN
57
- NULL;
58
- WHEN undefined_object THEN
59
- RAISE NOTICE 'Missing role when granting % to %', 'authenticated', 'administrator';
60
- END;
61
-
62
- BEGIN
63
- EXECUTE format('GRANT %I TO %I', 'administrator', 'app_admin');
64
- EXCEPTION
65
- WHEN unique_violation THEN
66
- NULL;
67
- WHEN undefined_object THEN
68
- RAISE NOTICE 'Missing role when granting % to %', 'administrator', 'app_admin';
69
- END;
70
- END
71
- $do$;
72
- COMMIT;
@@ -1,55 +0,0 @@
1
- BEGIN;
2
- DO $do$
3
- BEGIN
4
- -- anonymous
5
- BEGIN
6
- EXECUTE format('CREATE ROLE %I', 'anonymous');
7
- EXCEPTION
8
- WHEN duplicate_object THEN
9
- -- Role already exists; optionally sync attributes here with ALTER ROLE
10
- NULL;
11
- END;
12
-
13
- -- authenticated
14
- BEGIN
15
- EXECUTE format('CREATE ROLE %I', 'authenticated');
16
- EXCEPTION
17
- WHEN duplicate_object THEN
18
- -- Role already exists; optionally sync attributes here with ALTER ROLE
19
- NULL;
20
- END;
21
-
22
- -- administrator
23
- BEGIN
24
- EXECUTE format('CREATE ROLE %I', 'administrator');
25
- EXCEPTION
26
- WHEN duplicate_object THEN
27
- -- Role already exists; optionally sync attributes here with ALTER ROLE
28
- NULL;
29
- END;
30
- END
31
- $do$;
32
-
33
- -- Set role attributes (safe to run even if role already exists)
34
- ALTER USER anonymous WITH NOCREATEDB;
35
- ALTER USER anonymous WITH NOSUPERUSER;
36
- ALTER USER anonymous WITH NOCREATEROLE;
37
- ALTER USER anonymous WITH NOLOGIN;
38
- ALTER USER anonymous WITH NOREPLICATION;
39
- ALTER USER anonymous WITH NOBYPASSRLS;
40
-
41
- ALTER USER authenticated WITH NOCREATEDB;
42
- ALTER USER authenticated WITH NOSUPERUSER;
43
- ALTER USER authenticated WITH NOCREATEROLE;
44
- ALTER USER authenticated WITH NOLOGIN;
45
- ALTER USER authenticated WITH NOREPLICATION;
46
- ALTER USER authenticated WITH NOBYPASSRLS;
47
-
48
- ALTER USER administrator WITH NOCREATEDB;
49
- ALTER USER administrator WITH NOSUPERUSER;
50
- ALTER USER administrator WITH NOCREATEROLE;
51
- ALTER USER administrator WITH NOLOGIN;
52
- ALTER USER administrator WITH NOREPLICATION;
53
- -- they CAN bypass RLS
54
- ALTER USER administrator WITH BYPASSRLS;
55
- COMMIT;