Skip to content

Commit c26a04b

Browse files
committed
grant roles after upgrade
1 parent d501a7a commit c26a04b

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

docs/docs/cli/upgrade.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
usage: pum upgrade [-h] [-p PARAMETER PARAMETER] [-u MAX_VERSION] [--beta-testing] [--skip-drop-app]
1+
usage: pum upgrade [-h] [-p PARAMETER PARAMETER] [-u MAX_VERSION] [-g] [--beta-testing] [--skip-drop-app]
22
[--skip-create-app]
33
### options:
44
- `-h, --help`: show this help message and exit
55
- `-p PARAMETER PARAMETER, --parameter PARAMETER PARAMETER`: Assign variable for running SQL deltas. Format is name value.
66
- `-u MAX_VERSION, --max-version MAX_VERSION`: maximum version to upgrade
7+
- `-g, --grant`: Grant permissions to roles
78
- `--beta-testing`: Install in beta testing mode.
89
- `--skip-drop-app`: Skip drop app handlers during upgrade.
910
- `--skip-create-app`: Skip create app handlers during upgrade.

pum/cli.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ def create_parser() -> argparse.ArgumentParser:
240240
action="append",
241241
)
242242
parser_upgrade.add_argument("-u", "--max-version", help="maximum version to upgrade")
243+
parser_upgrade.add_argument(
244+
"-g", "--grant", help="Grant permissions to roles", action="store_true"
245+
)
243246
parser_upgrade.add_argument(
244247
"--beta-testing", help="Install in beta testing mode.", action="store_true"
245248
)
@@ -419,6 +422,7 @@ def cli() -> int: # noqa: PLR0912
419422
connection=conn,
420423
parameters=parameters,
421424
max_version=args.max_version,
425+
grant=args.grant,
422426
beta_testing=args.beta_testing,
423427
skip_drop_app=args.skip_drop_app,
424428
skip_create_app=args.skip_create_app,

pum/upgrader.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ def upgrade(
193193
beta_testing: bool = False,
194194
skip_drop_app: bool = False,
195195
skip_create_app: bool = False,
196+
grant: bool = True,
196197
) -> None:
197198
"""Upgrades the given module
198199
The changelogs are applied in the order they are found in the directory.
@@ -212,6 +213,8 @@ def upgrade(
212213
If True, drop app handlers will be skipped.
213214
skip_create_app:
214215
If True, create app handlers will be skipped.
216+
grant:
217+
If True, permissions will be granted to the roles.
215218
"""
216219
if not self.schema_migrations.exists(connection):
217220
msg = (
@@ -251,5 +254,8 @@ def upgrade(
251254
for create_app_hook in self.config.create_app_handlers():
252255
create_app_hook.execute(connection=connection, commit=False, parameters=parameters)
253256

257+
if grant:
258+
self.config.role_manager().grant_permissions(connection=connection, commit=False)
259+
254260
connection.commit()
255261
logger.info("Upgrade completed and changes committed to the database.")

test/test_upgrader.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ def tearDown(self) -> None:
2525
cur.execute("DROP SCHEMA IF EXISTS pum_test_data CASCADE;")
2626
cur.execute("DROP SCHEMA IF EXISTS pum_custom_migrations_schema CASCADE;")
2727
cur.execute("DROP SCHEMA IF EXISTS pum_test_app CASCADE;")
28+
cur.execute("DROP SCHEMA IF EXISTS pum_test_data_schema_1 CASCADE;")
29+
cur.execute("DROP SCHEMA IF EXISTS pum_test_data_schema_2 CASCADE;")
2830
cur.execute("DROP TABLE IF EXISTS public.pum_migrations;")
31+
cur.execute("DROP ROLE IF EXISTS pum_test_user;")
32+
cur.execute("DROP ROLE IF EXISTS pum_test_viewer;")
2933

3034
self.tmpdir.cleanup()
3135
self.tmp = None
@@ -43,7 +47,11 @@ def setUp(self) -> None:
4347
cur.execute("DROP SCHEMA IF EXISTS pum_test_data CASCADE;")
4448
cur.execute("DROP SCHEMA IF EXISTS pum_custom_migrations_schema CASCADE;")
4549
cur.execute("DROP SCHEMA IF EXISTS pum_test_app CASCADE;")
50+
cur.execute("DROP SCHEMA IF EXISTS pum_test_data_schema_1 CASCADE;")
51+
cur.execute("DROP SCHEMA IF EXISTS pum_test_data_schema_2 CASCADE;")
4652
cur.execute("DROP TABLE IF EXISTS public.pum_migrations;")
53+
cur.execute("DROP ROLE IF EXISTS pum_test_user;")
54+
cur.execute("DROP ROLE IF EXISTS pum_test_viewer;")
4755

4856
self.tmpdir = tempfile.TemporaryDirectory()
4957
self.tmp = self.tmpdir.name
@@ -465,6 +473,35 @@ def test_upgrade(self) -> None:
465473
upgrader.upgrade(connection=conn)
466474
self.assertEqual(sm.baseline(conn), Version("2.0.0"))
467475

476+
def test_upgrade_with_grant(self) -> None:
477+
"""Test that permissions are granted correctly after upgrade."""
478+
test_dir = Path("test") / "data" / "roles"
479+
cfg = PumConfig.from_yaml(test_dir / ".pum.yaml")
480+
with psycopg.connect(f"service={self.pg_service}") as conn:
481+
# Install with roles but without granting permissions
482+
Upgrader(cfg).install(connection=conn, roles=True, grant=False, commit=True)
483+
484+
cur = conn.cursor()
485+
# Verify viewer role doesn't have SELECT permission initially
486+
cur.execute(
487+
"SELECT has_table_privilege('pum_test_viewer', 'pum_test_data_schema_1.some_table_1', 'SELECT');"
488+
)
489+
self.assertFalse(cur.fetchone()[0])
490+
491+
# Now upgrade with grant=True (even though there are no new changelogs, it should grant permissions)
492+
Upgrader(cfg).upgrade(connection=conn, grant=True)
493+
494+
# Verify permissions were granted
495+
cur.execute(
496+
"SELECT has_table_privilege('pum_test_viewer', 'pum_test_data_schema_1.some_table_1', 'SELECT');"
497+
)
498+
self.assertTrue(cur.fetchone()[0])
499+
500+
cur.execute(
501+
"SELECT has_table_privilege('pum_test_user', 'pum_test_data_schema_2.some_table_2', 'INSERT');"
502+
)
503+
self.assertTrue(cur.fetchone()[0])
504+
468505

469506
if __name__ == "__main__":
470507
unittest.main()

0 commit comments

Comments
 (0)