mirror of https://github.com/citusdata/citus.git
207 lines
8.0 KiB
SQL
207 lines
8.0 KiB
SQL
--
|
|
-- MULTI_MULTIUSER_MASTER_PROTOCOL
|
|
--
|
|
|
|
-- Test multi_multiuser_master_protocol has an alternative output file because
|
|
-- PG17's support for the MAINTAIN privilege:
|
|
-- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ecb0fd337
|
|
-- means that calls of master_get_table_ddl_events() can show MAINTAIN and the
|
|
-- pg_class.relacl column may have 'm' for MAINTAIN
|
|
|
|
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 109079;
|
|
|
|
-- Tests that check the metadata returned by the master node. At the
|
|
-- same time ensure that any user, not just a superuser, can call
|
|
-- these. Note that, for now at least, any user can call these. That's
|
|
-- OK-ish, since the schema is visible from the catalogs anyway, and
|
|
-- exhausting shardids doesn't seem like a super viable attack path.
|
|
SET ROLE no_access;
|
|
|
|
SELECT * FROM master_get_table_ddl_events('lineitem') order by 1;
|
|
|
|
SELECT * FROM master_get_new_shardid();
|
|
|
|
SELECT * FROM master_get_active_worker_nodes();
|
|
|
|
RESET ROLE;
|
|
|
|
-- ensure GRANT/REVOKE's do something sane for creating shards of
|
|
CREATE TABLE checkperm(key int);
|
|
SELECT create_distributed_table('checkperm', 'key', 'append');
|
|
SELECT * FROM master_get_table_ddl_events('checkperm');
|
|
|
|
REVOKE ALL ON checkperm FROM PUBLIC;
|
|
SELECT * FROM master_get_table_ddl_events('checkperm');
|
|
|
|
GRANT SELECT ON checkperm TO read_access;
|
|
GRANT ALL ON checkperm TO full_access;
|
|
SELECT * FROM master_get_table_ddl_events('checkperm');
|
|
|
|
REVOKE ALL ON checkperm FROM read_access;
|
|
GRANT SELECT ON checkperm TO PUBLIC;
|
|
SELECT * FROM master_get_table_ddl_events('checkperm');
|
|
|
|
GRANT ALL ON checkperm TO full_access WITH GRANT OPTION;
|
|
SELECT * FROM master_get_table_ddl_events('checkperm');
|
|
|
|
-- create table as superuser/postgres
|
|
CREATE TABLE trivial_postgres (id int);
|
|
SELECT create_distributed_table('trivial_postgres', 'id', 'append');
|
|
GRANT ALL ON trivial_postgres TO full_access;
|
|
|
|
GRANT CREATE ON SCHEMA public TO full_access;
|
|
|
|
SET ROLE full_access;
|
|
CREATE TABLE trivial_full_access (id int);
|
|
SELECT create_distributed_table('trivial_full_access', 'id', 'append');
|
|
RESET ROLE;
|
|
|
|
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
|
|
|
|
SET citus.shard_replication_factor = 2; -- on all workers...
|
|
|
|
-- create shards as each user, verify ownership
|
|
|
|
SELECT master_create_empty_shard('trivial_postgres');
|
|
SELECT master_create_empty_shard('trivial_full_access');
|
|
SET ROLE full_access;
|
|
SELECT master_create_empty_shard('trivial_postgres');
|
|
SELECT master_create_empty_shard('trivial_full_access');
|
|
RESET ROLE;
|
|
|
|
SET ROLE full_access;
|
|
SELECT master_create_empty_shard('trivial_postgres');
|
|
SELECT master_create_empty_shard('trivial_full_access');
|
|
RESET ROLE;
|
|
|
|
\c - - - :worker_1_port
|
|
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
|
|
\c - - - :worker_2_port
|
|
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
|
|
\c - - - :master_port
|
|
|
|
-- ensure COPY into append tables works
|
|
CREATE TABLE stage_postgres(id) AS SELECT 2;
|
|
GRANT ALL ON stage_postgres TO full_access;
|
|
SET ROLE full_access;
|
|
CREATE TABLE stage_full_access(id) AS SELECT 1;
|
|
RESET ROLE;
|
|
|
|
SELECT master_create_empty_shard('trivial_postgres') AS shardid \gset
|
|
COPY trivial_postgres FROM STDIN WITH (append_to_shard :shardid);
|
|
1
|
|
2
|
|
\.
|
|
|
|
SELECT master_create_empty_shard('trivial_full_access') AS shardid \gset
|
|
COPY trivial_full_access FROM STDIN WITH (append_to_shard :shardid);
|
|
1
|
|
2
|
|
\.
|
|
|
|
SET ROLE full_access;
|
|
|
|
SELECT master_create_empty_shard('trivial_postgres') AS shardid \gset
|
|
COPY trivial_postgres FROM STDIN WITH (append_to_shard :shardid);
|
|
1
|
|
2
|
|
\.
|
|
|
|
SELECT master_create_empty_shard('trivial_full_access') AS shardid \gset
|
|
COPY trivial_full_access FROM STDIN WITH (append_to_shard :shardid);
|
|
1
|
|
2
|
|
\.
|
|
RESET ROLE;
|
|
|
|
SELECT * FROM trivial_postgres ORDER BY id;
|
|
SELECT * FROM trivial_full_access ORDER BY id;
|
|
SET ROLE full_access;
|
|
SELECT * FROM trivial_postgres ORDER BY id;
|
|
SELECT * FROM trivial_full_access ORDER BY id;
|
|
RESET ROLE;
|
|
|
|
-- verify column level grants are not supported
|
|
GRANT UPDATE (id) ON trivial_postgres TO read_access;
|
|
|
|
DROP TABLE trivial_full_access;
|
|
DROP TABLE trivial_postgres;
|
|
DROP TABLE stage_full_access;
|
|
DROP TABLE stage_postgres;
|
|
|
|
-- test GRANT/REVOKE on all tables in schema
|
|
CREATE SCHEMA multiuser_schema;
|
|
CREATE TABLE multiuser_schema.hash_table(a int, b int);
|
|
CREATE TABLE multiuser_schema.reference_table(a int, b int);
|
|
|
|
SET citus.shard_replication_factor TO 1;
|
|
SELECT create_distributed_table('multiuser_schema.hash_table', 'a', colocate_with => 'none');
|
|
|
|
|
|
-- usage right must be granted to user
|
|
GRANT USAGE ON SCHEMA multiuser_schema TO read_access;
|
|
|
|
-- verify test user (read_access) does not have select privilege on both tables
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- grant select
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA multiuser_schema TO read_access;
|
|
|
|
-- verify select is granted
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- distribute the second table
|
|
SELECT create_reference_table('multiuser_schema.reference_table');
|
|
|
|
-- verify select is also granted
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.reference_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- create another table in the schema, verify select is not granted
|
|
CREATE TABLE multiuser_schema.another_table(a int, b int);
|
|
SELECT create_distributed_table('multiuser_schema.another_table', 'a', colocate_with => 'none');
|
|
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.another_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- grant select again, verify it is granted
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA multiuser_schema TO read_access;
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.another_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- verify isolate tenant carries grants
|
|
SELECT isolate_tenant_to_new_shard('multiuser_schema.hash_table', 5, shard_transfer_mode => 'block_writes');
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- revoke select
|
|
REVOKE SELECT ON ALL TABLES IN SCHEMA multiuser_schema FROM read_access;
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- test multi-schema grants
|
|
CREATE SCHEMA multiuser_second_schema;
|
|
CREATE TABLE multiuser_second_schema.hash_table(a int, b int);
|
|
SELECT create_distributed_table('multiuser_second_schema.hash_table', 'a');
|
|
|
|
GRANT ALL ON ALL TABLES IN SCHEMA multiuser_schema, multiuser_second_schema TO read_access;
|
|
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
SELECT * FROM run_command_on_placements('multiuser_second_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
-- revoke from multiple schemas, verify result
|
|
REVOKE SELECT ON ALL TABLES IN SCHEMA multiuser_schema, multiuser_second_schema FROM read_access;
|
|
|
|
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
SELECT * FROM run_command_on_placements('multiuser_second_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
|
|
ORDER BY nodename, nodeport, shardid;
|
|
|
|
DROP SCHEMA multiuser_schema CASCADE;
|
|
DROP SCHEMA multiuser_second_schema CASCADE;
|
|
|