From ffed645c6a033171c1374fc0d6d37cca686d345e Mon Sep 17 00:00:00 2001 From: Dave Page Date: Wed, 26 Aug 2026 15:12:39 +0100 Subject: [PATCH 1/2] Fix MAINTAIN privilege silently dropped for views/mviews on PG17+ allowed_privs.json for the 17_plus bucket lived directly under the bucket directory instead of under a sql/ subdirectory like every other bucket (including default), so render_template() looked for views/pg/17_plus/sql/allowed_privs.json, didn't find it, and silently fell back to the default bucket's list - which predates MAINTAIN and lacks 'm'. Moved the four affected files (views/mviews x pg/ppas) to match the default bucket's layout. Closes #10350 --- .../pg/17_plus/{ => sql}/allowed_privs.json | 0 .../ppas/17_plus/{ => sql}/allowed_privs.json | 0 .../pg/17_plus/{ => sql}/allowed_privs.json | 0 .../ppas/17_plus/{ => sql}/allowed_privs.json | 0 .../tests/test_allowed_privs_json_path.py | 54 +++++++++++++++++++ 5 files changed, 54 insertions(+) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/{ => sql}/allowed_privs.json (100%) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/{ => sql}/allowed_privs.json (100%) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/{ => sql}/allowed_privs.json (100%) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/{ => sql}/allowed_privs.json (100%) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py new file mode 100644 index 00000000000..cc036ee894f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py @@ -0,0 +1,54 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2026, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""Verify that the PG17+ allowed_privs.json for views/materialized views +resolves via the versioned template loader (issue #10350). It previously +lived directly under the 17_plus bucket instead of under a sql/ +subdirectory like every other bucket, so it was never found and the +MAINTAIN privilege ('m') silently fell back to the default bucket's list, +which lacks it. +""" + +import json + +from flask import render_template + +from pgadmin.utils.route import BaseTestGenerator + +# PG17 in pgAdmin's version-number-times-10000 scheme. +PG17 = 170000 + +_ALLOWED_PRIVS_JSON = 'sql/allowed_privs.json' + + +class AllowedPrivsJsonPathTestCase(BaseTestGenerator): + """Loading allowed_privs.json for PG17+ must pick up the 17_plus + bucket's list (with MAINTAIN), not silently fall back to default. + """ + + scenarios = [ + ('views on pg', dict(base_template='views/pg/#{0}#')), + ('views on ppas', dict(base_template='views/ppas/#{0}#')), + ('materialized views on pg', dict( + base_template='mviews/pg/#{0}#')), + ('materialized views on ppas', dict( + base_template='mviews/ppas/#{0}#')), + ] + + def setUp(self): + pass + + def runTest(self): + template_path = self.base_template.format(PG17) + with self.app.app_context(): + rendered = render_template( + '/'.join([template_path, _ALLOWED_PRIVS_JSON]) + ) + allowed_acls = json.loads(rendered) + self.assertIn('m', allowed_acls['datacl']['acl']) From ab01c4be943efeb8574e9b90416b14f1eb37377d Mon Sep 17 00:00:00 2001 From: Dave Page Date: Wed, 26 Aug 2026 15:39:08 +0100 Subject: [PATCH 2/2] Add PG17+ RE-SQL fixture overrides for mview privilege grants Now that allowed_acls for views/mviews correctly includes MAINTAIN on PG17+, granting the same non-MAINTAIN privilege set as before no longer equals the full allowed set, so the generated SQL expands to the explicit privilege list instead of collapsing to "GRANT ALL" - this is the correct new behaviour, but it left the two mview msql fixtures (which fell back to the default bucket, written before MAINTAIN existed) stale. Added 17_plus overrides with the corrected expected output, alongside the existing 15_plus/16_plus buckets for these fixtures. --- .../tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql | 2 ++ .../schemas/views/tests/pg/17_plus/alter_mview_msql.sql | 1 + .../tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql | 2 ++ .../schemas/views/tests/ppas/17_plus/alter_mview_msql.sql | 1 + 4 files changed, 6 insertions(+) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql new file mode 100644 index 00000000000..c92eb9d341c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql @@ -0,0 +1,2 @@ +REVOKE ALL ON TABLE public."testmview_$%{}[]()&*^!/@`#" FROM ; +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql new file mode 100644 index 00000000000..bdf4b291a36 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql @@ -0,0 +1 @@ +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql new file mode 100644 index 00000000000..81ce5fe812e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql @@ -0,0 +1,2 @@ +REVOKE ALL ON TABLE public."testmview_$%{}[]()&*^!/@`#" FROM enterprisedb; +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql new file mode 100644 index 00000000000..bdf4b291a36 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql @@ -0,0 +1 @@ +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC;