Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check insert privileges to create chunk #2416

Merged
merged 1 commit into from Sep 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion tsl/src/chunk_api.c
Expand Up @@ -315,10 +315,17 @@ chunk_create(PG_FUNCTION_ARGS)
HeapTuple tuple;
bool created;
const char *parse_err;
AclResult acl_result;

Assert(NULL != ht);

ts_hypertable_permissions_check(hypertable_relid, GetUserId());
acl_result = pg_class_aclcheck(hypertable_relid, GetUserId(), ACL_INSERT);
if (acl_result != ACLCHECK_OK)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied for table \"%s\"", get_rel_name(hypertable_relid)),
errdetail("Insert privileges required on \"%s\" to create chunks.",
get_rel_name(hypertable_relid))));

if (NULL == slices)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid slices")));
Expand Down
14 changes: 10 additions & 4 deletions tsl/test/expected/chunk_api-11.out
Expand Up @@ -80,17 +80,23 @@ CONTEXT: JSON data, line 1: {"time: [1515024000000000] "device...
-- Valid chunk, but no permissions
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', 'ChunkSchema', 'My_chunk_Table_name');
ERROR: must be owner of hypertable "chunkapi"
SET ROLE :ROLE_DEFAULT_PERM_USER;
ERROR: permission denied for table "chunkapi"
DETAIL: Insert privileges required on "chunkapi" to create chunks.
\set ON_ERROR_STOP 1
\set VERBOSITY terse
-- Create a chunk that does not collide and with custom schema and name
-- Test that granting insert on tables allow create_chunk to be
-- called. This will also create a chunk that does not collide and has
-- a custom schema and name.
SET ROLE :ROLE_SUPERUSER;
GRANT INSERT ON chunkapi TO :ROLE_DEFAULT_PERM_USER_2;
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', 'ChunkSchema', 'My_chunk_Table_name');
chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
----------+---------------+-------------+---------------------+---------+----------------------------------------------------------------------------------------------+---------
2 | 1 | ChunkSchema | My_chunk_Table_name | r | {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]} | t
(1 row)

SET ROLE :ROLE_DEFAULT_PERM_USER;
\set VERBOSITY terse
mkindahl marked this conversation as resolved.
Show resolved Hide resolved
SELECT (_timescaledb_internal.show_chunk(show_chunks)).*
FROM show_chunks('chunkapi')
ORDER BY chunk_id;
Expand Down
14 changes: 10 additions & 4 deletions tsl/test/expected/chunk_api-12.out
Expand Up @@ -80,17 +80,23 @@ CONTEXT: JSON data, line 1: {"time: [1515024000000000] "device...
-- Valid chunk, but no permissions
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', 'ChunkSchema', 'My_chunk_Table_name');
ERROR: must be owner of hypertable "chunkapi"
SET ROLE :ROLE_DEFAULT_PERM_USER;
ERROR: permission denied for table "chunkapi"
mkindahl marked this conversation as resolved.
Show resolved Hide resolved
DETAIL: Insert privileges required on "chunkapi" to create chunks.
\set ON_ERROR_STOP 1
\set VERBOSITY terse
-- Create a chunk that does not collide and with custom schema and name
-- Test that granting insert on tables allow create_chunk to be
-- called. This will also create a chunk that does not collide and has
-- a custom schema and name.
SET ROLE :ROLE_SUPERUSER;
GRANT INSERT ON chunkapi TO :ROLE_DEFAULT_PERM_USER_2;
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', 'ChunkSchema', 'My_chunk_Table_name');
chunk_id | hypertable_id | schema_name | table_name | relkind | slices | created
----------+---------------+-------------+---------------------+---------+----------------------------------------------------------------------------------------------+---------
2 | 1 | ChunkSchema | My_chunk_Table_name | r | {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]} | t
(1 row)

SET ROLE :ROLE_DEFAULT_PERM_USER;
\set VERBOSITY terse
SELECT (_timescaledb_internal.show_chunk(show_chunks)).*
FROM show_chunks('chunkapi')
ORDER BY chunk_id;
Expand Down
32 changes: 32 additions & 0 deletions tsl/test/expected/dist_grant.out
Expand Up @@ -668,3 +668,35 @@ REVOKE SELECT ON _timescaledb_internal._hyper_3_35_chunk FROM PUBLIC;
| | | =w/cluster_super_user | |
(1 row)

DROP TABLE conditions;
-- Test that we can create a writer role, assign users to that role,
-- and allow the users to insert data and create new chunks.
\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER;
CREATE TABLE conditions(
time timestamptz,
device int CHECK (device > 0),
temp float,
PRIMARY KEY (time,device)
);
SELECT * FROM create_distributed_hypertable('conditions', 'time', 'device', 3);
WARNING: the number of partitions in dimension "device" is too low to make use of all attached data nodes
hypertable_id | schema_name | table_name | created
---------------+-------------+------------+---------
4 | public | conditions | t
(1 row)

-- Test that we can create a writer role, assign users to that role,
-- and allow the users to insert data and create new chunks.
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
\set ON_ERROR_STOP 0
INSERT INTO conditions
SELECT time, 1 + (random()*30)::int, random()*80
FROM generate_series('2019-01-01 00:00:00'::timestamptz, '2019-02-01 00:00:00', '1 min') AS time;
ERROR: permission denied for table conditions
\set ON_ERROR_STOP 1
RESET ROLE;
GRANT INSERT ON conditions TO :ROLE_DEFAULT_PERM_USER_2;
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
INSERT INTO conditions
SELECT time, 1 + (random()*30)::int, random()*80
FROM generate_series('2019-01-01 00:00:00'::timestamptz, '2019-02-01 00:00:00', '1 min') AS time;
14 changes: 10 additions & 4 deletions tsl/test/sql/chunk_api.sql.in
Expand Up @@ -43,14 +43,20 @@ SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time: [151502400
-- Valid chunk, but no permissions
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', 'ChunkSchema', 'My_chunk_Table_name');
SET ROLE :ROLE_DEFAULT_PERM_USER;

\set ON_ERROR_STOP 1
\set VERBOSITY terse

-- Create a chunk that does not collide and with custom schema and name
-- Test that granting insert on tables allow create_chunk to be
-- called. This will also create a chunk that does not collide and has
-- a custom schema and name.
SET ROLE :ROLE_SUPERUSER;
GRANT INSERT ON chunkapi TO :ROLE_DEFAULT_PERM_USER_2;
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
SELECT * FROM _timescaledb_internal.create_chunk('chunkapi',' {"time": [1515024000000000, 1519024000000000], "device": [-9223372036854775808, 1073741823]}', 'ChunkSchema', 'My_chunk_Table_name');

SET ROLE :ROLE_DEFAULT_PERM_USER;

\set VERBOSITY terse

SELECT (_timescaledb_internal.show_chunk(show_chunks)).*
FROM show_chunks('chunkapi')
ORDER BY chunk_id;
Expand Down
33 changes: 33 additions & 0 deletions tsl/test/sql/dist_grant.sql
Expand Up @@ -183,3 +183,36 @@ GRANT UPDATE ON _timescaledb_internal._hyper_3_35_chunk TO PUBLIC;
\z _timescaledb_internal._hyper_3_35_chunk
REVOKE SELECT ON _timescaledb_internal._hyper_3_35_chunk FROM PUBLIC;
\z _timescaledb_internal._hyper_3_35_chunk

DROP TABLE conditions;

-- Test that we can create a writer role, assign users to that role,
-- and allow the users to insert data and create new chunks.
\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER;

CREATE TABLE conditions(
time timestamptz,
device int CHECK (device > 0),
temp float,
PRIMARY KEY (time,device)
);

SELECT * FROM create_distributed_hypertable('conditions', 'time', 'device', 3);

-- Test that we can create a writer role, assign users to that role,
-- and allow the users to insert data and create new chunks.

SET ROLE :ROLE_DEFAULT_PERM_USER_2;
\set ON_ERROR_STOP 0
INSERT INTO conditions
SELECT time, 1 + (random()*30)::int, random()*80
FROM generate_series('2019-01-01 00:00:00'::timestamptz, '2019-02-01 00:00:00', '1 min') AS time;
\set ON_ERROR_STOP 1

RESET ROLE;
GRANT INSERT ON conditions TO :ROLE_DEFAULT_PERM_USER_2;

SET ROLE :ROLE_DEFAULT_PERM_USER_2;
INSERT INTO conditions
SELECT time, 1 + (random()*30)::int, random()*80
FROM generate_series('2019-01-01 00:00:00'::timestamptz, '2019-02-01 00:00:00', '1 min') AS time;