From 49772161c73f2d4c341bd7b353166045b4324a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Villemain?= Date: Tue, 25 Mar 2025 19:57:39 +0100 Subject: [PATCH] Improve testing of GRANT propagation When privileges are set for an attribute, it is required to propage the privileges when the command is executed but also on any future synchronisation with a (new) node. Add 2 tests case with GRANT executed: * before the distribution of the table * before a node is added --- .../expected/grant_on_table_propagation.out | 71 +++++++++++++++++++ .../expected/grant_on_table_propagation_0.out | 71 +++++++++++++++++++ .../sql/grant_on_table_propagation.sql | 50 +++++++++++++ 3 files changed, 192 insertions(+) diff --git a/src/test/regress/expected/grant_on_table_propagation.out b/src/test/regress/expected/grant_on_table_propagation.out index d1ccadc71..73e379cb4 100644 --- a/src/test/regress/expected/grant_on_table_propagation.out +++ b/src/test/regress/expected/grant_on_table_propagation.out @@ -462,3 +462,74 @@ DROP SCHEMA grant_on_table CASCADE; DROP ROLE grant_user_0, grant_user_1, nogrant_user; RESET client_min_messages; RESET search_path; +-- test propagation on columns when adding a node after GRANT has been executed +CREATE SCHEMA grant_on_table; +SET search_path TO grant_on_table; +CREATE ROLE grant_role_propagated; +CREATE TABLE grant_table_propagated (id int primary key); +GRANT ALL(id) ON grant_table_propagated TO grant_role_propagated; +SELECT create_distributed_table('grant_table_propagated', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT '$$SELECT array_agg((attname, attacl) order by attname) FROM pg_attribute +WHERE attrelid = ''grant_on_table.grant_table_propagated''::regclass +AND attacl IS NOT NULL$$' AS verify_grant_query \gset +SELECT result FROM run_command_on_all_nodes(:verify_grant_query); + result +--------------------------------------------------------------------- + {"(id,{grant_role_propagated=arwx/postgres})"} + {"(id,{grant_role_propagated=arwx/postgres})"} + {"(id,{grant_role_propagated=arwx/postgres})"} +(3 rows) + +-- cleanup +-- prevent useless messages on DROP objects. +SET client_min_messages TO ERROR; +DROP TABLE grant_table_propagated; +DROP ROLE grant_role_propagated; +RESET client_min_messages; +-- similar test but just adding a node after the fact +-- remove one of the worker nodes: +SELECT citus_remove_node('localhost', :worker_2_port); + citus_remove_node +--------------------------------------------------------------------- + +(1 row) + +CREATE ROLE grant_role_propagated_after; +CREATE TABLE grant_table_propagated_after (id int primary key); +SET citus.shard_replication_factor TO 1; +SELECT create_distributed_table('grant_on_table.grant_table_propagated_after', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SET citus.shard_replication_factor TO 2; +GRANT ALL(id) ON grant_table_propagated_after TO grant_role_propagated_after; +-- add back the worker node +SELECT FROM citus_add_node('localhost', :worker_2_port); +-- +(1 row) + +SELECT '$$SELECT array_agg((attname, attacl) order by attname) FROM pg_attribute +WHERE attrelid = ''grant_on_table.grant_table_propagated_after''::regclass +AND attacl IS NOT NULL$$' AS verify_grant_query \gset +SELECT result FROM run_command_on_all_nodes(:verify_grant_query); + result +--------------------------------------------------------------------- + {"(id,{grant_role_propagated_after=arwx/postgres})"} + {"(id,{grant_role_propagated_after=arwx/postgres})"} + {"(id,{grant_role_propagated_after=arwx/postgres})"} +(3 rows) + +-- cleanup +-- prevent useless messages on DROP objects. +SET client_min_messages TO ERROR; +DROP SCHEMA grant_on_table CASCADE; +DROP ROLE grant_role_propagated_after; +RESET client_min_messages; +RESET search_path; diff --git a/src/test/regress/expected/grant_on_table_propagation_0.out b/src/test/regress/expected/grant_on_table_propagation_0.out index 392b08105..653b9b43f 100644 --- a/src/test/regress/expected/grant_on_table_propagation_0.out +++ b/src/test/regress/expected/grant_on_table_propagation_0.out @@ -462,3 +462,74 @@ DROP SCHEMA grant_on_table CASCADE; DROP ROLE grant_user_0, grant_user_1, nogrant_user; RESET client_min_messages; RESET search_path; +-- test propagation on columns when adding a node after GRANT has been executed +CREATE SCHEMA grant_on_table; +SET search_path TO grant_on_table; +CREATE ROLE grant_role_propagated; +CREATE TABLE grant_table_propagated (id int primary key); +GRANT ALL(id) ON grant_table_propagated TO grant_role_propagated; +SELECT create_distributed_table('grant_table_propagated', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT '$$SELECT array_agg((attname, attacl) order by attname) FROM pg_attribute +WHERE attrelid = ''grant_on_table.grant_table_propagated''::regclass +AND attacl IS NOT NULL$$' AS verify_grant_query \gset +SELECT result FROM run_command_on_all_nodes(:verify_grant_query); + result +--------------------------------------------------------------------- + {"(id,{grant_role_propagated=arwx/postgres})"} + {"(id,{grant_role_propagated=arwx/postgres})"} + {"(id,{grant_role_propagated=arwx/postgres})"} +(3 rows) + +-- cleanup +-- prevent useless messages on DROP objects. +SET client_min_messages TO ERROR; +DROP TABLE grant_table_propagated; +DROP ROLE grant_role_propagated; +RESET client_min_messages; +-- similar test but just adding a node after the fact +-- remove one of the worker nodes: +SELECT citus_remove_node('localhost', :worker_2_port); + citus_remove_node +--------------------------------------------------------------------- + +(1 row) + +CREATE ROLE grant_role_propagated_after; +CREATE TABLE grant_table_propagated_after (id int primary key); +SET citus.shard_replication_factor TO 1; +SELECT create_distributed_table('grant_on_table.grant_table_propagated_after', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SET citus.shard_replication_factor TO 2; +GRANT ALL(id) ON grant_table_propagated_after TO grant_role_propagated_after; +-- add back the worker node +SELECT FROM citus_add_node('localhost', :worker_2_port); +-- +(1 row) + +SELECT '$$SELECT array_agg((attname, attacl) order by attname) FROM pg_attribute +WHERE attrelid = ''grant_on_table.grant_table_propagated_after''::regclass +AND attacl IS NOT NULL$$' AS verify_grant_query \gset +SELECT result FROM run_command_on_all_nodes(:verify_grant_query); + result +--------------------------------------------------------------------- + {"(id,{grant_role_propagated_after=arwx/postgres})"} + {"(id,{grant_role_propagated_after=arwx/postgres})"} + {"(id,{grant_role_propagated_after=arwx/postgres})"} +(3 rows) + +-- cleanup +-- prevent useless messages on DROP objects. +SET client_min_messages TO ERROR; +DROP SCHEMA grant_on_table CASCADE; +DROP ROLE grant_role_propagated_after; +RESET client_min_messages; +RESET search_path; diff --git a/src/test/regress/sql/grant_on_table_propagation.sql b/src/test/regress/sql/grant_on_table_propagation.sql index 4ebc82a3e..9db2c2339 100644 --- a/src/test/regress/sql/grant_on_table_propagation.sql +++ b/src/test/regress/sql/grant_on_table_propagation.sql @@ -262,3 +262,53 @@ DROP SCHEMA grant_on_table CASCADE; DROP ROLE grant_user_0, grant_user_1, nogrant_user; RESET client_min_messages; RESET search_path; + +-- test propagation on columns when adding a node after GRANT has been executed +CREATE SCHEMA grant_on_table; +SET search_path TO grant_on_table; + +CREATE ROLE grant_role_propagated; +CREATE TABLE grant_table_propagated (id int primary key); +GRANT ALL(id) ON grant_table_propagated TO grant_role_propagated; +SELECT create_distributed_table('grant_table_propagated', 'id'); + +SELECT '$$SELECT array_agg((attname, attacl) order by attname) FROM pg_attribute +WHERE attrelid = ''grant_on_table.grant_table_propagated''::regclass +AND attacl IS NOT NULL$$' AS verify_grant_query \gset + +SELECT result FROM run_command_on_all_nodes(:verify_grant_query); + +-- cleanup +-- prevent useless messages on DROP objects. +SET client_min_messages TO ERROR; +DROP TABLE grant_table_propagated; +DROP ROLE grant_role_propagated; +RESET client_min_messages; + +-- similar test but just adding a node after the fact +-- remove one of the worker nodes: +SELECT citus_remove_node('localhost', :worker_2_port); + +CREATE ROLE grant_role_propagated_after; +CREATE TABLE grant_table_propagated_after (id int primary key); +SET citus.shard_replication_factor TO 1; +SELECT create_distributed_table('grant_on_table.grant_table_propagated_after', 'id'); +SET citus.shard_replication_factor TO 2; +GRANT ALL(id) ON grant_table_propagated_after TO grant_role_propagated_after; + +-- add back the worker node +SELECT FROM citus_add_node('localhost', :worker_2_port); + +SELECT '$$SELECT array_agg((attname, attacl) order by attname) FROM pg_attribute +WHERE attrelid = ''grant_on_table.grant_table_propagated_after''::regclass +AND attacl IS NOT NULL$$' AS verify_grant_query \gset + +SELECT result FROM run_command_on_all_nodes(:verify_grant_query); + +-- cleanup +-- prevent useless messages on DROP objects. +SET client_min_messages TO ERROR; +DROP SCHEMA grant_on_table CASCADE; +DROP ROLE grant_role_propagated_after; +RESET client_min_messages; +RESET search_path;