2020-07-10 10:18:52 +00:00
import pytest
from helpers . cluster import ClickHouseCluster
from helpers . test_tools import TSV
cluster = ClickHouseCluster ( __file__ )
2021-06-29 13:01:15 +00:00
instance = cluster . add_instance ( ' instance ' )
2020-07-10 10:18:52 +00:00
@pytest.fixture ( scope = " module " , autouse = True )
def start_cluster ( ) :
try :
cluster . start ( )
2020-09-16 04:26:10 +00:00
2020-07-10 10:18:52 +00:00
instance . query ( " CREATE DATABASE test " )
instance . query ( " CREATE TABLE test.table(x UInt32, y UInt32) ENGINE = MergeTree ORDER BY tuple() " )
instance . query ( " INSERT INTO test.table VALUES (1,5), (2,10) " )
2020-09-16 04:26:10 +00:00
2020-07-10 10:18:52 +00:00
yield cluster
finally :
cluster . shutdown ( )
@pytest.fixture ( autouse = True )
def cleanup_after_test ( ) :
try :
yield
finally :
2021-03-11 13:44:00 +00:00
instance . query ( " DROP USER IF EXISTS A, B, C " )
2020-07-10 11:34:51 +00:00
instance . query ( " DROP TABLE IF EXISTS test.view_1 " )
2020-07-10 10:18:52 +00:00
2020-07-10 11:34:51 +00:00
def test_smoke ( ) :
2020-07-10 10:18:52 +00:00
instance . query ( " CREATE USER A " )
assert " Not enough privileges " in instance . query_and_get_error ( " SELECT * FROM test.table " , user = ' A ' )
2020-09-16 04:26:10 +00:00
2020-07-10 10:18:52 +00:00
instance . query ( ' GRANT SELECT ON test.table TO A ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' A ' ) == " 1 \t 5 \n 2 \t 10 \n "
instance . query ( ' REVOKE SELECT ON test.table FROM A ' )
assert " Not enough privileges " in instance . query_and_get_error ( " SELECT * FROM test.table " , user = ' A ' )
def test_grant_option ( ) :
instance . query ( " CREATE USER A " )
instance . query ( " CREATE USER B " )
instance . query ( ' GRANT SELECT ON test.table TO A ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' A ' ) == " 1 \t 5 \n 2 \t 10 \n "
assert " Not enough privileges " in instance . query_and_get_error ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
2020-09-16 04:26:10 +00:00
2020-07-10 10:18:52 +00:00
instance . query ( ' GRANT SELECT ON test.table TO A WITH GRANT OPTION ' )
instance . query ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' B ' ) == " 1 \t 5 \n 2 \t 10 \n "
instance . query ( ' REVOKE SELECT ON test.table FROM A, B ' )
def test_revoke_requires_grant_option ( ) :
instance . query ( " CREATE USER A " )
instance . query ( " CREATE USER B " )
2020-09-16 04:26:10 +00:00
2020-07-10 10:18:52 +00:00
instance . query ( " GRANT SELECT ON test.table TO B " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
expected_error = " Not enough privileges "
assert expected_error in instance . query_and_get_error ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " GRANT SELECT ON test.table TO A " )
expected_error = " privileges have been granted, but without grant option "
assert expected_error in instance . query_and_get_error ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " GRANT SELECT ON test.table TO A WITH GRANT OPTION " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " "
instance . query ( " GRANT SELECT ON test.table TO B " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " REVOKE SELECT ON test.* FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " "
instance . query ( " GRANT SELECT ON test.table TO B " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " REVOKE ALL ON test.* FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " "
instance . query ( " GRANT SELECT ON test.table TO B " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " REVOKE ALL ON *.* FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " "
instance . query ( " REVOKE GRANT OPTION FOR ALL ON *.* FROM A " )
instance . query ( " GRANT SELECT ON test.table TO B " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
expected_error = " privileges have been granted, but without grant option "
assert expected_error in instance . query_and_get_error ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " GRANT SELECT ON test.* TO A WITH GRANT OPTION " )
instance . query ( " GRANT SELECT ON test.table TO B " )
assert instance . query ( " SHOW GRANTS FOR B " ) == " GRANT SELECT ON test.table TO B \n "
instance . query ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " "
2021-03-11 13:44:00 +00:00
def test_allowed_grantees ( ) :
instance . query ( " CREATE USER A " )
instance . query ( " CREATE USER B " )
instance . query ( ' GRANT SELECT ON test.table TO A WITH GRANT OPTION ' )
instance . query ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' B ' ) == " 1 \t 5 \n 2 \t 10 \n "
instance . query ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
instance . query ( ' ALTER USER A GRANTEES NONE ' )
expected_error = " user `B` is not allowed as grantee "
assert expected_error in instance . query_and_get_error ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
instance . query ( ' ALTER USER A GRANTEES ANY EXCEPT B ' )
assert instance . query ( ' SHOW CREATE USER A ' ) == " CREATE USER A GRANTEES ANY EXCEPT B \n "
expected_error = " user `B` is not allowed as grantee "
assert expected_error in instance . query_and_get_error ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
instance . query ( ' ALTER USER A GRANTEES B ' )
instance . query ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' B ' ) == " 1 \t 5 \n 2 \t 10 \n "
instance . query ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
instance . query ( ' ALTER USER A GRANTEES ANY ' )
assert instance . query ( ' SHOW CREATE USER A ' ) == " CREATE USER A \n "
instance . query ( " GRANT SELECT ON test.table TO B " , user = ' A ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' B ' ) == " 1 \t 5 \n 2 \t 10 \n "
instance . query ( ' ALTER USER A GRANTEES NONE ' )
expected_error = " user `B` is not allowed as grantee "
assert expected_error in instance . query_and_get_error ( " REVOKE SELECT ON test.table FROM B " , user = ' A ' )
instance . query ( " CREATE USER C GRANTEES ANY EXCEPT C " )
assert instance . query ( ' SHOW CREATE USER C ' ) == " CREATE USER C GRANTEES ANY EXCEPT C \n "
instance . query ( ' GRANT SELECT ON test.table TO C WITH GRANT OPTION ' )
assert instance . query ( " SELECT * FROM test.table " , user = ' C ' ) == " 1 \t 5 \n 2 \t 10 \n "
expected_error = " user `C` is not allowed as grantee "
assert expected_error in instance . query_and_get_error ( " REVOKE SELECT ON test.table FROM C " , user = ' C ' )
2020-08-21 22:37:01 +00:00
def test_grant_all_on_table ( ) :
instance . query ( " CREATE USER A, B " )
instance . query ( " GRANT ALL ON test.table TO A WITH GRANT OPTION " )
instance . query ( " GRANT ALL ON test.table TO B " , user = ' A ' )
2022-02-10 09:39:33 +00:00
assert instance . query ( " SHOW GRANTS FOR B " ) == \
" GRANT SHOW TABLES, SHOW COLUMNS, SHOW DICTIONARIES, SELECT, INSERT, ALTER TABLE, ALTER VIEW, CREATE TABLE, CREATE VIEW, CREATE DICTIONARY, " \
" DROP TABLE, DROP VIEW, DROP DICTIONARY, TRUNCATE, OPTIMIZE, CREATE ROW POLICY, ALTER ROW POLICY, DROP ROW POLICY, SHOW ROW POLICIES, " \
" SYSTEM MERGES, SYSTEM TTL MERGES, SYSTEM FETCHES, SYSTEM MOVES, SYSTEM SENDS, SYSTEM REPLICATION QUEUES, SYSTEM DROP REPLICA, SYSTEM SYNC REPLICA, " \
" SYSTEM RESTART REPLICA, SYSTEM RESTORE REPLICA, SYSTEM FLUSH DISTRIBUTED, dictGet ON test.table TO B \n "
2020-08-21 22:37:01 +00:00
instance . query ( " REVOKE ALL ON test.table FROM B " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR B " ) == " "
2020-07-10 11:34:51 +00:00
def test_implicit_show_grants ( ) :
instance . query ( " CREATE USER A " )
assert instance . query ( " select count() FROM system.databases WHERE name= ' test ' " , user = " A " ) == " 0 \n "
assert instance . query ( " select count() FROM system.tables WHERE database= ' test ' AND name= ' table ' " , user = " A " ) == " 0 \n "
2020-09-16 04:26:10 +00:00
assert instance . query ( " select count() FROM system.columns WHERE database= ' test ' AND table= ' table ' " ,
user = " A " ) == " 0 \n "
2020-07-10 11:34:51 +00:00
instance . query ( " GRANT SELECT(x) ON test.table TO A " )
assert instance . query ( " SHOW GRANTS FOR A " ) == " GRANT SELECT(x) ON test.table TO A \n "
assert instance . query ( " select count() FROM system.databases WHERE name= ' test ' " , user = " A " ) == " 1 \n "
assert instance . query ( " select count() FROM system.tables WHERE database= ' test ' AND name= ' table ' " , user = " A " ) == " 1 \n "
2020-09-16 04:26:10 +00:00
assert instance . query ( " select count() FROM system.columns WHERE database= ' test ' AND table= ' table ' " ,
user = " A " ) == " 1 \n "
2020-07-10 11:34:51 +00:00
instance . query ( " GRANT SELECT ON test.table TO A " )
assert instance . query ( " SHOW GRANTS FOR A " ) == " GRANT SELECT ON test.table TO A \n "
assert instance . query ( " select count() FROM system.databases WHERE name= ' test ' " , user = " A " ) == " 1 \n "
assert instance . query ( " select count() FROM system.tables WHERE database= ' test ' AND name= ' table ' " , user = " A " ) == " 1 \n "
2020-09-16 04:26:10 +00:00
assert instance . query ( " select count() FROM system.columns WHERE database= ' test ' AND table= ' table ' " ,
user = " A " ) == " 2 \n "
2020-07-10 11:34:51 +00:00
instance . query ( " GRANT SELECT ON test.* TO A " )
assert instance . query ( " SHOW GRANTS FOR A " ) == " GRANT SELECT ON test.* TO A \n "
assert instance . query ( " select count() FROM system.databases WHERE name= ' test ' " , user = " A " ) == " 1 \n "
assert instance . query ( " select count() FROM system.tables WHERE database= ' test ' AND name= ' table ' " , user = " A " ) == " 1 \n "
2020-09-16 04:26:10 +00:00
assert instance . query ( " select count() FROM system.columns WHERE database= ' test ' AND table= ' table ' " ,
user = " A " ) == " 2 \n "
2020-07-10 11:34:51 +00:00
instance . query ( " GRANT SELECT ON *.* TO A " )
assert instance . query ( " SHOW GRANTS FOR A " ) == " GRANT SELECT ON *.* TO A \n "
assert instance . query ( " select count() FROM system.databases WHERE name= ' test ' " , user = " A " ) == " 1 \n "
assert instance . query ( " select count() FROM system.tables WHERE database= ' test ' AND name= ' table ' " , user = " A " ) == " 1 \n "
2020-09-16 04:26:10 +00:00
assert instance . query ( " select count() FROM system.columns WHERE database= ' test ' AND table= ' table ' " ,
user = " A " ) == " 2 \n "
2020-07-10 11:34:51 +00:00
instance . query ( " REVOKE ALL ON *.* FROM A " )
assert instance . query ( " select count() FROM system.databases WHERE name= ' test ' " , user = " A " ) == " 0 \n "
assert instance . query ( " select count() FROM system.tables WHERE database= ' test ' AND name= ' table ' " , user = " A " ) == " 0 \n "
2020-09-16 04:26:10 +00:00
assert instance . query ( " select count() FROM system.columns WHERE database= ' test ' AND table= ' table ' " ,
user = " A " ) == " 0 \n "
2020-07-10 11:34:51 +00:00
def test_implicit_create_view_grant ( ) :
instance . query ( " CREATE USER A " )
expected_error = " Not enough privileges "
assert expected_error in instance . query_and_get_error ( " CREATE VIEW test.view_1 AS SELECT 1 " , user = " A " )
instance . query ( " GRANT CREATE TABLE ON test.* TO A " )
instance . query ( " CREATE VIEW test.view_1 AS SELECT 1 " , user = " A " )
assert instance . query ( " SELECT * FROM test.view_1 " ) == " 1 \n "
instance . query ( " REVOKE CREATE TABLE ON test.* FROM A " )
instance . query ( " DROP TABLE test.view_1 " )
assert expected_error in instance . query_and_get_error ( " CREATE VIEW test.view_1 AS SELECT 1 " , user = " A " )
def test_implicit_create_temporary_table_grant ( ) :
instance . query ( " CREATE USER A " )
expected_error = " Not enough privileges "
assert expected_error in instance . query_and_get_error ( " CREATE TEMPORARY TABLE tmp(name String) " , user = " A " )
instance . query ( " GRANT CREATE TABLE ON test.* TO A " )
instance . query ( " CREATE TEMPORARY TABLE tmp(name String) " , user = " A " )
instance . query ( " REVOKE CREATE TABLE ON *.* FROM A " )
assert expected_error in instance . query_and_get_error ( " CREATE TEMPORARY TABLE tmp(name String) " , user = " A " )
2020-07-10 10:18:52 +00:00
def test_introspection ( ) :
instance . query ( " CREATE USER A " )
instance . query ( " CREATE USER B " )
instance . query ( ' GRANT SELECT ON test.table TO A ' )
instance . query ( ' GRANT CREATE ON *.* TO B WITH GRANT OPTION ' )
2020-09-16 04:26:10 +00:00
assert instance . query ( " SHOW USERS " ) == TSV ( [ " A " , " B " , " default " ] )
assert instance . query ( " SHOW CREATE USERS A " ) == TSV ( [ " CREATE USER A " ] )
assert instance . query ( " SHOW CREATE USERS B " ) == TSV ( [ " CREATE USER B " ] )
assert instance . query ( " SHOW CREATE USERS A,B " ) == TSV ( [ " CREATE USER A " , " CREATE USER B " ] )
assert instance . query ( " SHOW CREATE USERS " ) == TSV ( [ " CREATE USER A " , " CREATE USER B " ,
" CREATE USER default IDENTIFIED WITH plaintext_password SETTINGS PROFILE default " ] )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ " GRANT SELECT ON test.table TO A " ] )
assert instance . query ( " SHOW GRANTS FOR B " ) == TSV ( [ " GRANT CREATE ON *.* TO B WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS FOR A,B " ) == TSV (
[ " GRANT SELECT ON test.table TO A " , " GRANT CREATE ON *.* TO B WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS FOR B,A " ) == TSV (
[ " GRANT SELECT ON test.table TO A " , " GRANT CREATE ON *.* TO B WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS FOR ALL " ) == TSV (
[ " GRANT SELECT ON test.table TO A " , " GRANT CREATE ON *.* TO B WITH GRANT OPTION " ,
" GRANT ALL ON *.* TO default WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS " , user = ' A ' ) == TSV ( [ " GRANT SELECT ON test.table TO A " ] )
assert instance . query ( " SHOW GRANTS " , user = ' B ' ) == TSV ( [ " GRANT CREATE ON *.* TO B WITH GRANT OPTION " ] )
2022-02-01 12:55:24 +00:00
assert instance . query ( " SHOW GRANTS FOR ALL " , user = ' A ' ) == TSV ( [ " GRANT SELECT ON test.table TO A " ] )
assert instance . query ( " SHOW GRANTS FOR ALL " , user = ' B ' ) == TSV ( [ " GRANT CREATE ON *.* TO B WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS FOR ALL " ) == TSV ( [ " GRANT SELECT ON test.table TO A " ,
" GRANT CREATE ON *.* TO B WITH GRANT OPTION " ,
" GRANT ALL ON *.* TO default WITH GRANT OPTION " ] )
expected_error = " necessary to have grant SHOW USERS "
assert expected_error in instance . query_and_get_error ( " SHOW GRANTS FOR B " , user = ' A ' )
2020-09-16 04:26:10 +00:00
expected_access1 = " CREATE USER A \n " \
" CREATE USER B \n " \
2020-07-10 10:18:52 +00:00
" CREATE USER default IDENTIFIED WITH plaintext_password SETTINGS PROFILE default "
2020-09-16 04:26:10 +00:00
expected_access2 = " GRANT SELECT ON test.table TO A \n " \
" GRANT CREATE ON *.* TO B WITH GRANT OPTION \n " \
2020-07-10 10:18:52 +00:00
" GRANT ALL ON *.* TO default WITH GRANT OPTION \n "
assert expected_access1 in instance . query ( " SHOW ACCESS " )
assert expected_access2 in instance . query ( " SHOW ACCESS " )
2020-09-16 04:26:10 +00:00
assert instance . query (
" SELECT name, storage, auth_type, auth_params, host_ip, host_names, host_names_regexp, host_names_like, default_roles_all, default_roles_list, default_roles_except from system.users WHERE name IN ( ' A ' , ' B ' ) ORDER BY name " ) == \
TSV ( [ [ " A " , " local directory " , " no_password " , " {} " , " [ ' ::/0 ' ] " , " [] " , " [] " , " [] " , 1 , " [] " , " [] " ] ,
[ " B " , " local directory " , " no_password " , " {} " , " [ ' ::/0 ' ] " , " [] " , " [] " , " [] " , 1 , " [] " , " [] " ] ] )
assert instance . query (
" SELECT * from system.grants WHERE user_name IN ( ' A ' , ' B ' ) ORDER BY user_name, access_type, grant_option " ) == \
2020-10-02 16:54:07 +00:00
TSV ( [ [ " A " , " \\ N " , " SELECT " , " test " , " table " , " \\ N " , 0 , 0 ] ,
[ " B " , " \\ N " , " CREATE " , " \\ N " , " \\ N " , " \\ N " , 0 , 1 ] ] )
2020-07-10 10:18:52 +00:00
def test_current_database ( ) :
instance . query ( " CREATE USER A " )
instance . query ( " GRANT SELECT ON table TO A " , database = " test " )
2020-09-16 04:26:10 +00:00
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ " GRANT SELECT ON test.table TO A " ] )
assert instance . query ( " SHOW GRANTS FOR A " , database = " test " ) == TSV ( [ " GRANT SELECT ON test.table TO A " ] )
2020-07-10 10:18:52 +00:00
assert instance . query ( " SELECT * FROM test.table " , user = ' A ' ) == " 1 \t 5 \n 2 \t 10 \n "
assert instance . query ( " SELECT * FROM table " , user = ' A ' , database = ' test ' ) == " 1 \t 5 \n 2 \t 10 \n "
instance . query ( " CREATE TABLE default.table(x UInt32, y UInt32) ENGINE = MergeTree ORDER BY tuple() " )
assert " Not enough privileges " in instance . query_and_get_error ( " SELECT * FROM table " , user = ' A ' )
2021-08-10 14:06:22 +00:00
def test_grant_with_replace_option ( ) :
instance . query ( " CREATE USER A " )
instance . query ( ' GRANT SELECT ON test.table TO A ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ " GRANT SELECT ON test.table TO A " ] )
instance . query ( ' GRANT INSERT ON test.table TO A WITH REPLACE OPTION ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ " GRANT INSERT ON test.table TO A " ] )
instance . query ( ' GRANT NONE ON *.* TO A WITH REPLACE OPTION ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ ] )
instance . query ( ' CREATE USER B ' )
instance . query ( ' GRANT SELECT ON test.table TO B ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ ] )
assert instance . query ( " SHOW GRANTS FOR B " ) == TSV ( [ " GRANT SELECT ON test.table TO B " ] )
expected_error = " it ' s necessary to have grant INSERT ON test.table WITH GRANT OPTION "
assert expected_error in instance . query_and_get_error ( " GRANT INSERT ON test.table TO B WITH REPLACE OPTION " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ ] )
assert instance . query ( " SHOW GRANTS FOR B " ) == TSV ( [ " GRANT SELECT ON test.table TO B " ] )
instance . query ( " GRANT INSERT ON test.table TO A WITH GRANT OPTION " )
expected_error = " it ' s necessary to have grant SELECT ON test.table WITH GRANT OPTION "
assert expected_error in instance . query_and_get_error ( " GRANT INSERT ON test.table TO B WITH REPLACE OPTION " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ " GRANT INSERT ON test.table TO A WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS FOR B " ) == TSV ( [ " GRANT SELECT ON test.table TO B " ] )
instance . query ( " GRANT SELECT ON test.table TO A WITH GRANT OPTION " )
instance . query ( " GRANT INSERT ON test.table TO B WITH REPLACE OPTION " , user = ' A ' )
assert instance . query ( " SHOW GRANTS FOR A " ) == TSV ( [ " GRANT SELECT, INSERT ON test.table TO A WITH GRANT OPTION " ] )
assert instance . query ( " SHOW GRANTS FOR B " ) == TSV ( [ " GRANT INSERT ON test.table TO B " ] )