TFS tests

This commit is contained in:
MyroTk 2021-03-01 17:29:42 +01:00
parent 1f7aded743
commit 5d6b5bc276
115 changed files with 18688 additions and 11784 deletions

View File

@ -20,7 +20,7 @@ services:
test: clickhouse client --query='select 1'
interval: 10s
timeout: 10s
retries: 10
retries: 3
start_period: 300s
cap_add:
- SYS_PTRACE

View File

@ -2,7 +2,7 @@ version: '2.3'
services:
zookeeper:
image: zookeeper:3.6.2
image: zookeeper:3.4.12
expose:
- "2181"
environment:

View File

@ -2,6 +2,7 @@ import uuid
from contextlib import contextmanager
from multiprocessing.dummy import Pool
from multiprocessing import TimeoutError as PoolTaskTimeoutError
from testflows.core.name import basename, parentname
from testflows._core.testtype import TestSubType
@ -30,6 +31,9 @@ def instrument_clickhouse_server_log(self, node=None, clickhouse_server_log="/va
yield
finally:
if self.context.cluster.terminating is True:
return
with Finally("adding test name end message to the clickhouse-server.log", flags=TE):
node.command(f"echo -e \"\\n-- end: {current().name} --\\n\" >> {clickhouse_server_log}")
@ -38,15 +42,21 @@ def instrument_clickhouse_server_log(self, node=None, clickhouse_server_log="/va
with Then("dumping clickhouse-server.log for this test"):
node.command(f"tail -c +{logsize} {clickhouse_server_log}")
def join(tasks):
def join(tasks, polling_timeout=5):
"""Join all parallel tests.
"""
exc = None
while tasks:
try:
tasks[0].get()
try:
tasks[0].get(timeout=polling_timeout)
tasks.pop(0)
except PoolTaskTimeoutError as e:
task = tasks.pop(0)
tasks.append(task)
continue
except KeyboardInterrupt as e:
current().context.cluster.terminating = True
continue
@ -133,6 +143,23 @@ def role(node, role):
for role in roles:
with Finally("I drop the role"):
node.query(f"DROP ROLE IF EXISTS {role}")
@TestStep(Given)
def row_policy(self, name, table, node=None):
"""Create a row policy with a given name on a given table.
"""
if node is None:
node = self.context.node
try:
with Given(f"I create row policy {name}"):
node.query(f"CREATE ROW POLICY {name} ON {table}")
yield
finally:
with Finally(f"I delete row policy {name}"):
node.query(f"DROP ROW POLICY IF EXISTS {name} ON {table}")
tables = {
"table0" : 1 << 0,
"table1" : 1 << 1,

View File

@ -27,6 +27,8 @@ issue_17655 = "https://github.com/ClickHouse/ClickHouse/issues/17655"
issue_17766 = "https://github.com/ClickHouse/ClickHouse/issues/17766"
issue_18110 = "https://github.com/ClickHouse/ClickHouse/issues/18110"
issue_18206 = "https://github.com/ClickHouse/ClickHouse/issues/18206"
issue_21083 = "https://github.com/ClickHouse/ClickHouse/issues/21083"
issue_21084 = "https://github.com/ClickHouse/ClickHouse/issues/21084"
xfails = {
"syntax/show create quota/I show create quota current":
@ -131,6 +133,12 @@ xfails = {
[(Fail, issue_18206)],
"privileges/system replication queues/:/:/:/:/SYSTEM:":
[(Fail, issue_18206)],
"privileges/: row policy/nested live:":
[(Fail, issue_21083)],
"privileges/: row policy/nested mat:":
[(Fail, issue_21084)],
"privileges/: row policy/populate mat:":
[(Fail, "Investigating")],
}
xflags = {
@ -160,9 +168,9 @@ def regression(self, local, clickhouse_binary_path, stress=None, parallel=None):
if parallel is not None:
self.context.parallel = parallel
Feature(run=load("rbac.tests.syntax.feature", "feature"), flags=TE)
Feature(run=load("rbac.tests.privileges.feature", "feature"), flags=TE)
Feature(run=load("rbac.tests.views.feature", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.feature", "feature"))
Feature(run=load("rbac.tests.privileges.feature", "feature"))
Feature(run=load("rbac.tests.views.feature", "feature"))
if main():
regression()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(test=grant_role, flags=TE)(grant_target_name=user_name, user_name=user_name)
Suite(test=grant_role)(grant_target_name=user_name, user_name=user_name)
@TestSuite
def privileges_granted_via_role(self, node=None):
@ -35,7 +35,7 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(test=grant_role, flags=TE)(grant_target_name=role_name, user_name=user_name)
Suite(test=grant_role)(grant_target_name=role_name, user_name=user_name)
@TestSuite
def grant_role(self, grant_target_name, user_name, node=None):
@ -52,7 +52,13 @@ def grant_role(self, grant_target_name, user_name, node=None):
with user(node, target_user_name), role(node, grant_role_name):
with When("I check the user can't grant a role"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't grant a role"):
node.query(f"GRANT {grant_role_name} TO {target_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -109,6 +115,7 @@ def grant_role(self, grant_target_name, user_name, node=None):
@Name("admin option")
@Requirements(
RQ_SRS_006_RBAC_Privileges_AdminOption("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of ADMIN OPTION.

View File

@ -0,0 +1,37 @@
from testflows.core import *
from testflows.asserts import error
from rbac.requirements import *
from rbac.helper.common import *
import rbac.helper.errors as errors
@TestScenario
def privilege_check(self, node=None):
'''Check that a role named ALL only grants privileges that it already has.
'''
user_name = f"user_{getuid()}"
if node is None:
node = self.context.node
with user(node, f"{user_name}"), role(node, "ALL"):
with When("I grant the ALL role to the user"):
node.query(f"GRANT ALL TO {user_name}")
with Then("I check the user doesn't have any privileges"):
output = node.query("SHOW TABLES", settings=[("user",user_name)]).output
assert output == '', error()
@TestFeature
@Name("all role")
@Requirements(
RQ_SRS_006_RBAC_Privileges_RoleAll("1.0"),
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of the role 'ALL'.
"""
self.context.node = self.context.cluster.node(node)
Scenario(run=privilege_check, setup=instrument_clickhouse_server_log)

View File

@ -354,6 +354,10 @@ def check_add_column_when_privilege_is_not_granted(table, user, node, column=Non
node.query(f"ALTER TABLE {table} ADD COLUMN {column} String",
settings = [("user", user)], exitcode=exitcode, message=message)
with Then("I try to ADD COLUMN"):
node.query(f"ALTER TABLE {table} ADD COLUMN {column} String",
settings = [("user", user)], exitcode=exitcode, message=message)
def check_clear_column_when_privilege_is_not_granted(table, user, node, column=None):
"""Ensures CLEAR COLUMN errors as expected without the required privilege
for the specified user.
@ -366,6 +370,13 @@ def check_clear_column_when_privilege_is_not_granted(table, user, node, column=N
node.query(f"ALTER TABLE {table} CLEAR COLUMN {column}",
settings = [("user", user)], exitcode=exitcode, message=message)
with And(f"I grant NONE to the user"):
node.query(f"GRANT NONE TO {user}")
with Then("I try to CLEAR COLUMN"):
node.query(f"ALTER TABLE {table} CLEAR COLUMN {column}",
settings = [("user", user)], exitcode=exitcode, message=message)
def check_modify_column_when_privilege_is_not_granted(table, user, node, column=None):
"""Ensures MODIFY COLUMN errors as expected without the required privilege
for the specified user.
@ -378,6 +389,13 @@ def check_modify_column_when_privilege_is_not_granted(table, user, node, column=
node.query(f"ALTER TABLE {table} MODIFY COLUMN {column} String",
settings = [("user", user)], exitcode=exitcode, message=message)
with And(f"I grant NONE to the user"):
node.query(f"GRANT NONE TO {user}")
with Then("I try to MODIFY COLUMN"):
node.query(f"ALTER TABLE {table} MODIFY COLUMN {column} String",
settings = [("user", user)], exitcode=exitcode, message=message)
def check_rename_column_when_privilege_is_not_granted(table, user, node, column=None):
"""Ensures RENAME COLUMN errors as expected without the required privilege
for the specified user.
@ -392,6 +410,13 @@ def check_rename_column_when_privilege_is_not_granted(table, user, node, column=
node.query(f"ALTER TABLE {table} RENAME COLUMN {column} TO {new_column}",
settings = [("user", user)], exitcode=exitcode, message=message)
with And(f"I grant NONE to the user"):
node.query(f"GRANT NONE TO {user}")
with Then("I try to RENAME COLUMN"):
node.query(f"ALTER TABLE {table} RENAME COLUMN {column} TO {new_column}",
settings = [("user", user)], exitcode=exitcode, message=message)
def check_comment_column_when_privilege_is_not_granted(table, user, node, column=None):
"""Ensures COMMENT COLUMN errors as expected without the required privilege
for the specified user.
@ -404,6 +429,13 @@ def check_comment_column_when_privilege_is_not_granted(table, user, node, column
node.query(f"ALTER TABLE {table} COMMENT COLUMN {column} 'This is a comment.'",
settings = [("user", user)], exitcode=exitcode, message=message)
with And(f"I grant NONE to the user"):
node.query(f"GRANT NONE TO {user}")
with When("I try to COMMENT COLUMN"):
node.query(f"ALTER TABLE {table} COMMENT COLUMN {column} 'This is a comment.'",
settings = [("user", user)], exitcode=exitcode, message=message)
def check_drop_column_when_privilege_is_not_granted(table, user, node, column=None):
"""Ensures DROP COLUMN errors as expected without the required privilege
for the specified user.
@ -416,6 +448,13 @@ def check_drop_column_when_privilege_is_not_granted(table, user, node, column=No
node.query(f"ALTER TABLE {table} DROP COLUMN {column}",
settings = [("user", user)], exitcode=exitcode, message=message)
with And(f"I grant NONE to the user"):
node.query(f"GRANT NONE TO {user}")
with Then("I try to DROP COLUMN"):
node.query(f"ALTER TABLE {table} DROP COLUMN {column}",
settings = [("user", user)], exitcode=exitcode, message=message)
@TestScenario
def user_with_some_privileges(self, permutation, table_type, node=None):
"""Check that user with some privileges of ALTER COLUMN is able
@ -676,7 +715,8 @@ def scenario_parallelization(self, table_type, permutation):
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterColumn("1.0"),
RQ_SRS_006_RBAC_Privileges_AlterColumn_TableEngines("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0")
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -275,7 +275,8 @@ def user_with_privileges_on_cluster(self, table_type, node=None):
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterConstraint("1.0"),
RQ_SRS_006_RBAC_Privileges_AlterConstraint_TableEngines("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0")
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -1,5 +1,3 @@
from multiprocessing.dummy import Pool
from testflows.core import *
from testflows.asserts import error
@ -11,7 +9,8 @@ aliases = {"ALTER DELETE", "DELETE", "ALL"}
@TestSuite
def privilege_granted_directly_or_via_role(self, table_type, privilege, node=None):
"""Check that user is only able to execute ALTER DELETE when they have required privilege, either directly or via role.
"""Check that user is only able to execute ALTER DELETE when they have required privilege,
either directly or via role.
"""
role_name = f"role_{getuid()}"
user_name = f"user_{getuid()}"
@ -21,13 +20,16 @@ def privilege_granted_directly_or_via_role(self, table_type, privilege, node=Non
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute ALTER DELETE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, table_type=table_type, privilege=privilege, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And(f"I run checks that {user_name} with {role_name} is only able to execute ALTER DELETE with required privileges"):
privilege_check(grant_target_name=role_name, user_name=user_name, table_type=table_type, privilege=privilege, node=node)
@ -38,26 +40,41 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I attempt to delete columns without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to delete columns without privilege"):
node.query(f"ALTER TABLE {table_name} DELETE WHERE 1", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the delete privilege"):
node.query(f"GRANT {privilege} ON {table_name} TO {grant_target_name}")
with Then("I attempt to delete columns"):
node.query(f"ALTER TABLE {table_name} DELETE WHERE 1", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the delete privilege"):
node.query(f"GRANT {privilege} ON {table_name} TO {grant_target_name}")
with And("I revoke the delete privilege"):
node.query(f"REVOKE {privilege} ON {table_name} FROM {grant_target_name}")
with Then("I attempt to delete columns"):
node.query(f"ALTER TABLE {table_name} DELETE WHERE 1", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -65,7 +82,8 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterDelete("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0")
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -1,5 +1,3 @@
from multiprocessing.dummy import Pool
from testflows.core import *
from testflows.asserts import error
@ -41,9 +39,16 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I attempt to fetch a partition without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to fetch a partition without privilege"):
node.query(f"ALTER TABLE {table_name} FETCH PARTITION 1 FROM '/clickhouse/'", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -75,7 +80,8 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterFetch("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0")
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type",[
("ReplicatedMergeTree-sharded_cluster",),

View File

@ -1,5 +1,3 @@
from multiprocessing.dummy import Pool
from testflows.core import *
from testflows.asserts import error
@ -38,14 +36,22 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I attempt to freeze partitions without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to freeze partitions without privilege"):
node.query(f"ALTER TABLE {table_name} FREEZE", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the freeze privilege"):
@ -56,6 +62,7 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the freeze privilege"):
@ -70,7 +77,8 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterFreeze("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0")
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -26,7 +26,7 @@ aliases = {
"MATERIALIZE INDEX" : ["ALTER MATERIALIZE INDEX", "MATERIALIZE INDEX"],
"CLEAR INDEX": ["ALTER CLEAR INDEX", "CLEAR INDEX"],
"DROP INDEX": ["ALTER DROP INDEX", "DROP INDEX"],
"ALTER INDEX": ["ALTER INDEX", "INDEX"] # super-privilege
"ALTER INDEX": ["ALTER INDEX", "INDEX", "ALL"] # super-privilege
}
# Extra permutation is for 'ALTER INDEX' super-privilege
@ -302,7 +302,6 @@ def check_drop_index_when_privilege_is_not_granted(table, user, node):
settings = [("user", user)], exitcode=exitcode, message=message)
@TestScenario
@Flags(TE)
def user_with_some_privileges(self, table_type, node=None):
"""Check that user with any permutation of ALTER INDEX subprivileges is able
to alter the table for privileges granted, and not for privileges not granted.
@ -325,7 +324,6 @@ def user_with_some_privileges(self, table_type, node=None):
alter_index_privilege_handler(permutation, table_name, user_name, node)
@TestScenario
@Flags(TE)
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterIndex_Revoke("1.0"),
)
@ -355,7 +353,6 @@ def user_with_revoked_privileges(self, table_type, node=None):
alter_index_privilege_handler(0, table_name, user_name, node)
@TestScenario
@Flags(TE)
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterIndex_Grant("1.0"),
)
@ -385,7 +382,6 @@ def role_with_some_privileges(self, table_type, node=None):
alter_index_privilege_handler(permutation, table_name, user_name, node)
@TestScenario
@Flags(TE)
def user_with_revoked_role(self, table_type, node=None):
"""Check that user with a role that has ALTER INDEX privilege on a table is unable to
ALTER INDEX from that table after the role with privilege has been revoked from the user.
@ -416,7 +412,6 @@ def user_with_revoked_role(self, table_type, node=None):
alter_index_privilege_handler(0, table_name, user_name, node)
@TestScenario
@Flags(TE)
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterIndex_Cluster("1.0"),
)
@ -451,12 +446,13 @@ def user_with_privileges_on_cluster(self, table_type, node=None):
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterIndex("1.0"),
RQ_SRS_006_RBAC_Privileges_AlterIndex_TableEngines("1.0")
RQ_SRS_006_RBAC_Privileges_AlterIndex_TableEngines("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()
])
@Flags(TE)
@Name("alter index")
def feature(self, node="clickhouse1", stress=None, parallel=None):
self.context.node = self.context.cluster.node(node)

View File

@ -7,7 +7,7 @@ from rbac.requirements import *
from rbac.helper.common import *
import rbac.helper.errors as errors
aliases = {"ALTER MOVE PARTITION", "ALTER MOVE PART", "MOVE PARTITION", "MOVE PART"}
aliases = {"ALTER MOVE PARTITION", "ALTER MOVE PART", "MOVE PARTITION", "MOVE PART", "ALL"}
@TestSuite
def privilege_granted_directly_or_via_role(self, table_type, privilege, node=None):
@ -45,7 +45,13 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
with table(node, f"{source_table_name},{target_table_name}", table_type):
with When("I attempt to move partition without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to move partition without privilege"):
node.query(f"ALTER TABLE {source_table_name} MOVE PARTITION 1 TO TABLE {target_table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -151,6 +157,8 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterMove("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -31,7 +31,7 @@ def alter_quota_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=alter_quota, flags=TE,
Suite(run=alter_quota,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in alter_quota.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -52,13 +52,14 @@ def alter_quota_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=alter_quota, flags=TE,
Suite(run=alter_quota,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in alter_quota.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("ALTER QUOTA",),
])
@ -75,7 +76,13 @@ def alter_quota(self, privilege, grant_target_name, user_name, node=None):
with quota(node, alter_quota_name):
with When("I check the user can't alter a quota"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't alter a quota"):
node.query(f"ALTER QUOTA {alter_quota_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -127,6 +134,8 @@ def alter_quota(self, privilege, grant_target_name, user_name, node=None):
@Name("alter quota")
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterQuota("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of ALTER QUOTA.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=alter_role, flags=TE,
Suite(run=alter_role,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in alter_role.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=alter_role, flags=TE,
Suite(run=alter_role,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in alter_role.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("ALTER ROLE",),
])
@ -58,14 +59,22 @@ def alter_role(self, privilege, grant_target_name, user_name, node=None):
with Scenario("ALTER ROLE without privilege"):
alter_role_name = f"alter_role_{getuid()}"
with role(node, alter_role_name):
with When("I check the user can't alter a role"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't alter a role"):
node.query(f"ALTER ROLE {alter_role_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("ALTER ROLE with privilege"):
alter_role_name = f"alter_role_{getuid()}"
with role(node, alter_role_name):
with When(f"I grant {privilege}"):
@ -93,6 +102,7 @@ def alter_role(self, privilege, grant_target_name, user_name, node=None):
with Scenario("ALTER ROLE with revoked privilege"):
alter_role_name = f"alter_role_{getuid()}"
with role(node, alter_role_name):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -108,6 +118,8 @@ def alter_role(self, privilege, grant_target_name, user_name, node=None):
@Name("alter role")
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterRole("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of ALTER ROLE.

View File

@ -1,7 +1,5 @@
import json
from multiprocessing.dummy import Pool
from testflows.core import *
from testflows.asserts import error
@ -10,7 +8,7 @@ from rbac.helper.common import *
import rbac.helper.errors as errors
from rbac.helper.tables import table_types
aliases = {"ALTER SETTINGS", "ALTER SETTING", "ALTER MODIFY SETTING", "MODIFY SETTING"}
aliases = {"ALTER SETTINGS", "ALTER SETTING", "ALTER MODIFY SETTING", "MODIFY SETTING", "ALL"}
def check_alter_settings_when_privilege_is_granted(table, user, node):
"""Ensures ADD SETTINGS runs as expected when the privilege is granted to the specified user
@ -21,7 +19,7 @@ def check_alter_settings_when_privilege_is_granted(table, user, node):
with And(f"I modify settings"):
node.query(f"ALTER TABLE {table} MODIFY SETTING merge_with_ttl_timeout=5",
settings = [("user", user)])
settings=[("user", user)])
with Then("I verify that the setting is in the table"):
output = json.loads(node.query(f"SHOW CREATE TABLE {table} FORMAT JSONEachRow").output)
@ -30,10 +28,16 @@ def check_alter_settings_when_privilege_is_granted(table, user, node):
def check_alter_settings_when_privilege_is_not_granted(table, user, node):
"""Ensures CLEAR SETTINGS runs as expected when the privilege is granted to the specified user
"""
with When("I try to use ALTER SETTING, has not been granted"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user}")
with Then("I try to use ALTER SETTING, has not been granted"):
exitcode, message = errors.not_enough_privileges(user)
node.query(f"ALTER TABLE {table} MODIFY SETTING merge_with_ttl_timeout=5",
settings = [("user", user)], exitcode=exitcode, message=message)
settings=[("user", user)], exitcode=exitcode, message=message)
@TestScenario
def user_with_privileges(self, privilege, table_type, node=None):
@ -53,6 +57,7 @@ def user_with_privileges(self, privilege, table_type, node=None):
with Then(f"I try to ALTER SETTINGS"):
check_alter_settings_when_privilege_is_granted(table_name, user_name, node)
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterSettings_Revoke("1.0"),
@ -180,7 +185,9 @@ def scenario_parallelization(self, table_type, privilege):
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterSettings("1.0"),
RQ_SRS_006_RBAC_Privileges_AlterSettings_TableEngines("1.0")
RQ_SRS_006_RBAC_Privileges_AlterSettings_TableEngines("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()
@ -208,7 +215,9 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
tasks = []
try:
for alias in aliases:
run_scenario(pool, tasks, Suite(test=scenario_parallelization, name=alias, setup=instrument_clickhouse_server_log), {"table_type": table_type, "privilege": alias})
run_scenario(pool, tasks, Suite(test=scenario_parallelization, name=alias,
setup=instrument_clickhouse_server_log),
{"table_type": table_type, "privilege": alias})
finally:
join(tasks)
finally:

View File

@ -31,7 +31,7 @@ def alter_settings_profile_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=alter_settings_profile, flags=TE,
Suite(run=alter_settings_profile,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in alter_settings_profile.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -52,13 +52,14 @@ def alter_settings_profile_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=alter_settings_profile, flags=TE,
Suite(run=alter_settings_profile,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in alter_settings_profile.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("ALTER SETTINGS PROFILE",),
("ALTER PROFILE",),
@ -76,7 +77,13 @@ def alter_settings_profile(self, privilege, grant_target_name, user_name, node=N
with settings_profile(node, alter_settings_profile_name):
with When("I check the user can't alter a settings_profile"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't alter a settings_profile"):
node.query(f"ALTER SETTINGS PROFILE {alter_settings_profile_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -128,6 +135,8 @@ def alter_settings_profile(self, privilege, grant_target_name, user_name, node=N
@Name("alter settings profile")
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterSettingsProfile("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of ALTER SETTINGS PROFILE.

View File

@ -16,7 +16,7 @@ subprivileges = {
aliases = {
"TTL" : ["ALTER TTL", "ALTER MODIFY TTL", "MODIFY TTL"],
"MATERIALIZE TTL": ["ALTER MATERIALIZE TTL", "MATERIALIZE TTL"],
"MATERIALIZE TTL": ["ALTER MATERIALIZE TTL", "MATERIALIZE TTL", "ALL"],
}
permutation_count = (1 << len(subprivileges))
@ -250,7 +250,9 @@ def user_with_privileges_on_cluster(self, table_type, node=None):
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterTTL("1.0"),
RQ_SRS_006_RBAC_Privileges_AlterTTL_TableEngines("1.0")
RQ_SRS_006_RBAC_Privileges_AlterTTL_TableEngines("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -7,7 +7,7 @@ from rbac.requirements import *
from rbac.helper.common import *
import rbac.helper.errors as errors
aliases = {"ALTER UPDATE", "UPDATE"}
aliases = {"ALTER UPDATE", "UPDATE", "ALL"}
@TestSuite
def privilege_granted_directly_or_via_role(self, table_type, privilege, node=None):
@ -38,26 +38,41 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I attempt to update a column without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to update a column without privilege"):
node.query(f"ALTER TABLE {table_name} UPDATE a = x WHERE 1", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the update privilege"):
node.query(f"GRANT {privilege} ON {table_name} TO {grant_target_name}")
with Then("I attempt to update a column"):
node.query(f"ALTER TABLE {table_name} UPDATE a = x WHERE 1", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the update privilege"):
node.query(f"GRANT {privilege} ON {table_name} TO {grant_target_name}")
with And("I revoke the update privilege"):
node.query(f"REVOKE {privilege} ON {table_name} FROM {grant_target_name}")
with Then("I attempt to update a column"):
node.query(f"ALTER TABLE {table_name} UPDATE a = x WHERE 1", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -65,7 +80,9 @@ def privilege_check(grant_target_name, user_name, table_type, privilege, node=No
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterUpdate("1.0"),
RQ_SRS_006_RBAC_Privileges_AlterUpdate_TableEngines("1.0")
RQ_SRS_006_RBAC_Privileges_AlterUpdate_TableEngines("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()

View File

@ -17,7 +17,7 @@ def alter_user_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=alter_user, flags=TE,
Suite(run=alter_user,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in alter_user.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def alter_user_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=alter_user, flags=TE,
Suite(run=alter_user,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in alter_user.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("ALTER USER",),
])
@ -61,7 +62,13 @@ def alter_user(self, privilege, grant_target_name, user_name, node=None):
alter_user_name = f"alter_user_{getuid()}"
with user(node, alter_user_name):
with When("I check the user can't alter a user"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't alter a user"):
node.query(f"ALTER USER {alter_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -108,6 +115,8 @@ def alter_user(self, privilege, grant_target_name, user_name, node=None):
@Name("alter user")
@Requirements(
RQ_SRS_006_RBAC_Privileges_AlterUser("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of ALTER USER.

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE DATABASE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,11 +32,17 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
db_name = f"db_{getuid()}"
try:
with When("I attempt to attach a database without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to attach a database without privilege"):
node.query(f"ATTACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -44,14 +50,14 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
db_name = f"db_{getuid()}"
try:
with When("I grant create database privilege"):
node.query(f"GRANT CREATE DATABASE ON {db_name}.* TO {grant_target_name}")
with Then("I attempt to attach aa database"):
with Then("I attempt to attach a database"):
node.query(f"ATTACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=80, message="DB::Exception: Received from localhost:9000. DB::Exception: Database engine must be specified for ATTACH DATABASE query")
@ -59,7 +65,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
db_name = f"db_{getuid()}"
try:
@ -77,9 +83,44 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked ALL privilege"):
db_name = f"db_{getuid()}"
try:
with When("I grant the create database privilege"):
node.query(f"GRANT CREATE DATABASE ON {db_name}.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to attach a database"):
node.query(f"ATTACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with ALL privilege"):
db_name = f"db_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to attach a database"):
node.query(f"ATTACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=80, message="DB::Exception: Received from localhost:9000. DB::Exception: Database engine must be specified for ATTACH DATABASE query")
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AttachDatabase("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("attach database")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -92,5 +133,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE DICTIONARY with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,11 +32,17 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
dict_name = f"dict_{getuid()}"
try:
with When("I attempt to attach a dictionary without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to attach a dictionary without privilege"):
node.query(f"ATTACH DICTIONARY {dict_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -44,7 +50,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -59,7 +65,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -77,9 +83,44 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked ALL privilege"):
db_name = f"db_{getuid()}"
try:
with When("I grant the create database privilege"):
node.query(f"GRANT CREATE DATABASE ON {db_name}.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to attach a database"):
node.query(f"ATTACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with ALL privilege"):
dict_name = f"dict_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to attach a dictionary"):
node.query(f"ATTACH DICTIONARY {dict_name}", settings = [("user", user_name)],
exitcode=231, message=f"DB::Exception: Dictionary `{dict_name}` doesn't exist.")
finally:
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AttachDictionary("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("attach dictionary")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -92,5 +133,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE TABLE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,12 +32,17 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
table_name = f"table_{getuid()}"
try:
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with When("I attempt to attach a table without privilege"):
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to attach a table without privilege"):
node.query(f"ATTACH TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -45,7 +50,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
table_name = f"table_{getuid()}"
try:
@ -60,7 +65,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
table_name = f"table_{getuid()}"
try:
@ -78,9 +83,44 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with revoked ALL privilege"):
table_name = f"table_{getuid()}"
try:
with When("I grant the create table privilege"):
node.query(f"GRANT CREATE TABLE ON *.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to attach a table"):
node.query(f"ATTACH TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with ALL privilege"):
table_name = f"table_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to attach a table"):
node.query(f"ATTACH TABLE {table_name}", settings = [("user", user_name)],
exitcode=134, message=f"DB::Exception: Table `{table_name}` doesn't exist.")
finally:
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AttachTable("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("attach table")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -93,5 +133,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE TEMPORARY TABLE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,10 +32,16 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with When("I attempt to attach a temporary table without privilege"):
node.query(f"ATTACH TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -44,12 +50,13 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I grant create temporary table privilege"):
node.query(f"GRANT CREATE TEMPORARY TABLE ON *.* TO {grant_target_name}")
with Then("I attempt to attach a temporary table"):
node.query(f"ATTACH TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)])
@ -57,7 +64,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
@ -75,9 +82,43 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with revoked ALL privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I grant the create temporary table privilege"):
node.query(f"GRANT CREATE TEMPORARY TABLE ON *.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to attach a temporary table"):
node.query(f"ATTACH TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with ALL privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to attach a temporary table"):
node.query(f"ATTACH TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)])
finally:
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_AttachTemporaryTable("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("attach temporary table")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -90,5 +131,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE DATABASE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,11 +32,17 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
db_name = f"db_{getuid()}"
try:
with When("I attempt to create a database without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to create a database without privilege"):
node.query(f"CREATE DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -44,7 +50,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
db_name = f"db_{getuid()}"
try:
@ -58,7 +64,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
db_name = f"db_{getuid()}"
try:
@ -76,9 +82,43 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked ALL privilege"):
db_name = f"db_{getuid()}"
try:
with When("I grant the create database privilege"):
node.query(f"GRANT CREATE DATABASE ON {db_name}.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to create a database"):
node.query(f"CREATE DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with ALL privilege"):
db_name = f"db_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to create a database"):
node.query(f"CREATE DATABASE {db_name}", settings = [("user", user_name)])
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateDatabase("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("create database")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -91,5 +131,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE DICTIONARY with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,11 +32,17 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
dict_name = f"dict_{getuid()}"
try:
with When("I attempt to create a dictionary without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to create a dictionary without privilege"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -44,7 +50,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -58,7 +64,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -76,9 +82,44 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked ALL privilege"):
dict_name = f"dict_{getuid()}"
try:
with When("I grant the create dictionary privilege"):
node.query(f"GRANT CREATE DICTIONARY ON {dict_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to create a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with ALL privilege"):
dict_name = f"dict_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to create a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)", settings = [("user", user_name)])
finally:
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateDictionary("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("create dictionary")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -91,5 +132,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=create_quota, flags=TE,
Suite(run=create_quota,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in create_quota.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=create_quota, flags=TE,
Suite(run=create_quota,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in create_quota.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("CREATE QUOTA",),
])
@ -60,7 +61,13 @@ def create_quota(self, privilege, grant_target_name, user_name, node=None):
create_quota_name = f"create_quota_{getuid()}"
try:
with When("I check the user can't create a quota"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't create a quota"):
node.query(f"CREATE QUOTA {create_quota_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -118,6 +125,8 @@ def create_quota(self, privilege, grant_target_name, user_name, node=None):
@Name("create quota")
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateQuota("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of CREATE QUOTA.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=create_role, flags=TE,
Suite(run=create_role,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in create_role.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=create_role, flags=TE,
Suite(run=create_role,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in create_role.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("CREATE ROLE",),
])
@ -60,7 +61,13 @@ def create_role(self, privilege, grant_target_name, user_name, node=None):
create_role_name = f"create_role_{getuid()}"
try:
with When("I check the user can't create a role"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't create a role"):
node.query(f"CREATE ROLE {create_role_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -118,6 +125,8 @@ def create_role(self, privilege, grant_target_name, user_name, node=None):
@Name("create role")
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateRole("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of CREATE ROLE.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=create_row_policy, flags=TE,
Suite(run=create_row_policy,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in create_row_policy.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=create_row_policy, flags=TE,
Suite(run=create_row_policy,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in create_row_policy.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("CREATE ROW POLICY",),
("CREATE POLICY",),
@ -62,7 +63,13 @@ def create_row_policy(self, privilege, grant_target_name, user_name, node=None):
table_name = f"table_name_{getuid()}"
try:
with When("I check the user can't create a row policy"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't create a row policy"):
node.query(f"CREATE ROW POLICY {create_row_policy_name} ON {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -119,15 +126,962 @@ def create_row_policy(self, privilege, grant_target_name, user_name, node=None):
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {create_row_policy_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Restriction("1.0")
)
def no_grants(self, node=None):
"""Check that user is unable to select from a table without a row policy
after a row policy with a condition has been created on that table.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name}")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
with When("I create a row policy with a condition"):
node.query(f"CREATE ROW POLICY OR REPLACE {pol_name} ON {table_name} FOR SELECT USING 1")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Access_Permissive("1.0"),
)
def permissive(self, node=None):
"""Check that user is able to see from a table when they have a PERMISSIVE policy.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1), (2)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Access_Restrictive("1.0")
)
def restrictive(self, node=None):
"""Check that user is able to see values they have a RESTRICTIVE policy for.
"""
table_name = f"table_{getuid()}"
perm_pol_name = f"perm_pol_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a permissive row policy"):
node.query(f"CREATE ROW POLICY {perm_pol_name} ON {table_name} FOR SELECT USING y=1 OR y=2 TO default")
with And("I have a restrictive row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS RESTRICTIVE FOR SELECT USING y=1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1), (2)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the restrictive row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the permissive row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {perm_pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_ForSelect("1.0"),
)
def for_select(self, node=None):
"""Check that user is able to see values allowed by the row policy condition in the FOR SELECT clause.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a restrictive row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} FOR SELECT USING 1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0")
)
def condition(self, node=None):
"""Check that user is able to see values allowed by the row policy condition.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a restrictive row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} FOR SELECT USING y=1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0")
)
def if_not_exists(self, node=None):
"""Check that a row policy created using IF NOT EXISTS does not replace a row policy with the same name.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} FOR SELECT USING 1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
with When("I create another row policy with the same name using IF NOT EXISTS"):
node.query(f"CREATE ROW POLICY IF NOT EXISTS {pol_name} ON {table_name}")
with Then("I select from the table again"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0")
)
def or_replace(self, node=None):
"""Check that a row policy created using OR REPLACE does replace the row policy with the same name.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} FOR SELECT USING 1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
with When("I create another row policy with the same name using OR REPLACE"):
node.query(f"CREATE ROW POLICY OR REPLACE {pol_name} ON {table_name} AS RESTRICTIVE FOR SELECT USING 1 TO default")
with Then("I can no longer select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert output == '', error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0")
)
def on_cluster(self, node=None):
"""Check that a row policy created using ON CLUSTER applies to the nodes of the cluster correctly.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
node2 = self.context.node2
try:
with Given("I have a table on a cluster"):
node.query(f"CREATE TABLE {table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Memory")
with And("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON CLUSTER sharded_cluster ON {table_name} FOR SELECT USING 1")
with When("I insert some values into the table on the first node"):
node.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with And("I insert some values into the table on the second node"):
node2.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
with And("I select from another node on the cluster"):
output = node2.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON CLUSTER sharded_cluster ON {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE {table_name} ON CLUSTER sharded_cluster")
@TestScenario
def diff_policies_on_diff_nodes(self, node=None):
"""Check that a row policy created on a node, does not effect a different node.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
node2 = self.context.node2
try:
with Given("I have a table on a cluster"):
node.query(f"CREATE TABLE {table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Memory")
with And("I have a row policy on one node"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} FOR SELECT USING 1")
with When("I insert some values into the table on the first node"):
node.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with And("I insert some values into the table on the second node"):
node2.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
with And("I select from another node on the cluster"):
output = node2.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE {table_name} ON CLUSTER sharded_cluster")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"),
)
def assignment(self, node=None):
"""Check that user is able to see rows from a table when they have PERMISSIVE policy assigned to them.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_None("1.0"),
)
def assignment_none(self, node=None):
"""Check that no one is affected when a row policy is assigned to NONE.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO NONE")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_All("1.0"),
)
def assignment_all(self, node=None):
"""Check that everyone is effected with a row policy is assigned to ALL.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO ALL")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept("1.0"),
)
def assignment_all_except(self, node=None):
"""Check that everyone is except the specified user is effect by a row policy assigned to ALL EXCEPT.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO ALL EXCEPT default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0"),
)
def nested_view(self, node=None):
"""Check that if a user has a row policy on a table and a view is created on that table,
the user is only able to select rows specified by the assigned policies from the view.
"""
table_name = f"table_{getuid()}"
view_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with And("I create a view on the table"):
node.query(f"CREATE VIEW {view_name} AS SELECT * FROM {table_name}")
with Then("I try to select from the view"):
output = node.query(f"SELECT * FROM {view_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0"),
)
def nested_live_view_after_policy(self, node=None):
"""Check that if a user has a row policy on a table and a live view is created on that table,
the user is only able to select rows specified by the assigned policies from the view.
"""
table_name = f"table_{getuid()}"
view_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I add allow_experimental_live_view to the default query settings"):
default_query_settings = getsattr(current().context, "default_query_settings", [])
default_query_settings.append(("allow_experimental_live_view", 1))
with And("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with And("I create a live view on the table"):
node.query(f"CREATE LIVE VIEW {view_name} AS SELECT * FROM {table_name}")
with Then("I try to select from the view"):
output = node.query(f"SELECT * FROM {view_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the live view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
with And("I remove allow_experimental_live_view from the default query settings", flags=TE):
if default_query_settings:
try:
default_query_settings.pop(default_query_settings.index(("allow_experimental_live_view", 1)))
except ValueError:
pass
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0"),
)
def nested_live_view_before_policy(self, node=None):
"""Check that if a live view exists on a table and then a row policy is created,
the user is only able to select rows specified by the assigned policies from the view.
"""
table_name = f"table_{getuid()}"
view_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I add allow_experimental_live_view to the default query settings"):
default_query_settings = getsattr(current().context, "default_query_settings", [])
default_query_settings.append(("allow_experimental_live_view", 1))
with And("There is a live view on the table"):
node.query(f"CREATE LIVE VIEW {view_name} AS SELECT * FROM {table_name}")
with And("There is a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with When("I insert values into the table"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with Then("I try to select from the view"):
output = node.query(f"SELECT * FROM {view_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the live view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
with And("I remove allow_experimental_live_view from the default query settings", flags=TE):
if default_query_settings:
try:
default_query_settings.pop(default_query_settings.index(("allow_experimental_live_view", 1)))
except ValueError:
pass
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0"),
)
def nested_mat_view_after_policy(self, node=None):
"""Check that if a user has a row policy on a table and a materialized view is created on that table,
the user is only able to select rows specified by the assigned policies from the view.
"""
table_name = f"table_{getuid()}"
view_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with When("I create a view on the table"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ENGINE = Memory AS SELECT * FROM {table_name}")
with And("I insert some values on the table"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with Then("I try to select from the view"):
output = node.query(f"SELECT * FROM {view_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the materialized view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0"),
)
def nested_mat_view_before_policy(self, node=None):
"""Check that if a materialized view exists on a table and then a row policy is created,
the user is only able to select rows specified by the assigned policies from the view.
"""
table_name = f"table_{getuid()}"
view_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a view on the table"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ENGINE = Memory AS SELECT * FROM {table_name}")
with And("I have some values on the table"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with When("I create a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with Then("I try to select from the view"):
output = node.query(f"SELECT * FROM {view_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the materialized view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@TestScenario
def populate_mat_view(self, node=None):
"""Check that if a user has a row policy on a table and a materialized view is created using POPULATE from that table,
the user can only select the rows from the materialized view specified in the row policy.
"""
table_name = f"table_{getuid()}"
view_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name):
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with And("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with When("I create a mat view with POPULATE from the table"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ENGINE = Memory POPULATE AS SELECT * FROM {table_name}")
with Then("I try to select from the view"):
output = node.query(f"SELECT * FROM {view_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the materialized view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0")
)
def dist_table(self, node=None):
"""Check that if a user has a row policy on a table and a distributed table is created on that table,
the user is only able to select rows specified by the assigned policies from the distributed table.
"""
table_name = f"table_{getuid()}"
dist_table_name = f"dist_table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
node2 = self.context.node2
try:
with Given("I have a table on a cluster"):
node.query(f"CREATE TABLE {table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Memory")
with And("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON CLUSTER sharded_cluster ON {table_name} FOR SELECT USING 1")
with And("I have a distributed table"):
node.query(f"CREATE TABLE {dist_table_name} (x UInt64) ENGINE = Distributed(sharded_cluster, default, {table_name}, rand())")
with When("I insert some values into the table on the first node"):
node.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {dist_table_name}").output
assert '' == output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON CLUSTER sharded_cluster ON {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name} ON CLUSTER sharded_cluster")
with And("I drop the distributed table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {dist_table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0")
)
def dist_table_diff_policies_on_diff_nodes(self, node=None):
"""Check that the user can only access the rows of the distributed table that are allowed
by row policies on the the source tables. The row policies are different on different nodes.
"""
table_name = f"table_{getuid()}"
dist_table_name = f"dist_table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
node2 = self.context.node2
try:
with Given("I have a table on a cluster"):
node.query(f"CREATE TABLE {table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Memory")
with And("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} FOR SELECT USING 1")
with And("I have a distributed table"):
node.query(f"CREATE TABLE {dist_table_name} (x UInt64) ENGINE = Distributed(sharded_cluster, default, {table_name}, rand())")
with When("I insert some values into the table on the first node"):
node.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with And("I insert some values into the table on the second node"):
node2.query(f"INSERT INTO {table_name} (x) VALUES (2)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {dist_table_name}").output
assert '2' in output and '1' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON CLUSTER sharded_cluster ON {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name} ON CLUSTER sharded_cluster")
with And("I drop the distributed table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {dist_table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0")
)
def dist_table_on_dist_table(self, node=None):
"""Check that if a user has a row policy on a table and a distributed table is created on that table,
and another distributed table is created on top of that,
the user is only able to access rows on any of the tables specified by the assigned policies.
"""
table_name = f"table_{getuid()}"
dist_table_name = f"dist_table_{getuid()}"
dist_table_2_name = f"dist_table_2_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
node2 = self.context.node2
try:
with Given("I have a table on a cluster"):
node.query(f"CREATE TABLE {table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Memory")
with And("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON CLUSTER sharded_cluster ON {table_name} FOR SELECT USING 1")
with And("I have a distributed table on a cluster"):
node.query(f"CREATE TABLE {dist_table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Distributed(sharded_cluster, default, {table_name}, rand())")
with And("I have a distributed table on the other distributed table"):
node.query(f"CREATE TABLE {dist_table_2_name} (x UInt64) ENGINE = Distributed(sharded_cluster, default, {dist_table_name}, rand())")
with When("I insert some values into the table on the first node"):
node.query(f"INSERT INTO {dist_table_2_name} (x) VALUES (1)")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {dist_table_2_name}").output
assert '' == output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON CLUSTER sharded_cluster ON {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name} ON CLUSTER sharded_cluster")
with And("I drop the distributed table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {dist_table_name} ON CLUSTER sharded_cluster")
with And("I drop the outer distributed table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {dist_table_2_name}")
@TestScenario
def no_table(self, node=None):
"""Check that row policy is not created when the table is not specified.
"""
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
with When("I try to create a row policy without a table"):
node.query(f"CREATE ROW POLICY {pol_name}",
exitcode=62, message='Exception: Syntax error')
with And("I try to create a row policy on a database"):
node.query(f"CREATE ROW POLICY {pol_name} ON default.*",
exitcode=62, message='Exception: Syntax error')
@TestScenario
def policy_before_table(self, node=None):
"""Check that if the policy is created before the table,
then it is still applied correctly.
"""
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING y=1 TO default")
with table(node, table_name):
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1), (2)")
with Then("I try to select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Nesting("1.0"),
)
def dict(self, node=None):
"""Check that if a user has a row policy on a table and a dictionary is created on that table,
the user is only able to select rows specified by the assigned policies from the dict.
"""
table_name = f"table_{getuid()}"
dict_name = f"view_{getuid()}"
pol_name = f"pol_{getuid()}"
if node is None:
node = self.context.node
try:
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON {table_name} AS PERMISSIVE FOR SELECT USING key=1 TO default")
with And("I have a table"):
node.query(f"CREATE TABLE {table_name} (key UInt64, val UInt64 DEFAULT 5) ENGINE = Memory")
with When("The table has some values"):
node.query(f"INSERT INTO {table_name} (key) VALUES (1),(2)")
with And("I create a dict on the table"):
node.query(f"CREATE DICTIONARY {dict_name} (key UInt64 DEFAULT 0, val UInt64 DEFAULT 5) PRIMARY KEY key SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE {table_name} PASSWORD '' DB 'default')) LIFETIME(MIN 0 MAX 0) LAYOUT(FLAT())")
with Then("I try to select from the dict"):
output = node.query(f"SELECT * FROM {dict_name}").output
assert '1' in output and '2' not in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON {table_name}")
with And("I drop the materialized view", flags=TE):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestFeature
@Name("create row policy")
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateRowPolicy("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of CREATE ROW POLICY.
"""
self.context.node = self.context.cluster.node(node)
self.context.node2 = self.context.cluster.node("clickhouse2")
Suite(run=privileges_granted_directly, setup=instrument_clickhouse_server_log)
Suite(run=privileges_granted_via_role, setup=instrument_clickhouse_server_log)
Scenario(run=no_grants, setup=instrument_clickhouse_server_log)
Scenario(run=permissive, setup=instrument_clickhouse_server_log)
Scenario(run=restrictive, setup=instrument_clickhouse_server_log)
Scenario(run=for_select, setup=instrument_clickhouse_server_log)
Scenario(run=condition, setup=instrument_clickhouse_server_log)
Scenario(run=if_not_exists, setup=instrument_clickhouse_server_log)
Scenario(run=or_replace, setup=instrument_clickhouse_server_log)
Scenario(run=on_cluster, setup=instrument_clickhouse_server_log)
Scenario(run=assignment, setup=instrument_clickhouse_server_log)
Scenario(run=assignment_none, setup=instrument_clickhouse_server_log)
Scenario(run=assignment_all, setup=instrument_clickhouse_server_log)
Scenario(run=assignment_all_except, setup=instrument_clickhouse_server_log)
Scenario(run=nested_view, setup=instrument_clickhouse_server_log)
Scenario(run=nested_live_view_before_policy, setup=instrument_clickhouse_server_log)
Scenario(run=nested_live_view_after_policy, setup=instrument_clickhouse_server_log)
Scenario(run=nested_mat_view_before_policy, setup=instrument_clickhouse_server_log)
Scenario(run=nested_mat_view_after_policy, setup=instrument_clickhouse_server_log)
Scenario(run=populate_mat_view, setup=instrument_clickhouse_server_log)
Scenario(run=dist_table, setup=instrument_clickhouse_server_log)
Scenario(run=dist_table_on_dist_table, setup=instrument_clickhouse_server_log)
Scenario(run=dist_table_diff_policies_on_diff_nodes, setup=instrument_clickhouse_server_log)
Scenario(run=diff_policies_on_diff_nodes, setup=instrument_clickhouse_server_log)
Scenario(run=no_table, setup=instrument_clickhouse_server_log)
Scenario(run=policy_before_table, setup=instrument_clickhouse_server_log)
Scenario(run=dict, setup=instrument_clickhouse_server_log)

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=create_settings_profile, flags=TE,
Suite(run=create_settings_profile,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in create_settings_profile.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=create_settings_profile, flags=TE,
Suite(run=create_settings_profile,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in create_settings_profile.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("CREATE SETTINGS PROFILE",),
("CREATE PROFILE",),
@ -61,7 +62,13 @@ def create_settings_profile(self, privilege, grant_target_name, user_name, node=
create_settings_profile_name = f"create_settings_profile_{getuid()}"
try:
with When("I check the user can't create a settings_profile"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't create a settings_profile"):
node.query(f"CREATE SETTINGS PROFILE {create_settings_profile_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -119,6 +126,8 @@ def create_settings_profile(self, privilege, grant_target_name, user_name, node=
@Name("create settings profile")
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateSettingsProfile("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of CREATE SETTINGS PROFILE.

View File

@ -6,6 +6,9 @@ from rbac.helper.common import *
import rbac.helper.errors as errors
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def create_without_create_table_privilege(self, node=None):
"""Check that user is unable to create a table without CREATE TABLE privilege.
"""
@ -21,7 +24,13 @@ def create_without_create_table_privilege(self, node=None):
with Given("I don't have a table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with When("I try to create a table without CREATE TABLE privilege as the user"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I try to create a table without CREATE TABLE privilege as the user"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE = Memory", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
@ -74,6 +83,54 @@ def create_with_create_table_privilege(self, grant_target_name, user_name, node=
with Then("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_All("1.0")
)
def create_with_all_privilege_granted_directly_or_via_role(self, node=None):
"""Check that user is able to create a table with ALL privilege, either granted directly or through a role.
"""
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
if node is None:
node = self.context.node
with user(node, f"{user_name}"):
Scenario(test=create_with_all_privilege,
name="create with ALL privilege granted directly")(grant_target_name=user_name, user_name=user_name)
with user(node, f"{user_name}"), role(node, f"{role_name}"):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Scenario(test=create_with_all_privilege,
name="create with ALL privilege granted through a role")(grant_target_name=role_name, user_name=user_name)
@TestOutline
def create_with_all_privilege(self, grant_target_name, user_name, node=None):
"""Check that user is able to create a table with the granted privileges.
"""
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
try:
with Given("I don't have a table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I try to create a table without privilege as the user"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE = Memory", settings = [("user", f"{user_name}")])
finally:
with Then("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestScenario
def create_with_revoked_create_table_privilege_revoked_directly_or_from_role(self, node=None):
"""Check that user is unable to create table after the CREATE TABLE privilege is revoked, either directly or from a role.
@ -125,6 +182,57 @@ def create_with_revoked_create_table_privilege(self, grant_target_name, user_nam
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestScenario
def create_with_all_privileges_revoked_directly_or_from_role(self, node=None):
"""Check that user is unable to create table after ALL privileges are revoked, either directly or from a role.
"""
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
if node is None:
node = self.context.node
with user(node, f"{user_name}"):
Scenario(test=create_with_revoked_all_privilege,
name="create with all privilege revoked directly")(grant_target_name=user_name, user_name=user_name)
with user(node, f"{user_name}"), role(node, f"{role_name}"):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Scenario(test=create_with_revoked_all_privilege,
name="create with all privilege revoked from a role")(grant_target_name=role_name, user_name=user_name)
@TestOutline
def create_with_revoked_all_privilege(self, grant_target_name, user_name, node=None):
"""Revoke ALL privilege and check the user is unable to create a table.
"""
table_name = f"table_{getuid()}"
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
if node is None:
node = self.context.node
try:
with Given("I don't have a table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with When("I grant CREATE TABLE privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I try to create a table on the table as the user"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE = Memory", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestScenario
def create_without_source_table_privilege(self, node=None):
"""Check that user is unable to create a table without select

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute CREATE TEMPORARY TABLE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,11 +32,17 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I attempt to create a temporary table without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to create a temporary table without privilege"):
node.query(f"CREATE TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -44,7 +50,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
@ -58,7 +64,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
@ -76,9 +82,43 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with revoked ALL privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I grant the create temporary table privilege"):
node.query(f"GRANT CREATE TEMPORARY TABLE ON *.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to create a temporary table"):
node.query(f"CREATE TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
with Scenario("user with ALL privilege"):
temp_table_name = f"temp_table_{getuid()}"
try:
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to create aa temporary table"):
node.query(f"CREATE TEMPORARY TABLE {temp_table_name} (x Int8)", settings = [("user", user_name)])
finally:
with Finally("I drop the temporary table"):
node.query(f"DROP TEMPORARY TABLE IF EXISTS {temp_table_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateTemporaryTable("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("create temporary table")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -91,5 +131,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -17,7 +17,7 @@ def create_user_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=create_user, flags=TE,
Suite(run=create_user,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in create_user.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def create_user_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=create_user, flags=TE,
Suite(run=create_user,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in create_user.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("CREATE USER",),
])
@ -60,7 +61,13 @@ def create_user(self, privilege, grant_target_name, user_name, node=None):
create_user_name = f"create_user_{getuid()}"
try:
with When("I check the user can't create a user"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't create a user"):
node.query(f"CREATE USER {create_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -127,7 +134,7 @@ def default_role_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(test=default_role, flags=TE)(grant_target_name=user_name, user_name=user_name)
Suite(test=default_role)(grant_target_name=user_name, user_name=user_name)
@TestSuite
def default_role_granted_via_role(self, node=None):
@ -145,7 +152,7 @@ def default_role_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(test=default_role, flags=TE)(grant_target_name=role_name, user_name=user_name)
Suite(test=default_role)(grant_target_name=role_name, user_name=user_name)
@TestSuite
@Requirements(
@ -215,7 +222,7 @@ def default_role(self, grant_target_name, user_name, node=None):
settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the user", flags=TE):
with Finally("I drop the user"):
node.query(f"DROP USER IF EXISTS {create_user_name} ON CLUSTER sharded_cluster")
with And("I drop the role from the cluster"):
@ -264,6 +271,8 @@ def default_role(self, grant_target_name, user_name, node=None):
@Name("create user")
@Requirements(
RQ_SRS_006_RBAC_Privileges_CreateUser("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of CREATE USER.

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DETACH DATABASE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -39,7 +39,13 @@ def privilege_check(grant_target_name, user_name, node=None):
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with When("I attempt to detach the database"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to detach the database"):
node.query(f"DETACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
@ -48,7 +54,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the database", flags=TE):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
db_name = f"db_{getuid()}"
try:
@ -67,7 +73,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the database", flags=TE):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
db_name = f"db_{getuid()}"
try:
@ -90,9 +96,53 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the database", flags=TE):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked ALL privilege"):
db_name = f"db_{getuid()}"
try:
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with When("I grant the drop database privilege"):
node.query(f"GRANT DROP DATABASE ON {db_name}.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to detach a database"):
node.query(f"DETACH DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I reattach the database", flags=TE):
node.query(f"ATTACH DATABASE IF NOT EXISTS {db_name}")
with And("I drop the database", flags=TE):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with ALL privilege"):
db_name = f"db_{getuid()}"
try:
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to detach a database"):
node.query(f"DETACH DATABASE {db_name}", settings = [("user", user_name)])
finally:
with Finally("I reattach the database", flags=TE):
node.query(f"ATTACH DATABASE IF NOT EXISTS {db_name}")
with And("I drop the database", flags=TE):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DetachDatabase("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("detach database")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -105,5 +155,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DETACH DICTIONARY with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,14 +32,20 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
dict_name = f"dict_{getuid()}"
try:
with Given("I have a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with When("I attempt to detach a dictionary without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to detach a dictionary without privilege"):
node.query(f"DETACH DICTIONARY {dict_name}", settings = [("user", user_name)], exitcode=exitcode, message=message)
finally:
@ -48,7 +54,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the dictionary", flags=TE):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -67,7 +73,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the dictionary", flags=TE):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -89,9 +95,52 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the dictionary", flags=TE):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked ALL privilege"):
dict_name = f"dict_{getuid()}"
try:
with Given("I have a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with When("I grant the drop dictionary privilege"):
node.query(f"GRANT DROP DICTIONARY ON {dict_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to detach a dictionary"):
node.query(f"DETACH DICTIONARY {dict_name}", settings = [("user", user_name)], exitcode=exitcode, message=message)
finally:
with Finally("I reattach the dictionary", flags=TE):
node.query(f"ATTACH DICTIONARY IF NOT EXISTS {dict_name}")
with And("I drop the dictionary", flags=TE):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with ALL privilege"):
dict_name = f"dict_{getuid()}"
try:
with Given("I have a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to detach a dictionary"):
node.query(f"DETACH DICTIONARY {dict_name}", settings = [("user", user_name)])
finally:
with Finally("I reattach the dictionary", flags=TE):
node.query(f"ATTACH DICTIONARY IF NOT EXISTS {dict_name}")
with And("I drop the dictionary", flags=TE):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DetachDictionary("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("detach dictionary")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -104,5 +153,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DETACH TABLE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,13 +32,19 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE=Memory")
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with When("I attempt to detach a table without privilege"):
node.query(f"DETACH TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -49,7 +55,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
table_name = f"table_{getuid()}"
try:
@ -68,7 +74,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
table_name = f"table_{getuid()}"
try:
@ -91,9 +97,53 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with revoked ALL privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE=Memory")
with When("I grant the drop table privilege"):
node.query(f"GRANT DROP TABLE ON *.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to detach a table"):
node.query(f"DETACH TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I reattach the table", flags=TE):
node.query(f"ATTACH TABLE IF NOT EXISTS {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with ALL privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE=Memory")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to detach a table"):
node.query(f"DETACH TABLE {table_name}", settings = [("user", user_name)])
finally:
with Finally("I reattach the table", flags=TE):
node.query(f"ATTACH TABLE IF NOT EXISTS {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DetachTable("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("detach table")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -106,5 +156,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DETACH VIEW with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,13 +32,19 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
view_name = f"view_{getuid()}"
try:
with Given("I have a view"):
node.query(f"CREATE VIEW {view_name} AS SELECT 1")
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with When("I attempt to drop a view without privilege"):
node.query(f"DETACH VIEW {view_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -49,7 +55,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
view_name = f"view_{getuid()}"
try:
@ -68,7 +74,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the table", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
view_name = f"view_{getuid()}"
try:
@ -91,9 +97,53 @@ def privilege_check(grant_target_name, user_name, node=None):
with And("I drop the view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
with Scenario("user with revoked ALL privilege"):
view_name = f"view_{getuid()}"
try:
with Given("I have a view"):
node.query(f"CREATE VIEW {view_name} AS SELECT 1")
with When("I grant the drop view privilege"):
node.query(f"GRANT DROP VIEW ON {view_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to drop a view"):
node.query(f"DETACH VIEW {view_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I reattach the view as a table", flags=TE):
node.query(f"ATTACH VIEW IF NOT EXISTS {view_name} AS SELECT 1")
with And("I drop the view", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
with Scenario("user with ALL privilege"):
view_name = f"view_{getuid()}"
try:
with Given("I have a view"):
node.query(f"CREATE VIEW {view_name} AS SELECT 1")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to drop a view"):
node.query(f"DETACH VIEW {view_name}", settings = [("user", user_name)])
finally:
with Finally("I reattach the view as a table", flags=TE):
node.query(f"ATTACH VIEW IF NOT EXISTS {view_name} AS SELECT 1")
with And("I drop the table", flags=TE):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DetachView("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("detach view")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -106,5 +156,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -39,8 +39,8 @@ def dictGet_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=dictGet_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictGet_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictGet_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -60,60 +60,67 @@ def dictGet_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictGet_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictGet_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictGet_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("dictGet",),
("dictHas",),
("dictGetHierarchy",),
("dictIsIn",),
@Examples("privilege on",[
("ALL", "*.*"),
("dictGet", "dict"),
("dictHas", "dict"),
("dictGetHierarchy", "dict"),
("dictIsIn", "dict"),
])
@Requirements(
RQ_SRS_006_RBAC_dictGet_RequiredPrivilege("1.0")
)
def dictGet_check(self, privilege, grant_target_name, user_name, node=None):
def dictGet_check(self, privilege, on, grant_target_name, user_name, node=None):
"""Check that user is able to execute `dictGet` if and only if they have the necessary privileges.
"""
if node is None:
node = self.context.node
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
on = on.replace("dict", f"{dict_name}")
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege"):
with dict_setup(node, table_name, dict_name):
with When("I attempt to dictGet without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to dictGet without privilege"):
node.query(f"SELECT dictGet ({dict_name},'y',toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with Scenario("user with privilege"):
with dict_setup(node, table_name, dict_name):
with When(f"I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with Then("I attempt to dictGet with privilege"):
node.query(f"SELECT dictGet ({dict_name},'y',toUInt64(1))", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
with Scenario("user with revoked privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with And("I revoke privilege"):
node.query(f"REVOKE {privilege} ON {dict_name} FROM {grant_target_name}")
node.query(f"REVOKE {privilege} ON {on} FROM {grant_target_name}")
with When("I attempt to dictGet without privilege"):
node.query(f"SELECT dictGet ({dict_name},'y',toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
@ -130,8 +137,8 @@ def dictGetOrDefault_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=dictGetOrDefault_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictGetOrDefault_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictGetOrDefault_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -151,60 +158,67 @@ def dictGetOrDefault_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictGetOrDefault_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictGetOrDefault_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictGetOrDefault_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("dictGet",),
("dictHas",),
("dictGetHierarchy",),
("dictIsIn",),
@Examples("privilege on",[
("ALL", "*.*"),
("dictGet", "dict"),
("dictHas", "dict"),
("dictGetHierarchy", "dict"),
("dictIsIn", "dict"),
])
@Requirements(
RQ_SRS_006_RBAC_dictGet_OrDefault_RequiredPrivilege("1.0")
)
def dictGetOrDefault_check(self, privilege, grant_target_name, user_name, node=None):
def dictGetOrDefault_check(self, privilege, on, grant_target_name, user_name, node=None):
"""Check that user is able to execute `dictGetOrDefault` if and only if they have the necessary privileges.
"""
if node is None:
node = self.context.node
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
on = on.replace("dict", f"{dict_name}")
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege"):
with dict_setup(node, table_name, dict_name):
with When("I attempt to dictGetOrDefault without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to dictGetOrDefault without privilege"):
node.query(f"SELECT dictGetOrDefault ({dict_name},'y',toUInt64(1),toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with Scenario("user with privilege"):
with dict_setup(node, table_name, dict_name):
with When(f"I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with Then("I attempt to dictGetOrDefault with privilege"):
node.query(f"SELECT dictGetOrDefault ({dict_name},'y',toUInt64(1),toUInt64(1))", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
with Scenario("user with revoked privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with And("I revoke privilege"):
node.query(f"REVOKE {privilege} ON {dict_name} FROM {grant_target_name}")
node.query(f"REVOKE {privilege} ON {on} FROM {grant_target_name}")
with When("I attempt to dictGetOrDefault without privilege"):
node.query(f"SELECT dictGetOrDefault ({dict_name},'y',toUInt64(1),toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
@ -221,8 +235,8 @@ def dictHas_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=dictHas_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictHas_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictHas_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -242,60 +256,67 @@ def dictHas_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictHas_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictHas_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictHas_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("dictGet",),
("dictHas",),
("dictGetHierarchy",),
("dictIsIn",),
@Examples("privilege on",[
("ALL", "*.*"),
("dictGet", "dict"),
("dictHas", "dict"),
("dictGetHierarchy", "dict"),
("dictIsIn", "dict"),
])
@Requirements(
RQ_SRS_006_RBAC_dictHas_RequiredPrivilege("1.0")
)
def dictHas_check(self, privilege, grant_target_name, user_name, node=None):
def dictHas_check(self, privilege, on, grant_target_name, user_name, node=None):
"""Check that user is able to execute `dictHas` if and only if they have the necessary privileges.
"""
if node is None:
node = self.context.node
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
on = on.replace("dict", f"{dict_name}")
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege"):
with dict_setup(node, table_name, dict_name):
with When("I attempt to dictHas without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to dictHas without privilege"):
node.query(f"SELECT dictHas({dict_name},toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with Scenario("user with privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with Then("I attempt to dictHas with privilege"):
node.query(f"SELECT dictHas({dict_name},toUInt64(1))", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
with Scenario("user with revoked privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with And("I revoke privilege"):
node.query(f"REVOKE {privilege} ON {dict_name} FROM {grant_target_name}")
node.query(f"REVOKE {privilege} ON {on} FROM {grant_target_name}")
with When("I attempt to dictHas without privilege"):
node.query(f"SELECT dictHas({dict_name},toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
@ -311,8 +332,8 @@ def dictGetHierarchy_granted_directly(self, node=None):
node = self.context.node
with user(node, f"{user_name}"):
Suite(run=dictGetHierarchy_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictGetHierarchy_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictGetHierarchy_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -332,60 +353,67 @@ def dictGetHierarchy_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictGetHierarchy_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictGetHierarchy_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictGetHierarchy_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("dictGet",),
("dictHas",),
("dictGetHierarchy",),
("dictIsIn",),
@Examples("privilege on",[
("ALL", "*.*"),
("dictGet", "dict"),
("dictHas", "dict"),
("dictGetHierarchy", "dict"),
("dictIsIn", "dict"),
])
@Requirements(
RQ_SRS_006_RBAC_dictGetHierarchy_RequiredPrivilege("1.0")
)
def dictGetHierarchy_check(self, privilege, grant_target_name, user_name, node=None):
def dictGetHierarchy_check(self, privilege, on, grant_target_name, user_name, node=None):
"""Check that user is able to execute `dictGetHierarchy` if and only if they have the necessary privileges.
"""
if node is None:
node = self.context.node
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
on = on.replace("dict", f"{dict_name}")
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege"):
with dict_setup(node, table_name, dict_name):
with When("I attempt to dictGetHierarchy without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to dictGetHierarchy without privilege"):
node.query(f"SELECT dictGetHierarchy({dict_name},toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with Scenario("user with privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with Then("I attempt to dictGetHierarchy with privilege"):
node.query(f"SELECT dictGetHierarchy({dict_name},toUInt64(1))", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
with Scenario("user with revoked privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with And("I revoke privilege"):
node.query(f"REVOKE {privilege} ON {dict_name} FROM {grant_target_name}")
node.query(f"REVOKE {privilege} ON {on} FROM {grant_target_name}")
with When("I attempt to dictGetHierarchy without privilege"):
node.query(f"SELECT dictGetHierarchy({dict_name},toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
@ -401,8 +429,8 @@ def dictIsIn_granted_directly(self, node=None):
node = self.context.node
with user(node, f"{user_name}"):
Suite(run=dictIsIn_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictIsIn_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictIsIn_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -422,60 +450,67 @@ def dictIsIn_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictIsIn_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name", [
Suite(run=dictIsIn_check,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictIsIn_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("dictGet",),
("dictHas",),
("dictGetHierarchy",),
("dictIsIn",),
@Examples("privilege on",[
("ALL", "*.*"),
("dictGet", "dict"),
("dictHas", "dict"),
("dictGetHierarchy", "dict"),
("dictIsIn", "dict"),
])
@Requirements(
RQ_SRS_006_RBAC_dictIsIn_RequiredPrivilege("1.0")
)
def dictIsIn_check(self, privilege, grant_target_name, user_name, node=None):
def dictIsIn_check(self, privilege, on, grant_target_name, user_name, node=None):
"""Check that user is able to execute `dictIsIn` if and only if they have the necessary privileges.
"""
if node is None:
node = self.context.node
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
on = on.replace("dict", f"{dict_name}")
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege"):
with dict_setup(node, table_name, dict_name):
with When("I attempt to dictIsIn without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to dictIsIn without privilege"):
node.query(f"SELECT dictIsIn({dict_name},toUInt64(1),toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with Scenario("user with privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with Then("I attempt to dictIsIn with privilege"):
node.query(f"SELECT dictIsIn({dict_name},toUInt64(1),toUInt64(1))", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
with Scenario("user with revoked privilege"):
with dict_setup(node, table_name, dict_name):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with And("I revoke privilege"):
node.query(f"REVOKE {privilege} ON {dict_name} FROM {grant_target_name}")
node.query(f"REVOKE {privilege} ON {on} FROM {grant_target_name}")
with When("I attempt to dictIsIn without privilege"):
node.query(f"SELECT dictIsIn({dict_name},toUInt64(1),toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
@ -507,8 +542,8 @@ def dictGetType_granted_directly(self, type, node=None):
node = self.context.node
with user(node, f"{user_name}"):
Suite(run=dictGetType_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name type", [
Suite(run=dictGetType_check,
examples=Examples("privilege on grant_target_name user_name type", [
tuple(list(row)+[user_name,user_name,type]) for row in dictGetType_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -544,67 +579,76 @@ def dictGetType_granted_via_role(self, type, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictGetType_check, setup=instrument_clickhouse_server_log,
examples=Examples("privilege grant_target_name user_name type", [
Suite(run=dictGetType_check,
examples=Examples("privilege on grant_target_name user_name type", [
tuple(list(row)+[role_name,user_name,type]) for row in dictGetType_check.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("dictGet",),
("dictHas",),
("dictGetHierarchy",),
("dictIsIn",),
@Examples("privilege on",[
("ALL", "*.*"),
("dictGet", "dict"),
("dictHas", "dict"),
("dictGetHierarchy", "dict"),
("dictIsIn", "dict"),
])
@Requirements(
RQ_SRS_006_RBAC_dictGet_Type_RequiredPrivilege("1.0")
)
def dictGetType_check(self, privilege, grant_target_name, user_name, type, node=None):
def dictGetType_check(self, privilege, on, grant_target_name, user_name, type, node=None):
"""Check that user is able to execute `dictGet` if and only if they have the necessary privileges.
"""
if node is None:
node = self.context.node
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
on = on.replace("dict", f"{dict_name}")
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege"):
with dict_setup(node, table_name, dict_name, type):
with When("I attempt to dictGet without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to dictGet without privilege"):
node.query(f"SELECT dictGet{type}({dict_name},'z',toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with Scenario("user with privilege"):
with dict_setup(node, table_name, dict_name, type):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with Then("I attempt to dictGet with privilege"):
node.query(f"SELECT dictGet{type}({dict_name},'z',toUInt64(1))", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
dict_name = f"dict_{getuid()}"
with Scenario("user with revoked privilege"):
with dict_setup(node, table_name, dict_name, type):
with When("I grant privilege"):
node.query(f"GRANT {privilege} ON {dict_name} TO {grant_target_name}")
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
with And("I revoke privilege"):
node.query(f"REVOKE {privilege} ON {dict_name} FROM {grant_target_name}")
node.query(f"REVOKE {privilege} ON {on} FROM {grant_target_name}")
with When("I attempt to dictGet without privilege"):
node.query(f"SELECT dictGet{type}({dict_name},'z',toUInt64(1))", settings = [("user", user_name)], exitcode=exitcode, message=message)
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_dictGet_Privilege("1.0")
RQ_SRS_006_RBAC_dictGet_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("dictGet")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -622,23 +666,23 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
tasks = []
try:
run_scenario(pool, tasks, Suite(test=dictGet_granted_directly))
run_scenario(pool, tasks, Suite(test=dictGet_granted_via_role))
run_scenario(pool, tasks, Suite(test=dictGetOrDefault_granted_directly))
run_scenario(pool, tasks, Suite(test=dictGetOrDefault_granted_via_role))
run_scenario(pool, tasks, Suite(test=dictHas_granted_directly))
run_scenario(pool, tasks, Suite(test=dictHas_granted_via_role))
run_scenario(pool, tasks, Suite(test=dictGetHierarchy_granted_directly))
run_scenario(pool, tasks, Suite(test=dictGetHierarchy_granted_via_role))
run_scenario(pool, tasks, Suite(test=dictIsIn_granted_directly))
run_scenario(pool, tasks, Suite(test=dictIsIn_granted_via_role))
run_scenario(pool, tasks, Suite(test=dictGet_granted_directly, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictGet_granted_via_role, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictGetOrDefault_granted_directly, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictGetOrDefault_granted_via_role, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictHas_granted_directly, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictHas_granted_via_role, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictGetHierarchy_granted_directly, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictGetHierarchy_granted_via_role, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictIsIn_granted_directly, setup=instrument_clickhouse_server_log))
run_scenario(pool, tasks, Suite(test=dictIsIn_granted_via_role, setup=instrument_clickhouse_server_log))
for example in dictGetType_granted_directly.examples:
type, = example
with Example(example):
run_scenario(pool, tasks, Suite(test=dictGetType_granted_directly),{"type" : type})
run_scenario(pool, tasks, Suite(test=dictGetType_granted_via_role),{"type" : type})
run_scenario(pool, tasks, Suite(test=dictGetType_granted_directly, setup=instrument_clickhouse_server_log),{"type" : type})
run_scenario(pool, tasks, Suite(test=dictGetType_granted_via_role, setup=instrument_clickhouse_server_log),{"type" : type})
finally:
join(tasks)

View File

@ -69,6 +69,7 @@ def create(self):
create_scenarios=[
create_without_privilege,
create_with_privilege_granted_directly_or_via_role,
create_with_all_privilege_granted_directly_or_via_role,
]
for scenario in create_scenarios:
@ -79,18 +80,30 @@ def create_without_privilege(self, node=None):
"""Check that user is unable to create a distributed table without privileges.
"""
user_name = f"user_{getuid()}"
table0_name = f"table0_{getuid()}"
table1_name = f"table1_{getuid()}"
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
cluster = self.context.cluster_name
if node is None:
node = self.context.node
with Given("I have a user"):
user(name=user_name)
with And("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with When("I attempt to create the distributed table without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I attempt to create the distributed table without privilege"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed(sharded_cluster, default, {table0_name}, rand())", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
@ -101,20 +114,25 @@ def create_with_privilege_granted_directly_or_via_role(self, node=None):
"""
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
if node is None:
node = self.context.node
with Given("I have a user"):
user(name=user_name)
Scenario(test=create_with_privilege,
name="create with privilege granted directly")(grant_target_name=user_name, user_name=user_name)
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
Scenario(test=create_with_privilege,
name="create with privilege granted through a role")(grant_target_name=role_name, user_name=user_name)
@ -138,20 +156,24 @@ def create_with_privilege(self, user_name, grant_target_name, node=None):
with When("I grant create table privilege"):
node.query(f"GRANT CREATE ON {table1_name} TO {grant_target_name}")
with Then("I attempt to create the distributed table as the user"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke the create table privilege"):
node.query(f"REVOKE CREATE TABLE ON {table1_name} FROM {grant_target_name}")
with And("I grant remote privilege"):
node.query(f"GRANT REMOTE ON *.* to {grant_target_name}")
with Then("I attempt to create the distributed table as the user"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant create table privilege"):
node.query(f"GRANT CREATE ON {table1_name} TO {grant_target_name}")
with Then("I attempt to create the distributed table as the user"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())", settings = [("user", f"{user_name}")])
@ -159,6 +181,62 @@ def create_with_privilege(self, user_name, grant_target_name, node=None):
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
@TestScenario
def create_with_all_privilege_granted_directly_or_via_role(self, node=None):
"""Check that user is able to create a distributed table if and only if
they have ALL privilege granted either directly or through a role.
"""
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
if node is None:
node = self.context.node
with Given("I have a user"):
user(name=user_name)
Scenario(test=create_with_privilege,
name="create with privilege granted directly")(grant_target_name=user_name, user_name=user_name)
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
Scenario(test=create_with_privilege,
name="create with privilege granted through a role")(grant_target_name=role_name, user_name=user_name)
@TestOutline
def create_with_privilege(self, user_name, grant_target_name, node=None):
"""Grant ALL privilege and check the user is able is create the table.
"""
table0_name = f"table0_{getuid()}"
table1_name = f"table1_{getuid()}"
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
cluster = self.context.cluster_name
if node is None:
node = self.context.node
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I create the distributed table as the user"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
@TestSuite
@Requirements(
RQ_SRS_006_RBAC_DistributedTable_Select("1.0"),
@ -169,6 +247,7 @@ def select(self):
select_scenarios = [
select_without_privilege,
select_with_privilege_granted_directly_or_via_role,
select_with_all_privilege_granted_directly_or_via_role
]
for scenario in select_scenarios:
@ -191,11 +270,19 @@ def select_without_privilege(self, node=None):
try:
with Given("I have a user"):
user(name=user_name)
with And("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
@ -222,8 +309,10 @@ def select_with_privilege_granted_directly_or_via_role(self, node=None):
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -247,25 +336,89 @@ def select_with_privilege(self, user_name, grant_target_name, node=None):
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke select privilege on the distributed table"):
node.query(f"REVOKE SELECT ON {table1_name} FROM {grant_target_name}")
with And("I grant select privilege on the table used by the distributed table"):
node.query(f"GRANT SELECT ON {table0_name} to {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant the user select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
@TestScenario
def select_with_all_privilege_granted_directly_or_via_role(self, node=None):
"""Check that user is able to select from a distributed table if and only if
they have ALL privilege.
"""
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
if node is None:
node = self.context.node
with Given("I have a user"):
user(name=user_name)
Scenario(test=select_with_privilege,
name="select with privilege granted directly")(grant_target_name=user_name, user_name=user_name)
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
Scenario(test=select_with_privilege,
name="select with privilege granted through a role")(grant_target_name=role_name, user_name=user_name)
@TestOutline
def select_with_privilege(self, user_name, grant_target_name, node=None):
"""Grant ALL and check the user is able to select from the distributed table.
"""
table0_name = f"table0_{getuid()}"
table1_name = f"table1_{getuid()}"
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
cluster = self.context.cluster_name
if node is None:
node = self.context.node
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
@ -293,10 +446,12 @@ def insert_without_privilege(self, node=None):
"""Check that user is unable to insert into a distributed table without privileges.
"""
user_name = f"user_{getuid()}"
table0_name = f"table0_{getuid()}"
table1_name = f"table1_{getuid()}"
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
cluster = self.context.cluster_name
if node is None:
@ -305,11 +460,19 @@ def insert_without_privilege(self, node=None):
try:
with Given("I have a user"):
user(name=user_name)
with And("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
@ -336,8 +499,10 @@ def insert_with_privilege_granted_directly_or_via_role(self, node=None):
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -361,25 +526,43 @@ def insert_with_privilege(self, user_name, grant_target_name, node=None):
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant insert privilege on the distributed table"):
node.query(f"GRANT INSERT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke the insert privilege on the distributed table"):
node.query(f"REVOKE INSERT ON {table1_name} FROM {grant_target_name}")
with And("I grant insert privilege on the table used by the distributed table"):
node.query(f"GRANT INSERT ON {table0_name} to {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant insert privilege on the distributed table"):
node.query(f"GRANT INSERT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")])
@ -426,8 +609,10 @@ def select_with_table_on_materialized_view_privilege_granted_directly_or_via_rol
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -452,33 +637,63 @@ def select_with_table_on_materialized_view(self, user_name, grant_target_name, n
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a materialized view on a cluster"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ON CLUSTER {cluster} ENGINE = Memory() AS SELECT * FROM {table0_name}")
with And("I have a distributed table on the materialized view"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {view_name}, rand())")
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke the select privilege on the distributed table"):
node.query(f"REVOKE SELECT ON {table1_name} FROM {grant_target_name}")
with And("I grant select privilege on the materialized view"):
node.query(f"GRANT SELECT ON {view_name} to {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
with And("I drop the view"):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@ -501,8 +716,10 @@ def select_with_table_on_source_table_of_materialized_view_privilege_granted_dir
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -527,33 +744,53 @@ def select_with_table_on_source_table_of_materialized_view(self, user_name, gran
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a materialized view on a cluster"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ON CLUSTER {cluster} ENGINE = Memory() AS SELECT * FROM {table0_name}")
with And("I have a distributed table using the source table of the materialized view"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke select privilege on the distributed table"):
node.query(f"REVOKE SELECT ON {table1_name} FROM {grant_target_name}")
with And("I grant select privilege on the source table"):
node.query(f"GRANT SELECT ON {table0_name} to {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
with And("I drop the view"):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@ -576,8 +813,10 @@ def select_with_table_on_distributed_table_privilege_granted_directly_or_via_rol
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -602,26 +841,47 @@ def select_with_table_on_distributed_table(self, user_name, grant_target_name, n
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table on a cluster"):
node.query(f"CREATE TABLE {table1_name} ON CLUSTER {cluster} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with And("I have a distributed table on that distributed table"):
node.query(f"CREATE TABLE {table2_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table1_name}, rand())")
for permutation in permutations(table_count=3):
with grant_select_on_table(node, permutation, grant_target_name, table0_name, table1_name, table2_name) as tables_granted:
with When(f"permutation={permutation}, tables granted = {tables_granted}"):
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table2_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant select on all tables"):
with grant_select_on_table(node, max(permutations(table_count=3))+1, grant_target_name, table0_name, table1_name, table2_name):
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table2_name}", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table2_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt to select from the distributed table as the user"):
node.query(f"SELECT * FROM {table2_name}", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the first distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
with And("I drop the other distributed table"):
node.query(f"DROP TABLE IF EXISTS {table2_name}")
@ -644,8 +904,10 @@ def insert_with_table_on_materialized_view_privilege_granted_directly_or_via_rol
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -671,35 +933,56 @@ def insert_with_table_on_materialized_view(self, user_name, grant_target_name, n
try:
with Given(f"I have a table on cluster {cluster}"):
table(name=table0_name, cluster=cluster)
with And("I have another table on the same cluster"):
table(name=table1_name, cluster=cluster)
with And("I have a materialized view on a cluster"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ON CLUSTER {cluster} TO {table0_name} AS SELECT * FROM {table1_name}")
with And("I have a distributed table on the materialized view"):
node.query(f"CREATE TABLE {table2_name} (a UInt64) ENGINE = Distributed({cluster}, default, {view_name}, rand())")
with When("I grant insert privilege on the distributed table"):
node.query(f"GRANT INSERT ON {table2_name} TO {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke the insert privilege on the distributed table"):
node.query(f"REVOKE INSERT ON {table2_name} FROM {grant_target_name}")
with And("I grant insert privilege on the view"):
node.query(f"GRANT INSERT ON {view_name} to {grant_target_name}")
with Then("I attempt insert into the distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant insert privilege on the distributed table"):
node.query(f"GRANT INSERT ON {table2_name} TO {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt insert into the distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table2_name}")
with And("I drop the view"):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@ -722,8 +1005,10 @@ def insert_with_table_on_source_table_of_materialized_view_privilege_granted_dir
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -748,33 +1033,53 @@ def insert_with_table_on_source_table_of_materialized_view(self, user_name, gran
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a materialized view on a cluster"):
node.query(f"CREATE MATERIALIZED VIEW {view_name} ON CLUSTER {cluster} ENGINE = Memory() AS SELECT * FROM {table0_name}")
with And("I have a distributed table on the materialized view"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant insert privilege on the distributed table"):
node.query(f"GRANT INSERT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke insert privilege on the distributed table"):
node.query(f"REVOKE INSERT ON {table1_name} FROM {grant_target_name}")
with And("I grant insert privilege on the source table"):
node.query(f"GRANT INSERT ON {table0_name} to {grant_target_name}")
with Then("I attempt insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant insert privilege on the distributed table"):
node.query(f"GRANT INSERT ON {table1_name} TO {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt to insert into the distributed table as the user"):
node.query(f"INSERT INTO {table1_name} VALUES (8888)", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
with And("I drop the view"):
node.query(f"DROP VIEW IF EXISTS {view_name}")
@ -797,8 +1102,10 @@ def insert_with_table_on_distributed_table_privilege_granted_directly_or_via_rol
with Given("I have a user"):
user(name=user_name)
with And("I have a role"):
role(name=role_name)
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name} ON CLUSTER one_shard_cluster")
@ -823,47 +1130,70 @@ def insert_with_table_on_distributed_table(self, user_name, grant_target_name, n
try:
with Given("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table on a cluster"):
node.query(f"CREATE TABLE {table1_name} ON CLUSTER {cluster} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with And("I have a distributed table on that distributed table"):
node.query(f"CREATE TABLE {table2_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table1_name}, rand())")
with When("I grant insert privilege on the outer distributed table"):
node.query(f"GRANT INSERT ON {table2_name} TO {grant_target_name}")
with Then("I attempt to insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke the insert privilege on the outer distributed table"):
node.query(f"REVOKE INSERT ON {table2_name} FROM {grant_target_name}")
with And("I grant insert privilege on the inner distributed table"):
node.query(f"GRANT INSERT ON {table1_name} to {grant_target_name}")
with Then("I attempt insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I revoke the insert privilege on the inner distributed table"):
node.query(f"REVOKE INSERT ON {table1_name} FROM {grant_target_name}")
with And("I grant insert privilege on the innermost table"):
node.query(f"GRANT INSERT ON {table0_name} to {grant_target_name}")
with Then("I attempt insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant insert privilege on the inner distributed table"):
node.query(f"GRANT INSERT ON {table1_name} to {grant_target_name}")
with Then("I attempt insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant insert privilege on the outer distributed table"):
node.query(f"GRANT INSERT ON {table2_name} to {grant_target_name}")
with Then("I attempt insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {grant_target_name}")
with Then("I attempt insert into the outer distributed table as the user"):
node.query(f"INSERT INTO {table2_name} VALUES (8888)", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the outer distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
with And("I drop the inner distributed table"):
node.query(f"DROP TABLE IF EXISTS {table2_name}")
@ -882,6 +1212,7 @@ def local_user(self, cluster, node=None):
is able to execute queries they have privileges to.
"""
user_name = f"user_{getuid()}"
table0_name = f"table0_{getuid()}"
table1_name = f"table1_{getuid()}"
@ -891,22 +1222,35 @@ def local_user(self, cluster, node=None):
try:
with Given("I have a user on one node"):
node.query(f"CREATE USER {user_name}")
with And("I have a table on a cluster"):
table(name=table0_name, cluster=cluster)
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} (a UInt64) ENGINE = Distributed({cluster}, default, {table0_name}, rand())")
with When("I grant select privilege on the distributed table"):
node.query(f"GRANT SELECT ON {table1_name} TO {user_name}")
with And("I grant select privilege on the other table"):
node.query(f"GRANT SELECT ON {table0_name} TO {user_name}")
with Then("I select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
with When("I revoke ALL privileges"):
node.query(f"REVOKE ALL ON *.* FROM {user_name}")
with And("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* To {user_name}")
with Then("I select from the distributed table as the user"):
node.query(f"SELECT * FROM {table1_name}", settings = [("user", f"{user_name}")])
finally:
with Finally("I drop the user"):
node.query(f"DROP USER IF EXISTS {user_name}")
with And("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
@ -919,8 +1263,10 @@ def multiple_node_user(self, node=None):
if and only if they have the required privileges on the node they are executing the query from.
"""
user_name = f"user_{getuid()}"
table0_name = f"table0_{getuid()}"
table1_name = f"table1_{getuid()}"
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
if node is None:
@ -931,13 +1277,16 @@ def multiple_node_user(self, node=None):
try:
with Given("I have a user on a cluster with two nodes"):
node.query(f"CREATE USER {user_name} ON CLUSTER sharded_cluster12")
with And("I have a table on a cluster"):
table(name=table0_name, cluster="sharded_cluster12")
with And("I have a distributed table"):
node.query(f"CREATE TABLE {table1_name} ON CLUSTER sharded_cluster12 (a UInt64) ENGINE = Distributed(sharded_cluster12, default, {table0_name}, rand())")
with When("I grant select privilege on the distributed table on one node"):
node.query(f"GRANT SELECT ON {table1_name} TO {user_name}")
with And("I grant select privilege on the other table on one node"):
node.query(f"GRANT SELECT ON {table0_name} TO {user_name}")
@ -951,6 +1300,7 @@ def multiple_node_user(self, node=None):
finally:
with Finally("I drop the user"):
node.query(f"DROP USER IF EXISTS {user_name}")
with And("I drop the distributed table"):
node.query(f"DROP TABLE IF EXISTS {table1_name}")
@ -972,14 +1322,20 @@ def cluster_tests(self, cluster, node=None):
tasks = []
pool = Pool(3)
try:
try:
for suite in loads(current_module(), Suite):
run_scenario(pool, tasks, Suite(test=suite))
finally:
join(tasks)
finally:
pool.close()
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("distributed table")
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of queries executed using distributed tables.
@ -991,6 +1347,7 @@ def feature(self, node="clickhouse1"):
tasks = []
pool = Pool(3)
try:
try:
run_scenario(pool, tasks, Feature(test=cluster_tests))
run_scenario(pool, tasks, Scenario(test=local_user))
@ -998,3 +1355,6 @@ def feature(self, node="clickhouse1"):
finally:
join(tasks)
finally:
pool.close()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DROP DATABASE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,21 +32,27 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
db_name = f"db_{getuid()}"
try:
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with When("I attempt to drop the database"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to drop the database"):
node.query(f"DROP DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
db_name = f"db_{getuid()}"
try:
@ -63,7 +69,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
db_name = f"db_{getuid()}"
try:
@ -84,9 +90,49 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with revoked ALL privilege"):
db_name = f"db_{getuid()}"
try:
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with When("I grant the drop database privilege"):
node.query(f"GRANT DROP DATABASE ON {db_name}.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to drop a database"):
node.query(f"DROP DATABASE {db_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
with Scenario("user with ALL privilege"):
db_name = f"db_{getuid()}"
try:
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to drop a database"):
node.query(f"DROP DATABASE {db_name}", settings = [("user", user_name)])
finally:
with Finally("I drop the database"):
node.query(f"DROP DATABASE IF EXISTS {db_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropDatabase("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("drop database")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -99,5 +145,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,12 +12,12 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DROP DICTIONARY with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
@ -29,21 +29,27 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
dict_name = f"dict_{getuid()}"
try:
with Given("I have a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with When("I attempt to drop a dictionary without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to drop a dictionary without privilege"):
node.query(f"DROP DICTIONARY {dict_name}", settings = [("user", user_name)], exitcode=exitcode, message=message)
finally:
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -60,7 +66,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
dict_name = f"dict_{getuid()}"
try:
@ -80,9 +86,27 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
with Scenario("user with ALL privilege"):
dict_name = f"db_{getuid()}"
try:
with Given("I have a dictionary"):
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I drop the dictionary"):
node.query(f"DROP DICTIONARY {dict_name}", settings = [("user", user_name)])
finally:
with Finally("I drop the dictionary"):
node.query(f"DROP DICTIONARY IF EXISTS {dict_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropDictionary("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("drop dictionary")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -95,5 +119,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=drop_quota, flags=TE,
Suite(run=drop_quota,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in drop_quota.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=drop_quota, flags=TE,
Suite(run=drop_quota,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in drop_quota.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("DROP QUOTA",),
])
@ -63,7 +64,13 @@ def drop_quota(self, privilege, grant_target_name, user_name, node=None):
with Given("I have a quota"):
node.query(f"CREATE QUOTA {drop_row_policy_name}")
with When("I check the user can't drop a quota"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't drop a quota"):
node.query(f"DROP QUOTA {drop_row_policy_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -129,6 +136,8 @@ def drop_quota(self, privilege, grant_target_name, user_name, node=None):
@Name("drop quota")
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropQuota("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of DROP QUOTA.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=drop_role, flags=TE,
Suite(run=drop_role,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in drop_role.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=drop_role, flags=TE,
Suite(run=drop_role,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in drop_role.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("DROP ROLE",),
])
@ -58,14 +59,22 @@ def drop_role(self, privilege, grant_target_name, user_name, node=None):
with Scenario("DROP ROLE without privilege"):
drop_role_name = f"drop_role_{getuid()}"
with role(node, drop_role_name):
with When("I check the user can't drop a role"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't drop a role"):
node.query(f"DROP ROLE {drop_role_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("DROP ROLE with privilege"):
drop_role_name = f"drop_role_{getuid()}"
with role(node, drop_role_name):
with When(f"I grant {privilege}"):
@ -93,6 +102,7 @@ def drop_role(self, privilege, grant_target_name, user_name, node=None):
with Scenario("DROP ROLE with revoked privilege"):
drop_role_name = f"drop_role_{getuid()}"
with role(node, drop_role_name):
with When(f"I grant {privilege}"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -108,6 +118,8 @@ def drop_role(self, privilege, grant_target_name, user_name, node=None):
@Name("drop role")
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropRole("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of DROP ROLE.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=drop_row_policy, flags=TE,
Suite(run=drop_row_policy,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in drop_row_policy.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=drop_row_policy, flags=TE,
Suite(run=drop_row_policy,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in drop_row_policy.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("DROP ROW POLICY",),
("DROP POLICY",),
@ -65,7 +66,13 @@ def drop_row_policy(self, privilege, grant_target_name, user_name, node=None):
with Given("I have a row policy"):
node.query(f"CREATE ROW POLICY {drop_row_policy_name} ON {table_name}")
with When("I check the user can't drop a row policy"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't drop a row policy"):
node.query(f"DROP ROW POLICY {drop_row_policy_name} ON {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -130,15 +137,140 @@ def drop_row_policy(self, privilege, grant_target_name, user_name, node=None):
with Finally("I drop the row policy"):
node.query(f"DROP ROW POLICY IF EXISTS {drop_row_policy_name} ON {table_name}")
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Restriction("1.0")
)
def drop_all_pol_with_conditions(self, node=None):
"""Check that when all policies with conditions are dropped, the table becomes unrestricted.
"""
if node is None:
node = self.context.node
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
with table(node, table_name):
with Given("I have a row policy"):
row_policy(name=pol_name, table=table_name)
with And("The row policy has a condition"):
node.query(f"ALTER ROW POLICY {pol_name} ON {table_name} FOR SELECT USING 1")
with And("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with And("I can't see any of the rows on the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '' == output, error()
with When("I drop the row policy"):
node.query(f"DROP ROW POLICY {pol_name} ON {table_name}")
with Then("I select all the rows from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output and '2' in output, error()
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
)
def drop_on(self, node=None):
"""Check that when a row policy is dropped, users are able to access rows restricted by that policy.
"""
if node is None:
node = self.context.node
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
with table(node, table_name):
with Given("I have a row policy"):
row_policy(name=pol_name, table=table_name)
with And("The row policy has a condition"):
node.query(f"ALTER ROW POLICY {pol_name} ON {table_name} FOR SELECT USING y=1 TO default")
with And("The table has some values"):
node.query(f"INSERT INTO {table_name} (y) VALUES (1),(2)")
with And("I can't see one of the rows on the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output and '2' not in output, error()
with When("I drop the row policy"):
node.query(f"DROP ROW POLICY {pol_name} ON {table_name}")
with Then("I select all the rows from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output and '2' in output, error()
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
)
def drop_on_cluster(self, node=None):
"""Check that when a row policy is dropped on a cluster, it works on all nodes.
"""
if node is None:
node = self.context.node
node2 = self.context.node2
table_name = f"table_{getuid()}"
pol_name = f"pol_{getuid()}"
try:
with Given("I have a table on a cluster"):
node.query(f"CREATE TABLE {table_name} ON CLUSTER sharded_cluster (x UInt64) ENGINE = Memory")
with And("I have a row policy"):
node.query(f"CREATE ROW POLICY {pol_name} ON CLUSTER sharded_cluster ON {table_name} FOR SELECT USING 1")
with And("There are some values on the table on the first node"):
node.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with And("There are some values on the table on the second node"):
node2.query(f"INSERT INTO {table_name} (x) VALUES (1)")
with When("I drop the row policy on cluster"):
node.query(f"DROP ROW POLICY {pol_name} ON {table_name} ON CLUSTER sharded_cluster")
with Then("I select from the table"):
output = node.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
with And("I select from another node on the cluster"):
output = node2.query(f"SELECT * FROM {table_name}").output
assert '1' in output, error()
finally:
with Finally("I drop the row policy", flags=TE):
node.query(f"DROP ROW POLICY IF EXISTS {pol_name} ON CLUSTER sharded_cluster ON {table_name}")
with And("I drop the table", flags=TE):
node.query(f"DROP TABLE {table_name} ON CLUSTER sharded_cluster")
@TestFeature
@Name("drop row policy")
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropRowPolicy("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of DROP ROW POLICY.
"""
self.context.node = self.context.cluster.node(node)
self.context.node2 = self.context.cluster.node("clickhouse2")
Suite(run=privileges_granted_directly, setup=instrument_clickhouse_server_log)
Suite(run=privileges_granted_via_role, setup=instrument_clickhouse_server_log)
Scenario(run=drop_all_pol_with_conditions, setup=instrument_clickhouse_server_log)
Scenario(run=drop_on, setup=instrument_clickhouse_server_log)
Scenario(run=drop_on_cluster, setup=instrument_clickhouse_server_log)

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=drop_settings_profile, flags=TE,
Suite(run=drop_settings_profile,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in drop_settings_profile.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=drop_settings_profile, flags=TE,
Suite(run=drop_settings_profile,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in drop_settings_profile.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("DROP SETTINGS PROFILE",),
("DROP PROFILE",),
@ -64,7 +65,13 @@ def drop_settings_profile(self, privilege, grant_target_name, user_name, node=No
with Given("I have a settings_profile"):
node.query(f"CREATE SETTINGS PROFILE {drop_row_policy_name}")
with When("I check the user can't drop a settings_profile"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't drop a settings_profile"):
node.query(f"DROP SETTINGS PROFILE {drop_row_policy_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -130,6 +137,8 @@ def drop_settings_profile(self, privilege, grant_target_name, user_name, node=No
@Name("drop settings profile")
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropSettingsProfile("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of DROP SETTINGS PROFILE.

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute DROP TABLE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,14 +32,20 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE=Memory")
with When("I attempt to drop a table without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to drop a table without privilege"):
node.query(f"DROP TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
@ -47,7 +53,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
table_name = f"table_{getuid()}"
try:
@ -64,7 +70,7 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
@ -84,9 +90,48 @@ def privilege_check(grant_target_name, user_name, node=None):
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with revoked ALL privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE=Memory")
with When("I grant the drop table privilege"):
node.query(f"GRANT DROP TABLE ON *.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to drop a table"):
node.query(f"DROP TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
finally:
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
with Scenario("user with ALL privilege"):
table_name = f"table_{getuid()}"
try:
with Given("I have a table"):
node.query(f"CREATE TABLE {table_name} (x Int8) ENGINE=Memory")
with When("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I drop the table"):
node.query(f"DROP TABLE {table_name}", settings = [("user", user_name)])
finally:
with Finally("I drop the table"):
node.query(f"DROP TABLE IF EXISTS {table_name}")
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropTable("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("drop table")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -99,5 +144,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -17,7 +17,7 @@ def drop_user_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=drop_user, flags=TE,
Suite(run=drop_user,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in drop_user.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def drop_user_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=drop_user, flags=TE,
Suite(run=drop_user,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in drop_user.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("DROP USER",),
])
@ -59,14 +60,22 @@ def drop_user(self, privilege, grant_target_name, user_name, node=None):
with Scenario("DROP USER without privilege"):
drop_user_name = f"drop_user_{getuid()}"
with user(node, drop_user_name):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with When("I check the user can't drop a user"):
node.query(f"DROP USER {drop_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("DROP USER with privilege"):
drop_user_name = f"drop_user_{getuid()}"
with user(node, drop_user_name):
with When(f"I grant {privilege}"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -76,6 +85,7 @@ def drop_user(self, privilege, grant_target_name, user_name, node=None):
with Scenario("DROP USER on cluster"):
drop_user_name = f"drop_user_{getuid()}"
try:
with Given("I have a user on a cluster"):
node.query(f"CREATE USER {drop_user_name} ON CLUSTER sharded_cluster")
@ -93,6 +103,7 @@ def drop_user(self, privilege, grant_target_name, user_name, node=None):
with Scenario("DROP USER with revoked privilege"):
drop_user_name = f"drop_user_{getuid()}"
with user(node, drop_user_name):
with When(f"I grant {privilege}"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -108,6 +119,8 @@ def drop_user(self, privilege, grant_target_name, user_name, node=None):
@Name("drop user")
@Requirements(
RQ_SRS_006_RBAC_Privileges_DropUser("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of DROP USER.

View File

@ -11,91 +11,92 @@ def feature(self):
try:
try:
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.insert", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.select", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.public_tables", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.distributed_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.grant_option", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.truncate", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.optimize", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.kill_query", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.kill_mutation", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.role_admin", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.dictGet", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.introspection", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.sources", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.admin_option", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.insert", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.select", "feature"), ), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.public_tables", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.distributed_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.grant_option", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.truncate", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.optimize", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.kill_query", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.kill_mutation", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.role_admin", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.dictGet", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.introspection", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.sources", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.admin_option", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.all_role", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_tables", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_dictionaries", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_databases", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_columns", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_users", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_roles", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_quotas", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_settings_profiles", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_row_policies", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_tables", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_dictionaries", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_databases", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_columns", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_users", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_roles", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_quotas", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_settings_profiles", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.show.show_row_policies", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_column", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_index", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_constraint", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_ttl", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_settings", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_update", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_delete", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_freeze", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_fetch", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_move", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_user", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_role", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_row_policy", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_quota", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_settings_profile", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_column", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_index", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_constraint", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_ttl", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_settings", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_update", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_delete", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_freeze", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_fetch", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_move", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_user", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_role", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_row_policy", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_quota", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.alter.alter_settings_profile", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_database", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_dictionary", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_temp_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_user", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_role", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_row_policy", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_quota", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_settings_profile", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_database", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_dictionary", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_temp_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_user", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_role", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_row_policy", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_quota", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.create.create_settings_profile", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_database", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_dictionary", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_temp_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_database", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_dictionary", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_temp_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.attach.attach_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_database", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_dictionary", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_user", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_role", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_row_policy", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_quota", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_settings_profile", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_database", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_dictionary", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_user", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_role", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_row_policy", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_quota", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.drop.drop_settings_profile", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_database", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_dictionary", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_table", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_view", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_database", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_dictionary", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_table", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.detach.detach_view", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.drop_cache", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.reload", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.flush", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.merges", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.moves", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.replication_queues", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.ttl_merges", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.restart_replica", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.sends", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.sync_replica", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.fetches", "feature"), flags=TE), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.drop_cache", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.reload", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.flush", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.merges", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.moves", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.replication_queues", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.ttl_merges", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.restart_replica", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.sends", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.sync_replica", "feature")), {})
run_scenario(pool, tasks, Feature(test=load("rbac.tests.privileges.system.fetches", "feature")), {})
finally:
join(tasks)
finally:
pool.close()
Feature(test=load("rbac.tests.privileges.system.shutdown", "feature"), flags=TE)
Feature(test=load("rbac.tests.privileges.system.shutdown", "feature"))

View File

@ -16,6 +16,9 @@ def input_output_equality_check(node, input_columns, input_data, table_name):
return input_dict == output_dict
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def without_privilege(self, table_type, node=None):
"""Check that user without insert privilege on a table is not able to insert on that table.
"""
@ -28,7 +31,13 @@ def without_privilege(self, table_type, node=None):
with table(node, table_name, table_type):
with user(node, user_name):
with When("I run INSERT without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I run INSERT without privilege"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings = [("user", user_name)],
@ -60,6 +69,34 @@ def user_with_privilege(self, table_type, node=None):
output = node.query(f"SELECT d FROM {table_name} FORMAT JSONEachRow").output
assert output == '{"d":"2020-01-01"}', error()
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Grant_Privilege_Insert("1.0"),
)
def all_privilege(self, table_type, node=None):
"""Check that user can insert into a table on which they have insert privilege.
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name):
with When("I grant insert privilege"):
node.query(f"GRANT ALL ON *.* TO {user_name}")
with And("I use INSERT"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)])
with Then("I check the insert functioned"):
output = node.query(f"SELECT d FROM {table_name} FORMAT JSONEachRow").output
assert output == '{"d":"2020-01-01"}', error()
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Revoke_Privilege_Insert("1.0"),
@ -82,7 +119,31 @@ def user_with_revoked_privilege(self, table_type, node=None):
with And("I revoke insert privilege"):
node.query(f"REVOKE INSERT ON {table_name} FROM {user_name}")
with And("I use INSERT"):
with Then("I use INSERT"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')",
settings=[("user",user_name)], exitcode=exitcode, message=message)
@TestScenario
def user_with_all_revoked_privilege(self, table_type, node=None):
"""Check that user is unable to insert into a table after ALL privilege has been revoked from user.
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name):
with When("I grant insert privilege"):
node.query(f"GRANT INSERT ON {table_name} TO {user_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {user_name}")
with Then("I use INSERT"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')",
settings=[("user",user_name)], exitcode=exitcode, message=message)
@ -111,26 +172,36 @@ def user_column_privileges(self, grant_columns, insert_columns_pass, data_fail,
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name):
with When("I grant insert privilege"):
node.query(f"GRANT INSERT({grant_columns}) ON {table_name} TO {user_name}")
if insert_columns_fail is not None:
with And("I insert into a column without insert privilege"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} ({insert_columns_fail}) VALUES ({data_fail})",
settings=[("user",user_name)], exitcode=exitcode, message=message)
with And("I insert into granted column"):
node.query(f"INSERT INTO {table_name} ({insert_columns_pass}) VALUES ({data_pass})",
settings=[("user",user_name)])
with Then("I check the insert functioned"):
input_equals_output = input_output_equality_check(node, insert_columns_pass, data_pass, table_name)
assert input_equals_output, error()
if revoke_columns is not None:
with When("I revoke insert privilege from columns"):
node.query(f"REVOKE INSERT({revoke_columns}) ON {table_name} FROM {user_name}")
with And("I insert into revoked columns"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} ({insert_columns_pass}) VALUES ({data_pass})",
@ -147,16 +218,23 @@ def role_with_privilege(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name), role(node, role_name):
with When("I grant insert privilege to a role"):
node.query(f"GRANT INSERT ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And("I insert into the table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)])
with Then("I check the data matches the input"):
output = node.query(f"SELECT d FROM {table_name} FORMAT JSONEachRow").output
assert output == '{"d":"2020-01-01"}', error()
@ -173,16 +251,23 @@ def role_with_revoked_privilege(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name), role(node, role_name):
with When("I grant privilege to a role"):
node.query(f"GRANT INSERT ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And("I revoke privilege from the role"):
node.query(f"REVOKE INSERT ON {table_name} FROM {role_name}")
with And("I insert into the table"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')",
@ -196,16 +281,23 @@ def user_with_revoked_role(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name), role(node, role_name):
with When("I grant privilege to a role"):
node.query(f"GRANT INSERT ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And("I revoke the role from the user"):
node.query(f"REVOKE {role_name} FROM {user_name}")
with And("I insert into the table"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')",
@ -235,30 +327,41 @@ def role_column_privileges(self, grant_columns, insert_columns_pass, data_fail,
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name), role(node, role_name):
with When("I grant insert privilege"):
node.query(f"GRANT INSERT({grant_columns}) ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
if insert_columns_fail is not None:
with And("I insert into columns without insert privilege"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} ({insert_columns_fail}) VALUES ({data_fail})",
settings=[("user",user_name)], exitcode=exitcode, message=message)
with And("I insert into granted column"):
node.query(f"INSERT INTO {table_name} ({insert_columns_pass}) VALUES ({data_pass})",
settings=[("user",user_name)])
with Then("I check the insert functioned"):
input_equals_output = input_output_equality_check(node, insert_columns_pass, data_pass, table_name)
assert input_equals_output, error()
if revoke_columns is not None:
with When("I revoke insert privilege from columns"):
node.query(f"REVOKE INSERT({revoke_columns}) ON {table_name} FROM {role_name}")
with And("I insert into revoked columns"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} ({insert_columns_pass}) VALUES ({data_pass})",
settings=[("user",user_name)], exitcode=exitcode, message=message)
@ -272,29 +375,40 @@ def user_with_privilege_on_cluster(self, table_type, node=None):
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
try:
with Given("I have a user on a cluster"):
node.query(f"CREATE USER OR REPLACE {user_name} ON CLUSTER sharded_cluster")
with When("I grant insert privilege on a cluster without the node with the table"):
node.query(f"GRANT ON CLUSTER sharded_cluster23 INSERT ON {table_name} TO {user_name}")
with And("I insert into the table expecting a fail"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with And("I grant insert privilege on cluster including all nodes"):
node.query(f"GRANT ON CLUSTER sharded_cluster INSERT ON {table_name} TO {user_name}")
with And("I revoke insert privilege on cluster without the node with the table"):
node.query(f"REVOKE ON CLUSTER sharded_cluster23 INSERT ON {table_name} FROM {user_name}")
with And("I insert into the table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)])
with And("I check that I can read inserted data"):
output = node.query(f"SELECT d FROM {table_name} FORMAT JSONEachRow").output
assert output == '{"d":"2020-01-01"}', error()
with And("I revoke insert privilege on cluster with all nodes"):
node.query(f"REVOKE ON CLUSTER sharded_cluster INSERT ON {table_name} FROM {user_name}")
with Then("I insert into table expecting fail"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)],
@ -314,33 +428,46 @@ def role_with_privilege_on_cluster(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
try:
with Given("I have a user on a cluster"):
node.query(f"CREATE USER OR REPLACE {user_name} ON CLUSTER sharded_cluster")
with And("I have a role on a cluster"):
node.query(f"CREATE ROLE OR REPLACE {role_name} ON CLUSTER sharded_cluster")
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And("I grant insert privilege on a cluster without the node with the table"):
node.query(f"GRANT ON CLUSTER sharded_cluster23 INSERT ON {table_name} TO {role_name}")
with And("I insert into the table expecting a fail"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with And("I grant insert privilege on cluster including all nodes"):
node.query(f"GRANT ON CLUSTER sharded_cluster INSERT ON {table_name} TO {role_name}")
with And("I revoke insert privilege on cluster without the table node"):
node.query(f"REVOKE ON CLUSTER sharded_cluster23 INSERT ON {table_name} FROM {role_name}")
with And("I insert into the table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)])
with And("I check that I can read inserted data"):
output = node.query(f"SELECT d FROM {table_name} FORMAT JSONEachRow").output
assert output == '{"d":"2020-01-01"}', error()
with And("I revoke insert privilege on cluster with all nodes"):
node.query(f"REVOKE ON CLUSTER sharded_cluster INSERT ON {table_name} FROM {role_name}")
with Then("I insert into table expecting fail"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')", settings=[("user",user_name)],
@ -357,7 +484,6 @@ def role_with_privilege_on_cluster(self, table_type, node=None):
@Examples("table_type", [
(key,) for key in table_types.keys()
])
@Flags(TE)
@Name("insert")
def feature(self, table_type, parallel=None, stress=None, node="clickhouse1"):
"""Check the RBAC functionality of INSERT.
@ -376,8 +502,11 @@ def feature(self, table_type, parallel=None, stress=None, node="clickhouse1"):
tasks = []
pool = Pool(10)
try:
try:
for scenario in loads(current_module(), Scenario):
run_scenario(pool, tasks, Scenario(test=scenario, setup=instrument_clickhouse_server_log), {"table_type" : table_type})
finally:
join(tasks)
finally:
pool.close()

View File

@ -35,7 +35,7 @@ def addressToLine_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=addressToLine, flags=TE,
Suite(run=addressToLine,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in addressToLine.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -56,13 +56,14 @@ def addressToLine_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=addressToLine, flags=TE,
Suite(run=addressToLine,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in addressToLine.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("INTROSPECTION",),
("INTROSPECTION FUNCTIONS",),
("addressToLine",),
@ -80,7 +81,13 @@ def addressToLine(self, privilege, grant_target_name, user_name, node=None):
with Scenario("addressToLine without privilege"):
with When("I check the user can't use addressToLine"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use addressToLine"):
node.query(f"WITH addressToLine(toUInt64(dummy)) AS addr SELECT 1 WHERE addr = ''", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -116,7 +123,7 @@ def addressToSymbol_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=addressToSymbol, flags=TE,
Suite(run=addressToSymbol,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in addressToSymbol.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -137,13 +144,14 @@ def addressToSymbol_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=addressToSymbol, flags=TE,
Suite(run=addressToSymbol,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in addressToSymbol.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("INTROSPECTION",),
("INTROSPECTION FUNCTIONS",),
("addressToSymbol",),
@ -161,7 +169,13 @@ def addressToSymbol(self, privilege, grant_target_name, user_name, node=None):
with Scenario("addressToSymbol without privilege"):
with When("I check the user can't use addressToSymbol"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use addressToSymbol"):
node.query(f"WITH addressToSymbol(toUInt64(dummy)) AS addr SELECT 1 WHERE addr = ''", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -197,7 +211,7 @@ def demangle_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=demangle, flags=TE,
Suite(run=demangle,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in demangle.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -218,13 +232,14 @@ def demangle_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=demangle, flags=TE,
Suite(run=demangle,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in demangle.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("INTROSPECTION",),
("INTROSPECTION FUNCTIONS",),
("demangle",),
@ -242,7 +257,13 @@ def demangle(self, privilege, grant_target_name, user_name, node=None):
with Scenario("demangle without privilege"):
with When("I check the user can't use demangle"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use demangle"):
node.query(f"WITH demangle(toString(dummy)) AS addr SELECT 1 WHERE addr = ''", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -270,6 +291,8 @@ def demangle(self, privilege, grant_target_name, user_name, node=None):
@Name("introspection")
@Requirements(
RQ_SRS_006_RBAC_Privileges_Introspection("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of INTROSPECTION.

View File

@ -14,8 +14,16 @@ def no_privilege(self, node=None):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with user(node, user_name):
with When("I attempt to kill mutation on table"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I attempt to kill mutation on table"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
with Scenario("kill mutation on cluster"):
@ -23,8 +31,16 @@ def no_privilege(self, node=None):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with user(node, user_name):
with When("I attempt to kill mutation on cluster"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I attempt to kill mutation on cluster"):
node.query(f"KILL MUTATION ON CLUSTER sharded_cluster WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
@TestSuite
@ -40,9 +56,9 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(test=update, setup=instrument_clickhouse_server_log)(user_name=user_name, grant_target_name=user_name)
Suite(test=delete, setup=instrument_clickhouse_server_log)(user_name=user_name, grant_target_name=user_name)
Suite(test=drop_column, setup=instrument_clickhouse_server_log)(user_name=user_name, grant_target_name=user_name)
Suite(test=update)(user_name=user_name, grant_target_name=user_name)
Suite(test=delete)(user_name=user_name, grant_target_name=user_name)
Suite(test=drop_column)(user_name=user_name, grant_target_name=user_name)
@TestSuite
def privileges_granted_via_role(self, node=None):
@ -61,9 +77,9 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(test=update, setup=instrument_clickhouse_server_log)(user_name=user_name, grant_target_name=role_name)
Suite(test=delete, setup=instrument_clickhouse_server_log)(user_name=user_name, grant_target_name=role_name)
Suite(test=drop_column, setup=instrument_clickhouse_server_log)(user_name=user_name, grant_target_name=role_name)
Suite(test=update)(user_name=user_name, grant_target_name=role_name)
Suite(test=delete)(user_name=user_name, grant_target_name=role_name)
Suite(test=drop_column)(user_name=user_name, grant_target_name=role_name)
@TestSuite
@Requirements(
@ -78,6 +94,9 @@ def update(self, user_name, grant_target_name, node=None):
if node is None:
node = self.context.node
with Given("The user has no privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Scenario("KILL ALTER UPDATE without privilege"):
table_name = f"merge_tree_{getuid()}"
@ -86,7 +105,13 @@ def update(self, user_name, grant_target_name, node=None):
with Given("I have an ALTER UPDATE mutation"):
node.query(f"ALTER TABLE {table_name} UPDATE a = x WHERE 1")
with When("I try to KILL MUTATION"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
@ -101,7 +126,7 @@ def update(self, user_name, grant_target_name, node=None):
with When("I grant the ALTER UPDATE privilege"):
node.query(f"GRANT ALTER UPDATE ON {table_name} TO {grant_target_name}")
with When("I try to KILL MUTATION"):
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
with Scenario("KILL ALTER UPDATE with revoked privilege"):
@ -118,10 +143,42 @@ def update(self, user_name, grant_target_name, node=None):
with And("I revoke the ALTER UPDATE privilege"):
node.query(f"REVOKE ALTER UPDATE ON {table_name} FROM {grant_target_name}")
with When("I try to KILL MUTATION"):
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
with Scenario("KILL ALTER UPDATE with revoked ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with Given("I have an ALTER UPDATE mutation"):
node.query(f"ALTER TABLE {table_name} UPDATE a = x WHERE 1")
with When("I grant the ALTER UPDATE privilege"):
node.query(f"GRANT ALTER UPDATE ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
with Scenario("KILL ALTER UPDATE with ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with Given("I have an ALTER UPDATE mutation"):
node.query(f"ALTER TABLE {table_name} UPDATE a = x WHERE 1")
with When("I grant the ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
@TestSuite
@Requirements(
RQ_SRS_006_RBAC_Privileges_KillMutation_AlterDelete("1.0")
@ -135,6 +192,9 @@ def delete(self, user_name, grant_target_name, node=None):
if node is None:
node = self.context.node
with Given("The user has no privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Scenario("KILL ALTER DELETE without privilege"):
table_name = f"merge_tree_{getuid()}"
@ -143,7 +203,13 @@ def delete(self, user_name, grant_target_name, node=None):
with Given("I have an ALTER DELETE mutation"):
node.query(f"ALTER TABLE {table_name} DELETE WHERE 1")
with When("I try to KILL MUTATION"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
@ -158,7 +224,7 @@ def delete(self, user_name, grant_target_name, node=None):
with When("I grant the ALTER DELETE privilege"):
node.query(f"GRANT ALTER DELETE ON {table_name} TO {grant_target_name}")
with When("I try to KILL MUTATION"):
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
with Scenario("KILL ALTER DELETE with revoked privilege"):
@ -175,10 +241,42 @@ def delete(self, user_name, grant_target_name, node=None):
with And("I revoke the ALTER DELETE privilege"):
node.query(f"REVOKE ALTER DELETE ON {table_name} FROM {grant_target_name}")
with When("I try to KILL MUTATION"):
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
with Scenario("KILL ALTER DELETE with revoked ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with Given("I have an ALTER DELETE mutation"):
node.query(f"ALTER TABLE {table_name} DELETE WHERE 1")
with When("I grant the ALTER DELETE privilege"):
node.query(f"GRANT ALTER DELETE ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
with Scenario("KILL ALTER DELETE with ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with Given("I have an ALTER DELETE mutation"):
node.query(f"ALTER TABLE {table_name} DELETE WHERE 1")
with When("I grant the ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
@TestSuite
@Requirements(
RQ_SRS_006_RBAC_Privileges_KillMutation_AlterDropColumn("1.0")
@ -192,6 +290,9 @@ def drop_column(self, user_name, grant_target_name, node=None):
if node is None:
node = self.context.node
with Given("The user has no privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Scenario("KILL ALTER DROP COLUMN without privilege"):
table_name = f"merge_tree_{getuid()}"
@ -200,7 +301,13 @@ def drop_column(self, user_name, grant_target_name, node=None):
with Given("I have an ALTER DROP COLUMN mutation"):
node.query(f"ALTER TABLE {table_name} DROP COLUMN x")
with When("I try to KILL MUTATION"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
@ -215,7 +322,7 @@ def drop_column(self, user_name, grant_target_name, node=None):
with When("I grant the ALTER DROP COLUMN privilege"):
node.query(f"GRANT ALTER DROP COLUMN ON {table_name} TO {grant_target_name}")
with When("I try to KILL MUTATION"):
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
with Scenario("KILL ALTER DROP COLUMN with revoked privilege"):
@ -232,13 +339,47 @@ def drop_column(self, user_name, grant_target_name, node=None):
with And("I revoke the ALTER DROP COLUMN privilege"):
node.query(f"REVOKE ALTER DROP COLUMN ON {table_name} FROM {grant_target_name}")
with When("I try to KILL MUTATION"):
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
with Scenario("KILL ALTER DROP COLUMN with revoked privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with Given("I have an ALTER DROP COLUMN mutation"):
node.query(f"ALTER TABLE {table_name} DROP COLUMN x")
with When("I grant the ALTER DROP COLUMN privilege"):
node.query(f"GRANT ALTER DROP COLUMN ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)],
exitcode=exitcode, message="Exception: Not allowed to kill mutation.")
with Scenario("KILL ALTER DROP COLUMN with ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name):
with Given("I have an ALTER DROP COLUMN mutation"):
node.query(f"ALTER TABLE {table_name} DROP COLUMN x")
with When("I grant the ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I try to KILL MUTATION"):
node.query(f"KILL MUTATION WHERE database = 'default' AND table = '{table_name}'", settings = [("user", user_name)])
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_KillMutation("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("kill mutation")
def feature(self, node="clickhouse1", stress=None, parallel=None):

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute KILL QUERY with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,20 +32,27 @@ def privilege_check(grant_target_name, user_name, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
with When("I attempt to kill a query without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to kill a query without privilege"):
node.query(f"KILL QUERY WHERE user ='default'", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
with When("I grant kill query privilege"):
node.query(f"GRANT KILL QUERY TO {grant_target_name}")
with Then("I attempt to kill a query"):
node.query(f"KILL QUERY WHERE 1", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
with When("I grant the kill query privilege"):
node.query(f"GRANT KILL QUERY TO {grant_target_name}")
@ -57,7 +64,19 @@ def privilege_check(grant_target_name, user_name, node=None):
node.query(f"KILL QUERY WHERE 1", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("execute on cluster", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked ALL privilege"):
with When("I grant the kill query privilege"):
node.query(f"GRANT KILL QUERY TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to kill a query"):
node.query(f"KILL QUERY WHERE 1", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("execute on cluster"):
with When("I grant the truncate privilege"):
node.query(f"GRANT KILL QUERY TO {grant_target_name}")
@ -65,9 +84,22 @@ def privilege_check(grant_target_name, user_name, node=None):
with Then("I attempt to kill a query"):
node.query(f"KILL QUERY ON CLUSTER WHERE 1'", settings = [("user", user_name)])
with Scenario("user with ALL privilege"):
with When("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with And("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* ON {grant_target_name}")
with Then("I attempt to kill a query"):
node.query(f"KILL QUERY WHERE 1", settings = [("user", user_name)])
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_KillQuery("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Name("kill query")
def feature(self, node="clickhouse1", stress=None, parallel=None):
@ -80,5 +112,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
if stress is not None:
self.context.stress = stress
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role()

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, table_type, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute OPTIMIZE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, table_type=table_type, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,16 +32,22 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I attempt to optimize a table without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to optimize a table without privilege"):
node.query(f"OPTIMIZE TABLE {table_name} FINAL", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
@ -52,7 +58,7 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
with Then("I attempt to optimize a table"):
node.query(f"OPTIMIZE TABLE {table_name}", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
@ -67,7 +73,22 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
node.query(f"OPTIMIZE TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("execute on cluster", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the optimize privilege"):
node.query(f"GRANT OPTIMIZE ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to optimize a table"):
node.query(f"OPTIMIZE TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("execute on cluster"):
table_name = f"merge_tree_{getuid()}"
try:
@ -84,9 +105,24 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
with Finally("I drop the table from the cluster"):
node.query(f"DROP TABLE IF EXISTS {table_name} ON CLUSTER sharded_cluster")
with Scenario("user with ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with And("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to optimize a table"):
node.query(f"OPTIMIZE TABLE {table_name}", settings = [("user", user_name)])
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_Optimize("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()
@ -109,5 +145,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
continue
with Example(str(example)):
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role(table_type=table_type)

View File

@ -95,5 +95,5 @@ def sensitive_tables(self, node=None):
def feature(self, node="clickhouse1"):
self.context.node = self.context.cluster.node(node)
Scenario(run=public_tables, setup=instrument_clickhouse_server_log, flags=TE)
Scenario(run=sensitive_tables, setup=instrument_clickhouse_server_log, flags=TE)
Scenario(run=public_tables, setup=instrument_clickhouse_server_log)
Scenario(run=sensitive_tables, setup=instrument_clickhouse_server_log)

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(test=role_admin, flags=TE)(grant_target_name=user_name, user_name=user_name)
Suite(test=role_admin)(grant_target_name=user_name, user_name=user_name)
@TestSuite
def privileges_granted_via_role(self, node=None):
@ -35,7 +35,7 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(test=role_admin, flags=TE)(grant_target_name=role_name, user_name=user_name)
Suite(test=role_admin)(grant_target_name=role_name, user_name=user_name)
@TestSuite
def role_admin(self, grant_target_name, user_name, node=None):
@ -52,7 +52,13 @@ def role_admin(self, grant_target_name, user_name, node=None):
with user(node, target_user_name), role(node, role_admin_name):
with When("I check the user can't grant a role"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't grant a role"):
node.query(f"GRANT {role_admin_name} TO {target_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -105,10 +111,40 @@ def role_admin(self, grant_target_name, user_name, node=None):
node.query(f"GRANT {role_admin_name} TO {target_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("Grant role with revoked ALL privilege"):
role_admin_name = f"role_admin_{getuid()}"
target_user_name = f"target_user_{getuid()}"
with user(node, target_user_name), role(node, role_admin_name):
with When(f"I grant ROLE ADMIN"):
node.query(f"GRANT ROLE ADMIN ON *.* TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I check the user cannot grant a role"):
node.query(f"GRANT {role_admin_name} TO {target_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("Grant role with ALL privilege"):
role_admin_name = f"role_admin_{getuid()}"
target_user_name = f"target_user_{getuid()}"
with user(node, target_user_name), role(node, role_admin_name):
with When(f"I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I check the user can grant a role"):
node.query(f"GRANT {role_admin_name} TO {target_user_name}", settings = [("user", f"{user_name}")])
@TestFeature
@Name("role admin")
@Requirements(
RQ_SRS_006_RBAC_Privileges_RoleAdmin("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of ROLE ADMIN.

View File

@ -9,17 +9,31 @@ from rbac.helper.common import *
import rbac.helper.errors as errors
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def without_privilege(self, table_type, node=None):
"""Check that user without select privilege on a table is not able to select on that table.
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name):
with When("I run SELECT without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {user_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {user_name}")
with Then("I run SELECT without privilege"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT * FROM {table_name}", settings = [("user",user_name)],
exitcode=exitcode, message=message)
@ -32,16 +46,52 @@ def user_with_privilege(self, table_type, node=None):
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with Given("I have some data inserted into table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')")
with user(node, user_name):
with When("I grant privilege"):
node.query(f"GRANT SELECT ON {table_name} TO {user_name}")
with Then("I verify SELECT command"):
user_select = node.query(f"SELECT d FROM {table_name}", settings = [("user",user_name)])
default = node.query(f"SELECT d FROM {table_name}")
assert user_select.output == default.output, error()
@TestScenario
@Requirements(
RQ_SRS_006_RBAC_Privileges_All("1.0")
)
def user_with_all_privilege(self, table_type, node=None):
"""Check that user can select from a table if have ALL privilege.
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with Given("I have some data inserted into table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')")
with user(node, user_name):
with When("I grant privilege"):
node.query(f"GRANT ALL ON *.* TO {user_name}")
with Then("I verify SELECT command"):
user_select = node.query(f"SELECT d FROM {table_name}", settings = [("user",user_name)])
default = node.query(f"SELECT d FROM {table_name}")
assert user_select.output == default.output, error()
@ -55,15 +105,47 @@ def user_with_revoked_privilege(self, table_type, node=None):
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name):
with When("I grant privilege"):
node.query(f"GRANT SELECT ON {table_name} TO {user_name}")
with And("I revoke privilege"):
node.query(f"REVOKE SELECT ON {table_name} FROM {user_name}")
with And("I use SELECT, throws exception"):
with Then("I use SELECT, throws exception"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT * FROM {table_name}", settings = [("user",user_name)],
exitcode=exitcode, message=message)
@TestScenario
def user_with_revoked_all_privilege(self, table_type, node=None):
"""Check that user is unable to select from a table after ALL privilege
on that table has been revoked from the user.
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name):
with When("I grant privilege"):
node.query(f"GRANT SELECT ON {table_name} TO {user_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {user_name}")
with Then("I use SELECT, throws exception"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT * FROM {table_name}", settings = [("user",user_name)],
exitcode=exitcode, message=message)
@ -90,25 +172,35 @@ def user_column_privileges(self, grant_columns, select_columns_pass, data_pass,
"""
user_name = f"user_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type), user(node, user_name):
with Given("The table has some data on some columns"):
node.query(f"INSERT INTO {table_name} ({select_columns_pass}) VALUES ({data_pass})")
with When("I grant select privilege"):
node.query(f"GRANT SELECT({grant_columns}) ON {table_name} TO {user_name}")
if select_columns_fail is not None:
with And("I select from not granted column"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT ({select_columns_fail}) FROM {table_name}",
settings = [("user",user_name)], exitcode=exitcode, message=message)
with Then("I select from granted column, verify correct result"):
user_select = node.query(f"SELECT ({select_columns_pass}) FROM {table_name}", settings = [("user",user_name)])
default = node.query(f"SELECT ({select_columns_pass}) FROM {table_name}")
assert user_select.output == default.output
if revoke_columns is not None:
with When("I revoke select privilege for columns from user"):
node.query(f"REVOKE SELECT({revoke_columns}) ON {table_name} FROM {user_name}")
with And("I select from revoked columns"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT ({select_columns_pass}) FROM {table_name}", settings = [("user",user_name)], exitcode=exitcode, message=message)
@ -124,17 +216,25 @@ def role_with_privilege(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with Given("I have some data inserted into table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')")
with user(node, user_name):
with role(node, role_name):
with When("I grant select privilege to a role"):
node.query(f"GRANT SELECT ON {table_name} TO {role_name}")
with And("I grant role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
with Then("I verify SELECT command"):
user_select = node.query(f"SELECT d FROM {table_name}", settings = [("user",user_name)])
default = node.query(f"SELECT d FROM {table_name}")
@ -151,16 +251,23 @@ def role_with_revoked_privilege(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name), role(node, role_name):
with When("I grant privilege to a role"):
node.query(f"GRANT SELECT ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And("I revoke privilege from the role"):
node.query(f"REVOKE SELECT ON {table_name} FROM {role_name}")
with And("I select from the table"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT * FROM {table_name}", settings = [("user",user_name)],
@ -174,16 +281,23 @@ def user_with_revoked_role(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with user(node, user_name), role(node, role_name):
with When("I grant privilege to a role"):
node.query(f"GRANT SELECT ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
with And("I revoke the role from the user"):
node.query(f"REVOKE {role_name} FROM {user_name}")
with And("I select from the table"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT * FROM {table_name}", settings = [("user",user_name)],
@ -212,28 +326,39 @@ def role_column_privileges(self, grant_columns, select_columns_pass, data_pass,
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
with Given("The table has some data on some columns"):
node.query(f"INSERT INTO {table_name} ({select_columns_pass}) VALUES ({data_pass})")
with user(node, user_name), role(node, role_name):
with When("I grant select privilege"):
node.query(f"GRANT SELECT({grant_columns}) ON {table_name} TO {role_name}")
with And("I grant the role to a user"):
node.query(f"GRANT {role_name} TO {user_name}")
if select_columns_fail is not None:
with And("I select from not granted column"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT ({select_columns_fail}) FROM {table_name}",
settings = [("user",user_name)], exitcode=exitcode, message=message)
with Then("I verify SELECT command"):
user_select = node.query(f"SELECT d FROM {table_name}", settings = [("user",user_name)])
default = node.query(f"SELECT d FROM {table_name}")
assert user_select.output == default.output, error()
if revoke_columns is not None:
with When("I revoke select privilege for columns from role"):
node.query(f"REVOKE SELECT({revoke_columns}) ON {table_name} FROM {role_name}")
with And("I select from revoked columns"):
exitcode, message = errors.not_enough_privileges(name=user_name)
node.query(f"SELECT ({select_columns_pass}) FROM {table_name}",
@ -250,20 +375,26 @@ def user_with_privilege_on_cluster(self, table_type, node=None):
user_name = f"user_{getuid()}"
role_name = f"role_{getuid()}"
table_name = f"table_{getuid()}"
if node is None:
node = self.context.node
with table(node, table_name, table_type):
try:
with Given("I have some data inserted into table"):
node.query(f"INSERT INTO {table_name} (d) VALUES ('2020-01-01')")
with Given("I have a user on a cluster"):
node.query(f"CREATE USER OR REPLACE {user_name} ON CLUSTER sharded_cluster")
with When("I grant select privilege on a cluster"):
node.query(f"GRANT ON CLUSTER sharded_cluster SELECT ON {table_name} TO {user_name}")
with Then("I verify SELECT command"):
user_select = node.query(f"SELECT d FROM {table_name}", settings = [("user",user_name)])
default = node.query(f"SELECT d FROM {table_name}")
assert user_select.output == default.output, error()
finally:
with Finally("I drop the user"):
node.query(f"DROP USER {user_name} ON CLUSTER sharded_cluster")
@ -290,8 +421,11 @@ def feature(self, table_type, parallel=None, stress=None, node="clickhouse1"):
tasks = []
pool = Pool(10)
try:
try:
for scenario in loads(current_module(), Scenario):
run_scenario(pool, tasks, Scenario(test=scenario, setup=instrument_clickhouse_server_log), {"table_type" : table_type})
finally:
join(tasks)
finally:
pool.close()

View File

@ -18,7 +18,7 @@ def describe_with_privilege_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(test=describe, setup=instrument_clickhouse_server_log)(grant_target_name=user_name, user_name=user_name, table_name=table_name)
Suite(test=describe)(grant_target_name=user_name, user_name=user_name, table_name=table_name)
@TestSuite
def describe_with_privilege_granted_via_role(self, node=None):
@ -37,7 +37,7 @@ def describe_with_privilege_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(test=describe, setup=instrument_clickhouse_server_log)(grant_target_name=role_name, user_name=user_name, table_name=table_name)
Suite(test=describe)(grant_target_name=role_name, user_name=user_name, table_name=table_name)
@TestSuite
@Requirements(
@ -54,11 +54,19 @@ def describe(self, grant_target_name, user_name, table_name, node=None):
with table(node, table_name):
with Scenario("DESCRIBE table without privilege"):
with When(f"I attempt to DESCRIBE {table_name}"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I attempt to DESCRIBE {table_name}"):
node.query(f"DESCRIBE {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("DESCRIBE with privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT SHOW COLUMNS ON {table_name} TO {grant_target_name}")
@ -66,6 +74,7 @@ def describe(self, grant_target_name, user_name, table_name, node=None):
node.query(f"DESCRIBE TABLE {table_name}", settings=[("user",user_name)])
with Scenario("DESCRIBE with revoked privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT SHOW COLUMNS ON {table_name} TO {grant_target_name}")
@ -76,6 +85,26 @@ def describe(self, grant_target_name, user_name, table_name, node=None):
node.query(f"DESCRIBE {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("DESCRIBE with revoked ALL privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT SHOW COLUMNS ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then(f"I attempt to DESCRIBE {table_name}"):
node.query(f"DESCRIBE {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("DESCRIBE with ALL privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then(f"I attempt to DESCRIBE {table_name}"):
node.query(f"DESCRIBE TABLE {table_name}", settings=[("user",user_name)])
@TestSuite
def show_create_with_privilege_granted_directly(self, node=None):
"""Check that user is able to execute SHOW CREATE on a table if and only if
@ -89,7 +118,7 @@ def show_create_with_privilege_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(test=show_create, setup=instrument_clickhouse_server_log)(grant_target_name=user_name, user_name=user_name, table_name=table_name)
Suite(test=show_create)(grant_target_name=user_name, user_name=user_name, table_name=table_name)
@TestSuite
def show_create_with_privilege_granted_via_role(self, node=None):
@ -108,7 +137,7 @@ def show_create_with_privilege_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(test=show_create, setup=instrument_clickhouse_server_log)(grant_target_name=role_name, user_name=user_name, table_name=table_name)
Suite(test=show_create)(grant_target_name=role_name, user_name=user_name, table_name=table_name)
@TestSuite
@Requirements(
@ -125,11 +154,19 @@ def show_create(self, grant_target_name, user_name, table_name, node=None):
with table(node, table_name):
with Scenario("SHOW CREATE without privilege"):
with When(f"I attempt to SHOW CREATE {table_name}"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I attempt to SHOW CREATE {table_name}"):
node.query(f"SHOW CREATE TABLE {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("SHOW CREATE with privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT SHOW COLUMNS ON {table_name} TO {grant_target_name}")
@ -137,6 +174,7 @@ def show_create(self, grant_target_name, user_name, table_name, node=None):
node.query(f"SHOW CREATE TABLE {table_name}", settings=[("user",user_name)])
with Scenario("SHOW CREATE with revoked privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT SHOW COLUMNS ON {table_name} TO {grant_target_name}")
@ -147,10 +185,20 @@ def show_create(self, grant_target_name, user_name, table_name, node=None):
node.query(f"SHOW CREATE TABLE {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("SHOW CREATE with ALL privilege"):
with When(f"I grant SHOW COLUMNS on the table"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then(f"I attempt to SHOW CREATE {table_name}"):
node.query(f"SHOW CREATE TABLE {table_name}", settings=[("user",user_name)])
@TestFeature
@Name("show columns")
@Requirements(
RQ_SRS_006_RBAC_ShowColumns_Privilege("1.0")
RQ_SRS_006_RBAC_ShowColumns_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW COLUMNS.

View File

@ -20,7 +20,7 @@ def dict_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
db_name = f"db_name_{getuid()}"
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name db_name", [
tuple(list(row)+[user_name,user_name,db_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -44,13 +44,14 @@ def dict_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name db_name", [
tuple(list(row)+[role_name,user_name,db_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SHOW","*.*"),
("SHOW DATABASES","db"),
("CREATE DATABASE","db"),
@ -65,9 +66,9 @@ def check_privilege(self, privilege, on, grant_target_name, user_name, db_name,
on = on.replace("db", f"{db_name}")
Suite(test=show_db, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, db_name=db_name)
Suite(test=use, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, db_name=db_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, db_name=db_name)
Suite(test=show_db)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, db_name=db_name)
Suite(test=use)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, db_name=db_name)
Suite(test=show_create)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, db_name=db_name)
@TestSuite
@Requirements(
@ -83,14 +84,23 @@ def show_db(self, privilege, on, grant_target_name, user_name, db_name, node=Non
try:
with Given("I have a database"):
node.query(f"CREATE DATABASE {db_name}")
with Scenario("SHOW DATABASES without privilege"):
with When("I check the user doesn't see the database"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user doesn't see the database"):
output = node.query("SHOW DATABASES", settings = [("user", f"{user_name}")]).output
assert output == '', error()
with Scenario("SHOW DATABASES with privilege"):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON {db_name}.* TO {grant_target_name}")
@ -98,6 +108,7 @@ def show_db(self, privilege, on, grant_target_name, user_name, db_name, node=Non
output = node.query("SHOW DATABASES", settings = [("user", f"{user_name}")], message = f'{db_name}')
with Scenario("SHOW DATABASES with revoked privilege"):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON {db_name}.* TO {grant_target_name}")
@ -130,11 +141,19 @@ def use(self, privilege, on, grant_target_name, user_name, db_name, node=None):
node.query(f"CREATE DATABASE {db_name}")
with Scenario("USE without privilege"):
with When(f"I attempt to USE {db_name}"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I attempt to USE {db_name}"):
node.query(f"USE {db_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("USE with privilege"):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON {db_name}.* TO {grant_target_name}")
@ -142,6 +161,7 @@ def use(self, privilege, on, grant_target_name, user_name, db_name, node=None):
node.query(f"USE {db_name}", settings=[("user",user_name)])
with Scenario("USE with revoked privilege"):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON {db_name}.* TO {grant_target_name}")
@ -174,11 +194,19 @@ def show_create(self, privilege, on, grant_target_name, user_name, db_name, node
node.query(f"CREATE DATABASE {db_name}")
with Scenario("SHOW CREATE without privilege"):
with When(f"I attempt to SHOW CREATE {db_name}"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I attempt to SHOW CREATE {db_name}"):
node.query(f"SHOW CREATE DATABASE {db_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("SHOW CREATE with privilege"):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON {db_name}.* TO {grant_target_name}")
@ -186,6 +214,7 @@ def show_create(self, privilege, on, grant_target_name, user_name, db_name, node
node.query(f"SHOW CREATE DATABASE {db_name}", settings=[("user",user_name)])
with Scenario("SHOW CREATE with revoked privilege"):
with When(f"I grant {privilege} on the database"):
node.query(f"GRANT {privilege} ON {db_name}.* TO {grant_target_name}")
@ -203,7 +232,9 @@ def show_create(self, privilege, on, grant_target_name, user_name, db_name, node
@TestFeature
@Name("show databases")
@Requirements(
RQ_SRS_006_RBAC_ShowDatabases_Privilege("1.0")
RQ_SRS_006_RBAC_ShowDatabases_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW DATABASES.

View File

@ -20,7 +20,7 @@ def dict_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
dict_name = f"dict_name_{getuid()}"
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name dict_name", [
tuple(list(row)+[user_name,user_name,dict_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -44,13 +44,14 @@ def dict_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name dict_name", [
tuple(list(row)+[role_name,user_name,dict_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SHOW","*.*"),
("SHOW DICTIONARIES","dict"),
("CREATE DICTIONARY","dict"),
@ -65,9 +66,9 @@ def check_privilege(self, privilege, on, grant_target_name, user_name, dict_name
on = on.replace("dict", f"{dict_name}")
Suite(test=show_dict, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, dict_name=dict_name)
Suite(test=exists, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, dict_name=dict_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, dict_name=dict_name)
Suite(test=show_dict)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, dict_name=dict_name)
Suite(test=exists)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, dict_name=dict_name)
Suite(test=show_create)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, dict_name=dict_name)
@TestSuite
@Requirements(
@ -87,7 +88,14 @@ def show_dict(self, privilege, on, grant_target_name, user_name, dict_name, node
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with Scenario("SHOW DICTIONARIES without privilege"):
with When("I check the user doesn't see the dictionary"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user doesn't see the dictionary"):
output = node.query("SHOW DICTIONARIES", settings = [("user", f"{user_name}")]).output
assert output == '', error()
@ -131,7 +139,14 @@ def exists(self, privilege, on, grant_target_name, user_name, dict_name, node=No
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with Scenario("EXISTS without privilege"):
with When(f"I check if {dict_name} EXISTS"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I check if {dict_name} EXISTS"):
node.query(f"EXISTS {dict_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -175,7 +190,14 @@ def show_create(self, privilege, on, grant_target_name, user_name, dict_name, no
node.query(f"CREATE DICTIONARY {dict_name}(x Int32, y Int32) PRIMARY KEY x LAYOUT(FLAT()) SOURCE(CLICKHOUSE()) LIFETIME(0)")
with Scenario("SHOW CREATE without privilege"):
with When(f"I attempt to SHOW CREATE {dict_name}"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I attempt to SHOW CREATE {dict_name}"):
node.query(f"SHOW CREATE DICTIONARY {dict_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -205,6 +227,8 @@ def show_create(self, privilege, on, grant_target_name, user_name, dict_name, no
@Name("show dictionaries")
@Requirements(
RQ_SRS_006_RBAC_ShowDictionaries_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW DICTIONARIES.

View File

@ -29,7 +29,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -50,13 +50,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("SHOW ACCESS",),
("SHOW QUOTAS",),
@ -69,8 +70,8 @@ def check_privilege(self, privilege, grant_target_name, user_name, node=None):
if node is None:
node = self.context.node
Suite(test=show_quotas, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_quotas)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
@Requirements(
@ -86,7 +87,13 @@ def show_quotas(self, privilege, grant_target_name, user_name, node=None):
with Scenario("SHOW QUOTAS without privilege"):
with When("I check the user can't use SHOW QUOTAS"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW QUOTAS"):
node.query(f"SHOW QUOTAS", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -127,7 +134,13 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
with quota(node, target_quota_name):
with When("I check the user can't use SHOW CREATE QUOTA"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW CREATE QUOTA"):
node.query(f"SHOW CREATE QUOTA {target_quota_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -161,6 +174,8 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
@Name("show quotas")
@Requirements(
RQ_SRS_006_RBAC_ShowQuotas_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW QUOTAS.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("SHOW ACCESS",),
("SHOW ROLES",),
@ -57,8 +58,8 @@ def check_privilege(self, privilege, grant_target_name, user_name, node=None):
if node is None:
node = self.context.node
Suite(test=show_roles, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_roles)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
@Requirements(
@ -74,7 +75,13 @@ def show_roles(self, privilege, grant_target_name, user_name, node=None):
with Scenario("SHOW ROLES without privilege"):
with When("I check the user can't use SHOW ROLES"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW ROLES"):
node.query(f"SHOW ROLES", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -115,7 +122,13 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
with role(node, target_role_name):
with When("I check the user can't use SHOW CREATE ROLE"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW CREATE ROLE"):
node.query(f"SHOW CREATE ROLE {target_role_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -149,6 +162,8 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
@Name("show roles")
@Requirements(
RQ_SRS_006_RBAC_ShowRoles_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW ROLES.

View File

@ -29,7 +29,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -50,13 +50,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("SHOW ACCESS",),
("SHOW ROW POLICIES",),
@ -71,8 +72,8 @@ def check_privilege(self, privilege, grant_target_name, user_name, node=None):
if node is None:
node = self.context.node
Suite(test=show_row_policies, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_row_policies)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
@Requirements(
@ -88,7 +89,13 @@ def show_row_policies(self, privilege, grant_target_name, user_name, node=None):
with Scenario("SHOW ROW POLICIES without privilege"):
with When("I check the user can't use SHOW ROW POLICIES"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW ROW POLICIES"):
node.query(f"SHOW ROW POLICIES", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -130,7 +137,13 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
with row_policy(node, target_row_policy_name, table_name):
with When("I check the user can't use SHOW CREATE ROW POLICY"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW CREATE ROW POLICY"):
node.query(f"SHOW CREATE ROW POLICY {target_row_policy_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -166,6 +179,8 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
@Name("show row policies")
@Requirements(
RQ_SRS_006_RBAC_ShowRowPolicies_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW ROW POLICYS.

View File

@ -29,7 +29,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -50,13 +50,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("SHOW ACCESS",),
("SHOW SETTINGS PROFILES",),
@ -71,8 +72,8 @@ def check_privilege(self, privilege, grant_target_name, user_name, node=None):
if node is None:
node = self.context.node
Suite(test=show_settings_profiles, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_settings_profiles)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
@Requirements(
@ -88,7 +89,13 @@ def show_settings_profiles(self, privilege, grant_target_name, user_name, node=N
with Scenario("SHOW SETTINGS PROFILES without privilege"):
with When("I check the user can't use SHOW SETTINGS PROFILES"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW SETTINGS PROFILES"):
node.query(f"SHOW SETTINGS PROFILES", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -129,7 +136,13 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
with settings_profile(node, target_settings_profile_name):
with When("I check the user can't use SHOW CREATE SETTINGS PROFILE"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW CREATE SETTINGS PROFILE"):
node.query(f"SHOW CREATE SETTINGS PROFILE {target_settings_profile_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -163,6 +176,8 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
@Name("show settings profiles")
@Requirements(
RQ_SRS_006_RBAC_ShowSettingsProfiles_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW SETTINGS PROFILES.

View File

@ -20,7 +20,7 @@ def table_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[user_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -44,13 +44,14 @@ def table_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[role_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SHOW", "*.*"),
("SHOW TABLES", "table"),
("SELECT", "table"),
@ -67,9 +68,9 @@ def check_privilege(self, privilege, on, grant_target_name, user_name, table_nam
if node is None:
node = self.context.node
Suite(test=show_tables, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=exists, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=check, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=show_tables)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=exists)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=check)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
@TestSuite
@Requirements(
@ -88,11 +89,19 @@ def show_tables(self, privilege, on, grant_target_name, user_name, table_name, n
with table(node, table_name):
with Scenario("SHOW TABLES without privilege"):
with When("I check the user doesn't see the table"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user doesn't see the table"):
output = node.query("SHOW TABLES", settings = [("user", f"{user_name}")]).output
assert output == '', error()
with Scenario("SHOW TABLES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -100,6 +109,7 @@ def show_tables(self, privilege, on, grant_target_name, user_name, table_name, n
node.query("SHOW TABLES", settings = [("user", f"{user_name}")], message=f"{table_name}")
with Scenario("SHOW TABLES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -127,12 +137,21 @@ def exists(self, privilege, on, grant_target_name, user_name, table_name, node=N
on = f"{table_name}"
with table(node, table_name):
with Scenario("EXISTS without privilege"):
with When(f"I check if {table_name} EXISTS"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I check if {table_name} EXISTS"):
node.query(f"EXISTS {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("EXISTS with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -140,6 +159,7 @@ def exists(self, privilege, on, grant_target_name, user_name, table_name, node=N
node.query(f"EXISTS {table_name}", settings=[("user",user_name)])
with Scenario("EXISTS with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -167,12 +187,21 @@ def check(self, privilege, on, grant_target_name, user_name, table_name, node=No
on = f"{table_name}"
with table(node, table_name):
with Scenario("CHECK without privilege"):
with When(f"I CHECK {table_name}"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then(f"I CHECK {table_name}"):
node.query(f"CHECK TABLE {table_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
with Scenario("CHECK with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -180,6 +209,7 @@ def check(self, privilege, on, grant_target_name, user_name, table_name, node=No
node.query(f"CHECK TABLE {table_name}", settings=[("user",user_name)])
with Scenario("CHECK with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -194,6 +224,8 @@ def check(self, privilege, on, grant_target_name, user_name, table_name, node=No
@Name("show tables")
@Requirements(
RQ_SRS_006_RBAC_ShowTables_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW TABLES.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("ACCESS MANAGEMENT",),
("SHOW ACCESS",),
("SHOW USERS",),
@ -57,8 +58,8 @@ def check_privilege(self, privilege, grant_target_name, user_name, node=None):
if node is None:
node = self.context.node
Suite(test=show_users, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_users)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=show_create)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
@Requirements(
@ -74,7 +75,13 @@ def show_users(self, privilege, grant_target_name, user_name, node=None):
with Scenario("SHOW USERS without privilege"):
with When("I check the user can't use SHOW USERS"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW USERS"):
node.query(f"SHOW USERS", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -115,7 +122,13 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
with user(node, target_user_name):
with When("I check the user can't use SHOW CREATE USER"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SHOW CREATE USER"):
node.query(f"SHOW CREATE USER {target_user_name}", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -149,6 +162,8 @@ def show_create(self, privilege, grant_target_name, user_name, node=None):
@Name("show users")
@Requirements(
RQ_SRS_006_RBAC_ShowUsers_Privilege("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW USERS.

View File

@ -17,7 +17,7 @@ def file_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=file, flags=TE,
Suite(run=file,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in file.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def file_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=file, flags=TE,
Suite(run=file,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in file.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("FILE",),
])
@ -65,7 +66,13 @@ def file(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the File source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the File source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=File()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -102,7 +109,7 @@ def url_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=url, flags=TE,
Suite(run=url,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in url.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -123,13 +130,14 @@ def url_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=url, flags=TE,
Suite(run=url,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in url.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("URL",),
])
@ -150,7 +158,13 @@ def url(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the URL source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the URL source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=URL()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -187,7 +201,7 @@ def remote_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=remote, flags=TE,
Suite(run=remote,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in remote.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -208,13 +222,14 @@ def remote_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=remote, flags=TE,
Suite(run=remote,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in remote.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("REMOTE",),
])
@ -235,7 +250,13 @@ def remote(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the Remote source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the Remote source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE = Distributed()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -272,7 +293,7 @@ def MySQL_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=MySQL, flags=TE,
Suite(run=MySQL,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in MySQL.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -293,13 +314,14 @@ def MySQL_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=MySQL, flags=TE,
Suite(run=MySQL,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in MySQL.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("MYSQL",),
])
@ -320,7 +342,13 @@ def MySQL(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the MySQL source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the MySQL source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=MySQL()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -357,7 +385,7 @@ def ODBC_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=ODBC, flags=TE,
Suite(run=ODBC,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in ODBC.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -378,13 +406,14 @@ def ODBC_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=ODBC, flags=TE,
Suite(run=ODBC,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in ODBC.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("ODBC",),
])
@ -405,7 +434,13 @@ def ODBC(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the ODBC source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the ODBC source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=ODBC()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -442,7 +477,7 @@ def JDBC_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=JDBC, flags=TE,
Suite(run=JDBC,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in JDBC.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -463,13 +498,14 @@ def JDBC_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=JDBC, flags=TE,
Suite(run=JDBC,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in JDBC.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("JDBC",),
])
@ -490,7 +526,13 @@ def JDBC(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the JDBC source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the JDBC source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=JDBC()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -527,7 +569,7 @@ def HDFS_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=HDFS, flags=TE,
Suite(run=HDFS,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in HDFS.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -548,13 +590,14 @@ def HDFS_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=HDFS, flags=TE,
Suite(run=HDFS,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in HDFS.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("HDFS",),
])
@ -575,7 +618,13 @@ def HDFS(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the HDFS source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the HDFS source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=HDFS()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -612,7 +661,7 @@ def S3_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=S3, flags=TE,
Suite(run=S3,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in S3.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -633,13 +682,14 @@ def S3_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=S3, flags=TE,
Suite(run=S3,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in S3.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SOURCES",),
("S3",),
])
@ -660,7 +710,13 @@ def S3(self, privilege, grant_target_name, user_name, node=None):
with Given("The user has table privilege"):
node.query(f"GRANT CREATE TABLE ON {table_name} TO {grant_target_name}")
with When("I check the user can't use the S3 source"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use the S3 source"):
node.query(f"CREATE TABLE {table_name} (x String) ENGINE=S3()", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -689,6 +745,8 @@ def S3(self, privilege, grant_target_name, user_name, node=None):
@Name("sources")
@Requirements(
RQ_SRS_006_RBAC_Privileges_Sources("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SOURCES.

View File

@ -17,7 +17,7 @@ def dns_cache_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=dns_cache, flags=TE,
Suite(run=dns_cache,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dns_cache.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,7 +38,7 @@ def dns_cache_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dns_cache, flags=TE,
Suite(run=dns_cache,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dns_cache.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -48,6 +48,7 @@ def dns_cache_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_DropCache_DNS("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM DROP CACHE",),
("SYSTEM DROP DNS CACHE",),
@ -65,11 +66,19 @@ def dns_cache(self, privilege, grant_target_name, user_name, node=None):
node = self.context.node
with Scenario("SYSTEM DROP DNS CACHE without privilege"):
with When("I check the user is unable to execute SYSTEM DROP DNS CACHE"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM DROP DNS CACHE"):
node.query("SYSTEM DROP DNS CACHE", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM DROP DNS CACHE with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -77,6 +86,7 @@ def dns_cache(self, privilege, grant_target_name, user_name, node=None):
node.query("SYSTEM DROP DNS CACHE", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM DROP DNS CACHE with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -99,7 +109,7 @@ def mark_cache_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=mark_cache, flags=TE,
Suite(run=mark_cache,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in mark_cache.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -120,7 +130,7 @@ def mark_cache_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=mark_cache, flags=TE,
Suite(run=mark_cache,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in mark_cache.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -130,6 +140,7 @@ def mark_cache_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_DropCache_Mark("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM DROP CACHE",),
("SYSTEM DROP MARK CACHE",),
@ -147,11 +158,19 @@ def mark_cache(self, privilege, grant_target_name, user_name, node=None):
node = self.context.node
with Scenario("SYSTEM DROP MARK CACHE without privilege"):
with When("I check the user is unable to execute SYSTEM DROP MARK CACHE"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM DROP MARK CACHE"):
node.query("SYSTEM DROP MARK CACHE", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM DROP MARK CACHE with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -159,6 +178,7 @@ def mark_cache(self, privilege, grant_target_name, user_name, node=None):
node.query("SYSTEM DROP MARK CACHE", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM DROP MARK CACHE with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -181,7 +201,7 @@ def uncompressed_cache_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=uncompressed_cache, flags=TE,
Suite(run=uncompressed_cache,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in uncompressed_cache.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -202,7 +222,7 @@ def uncompressed_cache_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=uncompressed_cache, flags=TE,
Suite(run=uncompressed_cache,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in uncompressed_cache.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -212,6 +232,7 @@ def uncompressed_cache_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_DropCache_Uncompressed("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM DROP CACHE",),
("SYSTEM DROP UNCOMPRESSED CACHE",),
@ -229,11 +250,19 @@ def uncompressed_cache(self, privilege, grant_target_name, user_name, node=None)
node = self.context.node
with Scenario("SYSTEM DROP UNCOMPRESSED CACHE without privilege"):
with When("I check the user is unable to execute SYSTEM DROP UNCOMPRESSED CACHE"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM DROP UNCOMPRESSED CACHE"):
node.query("SYSTEM DROP UNCOMPRESSED CACHE", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM DROP UNCOMPRESSED CACHE with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -241,6 +270,7 @@ def uncompressed_cache(self, privilege, grant_target_name, user_name, node=None)
node.query("SYSTEM DROP UNCOMPRESSED CACHE", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM DROP UNCOMPRESSED CACHE with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -255,6 +285,8 @@ def uncompressed_cache(self, privilege, grant_target_name, user_name, node=None)
@Name("system drop cache")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_DropCache("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM DROP CACHE.

View File

@ -17,7 +17,7 @@ def replicated_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_replicated_privilege, flags=TE,
Suite(run=check_replicated_privilege,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_replicated_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def replicated_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_replicated_privilege, flags=TE,
Suite(run=check_replicated_privilege,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_replicated_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM FETCHES", "table"),
("SYSTEM STOP FETCHES", "table"),
@ -59,8 +60,8 @@ def check_replicated_privilege(self, privilege, on, grant_target_name, user_name
if node is None:
node = self.context.node
Suite(test=start_replication_queues, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=stop_replication_queues, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=start_replication_queues)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=stop_replication_queues)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
def start_replication_queues(self, privilege, on, grant_target_name, user_name, node=None):
@ -77,11 +78,19 @@ def start_replication_queues(self, privilege, on, grant_target_name, user_name,
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM START FETCHES without privilege"):
with When("I check the user can't start fetches"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start fetches"):
node.query(f"SYSTEM START FETCHES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START FETCHES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -89,6 +98,7 @@ def start_replication_queues(self, privilege, on, grant_target_name, user_name,
node.query(f"SYSTEM START FETCHES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START FETCHES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -114,11 +124,19 @@ def stop_replication_queues(self, privilege, on, grant_target_name, user_name, n
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM STOP FETCHES without privilege"):
with When("I check the user can't stop fetches"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop fetches"):
node.query(f"SYSTEM STOP FETCHES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP FETCHES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -126,6 +144,7 @@ def stop_replication_queues(self, privilege, on, grant_target_name, user_name, n
node.query(f"SYSTEM STOP FETCHES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP FETCHES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -140,6 +159,8 @@ def stop_replication_queues(self, privilege, on, grant_target_name, user_name, n
@Name("system fetches")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Fetches("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM FETCHES.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=flush_logs, flags=TE,
Suite(run=flush_logs,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in flush_logs.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=flush_logs, flags=TE,
Suite(run=flush_logs,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in flush_logs.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM FLUSH", "*.*"),
("SYSTEM FLUSH LOGS", "*.*"),
@ -62,11 +63,19 @@ def flush_logs(self, privilege, on, grant_target_name, user_name, node=None):
node = self.context.node
with Scenario("SYSTEM FLUSH LOGS without privilege"):
with When("I check the user can't flush logs"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't flush logs"):
node.query(f"SYSTEM FLUSH LOGS", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM FLUSH LOGS with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -74,6 +83,7 @@ def flush_logs(self, privilege, on, grant_target_name, user_name, node=None):
node.query(f"SYSTEM FLUSH LOGS", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM FLUSH LOGS with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -97,7 +107,7 @@ def distributed_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(run=flush_distributed, flags=TE,
Suite(run=flush_distributed,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[user_name,user_name,table_name]) for row in flush_distributed.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -119,13 +129,14 @@ def distributed_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=flush_distributed, flags=TE,
Suite(run=flush_distributed,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[role_name,user_name,table_name]) for row in flush_distributed.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM FLUSH", "*.*"),
("SYSTEM FLUSH DISTRIBUTED", "table"),
@ -151,11 +162,19 @@ def flush_distributed(self, privilege, on, grant_target_name, user_name, table_n
node.query(f"CREATE TABLE {table_name} (a UInt64) ENGINE = Distributed(sharded_cluster, default, {table0_name}, rand())")
with Scenario("SYSTEM FLUSH DISTRIBUTED without privilege"):
with When("I check the user can't flush distributed"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't flush distributed"):
node.query(f"SYSTEM FLUSH DISTRIBUTED {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM FLUSH DISTRIBUTED with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -163,6 +182,7 @@ def flush_distributed(self, privilege, on, grant_target_name, user_name, table_n
node.query(f"SYSTEM FLUSH DISTRIBUTED {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM FLUSH DISTRIBUTED with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -182,6 +202,8 @@ def flush_distributed(self, privilege, on, grant_target_name, user_name, table_n
@Name("system flush")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Flush("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM FLUSH.

View File

@ -18,7 +18,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[user_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -40,13 +40,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[role_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM MERGES", "table"),
("SYSTEM STOP MERGES", "table"),
@ -61,8 +62,8 @@ def check_privilege(self, privilege, on, grant_target_name, user_name, table_nam
if node is None:
node = self.context.node
Suite(test=start_merges, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_merges, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=start_merges)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_merges)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
@TestSuite
def start_merges(self, privilege, on, grant_target_name, user_name, table_name, node=None):
@ -78,11 +79,19 @@ def start_merges(self, privilege, on, grant_target_name, user_name, table_name,
with table(node, table_name):
with Scenario("SYSTEM START MERGES without privilege"):
with When("I check the user can't start merges"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start merges"):
node.query(f"SYSTEM START MERGES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START MERGES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -90,6 +99,7 @@ def start_merges(self, privilege, on, grant_target_name, user_name, table_name,
node.query(f"SYSTEM START MERGES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START MERGES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -114,11 +124,19 @@ def stop_merges(self, privilege, on, grant_target_name, user_name, table_name, n
with table(node, table_name):
with Scenario("SYSTEM STOP MERGES without privilege"):
with When("I check the user can't stop merges"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop merges"):
node.query(f"SYSTEM STOP MERGES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP MERGES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -126,6 +144,7 @@ def stop_merges(self, privilege, on, grant_target_name, user_name, table_name, n
node.query(f"SYSTEM STOP MERGES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP MERGES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -140,6 +159,8 @@ def stop_merges(self, privilege, on, grant_target_name, user_name, table_name, n
@Name("system merges")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Merges("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM MERGES.

View File

@ -18,7 +18,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[user_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -40,13 +40,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[role_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM MOVES", "table"),
("SYSTEM STOP MOVES", "table"),
@ -61,8 +62,8 @@ def check_privilege(self, privilege, on, grant_target_name, user_name, table_nam
if node is None:
node = self.context.node
Suite(test=start_moves, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_moves, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=start_moves)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_moves)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
@TestSuite
def start_moves(self, privilege, on, grant_target_name, user_name, table_name, node=None):
@ -78,11 +79,19 @@ def start_moves(self, privilege, on, grant_target_name, user_name, table_name, n
with table(node, table_name):
with Scenario("SYSTEM START MOVES without privilege"):
with When("I check the user can't start moves"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start moves"):
node.query(f"SYSTEM START MOVES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START MOVES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -90,6 +99,7 @@ def start_moves(self, privilege, on, grant_target_name, user_name, table_name, n
node.query(f"SYSTEM START MOVES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START MOVES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -114,11 +124,19 @@ def stop_moves(self, privilege, on, grant_target_name, user_name, table_name, no
with table(node, table_name):
with Scenario("SYSTEM STOP MOVES without privilege"):
with When("I check the user can't stop moves"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop moves"):
node.query(f"SYSTEM STOP MOVES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP MOVES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -126,6 +144,7 @@ def stop_moves(self, privilege, on, grant_target_name, user_name, table_name, no
node.query(f"SYSTEM STOP MOVES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP MOVES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -140,6 +159,8 @@ def stop_moves(self, privilege, on, grant_target_name, user_name, table_name, no
@Name("system moves")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Moves("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM MOVES.

View File

@ -38,7 +38,7 @@ def config_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=config, flags=TE,
Suite(run=config,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in config.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -59,7 +59,7 @@ def config_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=config, flags=TE,
Suite(run=config,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in config.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -69,6 +69,7 @@ def config_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_Reload_Config("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM RELOAD",),
("SYSTEM RELOAD CONFIG",),
@ -83,11 +84,19 @@ def config(self, privilege, grant_target_name, user_name, node=None):
node = self.context.node
with Scenario("SYSTEM RELOAD CONFIG without privilege"):
with When("I check the user is unable to execute SYSTEM RELOAD CONFIG"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM RELOAD CONFIG"):
node.query("SYSTEM RELOAD CONFIG", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM RELOAD CONFIG with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -95,6 +104,7 @@ def config(self, privilege, grant_target_name, user_name, node=None):
node.query("SYSTEM RELOAD CONFIG", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM RELOAD CONFIG with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -117,7 +127,7 @@ def dictionary_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=dictionary, flags=TE,
Suite(run=dictionary,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictionary.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -138,7 +148,7 @@ def dictionary_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictionary, flags=TE,
Suite(run=dictionary,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictionary.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -148,6 +158,7 @@ def dictionary_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_Reload_Dictionary("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM RELOAD",),
("SYSTEM RELOAD DICTIONARIES",),
@ -163,16 +174,24 @@ def dictionary(self, privilege, grant_target_name, user_name, node=None):
node = self.context.node
with Scenario("SYSTEM RELOAD DICTIONARY without privilege"):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
with dict_setup(node, table_name, dict_name):
with When("I check the user is unable to execute SYSTEM RELOAD DICTIONARY"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM RELOAD DICTIONARY"):
node.query(f"SYSTEM RELOAD DICTIONARY default.{dict_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM RELOAD DICTIONARY with privilege"):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
@ -185,6 +204,7 @@ def dictionary(self, privilege, grant_target_name, user_name, node=None):
node.query(f"SYSTEM RELOAD DICTIONARY default.{dict_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM RELOAD DICTIONARY with revoked privilege"):
dict_name = f"dict_{getuid()}"
table_name = f"table_{getuid()}"
@ -212,7 +232,7 @@ def dictionaries_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=dictionaries, flags=TE,
Suite(run=dictionaries,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in dictionaries.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -233,7 +253,7 @@ def dictionaries_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=dictionaries, flags=TE,
Suite(run=dictionaries,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in dictionaries.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -243,6 +263,7 @@ def dictionaries_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_Reload_Dictionaries("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM RELOAD",),
("SYSTEM RELOAD DICTIONARIES",),
@ -258,11 +279,19 @@ def dictionaries(self, privilege, grant_target_name, user_name, node=None):
node = self.context.node
with Scenario("SYSTEM RELOAD DICTIONARIES without privilege"):
with When("I check the user is unable to execute SYSTEM RELOAD DICTIONARIES"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM RELOAD DICTIONARIES"):
node.query("SYSTEM RELOAD DICTIONARIES", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM RELOAD DICTIONARIES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -270,6 +299,7 @@ def dictionaries(self, privilege, grant_target_name, user_name, node=None):
node.query("SYSTEM RELOAD DICTIONARIES", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM RELOAD DICTIONARIES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -292,7 +322,7 @@ def embedded_dictionaries_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=embedded_dictionaries, flags=TE,
Suite(run=embedded_dictionaries,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in embedded_dictionaries.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -313,7 +343,7 @@ def embedded_dictionaries_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=embedded_dictionaries, flags=TE,
Suite(run=embedded_dictionaries,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in embedded_dictionaries.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -323,6 +353,7 @@ def embedded_dictionaries_privileges_granted_via_role(self, node=None):
RQ_SRS_006_RBAC_Privileges_System_Reload_EmbeddedDictionaries("1.0"),
)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM RELOAD",),
("SYSTEM RELOAD EMBEDDED DICTIONARIES",),
@ -337,11 +368,19 @@ def embedded_dictionaries(self, privilege, grant_target_name, user_name, node=No
node = self.context.node
with Scenario("SYSTEM RELOAD EMBEDDED DICTIONARIES without privilege"):
with When("I check the user is unable to execute SYSTEM RELOAD EMBEDDED DICTIONARIES"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user is unable to execute SYSTEM RELOAD EMBEDDED DICTIONARIES"):
node.query("SYSTEM RELOAD EMBEDDED DICTIONARIES", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM RELOAD EMBEDDED DICTIONARIES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -349,6 +388,7 @@ def embedded_dictionaries(self, privilege, grant_target_name, user_name, node=No
node.query("SYSTEM RELOAD EMBEDDED DICTIONARIES", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM RELOAD EMBEDDED DICTIONARIES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")
@ -363,6 +403,8 @@ def embedded_dictionaries(self, privilege, grant_target_name, user_name, node=No
@Name("system reload")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Reload("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM RELOAD.

View File

@ -17,7 +17,7 @@ def replicated_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_replicated_privilege, flags=TE,
Suite(run=check_replicated_privilege,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_replicated_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def replicated_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_replicated_privilege, flags=TE,
Suite(run=check_replicated_privilege,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_replicated_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM REPLICATION QUEUES", "table"),
("SYSTEM STOP REPLICATION QUEUES", "table"),
@ -59,8 +60,8 @@ def check_replicated_privilege(self, privilege, on, grant_target_name, user_name
if node is None:
node = self.context.node
Suite(test=start_replication_queues, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=stop_replication_queues, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=start_replication_queues)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=stop_replication_queues)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
def start_replication_queues(self, privilege, on, grant_target_name, user_name, node=None):
@ -77,11 +78,19 @@ def start_replication_queues(self, privilege, on, grant_target_name, user_name,
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM START REPLICATION QUEUES without privilege"):
with When("I check the user can't start sends"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start sends"):
node.query(f"SYSTEM START REPLICATION QUEUES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START REPLICATION QUEUES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -89,6 +98,7 @@ def start_replication_queues(self, privilege, on, grant_target_name, user_name,
node.query(f"SYSTEM START REPLICATION QUEUES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START REPLICATION QUEUES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -114,11 +124,19 @@ def stop_replication_queues(self, privilege, on, grant_target_name, user_name, n
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM STOP REPLICATION QUEUES without privilege"):
with When("I check the user can't stop sends"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop sends"):
node.query(f"SYSTEM STOP REPLICATION QUEUES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP REPLICATION QUEUES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -126,6 +144,7 @@ def stop_replication_queues(self, privilege, on, grant_target_name, user_name, n
node.query(f"SYSTEM STOP REPLICATION QUEUES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP REPLICATION QUEUES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -140,6 +159,8 @@ def stop_replication_queues(self, privilege, on, grant_target_name, user_name, n
@Name("system replication queues")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_ReplicationQueues("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM REPLICATION QUEUES.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=restart_replica, flags=TE,
Suite(run=restart_replica,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in restart_replica.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=restart_replica, flags=TE,
Suite(run=restart_replica,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in restart_replica.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM RESTART REPLICA", "table"),
("RESTART REPLICA", "table"),
@ -63,11 +64,19 @@ def restart_replica(self, privilege, on, grant_target_name, user_name, node=None
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM RESTART REPLICA without privilege"):
with When("I check the user can't restart replica"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't restart replica"):
node.query(f"SYSTEM RESTART REPLICA {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM RESTART REPLICA with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -75,6 +84,7 @@ def restart_replica(self, privilege, on, grant_target_name, user_name, node=None
node.query(f"SYSTEM RESTART REPLICA {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM RESTART REPLICA with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -89,6 +99,8 @@ def restart_replica(self, privilege, on, grant_target_name, user_name, node=None
@Name("system restart replica")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_RestartReplica("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM RESTART REPLICA.

View File

@ -17,7 +17,7 @@ def replicated_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_replicated_privilege, flags=TE,
Suite(run=check_replicated_privilege,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_replicated_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def replicated_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_replicated_privilege, flags=TE,
Suite(run=check_replicated_privilege,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_replicated_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM SENDS", "*.*"),
("SYSTEM START SENDS", "*.*"),
@ -67,8 +68,8 @@ def check_replicated_privilege(self, privilege, on, grant_target_name, user_name
if node is None:
node = self.context.node
Suite(test=start_replicated_sends, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=stop_replicated_sends, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=start_replicated_sends)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=stop_replicated_sends)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
def start_replicated_sends(self, privilege, on, grant_target_name, user_name, node=None):
@ -85,11 +86,19 @@ def start_replicated_sends(self, privilege, on, grant_target_name, user_name, no
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM START REPLICATED SENDS without privilege"):
with When("I check the user can't start sends"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start sends"):
node.query(f"SYSTEM START REPLICATED SENDS {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START REPLICATED SENDS with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -97,6 +106,7 @@ def start_replicated_sends(self, privilege, on, grant_target_name, user_name, no
node.query(f"SYSTEM START REPLICATED SENDS {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START REPLICATED SENDS with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -122,11 +132,19 @@ def stop_replicated_sends(self, privilege, on, grant_target_name, user_name, nod
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM STOP REPLICATED SENDS without privilege"):
with When("I check the user can't stop sends"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop sends"):
node.query(f"SYSTEM STOP REPLICATED SENDS {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP REPLICATED SENDS with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -134,6 +152,7 @@ def stop_replicated_sends(self, privilege, on, grant_target_name, user_name, nod
node.query(f"SYSTEM STOP REPLICATED SENDS {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP REPLICATED SENDS with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -157,7 +176,7 @@ def distributed_privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(run=check_distributed_privilege, flags=TE,
Suite(run=check_distributed_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[user_name,user_name,table_name]) for row in check_distributed_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -179,13 +198,14 @@ def distributed_privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_distributed_privilege, flags=TE,
Suite(run=check_distributed_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[role_name,user_name,table_name]) for row in check_distributed_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM SENDS", "*.*"),
("SYSTEM START SENDS", "*.*"),
@ -208,8 +228,8 @@ def check_distributed_privilege(self, privilege, on, grant_target_name, user_nam
if node is None:
node = self.context.node
Suite(test=start_distributed_moves, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_distributed_moves, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=start_distributed_moves)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_distributed_moves)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
@TestSuite
def start_distributed_moves(self, privilege, on, grant_target_name, user_name, table_name, node=None):
@ -229,11 +249,19 @@ def start_distributed_moves(self, privilege, on, grant_target_name, user_name, t
node.query(f"CREATE TABLE {table_name} (a UInt64) ENGINE = Distributed(sharded_cluster, default, {table0_name}, rand())")
with Scenario("SYSTEM START DISTRIBUTED SENDS without privilege"):
with When("I check the user can't start merges"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start merges"):
node.query(f"SYSTEM START DISTRIBUTED SENDS {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START DISTRIBUTED SENDS with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -241,6 +269,7 @@ def start_distributed_moves(self, privilege, on, grant_target_name, user_name, t
node.query(f"SYSTEM START DISTRIBUTED SENDS {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START DISTRIBUTED SENDS with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -273,11 +302,19 @@ def stop_distributed_moves(self, privilege, on, grant_target_name, user_name, ta
node.query(f"CREATE TABLE {table_name} (a UInt64) ENGINE = Distributed(sharded_cluster, default, {table0_name}, rand())")
with Scenario("SYSTEM STOP DISTRIBUTED SENDS without privilege"):
with When("I check the user can't stop merges"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop merges"):
node.query(f"SYSTEM STOP DISTRIBUTED SENDS {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP DISTRIBUTED SENDS with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -285,6 +322,7 @@ def stop_distributed_moves(self, privilege, on, grant_target_name, user_name, ta
node.query(f"SYSTEM STOP DISTRIBUTED SENDS {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP DISTRIBUTED SENDS with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -302,6 +340,8 @@ def stop_distributed_moves(self, privilege, on, grant_target_name, user_name, ta
@Name("system sends")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Sends("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM SENDS.

View File

@ -19,7 +19,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@ -40,13 +40,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in check_privilege.examples
], args=Args(name="privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege",[
("ALL",),
("SYSTEM",),
("SYSTEM SHUTDOWN",),
("SHUTDOWN",),
@ -59,8 +60,8 @@ def check_privilege(self, privilege, grant_target_name, user_name, node=None):
if node is None:
node = self.context.node
Suite(test=shutdown, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=kill, setup=instrument_clickhouse_server_log)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=shutdown)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
Suite(test=kill)(privilege=privilege, grant_target_name=grant_target_name, user_name=user_name)
@TestSuite
def shutdown(self, privilege, grant_target_name, user_name, node=None):
@ -75,7 +76,13 @@ def shutdown(self, privilege, grant_target_name, user_name, node=None):
with Scenario("SYSTEM SHUTDOWN without privilege"):
with When("I check the user can't use SYSTEM SHUTDOWN"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SYSTEM SHUTDOWN"):
node.query(f"SYSTEM SHUTDOWN", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -136,7 +143,13 @@ def kill(self, privilege, grant_target_name, user_name, node=None):
with Scenario("SYSTEM KILL without privilege"):
with When("I check the user can't use SYSTEM KILL"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't use SYSTEM KILL"):
node.query(f"SYSTEM KILL", settings=[("user",user_name)],
exitcode=exitcode, message=message)
@ -190,6 +203,8 @@ def kill(self, privilege, grant_target_name, user_name, node=None):
@Name("system shutdown")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_Shutdown("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM SHUTDOWN.

View File

@ -17,7 +17,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
Suite(run=sync_replica, flags=TE,
Suite(run=sync_replica,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[user_name,user_name]) for row in sync_replica.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -38,13 +38,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=sync_replica, flags=TE,
Suite(run=sync_replica,
examples=Examples("privilege on grant_target_name user_name", [
tuple(list(row)+[role_name,user_name]) for row in sync_replica.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM SYNC REPLICA", "table"),
("SYNC REPLICA", "table"),
@ -63,11 +64,19 @@ def sync_replica(self, privilege, on, grant_target_name, user_name, node=None):
with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):
with Scenario("SYSTEM SYNC REPLICA without privilege"):
with When("I check the user can't sync replica"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't sync replica"):
node.query(f"SYSTEM SYNC REPLICA {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM SYNC REPLICA with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -75,6 +84,7 @@ def sync_replica(self, privilege, on, grant_target_name, user_name, node=None):
node.query(f"SYSTEM SYNC REPLICA {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM SYNC REPLICA with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -89,6 +99,8 @@ def sync_replica(self, privilege, on, grant_target_name, user_name, node=None):
@Name("system sync replica")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_SyncReplica("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM SYNC REPLICA.

View File

@ -18,7 +18,7 @@ def privileges_granted_directly(self, node=None):
with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[user_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@ -40,13 +40,14 @@ def privileges_granted_via_role(self, node=None):
with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")
Suite(run=check_privilege, flags=TE,
Suite(run=check_privilege,
examples=Examples("privilege on grant_target_name user_name table_name", [
tuple(list(row)+[role_name,user_name,table_name]) for row in check_privilege.examples
], args=Args(name="check privilege={privilege}", format_name=True)))
@TestOutline(Suite)
@Examples("privilege on",[
("ALL", "*.*"),
("SYSTEM", "*.*"),
("SYSTEM TTL MERGES", "table"),
("SYSTEM STOP TTL MERGES", "table"),
@ -61,8 +62,8 @@ def check_privilege(self, privilege, on, grant_target_name, user_name, table_nam
if node is None:
node = self.context.node
Suite(test=start_ttl_merges, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_ttl_merges, setup=instrument_clickhouse_server_log)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=start_ttl_merges)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
Suite(test=stop_ttl_merges)(privilege=privilege, on=on, grant_target_name=grant_target_name, user_name=user_name, table_name=table_name)
@TestSuite
def start_ttl_merges(self, privilege, on, grant_target_name, user_name, table_name, node=None):
@ -78,11 +79,19 @@ def start_ttl_merges(self, privilege, on, grant_target_name, user_name, table_na
with table(node, table_name):
with Scenario("SYSTEM START TTL MERGES without privilege"):
with When("I check the user can't start merges"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't start merges"):
node.query(f"SYSTEM START TTL MERGES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM START TTL MERGES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -90,6 +99,7 @@ def start_ttl_merges(self, privilege, on, grant_target_name, user_name, table_na
node.query(f"SYSTEM START TTL MERGES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM START TTL MERGES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -114,11 +124,19 @@ def stop_ttl_merges(self, privilege, on, grant_target_name, user_name, table_nam
with table(node, table_name):
with Scenario("SYSTEM STOP TTL MERGES without privilege"):
with When("I check the user can't stop merges"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I check the user can't stop merges"):
node.query(f"SYSTEM STOP TTL MERGES {table_name}", settings = [("user", f"{user_name}")],
exitcode=exitcode, message=message)
with Scenario("SYSTEM STOP TTL MERGES with privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -126,6 +144,7 @@ def stop_ttl_merges(self, privilege, on, grant_target_name, user_name, table_nam
node.query(f"SYSTEM STOP TTL MERGES {table_name}", settings = [("user", f"{user_name}")])
with Scenario("SYSTEM STOP TTL MERGES with revoked privilege"):
with When(f"I grant {privilege} on the table"):
node.query(f"GRANT {privilege} ON {on} TO {grant_target_name}")
@ -140,6 +159,8 @@ def stop_ttl_merges(self, privilege, on, grant_target_name, user_name, table_nam
@Name("system ttl merges")
@Requirements(
RQ_SRS_006_RBAC_Privileges_System_TTLMerges("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SYSTEM TTL MERGES.

View File

@ -12,13 +12,13 @@ def privilege_granted_directly_or_via_role(self, table_type, node=None):
if node is None:
node = self.context.node
with Suite("user with direct privilege", setup=instrument_clickhouse_server_log):
with Suite("user with direct privilege"):
with user(node, user_name):
with When(f"I run checks that {user_name} is only able to execute TRUNCATE with required privileges"):
privilege_check(grant_target_name=user_name, user_name=user_name, table_type=table_type, node=node)
with Suite("user with privilege via role", setup=instrument_clickhouse_server_log):
with Suite("user with privilege via role"):
with user(node, user_name), role(node, role_name):
with When("I grant the role to the user"):
@ -32,16 +32,22 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
"""
exitcode, message = errors.not_enough_privileges(name=f"{user_name}")
with Scenario("user without privilege", setup=instrument_clickhouse_server_log):
with Scenario("user without privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I attempt to truncate a table without privilege"):
with When("I grant the user NONE privilege"):
node.query(f"GRANT NONE TO {grant_target_name}")
with And("I grant the user USAGE privilege"):
node.query(f"GRANT USAGE ON *.* TO {grant_target_name}")
with Then("I attempt to truncate a table without privilege"):
node.query(f"TRUNCATE TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("user with privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
@ -52,7 +58,7 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
with Then("I attempt to truncate a table"):
node.query(f"TRUNCATE TABLE {table_name}", settings = [("user", user_name)])
with Scenario("user with revoked privilege", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
@ -67,7 +73,22 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
node.query(f"TRUNCATE TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("execute on cluster", setup=instrument_clickhouse_server_log):
with Scenario("user with revoked ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I grant the truncate privilege"):
node.query(f"GRANT TRUNCATE ON {table_name} TO {grant_target_name}")
with And("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with Then("I attempt to truncate a table"):
node.query(f"TRUNCATE TABLE {table_name}", settings = [("user", user_name)],
exitcode=exitcode, message=message)
with Scenario("execute on cluster"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
@ -78,9 +99,25 @@ def privilege_check(grant_target_name, user_name, table_type, node=None):
with Then("I attempt to truncate a table"):
node.query(f"TRUNCATE TABLE IF EXISTS {table_name} ON CLUSTER sharded_cluster", settings = [("user", user_name)])
with Scenario("user with ALL privilege"):
table_name = f"merge_tree_{getuid()}"
with table(node, table_name, table_type):
with When("I revoke ALL privilege"):
node.query(f"REVOKE ALL ON *.* FROM {grant_target_name}")
with And("I grant ALL privilege"):
node.query(f"GRANT ALL ON *.* TO {grant_target_name}")
with Then("I attempt to truncate a table"):
node.query(f"TRUNCATE TABLE {table_name}", settings = [("user", user_name)])
@TestFeature
@Requirements(
RQ_SRS_006_RBAC_Privileges_Truncate("1.0"),
RQ_SRS_006_RBAC_Privileges_All("1.0"),
RQ_SRS_006_RBAC_Privileges_None("1.0")
)
@Examples("table_type", [
(key,) for key in table_types.keys()
@ -103,5 +140,5 @@ def feature(self, node="clickhouse1", stress=None, parallel=None):
continue
with Example(str(example)):
with Suite(test=privilege_granted_directly_or_via_role):
with Suite(test=privilege_granted_directly_or_via_role, setup=instrument_clickhouse_server_log):
privilege_granted_directly_or_via_role(table_type=table_type)

View File

@ -33,12 +33,12 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER user0")
node.query(f"CREATE ROLE role0")
with Scenario("I alter quota with no options", flags=TE, requirements=[
with Scenario("I alter quota with no options", requirements=[
RQ_SRS_006_RBAC_Quota_Alter("1.0")]):
with When("I alter quota"):
node.query("ALTER QUOTA quota0")
with Scenario("I alter quota that does not exist, throws an exception", flags=TE, requirements=[
with Scenario("I alter quota that does not exist, throws an exception", requirements=[
RQ_SRS_006_RBAC_Quota_Alter("1.0")]):
quota = "quota1"
cleanup_quota(quota)
@ -47,11 +47,11 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER QUOTA {quota}", exitcode=exitcode, message=message)
del quota
with Scenario("I alter quota with if exists, quota does exist", flags=TE, requirements=[
with Scenario("I alter quota with if exists, quota does exist", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_IfExists("1.0")]):
node.query("ALTER QUOTA IF EXISTS quota0")
with Scenario("I alter quota with if exists, quota does not exist", flags=TE, requirements=[
with Scenario("I alter quota with if exists, quota does not exist", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_IfExists("1.0")]):
quota = "quota1"
cleanup_quota(quota)
@ -59,11 +59,11 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER QUOTA IF EXISTS {quota}")
del quota
with Scenario("I alter quota using rename, target available", flags=TE, requirements=[
with Scenario("I alter quota using rename, target available", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Rename("1.0")]):
node.query("ALTER QUOTA quota0 RENAME TO quota0")
with Scenario("I alter quota using rename, target unavailable", flags=TE, requirements=[
with Scenario("I alter quota using rename, target unavailable", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Rename("1.0")]):
new_quota = "quota1"
@ -82,20 +82,20 @@ def feature(self, node="clickhouse1"):
keys = ['none', 'user name', 'ip address', 'client key', 'client key or user name', 'client key or ip address']
for key in keys:
with Scenario(f"I alter quota keyed by {key}", flags=TE, requirements=[
with Scenario(f"I alter quota keyed by {key}", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_KeyedBy("1.0"),
RQ_SRS_006_RBAC_Quota_Alter_KeyedByOptions("1.0")]):
with When("I alter quota with a key"):
node.query(f"ALTER QUOTA quota0 KEYED BY '{key}'")
with Scenario("I alter quota for randomized interval", flags=TE, requirements=[
with Scenario("I alter quota for randomized interval", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Interval_Randomized("1.0")]):
with When("I alter quota on a randomized interval"):
node.query("ALTER QUOTA quota0 FOR RANDOMIZED INTERVAL 1 DAY NO LIMITS")
intervals = ['SECOND', 'MINUTE', 'HOUR', 'DAY', 'MONTH']
for i, interval in enumerate(intervals):
with Scenario(f"I alter quota for interval {interval}", flags=TE, requirements=[
with Scenario(f"I alter quota for interval {interval}", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Interval("1.0")]):
with When(f"I alter quota for {interval}"):
node.query(f"ALTER QUOTA quota0 FOR INTERVAL 1 {interval} NO LIMITS")
@ -104,7 +104,7 @@ def feature(self, node="clickhouse1"):
'MAX RESULT BYTES', 'MAX READ ROWS', 'MAX READ BYTES', 'MAX EXECUTION TIME',
'NO LIMITS', 'TRACKING ONLY']
for i, constraint in enumerate(constraints):
with Scenario(f"I alter quota for {constraint.lower()}", flags=TE, requirements=[
with Scenario(f"I alter quota for {constraint.lower()}", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Queries("1.0"),
RQ_SRS_006_RBAC_Quota_Alter_Errors("1.0"),
RQ_SRS_006_RBAC_Quota_Alter_ResultRows("1.0"),
@ -117,7 +117,7 @@ def feature(self, node="clickhouse1"):
with When("I alter quota for a constraint"):
node.query(f"ALTER QUOTA quota0 FOR INTERVAL 1 DAY {constraint}{' 1024' if constraint.startswith('MAX') else ''}")
with Scenario("I create quota for multiple constraints", flags=TE, requirements=[
with Scenario("I create quota for multiple constraints", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Interval("1.0"),
RQ_SRS_006_RBAC_Quota_Alter_Queries("1.0")]):
node.query("ALTER QUOTA quota0 \
@ -125,12 +125,12 @@ def feature(self, node="clickhouse1"):
FOR INTERVAL 2 DAY MAX QUERIES 124, \
FOR INTERVAL 1 MONTH TRACKING ONLY")
with Scenario("I alter quota to assign to one role", flags=TE, requirements=[
with Scenario("I alter quota to assign to one role", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]):
with When("I alter quota to a role"):
node.query("ALTER QUOTA quota0 TO role0")
with Scenario("I alter quota to assign to role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter quota to assign to role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -140,7 +140,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER QUOTA quota0 TO {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter quota to assign to all except role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter quota to assign to all except role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -150,32 +150,32 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER QUOTA quota0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter quota to assign to one role and one user", flags=TE, requirements=[
with Scenario("I alter quota to assign to one role and one user", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]):
with When("I alter quota to a role and a user"):
node.query("ALTER QUOTA quota0 TO role0, user0")
with Scenario("I alter quota assigned to none", flags=TE, requirements=[
with Scenario("I alter quota assigned to none", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment_None("1.0")]):
with When("I alter quota to none"):
node.query("ALTER QUOTA quota0 TO NONE")
with Scenario("I alter quota to assign to all", flags=TE, requirements=[
with Scenario("I alter quota to assign to all", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment_All("1.0")]):
with When("I alter quota to all"):
node.query("ALTER QUOTA quota0 TO ALL")
with Scenario("I alter quota to assign to all except one role", flags=TE, requirements=[
with Scenario("I alter quota to assign to all except one role", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment_Except("1.0")]):
with When("I alter quota to all except one role"):
node.query("ALTER QUOTA quota0 TO ALL EXCEPT role0")
with Scenario("I alter quota to assign to all except multiple roles", flags=TE, requirements=[
with Scenario("I alter quota to assign to all except multiple roles", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Assignment_Except("1.0")]):
with When("I alter quota to all except one multiple roles"):
node.query("ALTER QUOTA quota0 TO ALL EXCEPT role0, user0")
with Scenario("I alter quota on cluster", flags=TE, requirements=[
with Scenario("I alter quota on cluster", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Cluster("1.0")]):
try:
with Given("I have a quota on a cluster"):
@ -193,7 +193,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the quota"):
node.query("DROP QUOTA IF EXISTS quota1 ON CLUSTER sharded_cluster")
with Scenario("I alter quota on nonexistent cluster, throws exception", flags=TE, requirements=[
with Scenario("I alter quota on nonexistent cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Alter_Cluster("1.0")]):
with When("I run alter quota on a cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -38,13 +38,13 @@ def feature(self, node="clickhouse1"):
with Given(f"I ensure that role {role} does not exist"):
node.query(f"DROP ROLE IF EXISTS {role}")
with Scenario("I alter role with no options", flags=TE, requirements=[
with Scenario("I alter role with no options", requirements=[
RQ_SRS_006_RBAC_Role_Alter("1.0")]):
with setup("role0"):
with When("I alter role"):
node.query("ALTER ROLE role0")
with Scenario("I alter role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Alter("1.0")]):
role = "role0"
cleanup_role(role)
@ -53,13 +53,13 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER ROLE {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter role if exists, role does exist", flags=TE, requirements=[
with Scenario("I alter role if exists, role does exist", requirements=[
RQ_SRS_006_RBAC_Role_Alter_IfExists("1.0")]):
with setup("role1"):
with When("I alter role with if exists"):
node.query("ALTER ROLE IF EXISTS role1")
with Scenario("I alter role if exists, role does not exist", flags=TE, requirements=[
with Scenario("I alter role if exists, role does not exist", requirements=[
RQ_SRS_006_RBAC_Role_Alter_IfExists("1.0")]):
role = "role0"
cleanup_role(role)
@ -67,7 +67,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER ROLE IF EXISTS {role}")
del role
with Scenario("I alter role on cluster", flags=TE, requirements=[
with Scenario("I alter role on cluster", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Cluster("1.0")]):
try:
with Given("I have a role on a cluster"):
@ -82,13 +82,13 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the role"):
node.query("DROP ROLE IF EXISTS role1,role2 ON CLUSTER sharded_cluster")
with Scenario("I alter role on nonexistent cluster, throws exception", flags=TE, requirements=[
with Scenario("I alter role on nonexistent cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Cluster("1.0")]):
with When("I run alter role on a cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")
node.query("ALTER ROLE role1 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
with Scenario("I alter role to rename, new name is available", flags=TE, requirements=[
with Scenario("I alter role to rename, new name is available", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Rename("1.0")]):
with setup("role2"):
new_role = "role3"
@ -102,7 +102,7 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP ROLE IF EXISTS {new_role}")
del new_role
with Scenario("I alter role to rename, new name is not available, throws exception", flags=TE, requirements=[
with Scenario("I alter role to rename, new name is not available, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Rename("1.0")]):
with setup("role2a"):
new_role = "role3a"
@ -117,13 +117,13 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP ROLE IF EXISTS {new_role}")
del new_role
with Scenario("I alter role settings profile", flags=TE, requirements=[
with Scenario("I alter role settings profile", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role4"):
with When("I alter role with settings profile"):
node.query("ALTER ROLE role4 SETTINGS PROFILE default, max_memory_usage=10000000 READONLY")
with Scenario("I alter role settings profile, profile does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter role settings profile, profile does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role4a"):
with Given("I ensure profile profile0 does not exist"):
@ -132,20 +132,20 @@ def feature(self, node="clickhouse1"):
exitcode, message = errors.settings_profile_not_found_in_disk("profile0")
node.query("ALTER ROLE role4a SETTINGS PROFILE profile0", exitcode=exitcode, message=message)
with Scenario("I alter role settings profile multiple", flags=TE, requirements=[
with Scenario("I alter role settings profile multiple", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role4b", profile="profile0"):
with When("I alter role with multiple profiles"):
node.query("ALTER ROLE role4b SETTINGS PROFILE default, PROFILE profile0, \
max_memory_usage=10000000 READONLY")
with Scenario("I alter role settings without profile", flags=TE, requirements=[
with Scenario("I alter role settings without profile", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role5"):
with When("I alter role with settings and no profile"):
node.query("ALTER ROLE role5 SETTINGS max_memory_usage=10000000 READONLY")
with Scenario("I alter role settings, variable does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter role settings, variable does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role5a"):
with When("I alter role using settings and nonexistent value"):
@ -153,33 +153,33 @@ def feature(self, node="clickhouse1"):
node.query("ALTER ROLE role5a SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message)
with Scenario("I alter role settings without profile multiple", flags=TE, requirements=[
with Scenario("I alter role settings without profile multiple", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role6"):
with When("I alter role with multiple settings and no profile"):
node.query("ALTER ROLE role6 SETTINGS max_memory_usage=10000000 READONLY, \
max_rows_to_read MIN 20 MAX 25")
with Scenario("I alter role settings with multiple profiles multiple variables", flags=TE, requirements=[
with Scenario("I alter role settings with multiple profiles multiple variables", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role7", profile="profile1"):
with When("I alter role with multiple settings and profiles"):
node.query("ALTER ROLE role7 SETTINGS PROFILE default, PROFILE profile1, \
max_memory_usage=10000000 READONLY, max_rows_to_read MIN 20 MAX 25")
with Scenario("I alter role settings readonly", flags=TE, requirements=[
with Scenario("I alter role settings readonly", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role8"):
with When("I alter role with readonly"):
node.query("ALTER ROLE role8 SETTINGS max_memory_usage READONLY")
with Scenario("I alter role settings writable", flags=TE, requirements=[
with Scenario("I alter role settings writable", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role9"):
with When("I alter role with writable"):
node.query("ALTER ROLE role9 SETTINGS max_memory_usage WRITABLE")
with Scenario("I alter role settings min, with and without = sign", flags=TE, requirements=[
with Scenario("I alter role settings min, with and without = sign", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role10"):
with When("I set min, no equals"):
@ -187,7 +187,7 @@ def feature(self, node="clickhouse1"):
with When("I set min, yes equals"):
node.query("ALTER ROLE role10 SETTINGS max_memory_usage MIN = 200")
with Scenario("I alter role settings max, with and without = sign", flags=TE, requirements=[
with Scenario("I alter role settings max, with and without = sign", requirements=[
RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]):
with setup("role11"):
with When("I set max, no equals"):

View File

@ -42,21 +42,21 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE role0")
node.query(f"CREATE ROLE role1")
with Scenario("I alter row policy with no options", flags=TE, requirements=[
with Scenario("I alter row policy with no options", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy0"):
with When("I alter row policy"):
node.query("ALTER ROW POLICY policy0 ON default.foo")
with Scenario("I alter row policy using short syntax with no options", flags=TE, requirements=[
with Scenario("I alter row policy using short syntax with no options", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy1"):
with When("I alter row policy short form"):
node.query("ALTER POLICY policy1 ON default.foo")
with Scenario("I alter row policy, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter row policy, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
policy = "policy2"
@ -66,14 +66,14 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER ROW POLICY {policy} ON default.foo", exitcode=exitcode, message=message)
del policy
with Scenario("I alter row policy if exists", flags=TE, requirements=[
with Scenario("I alter row policy if exists", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_IfExists("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy2"):
with When("I alter row policy using if exists"):
node.query("ALTER ROW POLICY IF EXISTS policy2 ON default.foo")
with Scenario("I alter row policy if exists, policy does not exist", flags=TE, requirements=[
with Scenario("I alter row policy if exists, policy does not exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_IfExists("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
policy = "policy2"
@ -82,14 +82,14 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER ROW POLICY IF EXISTS {policy} ON default.foo")
del policy
with Scenario("I alter row policy to rename, target available", flags=TE, requirements=[
with Scenario("I alter row policy to rename, target available", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Rename("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy3"):
with When("I alter row policy with rename"):
node.query("ALTER ROW POLICY policy3 ON default.foo RENAME TO policy3")
with Scenario("I alter row policy to rename, target unavailable", flags=TE, requirements=[
with Scenario("I alter row policy to rename, target unavailable", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Rename("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy3"):
@ -106,49 +106,49 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP ROW POLICY IF EXISTS {new_policy} ON default.foo")
del new_policy
with Scenario("I alter row policy to permissive", flags=TE, requirements=[
with Scenario("I alter row policy to permissive", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Access_Permissive("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy4"):
with When("I alter row policy as permissive"):
node.query("ALTER ROW POLICY policy4 ON default.foo AS PERMISSIVE")
with Scenario("I alter row policy to restrictive", flags=TE, requirements=[
with Scenario("I alter row policy to restrictive", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Access_Restrictive("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy5"):
with When("I alter row policy as restrictive"):
node.query("ALTER ROW POLICY policy5 ON default.foo AS RESTRICTIVE")
with Scenario("I alter row policy for select", flags=TE, requirements=[
with Scenario("I alter row policy for select", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_ForSelect("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy6"):
with When("I alter row policy using for select"):
node.query("ALTER ROW POLICY policy6 ON default.foo FOR SELECT USING x > 10")
with Scenario("I alter row policy using condition", flags=TE, requirements=[
with Scenario("I alter row policy using condition", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Condition("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy6"):
with When("I alter row policy wtih condition"):
node.query("ALTER ROW POLICY policy6 ON default.foo USING x > 10")
with Scenario("I alter row policy using condition none", flags=TE, requirements=[
with Scenario("I alter row policy using condition none", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Condition_None("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy7"):
with When("I alter row policy using no condition"):
node.query("ALTER ROW POLICY policy7 ON default.foo USING NONE")
with Scenario("I alter row policy to one role", flags=TE, requirements=[
with Scenario("I alter row policy to one role", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy8"):
with When("I alter row policy to a role"):
node.query("ALTER ROW POLICY policy8 ON default.foo TO role0")
with Scenario("I alter row policy to assign to role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter row policy to assign to role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0")]):
role = "role2"
with cleanup("policy8a"):
@ -159,7 +159,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER ROW POLICY policy8a ON default.foo TO {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter row policy to assign to all excpet role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter row policy to assign to all excpet role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0")]):
role = "role2"
with cleanup("policy8a"):
@ -170,35 +170,35 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER ROW POLICY policy8a ON default.foo TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter row policy assigned to multiple roles", flags=TE, requirements=[
with Scenario("I alter row policy assigned to multiple roles", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy9"):
with When("I alter row policy to multiple roles"):
node.query("ALTER ROW POLICY policy9 ON default.foo TO role0, role1")
with Scenario("I alter row policy assigned to all", flags=TE, requirements=[
with Scenario("I alter row policy assigned to all", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_All("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy10"):
with When("I alter row policy to all"):
node.query("ALTER ROW POLICY policy10 ON default.foo TO ALL")
with Scenario("I alter row policy assigned to all except one role", flags=TE, requirements=[
with Scenario("I alter row policy assigned to all except one role", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_AllExcept("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy11"):
with When("I alter row policy to all except"):
node.query("ALTER ROW POLICY policy11 ON default.foo TO ALL EXCEPT role0")
with Scenario("I alter row policy assigned to all except multiple roles", flags=TE, requirements=[
with Scenario("I alter row policy assigned to all except multiple roles", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_AllExcept("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy12"):
with When("I alter row policy to all except multiple roles"):
node.query("ALTER ROW POLICY policy12 ON default.foo TO ALL EXCEPT role0, role1")
with Scenario("I alter row policy assigned to none", flags=TE, requirements=[
with Scenario("I alter row policy assigned to none", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_None("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with cleanup("policy12"):
@ -208,7 +208,7 @@ def feature(self, node="clickhouse1"):
# Official syntax: ON CLUSTER cluster_name ON database.table
# Working syntax: both orderings of ON CLUSTER and TABLE clauses work
with Scenario("I alter row policy on cluster", flags=TE, requirements=[
with Scenario("I alter row policy on cluster", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
try:
@ -220,14 +220,14 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the row policy"):
node.query("DROP ROW POLICY IF EXISTS policy13 ON CLUSTER sharded_cluster ON default.foo")
with Scenario("I alter row policy on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I alter row policy on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
with When("I run alter row policy command"):
exitcode, message = errors.cluster_not_found("fake_cluster")
node.query("ALTER ROW POLICY policy13 ON CLUSTER fake_cluster ON default.foo", exitcode=exitcode, message=message)
with Scenario("I alter row policy on cluster after table", flags=TE, requirements=[
with Scenario("I alter row policy on cluster after table", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
try:

View File

@ -31,15 +31,15 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER user0")
node.query(f"CREATE ROLE role0")
with Scenario("I alter settings profile with no options", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
with Scenario("I alter settings profile with no options", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
with When("I alter settings profile"):
node.query("ALTER SETTINGS PROFILE profile0")
with Scenario("I alter settings profile short form", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
with Scenario("I alter settings profile short form", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
with When("I short form alter settings profile"):
node.query("ALTER PROFILE profile0")
with Scenario("I alter settings profile that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
with Scenario("I alter settings profile that does not exist, throws exception", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
profile = "profile1"
cleanup_profile(profile)
@ -48,11 +48,11 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER SETTINGS PROFILE {profile}", exitcode=exitcode, message=message)
del profile
with Scenario("I alter settings profile if exists", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0")]):
with Scenario("I alter settings profile if exists", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0")]):
with When("I alter settings profile using if exists"):
node.query("ALTER SETTINGS PROFILE IF EXISTS profile0")
with Scenario("I alter settings profile if exists, profile does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0")]):
with Scenario("I alter settings profile if exists, profile does not exist", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0")]):
profile = "profile1"
cleanup_profile(profile)
@ -61,11 +61,11 @@ def feature(self, node="clickhouse1"):
del profile
with Scenario("I alter settings profile to rename, target available", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0")]):
with Scenario("I alter settings profile to rename, target available", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0")]):
with When("I alter settings profile by renaming it"):
node.query("ALTER SETTINGS PROFILE profile0 RENAME TO profile0")
with Scenario("I alter settings profile to rename, target unavailable", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0")]):
with Scenario("I alter settings profile to rename, target unavailable", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0")]):
new_profile = "profile1"
try:
@ -81,52 +81,52 @@ def feature(self, node="clickhouse1"):
del new_profile
with Scenario("I alter settings profile with a setting value", flags=TE, requirements=[
with Scenario("I alter settings profile with a setting value", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
with When("I alter settings profile using settings"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage = 100000001")
with Scenario("I alter settings profile with a setting value, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter settings profile with a setting value, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
with When("I alter settings profile using settings and nonexistent value"):
exitcode, message = errors.unknown_setting("fake_setting")
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message)
with Scenario("I alter settings profile with a min setting value", flags=TE, requirements=[
with Scenario("I alter settings profile with a min setting value", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
with When("I alter settings profile using 2 minimum formats"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN 100000001")
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN = 100000001")
with Scenario("I alter settings profile with a max setting value", flags=TE, requirements=[
with Scenario("I alter settings profile with a max setting value", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
with When("I alter settings profile using 2 maximum formats"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MAX 100000001")
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MAX = 100000001")
with Scenario("I alter settings profile with min and max setting values", flags=TE, requirements=[
with Scenario("I alter settings profile with min and max setting values", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
with When("I alter settings profile with both min and max"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN 100000001 MAX 200000001")
with Scenario("I alter settings profile with a readonly setting", flags=TE, requirements=[
with Scenario("I alter settings profile with a readonly setting", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
with When("I alter settings profile with with readonly"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage READONLY")
with Scenario("I alter settings profile with a writable setting", flags=TE, requirements=[
with Scenario("I alter settings profile with a writable setting", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
with When("I alter settings profile with writable"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage WRITABLE")
with Scenario("I alter settings profile with inherited settings", flags=TE, requirements=[
with Scenario("I alter settings profile with inherited settings", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_Inherit("1.0")]):
with When("I alter settings profile with inherit"):
node.query("ALTER SETTINGS PROFILE profile0 SETTINGS INHERIT 'default'")
with Scenario("I alter settings profile with inherit, parent profile does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter settings profile with inherit, parent profile does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_Inherit("1.0")]):
profile = "profile3"
with Given(f"I ensure that profile {profile} does not exist"):
@ -136,7 +136,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER PROFILE profile0 SETTINGS INHERIT {profile}", exitcode=exitcode, message=message)
del profile
with Scenario("I alter settings profile with multiple settings", flags=TE, requirements=[
with Scenario("I alter settings profile with multiple settings", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
with When("I alter settings profile with multiple settings"):
@ -144,7 +144,7 @@ def feature(self, node="clickhouse1"):
" SETTINGS max_memory_usage = 100000001"
" SETTINGS max_memory_usage_for_user = 100000001")
with Scenario("I alter settings profile with multiple settings short form", flags=TE, requirements=[
with Scenario("I alter settings profile with multiple settings short form", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
with When("I alter settings profile with short form multiple settings"):
@ -152,12 +152,12 @@ def feature(self, node="clickhouse1"):
" SETTINGS max_memory_usage = 100000001,"
" max_memory_usage_for_user = 100000001")
with Scenario("I alter settings profile assigned to one role", flags=TE, requirements=[
with Scenario("I alter settings profile assigned to one role", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
with When("I alter settings profile with assignment to role"):
node.query("ALTER SETTINGS PROFILE profile0 TO role0")
with Scenario("I alter settings profile to assign to role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter settings profile to assign to role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -167,7 +167,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER SETTINGS PROFILE profile0 TO {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter settings profile to assign to all except role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I alter settings profile to assign to all except role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -177,32 +177,32 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
del role
with Scenario("I alter settings profile assigned to multiple roles", flags=TE, requirements=[
with Scenario("I alter settings profile assigned to multiple roles", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
with When("I alter settings profile with assignment to multiple roles"):
node.query("ALTER SETTINGS PROFILE profile0 TO role0, user0")
with Scenario("I alter settings profile assigned to all", flags=TE, requirements=[
with Scenario("I alter settings profile assigned to all", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_All("1.0")]):
with When("I alter settings profile with assignment to all"):
node.query("ALTER SETTINGS PROFILE profile0 TO ALL")
with Scenario("I alter settings profile assigned to all except one role", flags=TE, requirements=[
with Scenario("I alter settings profile assigned to all except one role", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_AllExcept("1.0")]):
with When("I alter settings profile with assignment to all except a role"):
node.query("ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT role0")
with Scenario("I alter settings profile assigned to all except multiple roles", flags=TE, requirements=[
with Scenario("I alter settings profile assigned to all except multiple roles", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_AllExcept("1.0")]):
with When("I alter settings profile with assignmentto all except multiple roles"):
node.query("ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT role0, user0")
with Scenario("I alter settings profile assigned to none", flags=TE, requirements=[
with Scenario("I alter settings profile assigned to none", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_None("1.0")]):
with When("I alter settings profile with assignment to none"):
node.query("ALTER SETTINGS PROFILE profile0 TO NONE")
with Scenario("I alter settings profile on cluster", flags=TE, requirements=[
with Scenario("I alter settings profile on cluster", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_OnCluster("1.0")]):
try:
with Given("I have a settings profile on cluster"):
@ -219,7 +219,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the settings profile"):
node.query("DROP SETTINGS PROFILE IF EXISTS profile1 ON CLUSTER sharded_cluster")
with Scenario("I alter settings profile on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I alter settings profile on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_OnCluster("1.0")]):
with When("I run alter settings profile command"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -30,28 +30,28 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER OR REPLACE {user}")
yield
finally:
with Finally("I drop the user", flags=TE):
with Finally("I drop the user"):
node.query(f"DROP USER IF EXISTS {user}")
with Scenario("I alter user, base command", flags=TE, requirements=[
with Scenario("I alter user, base command", requirements=[
RQ_SRS_006_RBAC_User_Alter("1.0")]):
with setup("user0"):
with When("I alter user"):
node.query("ALTER USER user0")
with Scenario("I alter user that does not exist without if exists, throws exception", flags=TE, requirements=[
with Scenario("I alter user that does not exist without if exists, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Alter("1.0")]):
with When("I run alter user command, expecting error 192"):
exitcode, message = errors.user_not_found_in_disk(name="user0")
node.query(f"ALTER USER user0",exitcode=exitcode, message=message)
with Scenario("I alter user with if exists", flags=TE, requirements=[
with Scenario("I alter user with if exists", requirements=[
RQ_SRS_006_RBAC_User_Alter_IfExists("1.0")]):
with setup("user0"):
with When(f"I alter user with if exists"):
node.query(f"ALTER USER IF EXISTS user0")
with Scenario("I alter user that does not exist with if exists", flags=TE, requirements=[
with Scenario("I alter user that does not exist with if exists", requirements=[
RQ_SRS_006_RBAC_User_Alter_IfExists("1.0")]):
user = "user0"
with Given("I don't have a user"):
@ -60,7 +60,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER USER IF EXISTS {user}")
del user
with Scenario("I alter user on a cluster", flags=TE, requirements=[
with Scenario("I alter user on a cluster", requirements=[
RQ_SRS_006_RBAC_User_Alter_Cluster("1.0")]):
with Given("I have a user on a cluster"):
node.query("CREATE USER OR REPLACE user0 ON CLUSTER sharded_cluster")
@ -69,19 +69,19 @@ def feature(self, node="clickhouse1"):
with Finally("I drop user from cluster"):
node.query("DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster")
with Scenario("I alter user on a fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I alter user on a fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Alter_Cluster("1.0")]):
with When("I alter user on a fake cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")
node.query("ALTER USER user0 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
with Scenario("I alter user to rename, target available", flags=TE, requirements=[
with Scenario("I alter user to rename, target available", requirements=[
RQ_SRS_006_RBAC_User_Alter_Rename("1.0")]):
with setup("user15"):
with When("I alter user name"):
node.query("ALTER USER user15 RENAME TO user15")
with Scenario("I alter user to rename, target unavailable", flags=TE, requirements=[
with Scenario("I alter user to rename, target unavailable", requirements=[
RQ_SRS_006_RBAC_User_Alter_Rename("1.0")]):
with setup("user15"):
new_user = "user16"
@ -96,20 +96,20 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP USER IF EXISTS {new_user}")
del new_user
with Scenario("I alter user password plaintext password", flags=TE, requirements=[
with Scenario("I alter user password plaintext password", requirements=[
RQ_SRS_006_RBAC_User_Alter_Password_PlainText("1.0")]):
with setup("user1"):
with When("I alter user with plaintext password"):
node.query("ALTER USER user1 IDENTIFIED WITH PLAINTEXT_PASSWORD BY 'mypassword'", step=When)
with Scenario("I alter user password to sha256", flags=TE, requirements=[
with Scenario("I alter user password to sha256", requirements=[
RQ_SRS_006_RBAC_User_Alter_Password_Sha256Password("1.0")]):
with setup("user2"):
with When("I alter user with sha256_password"):
password = hashlib.sha256("mypassword".encode("utf-8")).hexdigest()
node.query(f"ALTER USER user2 IDENTIFIED WITH SHA256_PASSWORD BY '{password}'",step=When)
with Scenario("I alter user password to double_sha1_password", flags=TE, requirements=[
with Scenario("I alter user password to double_sha1_password", requirements=[
RQ_SRS_006_RBAC_User_Alter_Password_DoubleSha1Password("1.0")]):
with setup("user3"):
with When("I alter user with double_sha1_password"):
@ -118,56 +118,56 @@ def feature(self, node="clickhouse1"):
password = hash(hash("mypassword"))
node.query(f"ALTER USER user3 IDENTIFIED WITH DOUBLE_SHA1_PASSWORD BY '{password}'", step=When)
with Scenario("I alter user host local", flags=TE, requirements=[
with Scenario("I alter user host local", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_Local("1.0")]):
with setup("user4"):
with When("I alter user with host local"):
node.query("ALTER USER user4 HOST LOCAL")
with Scenario("I alter user host name", flags=TE, requirements=[
with Scenario("I alter user host name", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_Name("1.0")]):
with setup("user5"):
with When("I alter user with host name"):
node.query("ALTER USER user5 HOST NAME 'localhost', NAME 'clickhouse.com'")
with Scenario("I alter user host regexp", flags=TE, requirements=[
with Scenario("I alter user host regexp", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_Regexp("1.0")]):
with setup("user6"):
with When("I alter user with host regexp"):
node.query("ALTER USER user6 HOST REGEXP 'lo..*host', 'lo*host'")
with Scenario("I alter user host ip", flags=TE, requirements=[
with Scenario("I alter user host ip", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_IP("1.0")]):
with setup("user7"):
with When("I alter user with host ip"):
node.query("ALTER USER user7 HOST IP '127.0.0.1', IP '127.0.0.2'")
with Scenario("I alter user host like", flags=TE, requirements=[
with Scenario("I alter user host like", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_Like("1.0")]):
with setup("user8"):
with When("I alter user with host like"):
node.query("ALTER USER user8 HOST LIKE '%.clickhouse.com'")
with Scenario("I alter user host any", flags=TE, requirements=[
with Scenario("I alter user host any", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_Any("1.0")]):
with setup("user9"):
with When("I alter user with host any"):
node.query("ALTER USER user9 HOST ANY")
with Scenario("I alter user host many hosts", flags=TE, requirements=[
with Scenario("I alter user host many hosts", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_Like("1.0")]):
with setup("user11"):
with When("I alter user with multiple hosts"):
node.query("ALTER USER user11 HOST LIKE '%.clickhouse.com', \
IP '127.0.0.2', NAME 'localhost', REGEXP 'lo*host'")
with Scenario("I alter user default role set to none", flags=TE, requirements=[
with Scenario("I alter user default role set to none", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_None("1.0")]):
with setup("user12"):
with When("I alter user with default role none"):
node.query("ALTER USER user12 DEFAULT ROLE NONE")
with Scenario("I alter user default role set to all", flags=TE, requirements=[
with Scenario("I alter user default role set to all", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole_All("1.0")]):
with setup("user13"):
with When("I alter user with all roles set to default"):
@ -183,7 +183,7 @@ def feature(self, node="clickhouse1"):
with Finally(f"I drop the role {role}", flags=TE):
node.query(f"DROP ROLE IF EXISTS {role}")
with Scenario("I alter user default role", flags=TE, requirements=[
with Scenario("I alter user default role", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
with setup("user14"), setup_role("role2"):
with Given("I have a user with a role"):
@ -191,7 +191,7 @@ def feature(self, node="clickhouse1"):
with When("I alter user default role"):
node.query("ALTER USER user14 DEFAULT ROLE role2")
with Scenario("I alter user default role, setting default role", flags=TE, requirements=[
with Scenario("I alter user default role, setting default role", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
with setup("user14a"), setup_role("default"):
with Given("I grant default role to the user"):
@ -199,7 +199,7 @@ def feature(self, node="clickhouse1"):
with When("I alter user default role"):
node.query("ALTER USER user14a DEFAULT ROLE default")
with Scenario("I alter user default role, role doesn't exist, throws exception", flags=TE, requirements=[
with Scenario("I alter user default role, role doesn't exist, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
with setup("user12"):
role = "role0"
@ -210,7 +210,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER USER user12 DEFAULT ROLE {role}",exitcode=exitcode, message=message)
del role
with Scenario("I alter user default role, all except role doesn't exist, throws exception", flags=TE, requirements=[
with Scenario("I alter user default role, all except role doesn't exist, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
with setup("user12"):
role = "role0"
@ -221,7 +221,7 @@ def feature(self, node="clickhouse1"):
node.query(f"ALTER USER user12 DEFAULT ROLE ALL EXCEPT {role}",exitcode=exitcode, message=message)
del role
with Scenario("I alter user default role multiple", flags=TE, requirements=[
with Scenario("I alter user default role multiple", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
with setup("user15"), setup_role("second"), setup_role("third"):
with Given("I have a user with multiple roles"):
@ -229,7 +229,7 @@ def feature(self, node="clickhouse1"):
with When("I alter user default role to second, third"):
node.query("ALTER USER user15 DEFAULT ROLE second, third")
with Scenario("I alter user default role set to all except", flags=TE, requirements=[
with Scenario("I alter user default role set to all except", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole_AllExcept("1.0")]):
with setup("user16"), setup_role("second"):
with Given("I have a user with a role"):
@ -237,7 +237,7 @@ def feature(self, node="clickhouse1"):
with When("I alter user default role"):
node.query("ALTER USER user16 DEFAULT ROLE ALL EXCEPT second")
with Scenario("I alter user default role multiple all except", flags=TE, requirements=[
with Scenario("I alter user default role multiple all except", requirements=[
RQ_SRS_006_RBAC_User_Alter_DefaultRole_AllExcept("1.0")]):
with setup("user17"), setup_role("second"), setup_role("third"):
with Given("I have a user with multiple roles"):
@ -245,7 +245,7 @@ def feature(self, node="clickhouse1"):
with When("I alter user default role to all except second"):
node.query("ALTER USER user17 DEFAULT ROLE ALL EXCEPT second")
with Scenario("I alter user settings profile", flags=TE, requirements=[
with Scenario("I alter user settings profile", requirements=[
RQ_SRS_006_RBAC_User_Alter_Settings("1.0"), \
RQ_SRS_006_RBAC_User_Alter_Settings_Profile("1.0")]):
with setup("user18"):
@ -258,7 +258,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the profile"):
node.query(f"DROP SETTINGS PROFILE profile10")
with Scenario("I alter user settings profile, fake profile, throws exception", flags=TE, requirements=[
with Scenario("I alter user settings profile, fake profile, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),
RQ_SRS_006_RBAC_User_Alter_Settings_Profile("1.0")]):
with setup("user18a"):
@ -270,14 +270,14 @@ def feature(self, node="clickhouse1"):
node.query("ALTER USER user18a SETTINGS PROFILE profile0", exitcode=exitcode, message=message)
del profile
with Scenario("I alter user settings with a fake setting, throws exception", flags=TE, requirements=[
with Scenario("I alter user settings with a fake setting, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Alter_Settings("1.0")]):
with setup("user18b"):
with When("I alter settings profile using settings and nonexistent value"):
exitcode, message = errors.unknown_setting("fake_setting")
node.query("ALTER USER user18b SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message)
with Scenario("I alter user settings without profile (no equals)", flags=TE, requirements=[
with Scenario("I alter user settings without profile (no equals)", requirements=[
RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),
RQ_SRS_006_RBAC_User_Alter_Settings_Min("1.0"),
RQ_SRS_006_RBAC_User_Alter_Settings_Max("1.0")]):
@ -286,7 +286,7 @@ def feature(self, node="clickhouse1"):
node.query("ALTER USER user19 SETTINGS max_memory_usage=10000000 MIN 100000 MAX 1000000000 READONLY")
#equals sign (=) syntax verify
with Scenario("I alter user settings without profile (yes equals)", flags=TE, requirements=[
with Scenario("I alter user settings without profile (yes equals)", requirements=[
RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),
RQ_SRS_006_RBAC_User_Alter_Settings_Min("1.0"),
RQ_SRS_006_RBAC_User_Alter_Settings_Max("1.0")]):
@ -295,7 +295,7 @@ def feature(self, node="clickhouse1"):
node.query("ALTER USER user20 SETTINGS max_memory_usage=10000000 MIN=100000 MAX=1000000000 READONLY")
#Add requirement to host: add/drop
with Scenario("I alter user to add host", flags=TE, requirements=[
with Scenario("I alter user to add host", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_AddDrop("1.0")]):
with setup("user21"):
with When("I alter user by adding local host"):
@ -309,7 +309,7 @@ def feature(self, node="clickhouse1"):
with And("I alter user by adding host name"):
node.query("ALTER USER user21 ADD HOST NAME 'localhost'")
with Scenario("I alter user to remove host", flags=TE, requirements=[
with Scenario("I alter user to remove host", requirements=[
RQ_SRS_006_RBAC_User_Alter_Host_AddDrop("1.0")]):
with setup("user22"):
with When("I alter user by removing local host"):

View File

@ -41,13 +41,13 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER user0")
node.query(f"CREATE ROLE role0")
with Scenario("I create quota with no options", flags=TE, requirements=[
with Scenario("I create quota with no options", requirements=[
RQ_SRS_006_RBAC_Quota_Create("1.0")]):
with cleanup("quota0"):
with When("I create a quota with no options"):
node.query("CREATE QUOTA quota0")
with Scenario("I create quota that already exists, throws exception", flags=TE, requirements=[
with Scenario("I create quota that already exists, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Create("1.0")]):
quota = "quota0"
with cleanup(quota):
@ -57,7 +57,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA {quota}", exitcode=exitcode, message=message)
del quota
with Scenario("I create quota if not exists, quota does not exist", flags=TE, requirements=[
with Scenario("I create quota if not exists, quota does not exist", requirements=[
RQ_SRS_006_RBAC_Quota_Create_IfNotExists("1.0")]):
quota = "quota1"
with cleanup(quota):
@ -65,7 +65,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA IF NOT EXISTS {quota}")
del quota
with Scenario("I create quota if not exists, quota does exist", flags=TE, requirements=[
with Scenario("I create quota if not exists, quota does exist", requirements=[
RQ_SRS_006_RBAC_Quota_Create_IfNotExists("1.0")]):
quota = "quota1"
with cleanup(quota):
@ -74,7 +74,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA IF NOT EXISTS {quota}")
del quota
with Scenario("I create quota or replace, quota does not exist", flags=TE, requirements=[
with Scenario("I create quota or replace, quota does not exist", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Replace("1.0")]):
quota = "quota2"
with cleanup(quota):
@ -82,7 +82,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA OR REPLACE {quota}")
del quota
with Scenario("I create quota or replace, quota does exist", flags=TE, requirements=[
with Scenario("I create quota or replace, quota does exist", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Replace("1.0")]):
quota = "quota2"
with cleanup(quota):
@ -93,7 +93,7 @@ def feature(self, node="clickhouse1"):
keys = ['none', 'user name', 'ip address', 'client key', 'client key or user name', 'client key or ip address']
for i, key in enumerate(keys):
with Scenario(f"I create quota keyed by {key}", flags=TE, requirements=[
with Scenario(f"I create quota keyed by {key}", requirements=[
RQ_SRS_006_RBAC_Quota_Create_KeyedBy("1.0"),
RQ_SRS_006_RBAC_Quota_Create_KeyedByOptions("1.0")]):
name = f'quota{3 + i}'
@ -101,7 +101,7 @@ def feature(self, node="clickhouse1"):
with When(f"I create a quota with {key}"):
node.query(f"CREATE QUOTA {name} KEYED BY '{key}'")
with Scenario("I create quota for randomized interval", flags=TE, requirements=[
with Scenario("I create quota for randomized interval", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Interval_Randomized("1.0")]):
with cleanup("quota9"):
with When("I create a quota for randomized interval"):
@ -109,7 +109,7 @@ def feature(self, node="clickhouse1"):
intervals = ['SECOND', 'MINUTE', 'HOUR', 'DAY', 'MONTH']
for i, interval in enumerate(intervals):
with Scenario(f"I create quota for interval {interval}", flags=TE, requirements=[
with Scenario(f"I create quota for interval {interval}", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Interval("1.0")]):
name = f'quota{10 + i}'
with cleanup(name):
@ -120,7 +120,7 @@ def feature(self, node="clickhouse1"):
'MAX RESULT BYTES', 'MAX READ ROWS', 'MAX READ BYTES', 'MAX EXECUTION TIME',
'NO LIMITS', 'TRACKING ONLY']
for i, constraint in enumerate(constraints):
with Scenario(f"I create quota for {constraint.lower()}", flags=TE, requirements=[
with Scenario(f"I create quota for {constraint.lower()}", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Queries("1.0"),
RQ_SRS_006_RBAC_Quota_Create_Errors("1.0"),
RQ_SRS_006_RBAC_Quota_Create_ResultRows("1.0"),
@ -135,7 +135,7 @@ def feature(self, node="clickhouse1"):
with When(f"I create quota for {constraint.lower()}"):
node.query(f"CREATE QUOTA {name} FOR INTERVAL 1 DAY {constraint}{' 1024' if constraint.startswith('MAX') else ''}")
with Scenario("I create quota for multiple constraints", flags=TE, requirements=[
with Scenario("I create quota for multiple constraints", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Interval("1.0"),
RQ_SRS_006_RBAC_Quota_Create_Queries("1.0")]):
with cleanup("quota23"):
@ -145,13 +145,13 @@ def feature(self, node="clickhouse1"):
FOR INTERVAL 2 DAY MAX QUERIES 124, \
FOR INTERVAL 1 HOUR TRACKING ONLY')
with Scenario("I create quota assigned to one role", flags=TE, requirements=[
with Scenario("I create quota assigned to one role", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
with cleanup("quota24"):
with When("I create quota for role"):
node.query("CREATE QUOTA quota24 TO role0")
with Scenario("I create quota to assign to role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create quota to assign to role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -161,7 +161,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA quota0 TO {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create quota to assign to all except role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create quota to assign to all except role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -171,36 +171,36 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA quota0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create quota assigned to no role", flags=TE, requirements=[
with Scenario("I create quota assigned to no role", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment_None("1.0")]):
with When("I create quota for no role"):
node.query("CREATE QUOTA quota24 TO NONE")
with Scenario("I create quota assigned to multiple roles", flags=TE, requirements=[
with Scenario("I create quota assigned to multiple roles", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
with cleanup("quota25"):
with When("I create quota for multiple roles"):
node.query("CREATE QUOTA quota25 TO role0, user0")
with Scenario("I create quota assigned to all", flags=TE,requirements=[
with Scenario("I create quota assigned to all", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment_All("1.0")]):
with cleanup("quota26"):
with When("I create quota for all"):
node.query("CREATE QUOTA quota26 TO ALL")
with Scenario("I create quota assigned to all except one role", flags=TE, requirements=[
with Scenario("I create quota assigned to all except one role", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment_Except("1.0")]):
with cleanup("quota27"):
with When("I create quota for all except one role"):
node.query("CREATE QUOTA quota27 TO ALL EXCEPT role0")
with Scenario("I create quota assigned to all except multiple roles", flags=TE, requirements=[
with Scenario("I create quota assigned to all except multiple roles", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Assignment_Except("1.0")]):
with cleanup("quota28"):
with When("I create quota for all except multiple roles"):
node.query("CREATE QUOTA quota28 TO ALL EXCEPT role0, user0")
with Scenario("I create quota on cluster", flags=TE, requirements=[
with Scenario("I create quota on cluster", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Cluster("1.0")]):
try:
with When("I run create quota command on cluster"):
@ -215,7 +215,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the quota from cluster"):
node.query("DROP QUOTA IF EXISTS quota29 ON CLUSTER sharded_cluster")
with Scenario("I create quota on nonexistent cluster, throws exception", flags=TE, requirements=[
with Scenario("I create quota on nonexistent cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Create_Cluster("1.0")]):
with When("I run create quota on a cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -32,13 +32,13 @@ def feature(self, node="clickhouse1"):
with Given(f"I ensure I do have role {role}"):
node.query(f"CREATE ROLE OR REPLACE {role}")
with Scenario("I create role with no options", flags=TE, requirements=[
with Scenario("I create role with no options", requirements=[
RQ_SRS_006_RBAC_Role_Create("1.0")]):
with cleanup("role0"):
with When("I create role"):
node.query("CREATE ROLE role0")
with Scenario("I create role that already exists, throws exception", flags=TE, requirements=[
with Scenario("I create role that already exists, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Create("1.0")]):
role = "role0"
with cleanup(role):
@ -49,7 +49,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create role if not exists, role does not exist", flags=TE, requirements=[
with Scenario("I create role if not exists, role does not exist", requirements=[
RQ_SRS_006_RBAC_Role_Create_IfNotExists("1.0")]):
role = "role1"
with cleanup(role):
@ -57,7 +57,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE IF NOT EXISTS {role}")
del role
with Scenario("I create role if not exists, role does exist", flags=TE, requirements=[
with Scenario("I create role if not exists, role does exist", requirements=[
RQ_SRS_006_RBAC_Role_Create_IfNotExists("1.0")]):
role = "role1"
with cleanup(role):
@ -66,7 +66,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE IF NOT EXISTS {role}")
del role
with Scenario("I create role or replace, role does not exist", flags=TE, requirements=[
with Scenario("I create role or replace, role does not exist", requirements=[
RQ_SRS_006_RBAC_Role_Create_Replace("1.0")]):
role = "role2"
with cleanup(role):
@ -74,7 +74,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE OR REPLACE {role}")
del role
with Scenario("I create role or replace, role does exist", flags=TE, requirements=[
with Scenario("I create role or replace, role does exist", requirements=[
RQ_SRS_006_RBAC_Role_Create_Replace("1.0")]):
role = "role2"
with cleanup(role):
@ -83,7 +83,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE OR REPLACE {role}")
del role
with Scenario("I create role on cluster", flags=TE, requirements=[
with Scenario("I create role on cluster", requirements=[
RQ_SRS_006_RBAC_Role_Create("1.0")]):
try:
with When("I have a role on a cluster"):
@ -96,19 +96,19 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the role"):
node.query("DROP ROLE IF EXISTS role1,role2 ON CLUSTER sharded_cluster")
with Scenario("I create role on nonexistent cluster, throws exception", flags=TE, requirements=[
with Scenario("I create role on nonexistent cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Create("1.0")]):
with When("I run create role on a cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")
node.query("CREATE ROLE role1 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
with Scenario("I create role with settings profile", flags=TE, requirements=[
with Scenario("I create role with settings profile", requirements=[
RQ_SRS_006_RBAC_Role_Create_Settings("1.0")]):
with cleanup("role3"):
with When("I create role with settings profile"):
node.query("CREATE ROLE role3 SETTINGS PROFILE default, max_memory_usage=10000000 WRITABLE")
with Scenario("I create role settings profile, fake profile, throws exception", flags=TE, requirements=[
with Scenario("I create role settings profile, fake profile, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Create_Settings("1.0")]):
with cleanup("role4a"):
with Given("I ensure profile profile0 does not exist"):
@ -117,7 +117,7 @@ def feature(self, node="clickhouse1"):
exitcode, message = errors.settings_profile_not_found_in_disk("profile0")
node.query("CREATE ROLE role4a SETTINGS PROFILE profile0", exitcode=exitcode, message=message)
with Scenario("I create role with settings without profile", flags=TE, requirements=[
with Scenario("I create role with settings without profile", requirements=[
RQ_SRS_006_RBAC_Role_Create_Settings("1.0")]):
with cleanup("role4"):
with When("I create role with settings without profile"):

View File

@ -41,21 +41,21 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROLE role0")
node.query(f"CREATE ROLE role1")
with Scenario("I create row policy with no options", flags=TE, requirements=[
with Scenario("I create row policy with no options", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy0"):
with When("I create row policy"):
node.query("CREATE ROW POLICY policy0 ON default.foo")
with Scenario("I create row policy using short syntax with no options", flags=TE, requirements=[
with Scenario("I create row policy using short syntax with no options", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy1"):
with When("I create row policy short form"):
node.query("CREATE POLICY policy1 ON default.foo")
with Scenario("I create row policy that already exists, throws exception", flags=TE, requirements=[
with Scenario("I create row policy that already exists, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
policy = "policy0"
@ -66,14 +66,14 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROW POLICY {policy} ON default.foo", exitcode=exitcode, message=message)
del policy
with Scenario("I create row policy if not exists, policy does not exist", flags=TE, requirements=[
with Scenario("I create row policy if not exists, policy does not exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy2"):
with When("I create row policy with if not exists"):
node.query("CREATE ROW POLICY IF NOT EXISTS policy2 ON default.foo")
with Scenario("I create row policy if not exists, policy does exist", flags=TE, requirements=[
with Scenario("I create row policy if not exists, policy does exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
policy = "policy2"
@ -83,14 +83,14 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROW POLICY IF NOT EXISTS {policy} ON default.foo")
del policy
with Scenario("I create row policy or replace, policy does not exist", flags=TE, requirements=[
with Scenario("I create row policy or replace, policy does not exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy3"):
with When("I create row policy with or replace"):
node.query("CREATE ROW POLICY OR REPLACE policy3 ON default.foo")
with Scenario("I create row policy or replace, policy does exist", flags=TE, requirements=[
with Scenario("I create row policy or replace, policy does exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
policy = "policy3"
@ -100,21 +100,21 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROW POLICY OR REPLACE {policy} ON default.foo")
del policy
with Scenario("I create row policy as permissive", flags=TE, requirements=[
with Scenario("I create row policy as permissive", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Access_Permissive("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy4"):
with When("I create row policy as permissive"):
node.query("CREATE ROW POLICY policy4 ON default.foo AS PERMISSIVE")
with Scenario("I create row policy as restrictive", flags=TE, requirements=[
with Scenario("I create row policy as restrictive", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Access_Restrictive("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy5"):
with When("I create row policy as restrictive"):
node.query("CREATE ROW POLICY policy5 ON default.foo AS RESTRICTIVE")
with Scenario("I create row policy for select", flags=TE, requirements=[
with Scenario("I create row policy for select", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_ForSelect("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0")]):
@ -122,21 +122,21 @@ def feature(self, node="clickhouse1"):
with When("I create row policy with for select"):
node.query("CREATE ROW POLICY policy6 ON default.foo FOR SELECT USING x > 10")
with Scenario("I create row policy using condition", flags=TE, requirements=[
with Scenario("I create row policy using condition", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy6"):
with When("I create row policy with condition"):
node.query("CREATE ROW POLICY policy6 ON default.foo USING x > 10")
with Scenario("I create row policy assigned to one role", flags=TE, requirements=[
with Scenario("I create row policy assigned to one role", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy7"):
with When("I create row policy for one role"):
node.query("CREATE ROW POLICY policy7 ON default.foo TO role0")
with Scenario("I create row policy to assign to role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create row policy to assign to role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0")]):
role = "role2"
with cleanup("policy8a"):
@ -147,7 +147,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROW POLICY policy8a ON default.foo TO {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create row policy to assign to all excpet role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create row policy to assign to all excpet role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0")]):
role = "role2"
with cleanup("policy8a"):
@ -158,42 +158,42 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE ROW POLICY policy8a ON default.foo TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create row policy assigned to multiple roles", flags=TE, requirements=[
with Scenario("I create row policy assigned to multiple roles", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy8b"):
with When("I create row policy for multiple roles"):
node.query("CREATE ROW POLICY policy8b ON default.foo TO role0, role1")
with Scenario("I create row policy assigned to all", flags=TE, requirements=[
with Scenario("I create row policy assigned to all", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_All("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy9"):
with When("I create row policy for all"):
node.query("CREATE ROW POLICY policy9 ON default.foo TO ALL")
with Scenario("I create row policy assigned to all except one role", flags=TE, requirements=[
with Scenario("I create row policy assigned to all except one role", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy10"):
with When("I create row policy for all except one"):
node.query("CREATE ROW POLICY policy10 ON default.foo TO ALL EXCEPT role0")
with Scenario("I create row policy assigned to all except multiple roles", flags=TE, requirements=[
with Scenario("I create row policy assigned to all except multiple roles", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy11"):
with When("I create row policy for all except multiple roles"):
node.query("CREATE ROW POLICY policy11 ON default.foo TO ALL EXCEPT role0, role1")
with Scenario("I create row policy assigned to none", flags=TE, requirements=[
with Scenario("I create row policy assigned to none", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_None("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with cleanup("policy11"):
with When("I create row policy for none"):
node.query("CREATE ROW POLICY policy11 ON default.foo TO NONE")
with Scenario("I create row policy on cluster", flags=TE, requirements=[
with Scenario("I create row policy on cluster", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
try:
@ -203,14 +203,14 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the row policy from cluster"):
node.query("DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster")
with Scenario("I create row policy on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I create row policy on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
with When("I run create row policy command"):
exitcode, message = errors.cluster_not_found("fake_cluster")
node.query("CREATE ROW POLICY policy13 ON CLUSTER fake_cluster ON default.foo", exitcode=exitcode, message=message)
with Scenario("I create row policy on cluster after table", flags=TE, requirements=[
with Scenario("I create row policy on cluster after table", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")]):
try:

View File

@ -39,13 +39,13 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER user0")
node.query(f"CREATE ROLE role0")
with Scenario("I create settings profile with no options", flags=TE, requirements=[
with Scenario("I create settings profile with no options", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]):
with cleanup("profile0"):
with When("I create settings profile"):
node.query("CREATE SETTINGS PROFILE profile0")
with Scenario("I create settings profile that already exists, throws exception", flags=TE, requirements=[
with Scenario("I create settings profile that already exists, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]):
profile = "profile0"
with cleanup(profile):
@ -55,13 +55,13 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE SETTINGS PROFILE {profile}", exitcode=exitcode, message=message)
del profile
with Scenario("I create settings profile if not exists, profile does not exist", flags=TE, requirements=[
with Scenario("I create settings profile if not exists, profile does not exist", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_IfNotExists("1.0")]):
with cleanup("profile1"):
with When("I create settings profile with if not exists"):
node.query("CREATE SETTINGS PROFILE IF NOT EXISTS profile1")
with Scenario("I create settings profile if not exists, profile does exist", flags=TE, requirements=[
with Scenario("I create settings profile if not exists, profile does exist", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_IfNotExists("1.0")]):
profile = "profile1"
with cleanup(profile):
@ -70,78 +70,78 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE SETTINGS PROFILE IF NOT EXISTS {profile}")
del profile
with Scenario("I create settings profile or replace, profile does not exist", flags=TE, requirements=[
with Scenario("I create settings profile or replace, profile does not exist", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Replace("1.0")]):
with cleanup("profile2"):
with When("I create settings policy with or replace"):
node.query("CREATE SETTINGS PROFILE OR REPLACE profile2")
with Scenario("I create settings profile or replace, profile does exist", flags=TE, requirements=[
with Scenario("I create settings profile or replace, profile does exist", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Replace("1.0")]):
with cleanup("profile2"):
create_profile("profile2")
with When("I create settings policy with or replace"):
node.query("CREATE SETTINGS PROFILE OR REPLACE profile2")
with Scenario("I create settings profile short form", flags=TE, requirements=[
with Scenario("I create settings profile short form", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]):
with cleanup("profile3"):
with When("I create settings profile short form"):
node.query("CREATE PROFILE profile3")
with Scenario("I create settings profile with a setting value", flags=TE, requirements=[
with Scenario("I create settings profile with a setting value", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables("1.0"),
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Value("1.0")]):
with cleanup("profile4"):
with When("I create settings profile with settings"):
node.query("CREATE SETTINGS PROFILE profile4 SETTINGS max_memory_usage = 100000001")
with Scenario("I create settings profile with a setting value, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create settings profile with a setting value, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables("1.0"),
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Value("1.0")]):
with When("I create settings profile using settings and nonexistent value"):
exitcode, message = errors.unknown_setting("fake_setting")
node.query("CREATE SETTINGS PROFILE profile0 SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message)
with Scenario("I create settings profile with a min setting value", flags=TE, requirements=[
with Scenario("I create settings profile with a min setting value", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile5"), cleanup("profile6"):
with When("I create settings profile with min setting with and without equals"):
node.query("CREATE SETTINGS PROFILE profile5 SETTINGS max_memory_usage MIN 100000001")
node.query("CREATE SETTINGS PROFILE profile6 SETTINGS max_memory_usage MIN = 100000001")
with Scenario("I create settings profile with a max setting value", flags=TE, requirements=[
with Scenario("I create settings profile with a max setting value", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile7"), cleanup("profile8"):
with When("I create settings profile with max setting with and without equals"):
node.query("CREATE SETTINGS PROFILE profile7 SETTINGS max_memory_usage MAX 100000001")
node.query("CREATE SETTINGS PROFILE profile8 SETTINGS max_memory_usage MAX = 100000001")
with Scenario("I create settings profile with min and max setting values", flags=TE, requirements=[
with Scenario("I create settings profile with min and max setting values", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile9"):
with When("I create settings profile with min and max setting"):
node.query("CREATE SETTINGS PROFILE profile9 SETTINGS max_memory_usage MIN 100000001 MAX 200000001")
with Scenario("I create settings profile with a readonly setting", flags=TE, requirements=[
with Scenario("I create settings profile with a readonly setting", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile10"):
with When("I create settings profile with readonly"):
node.query("CREATE SETTINGS PROFILE profile10 SETTINGS max_memory_usage READONLY")
with Scenario("I create settings profile with a writable setting", flags=TE, requirements=[
with Scenario("I create settings profile with a writable setting", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile21"):
with When("I create settings profile with writable"):
node.query("CREATE SETTINGS PROFILE profile21 SETTINGS max_memory_usage WRITABLE")
with Scenario("I create settings profile with inherited settings", flags=TE, requirements=[
with Scenario("I create settings profile with inherited settings", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")]):
with cleanup("profile11"):
with When("I create settings profile with inherit"):
node.query("CREATE SETTINGS PROFILE profile11 SETTINGS INHERIT 'default'")
with Scenario("I create settings profile with inherit/from profile, fake profile, throws exception", flags=TE, requirements=[
with Scenario("I create settings profile with inherit/from profile, fake profile, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")]):
profile = "profile3"
with Given(f"I ensure that profile {profile} does not exist"):
@ -153,13 +153,13 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE PROFILE profile0 SETTINGS {source} {profile}", exitcode=exitcode, message=message)
del profile
with Scenario("I create settings profile with inherited settings other form", flags=TE, requirements=[
with Scenario("I create settings profile with inherited settings other form", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")]):
with cleanup("profile12"):
with When("I create settings profile with inherit short form"):
node.query("CREATE PROFILE profile12 SETTINGS PROFILE 'default'")
with Scenario("I create settings profile with multiple settings", flags=TE, requirements=[
with Scenario("I create settings profile with multiple settings", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile13"):
with When("I create settings profile with multiple settings"):
@ -167,7 +167,7 @@ def feature(self, node="clickhouse1"):
" SETTINGS max_memory_usage = 100000001"
" SETTINGS max_memory_usage_for_user = 100000001")
with Scenario("I create settings profile with multiple settings short form", flags=TE, requirements=[
with Scenario("I create settings profile with multiple settings short form", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]):
with cleanup("profile14"):
with When("I create settings profile with multiple settings short form"):
@ -175,13 +175,13 @@ def feature(self, node="clickhouse1"):
" SETTINGS max_memory_usage = 100000001,"
" max_memory_usage_for_user = 100000001")
with Scenario("I create settings profile assigned to one role", flags=TE, requirements=[
with Scenario("I create settings profile assigned to one role", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]):
with cleanup("profile15"):
with When("I create settings profile for a role"):
node.query("CREATE SETTINGS PROFILE profile15 TO role0")
with Scenario("I create settings profile to assign to role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create settings profile to assign to role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -191,7 +191,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE SETTINGS PROFILE profile0 TO {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create settings profile to assign to all except role that does not exist, throws exception", flags=TE, requirements=[
with Scenario("I create settings profile to assign to all except role that does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]):
role = "role1"
with Given(f"I drop {role} if it exists"):
@ -201,37 +201,37 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE SETTINGS PROFILE profile0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
del role
with Scenario("I create settings profile assigned to multiple roles", flags=TE, requirements=[
with Scenario("I create settings profile assigned to multiple roles", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]):
with cleanup("profile16"):
with When("I create settings profile for multiple roles"):
node.query("CREATE SETTINGS PROFILE profile16 TO role0, user0")
with Scenario("I create settings profile assigned to all", flags=TE, requirements=[
with Scenario("I create settings profile assigned to all", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_All("1.0")]):
with cleanup("profile17"):
with When("I create settings profile for all"):
node.query("CREATE SETTINGS PROFILE profile17 TO ALL")
with Scenario("I create settings profile assigned to all except one role", flags=TE,requirements=[
with Scenario("I create settings profile assigned to all except one role",requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_AllExcept("1.0")]):
with cleanup("profile18"):
with When("I create settings profile for all except one role"):
node.query("CREATE SETTINGS PROFILE profile18 TO ALL EXCEPT role0")
with Scenario("I create settings profile assigned to all except multiple roles", flags=TE, requirements=[
with Scenario("I create settings profile assigned to all except multiple roles", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_AllExcept("1.0")]):
with cleanup("profile19"):
with When("I create settings profile for all except multiple roles"):
node.query("CREATE SETTINGS PROFILE profile19 TO ALL EXCEPT role0, user0")
with Scenario("I create settings profile assigned to none", flags=TE, requirements=[
with Scenario("I create settings profile assigned to none", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_None("1.0")]):
with cleanup("profile22"):
with When("I create settings profile for none"):
node.query("CREATE SETTINGS PROFILE profile22 TO NONE")
with Scenario("I create settings profile on cluster", flags=TE, requirements=[
with Scenario("I create settings profile on cluster", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_OnCluster("1.0")]):
try:
with When("I run create settings profile command"):
@ -243,7 +243,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the settings profile"):
node.query("DROP SETTINGS PROFILE IF EXISTS profile20 ON CLUSTER sharded_cluster")
with Scenario("I create settings profile on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I create settings profile on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Create_OnCluster("1.0")]):
with When("I run create settings profile command"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -25,7 +25,7 @@ def feature(self, node="clickhouse1"):
@contextmanager
def cleanup(user):
try:
with Given("I ensure the user does not already exist", flags=TE):
with Given("I ensure the user does not already exist"):
node.query(f"DROP USER IF EXISTS {user}")
yield
finally:
@ -36,14 +36,14 @@ def feature(self, node="clickhouse1"):
with Given(f"I ensure I do have user {user}"):
node.query(f"CREATE USER OR REPLACE {user}")
with Scenario("I create user with no options", flags=TE, requirements=[
with Scenario("I create user with no options", requirements=[
RQ_SRS_006_RBAC_User_Create("1.0"),
RQ_SRS_006_RBAC_User_Create_Host_Default("1.0")]):
with cleanup("user0"):
with When("I create a user with no options"):
node.query("CREATE USER user0")
with Scenario("I create user that already exists, throws exception", flags=TE, requirements=[
with Scenario("I create user that already exists, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Create("1.0"),
RQ_SRS_006_RBAC_User_Create_Host_Default("1.0")]):
user = "user0"
@ -54,7 +54,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER {user}", exitcode=exitcode, message=message)
del user
with Scenario("I create user with if not exists, user does not exist", flags=TE, requirements=[
with Scenario("I create user with if not exists, user does not exist", requirements=[
RQ_SRS_006_RBAC_User_Create_IfNotExists("1.0")]):
user = "user0"
with cleanup(user):
@ -63,7 +63,7 @@ def feature(self, node="clickhouse1"):
del user
#Bug exists, mark as xfail
with Scenario("I create user with if not exists, user does exist", flags=TE, requirements=[
with Scenario("I create user with if not exists, user does exist", requirements=[
RQ_SRS_006_RBAC_User_Create_IfNotExists("1.0")]):
user = "user0"
with cleanup(user):
@ -72,7 +72,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER IF NOT EXISTS {user}")
del user
with Scenario("I create user or replace, user does not exist", flags=TE, requirements=[
with Scenario("I create user or replace, user does not exist", requirements=[
RQ_SRS_006_RBAC_User_Create_Replace("1.0")]):
user = "user0"
with cleanup(user):
@ -80,7 +80,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER OR REPLACE {user}")
del user
with Scenario("I create user or replace, user does exist", flags=TE, requirements=[
with Scenario("I create user or replace, user does exist", requirements=[
RQ_SRS_006_RBAC_User_Create_Replace("1.0")]):
user = "user0"
with cleanup(user):
@ -89,33 +89,33 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER OR REPLACE {user}")
del user
with Scenario("I create user with no password", flags=TE, requirements=[
with Scenario("I create user with no password", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_NoPassword("1.0")]):
with cleanup("user1"):
with When("I create a user with no password"):
node.query("CREATE USER user1 IDENTIFIED WITH NO_PASSWORD")
with Scenario("I create user with plaintext password", flags=TE, requirements=[
with Scenario("I create user with plaintext password", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_PlainText("1.0")]):
with cleanup("user1"):
with When("I create a user with plaintext password"):
node.query("CREATE USER user1 IDENTIFIED WITH PLAINTEXT_PASSWORD BY 'mypassword'")
with Scenario("I create user with sha256 password", flags=TE, requirements=[
with Scenario("I create user with sha256 password", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_Sha256Password("1.0")]):
with cleanup("user2"):
with When("I create a user with sha256 password"):
password = hashlib.sha256("mypassword".encode("utf-8")).hexdigest()
node.query(f"CREATE USER user2 IDENTIFIED WITH SHA256_PASSWORD BY '{password}'")
with Scenario("I create user with sha256 password using IDENTIFIED BY", flags=TE, requirements=[
with Scenario("I create user with sha256 password using IDENTIFIED BY", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_Sha256Password("1.0")]):
with cleanup("user2"):
with When("I create a user with sha256 password using short form"):
password = hashlib.sha256("mypassword".encode("utf-8")).hexdigest()
node.query(f"CREATE USER user2 IDENTIFIED BY '{password}'")
with Scenario("I create user with sha256_hash password", flags=TE, requirements=[
with Scenario("I create user with sha256_hash password", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_Sha256Hash("1.0")]):
with cleanup("user3"):
with When("I create a user with sha256_hash"):
@ -124,13 +124,13 @@ def feature(self, node="clickhouse1"):
password = hash(hash("mypassword"))
node.query(f"CREATE USER user3 IDENTIFIED WITH SHA256_HASH BY '{password}'")
with Scenario("I create user with double sha1 password", flags=TE, requirements=[
with Scenario("I create user with double sha1 password", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_DoubleSha1Password("1.0")]):
with cleanup("user3"):
with When("I create a user with double_sha1_password"):
node.query(f"CREATE USER user3 IDENTIFIED WITH DOUBLE_SHA1_PASSWORD BY 'mypassword'")
with Scenario("I create user with double sha1 hash", flags=TE, requirements=[
with Scenario("I create user with double sha1 hash", requirements=[
RQ_SRS_006_RBAC_User_Create_Password_DoubleSha1Hash("1.0")]):
with cleanup("user3"):
with When("I create a user with double_sha1_hash"):
@ -139,55 +139,55 @@ def feature(self, node="clickhouse1"):
password = hash(hash("mypassword"))
node.query(f"CREATE USER user3 IDENTIFIED WITH DOUBLE_SHA1_HASH BY '{password}'")
with Scenario("I create user with host name", flags=TE, requirements=[
with Scenario("I create user with host name", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_Name("1.0")]):
with cleanup("user4"):
with When("I create a user with host name"):
node.query("CREATE USER user4 HOST NAME 'localhost', NAME 'clickhouse.com'")
with Scenario("I create user with host regexp", flags=TE, requirements=[
with Scenario("I create user with host regexp", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_Regexp("1.0")]):
with cleanup("user5"):
with When("I create a user with host regexp"):
node.query("CREATE USER user5 HOST REGEXP 'lo.?*host', REGEXP 'lo*host'")
with Scenario("I create user with host ip", flags=TE, requirements=[
with Scenario("I create user with host ip", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_IP("1.0")]):
with cleanup("user6"):
with When("I create a user with host ip"):
node.query("CREATE USER user6 HOST IP '127.0.0.1', IP '127.0.0.2'")
with Scenario("I create user with host like", flags=TE, requirements=[
with Scenario("I create user with host like", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_Like("1.0")]):
with cleanup("user7"):
with When("I create a user with host like"):
node.query("CREATE USER user7 HOST LIKE 'local%'")
with Scenario("I create user with host none", flags=TE, requirements=[
with Scenario("I create user with host none", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_None("1.0")]):
with cleanup("user7"):
with When("I create a user with host none"):
node.query("CREATE USER user7 HOST NONE")
with Scenario("I create user with host local", flags=TE, requirements=[
with Scenario("I create user with host local", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_Local("1.0")]):
with cleanup("user7"):
with When("I create a user with host local"):
node.query("CREATE USER user7 HOST LOCAL")
with Scenario("I create user with host any", flags=TE, requirements=[
with Scenario("I create user with host any", requirements=[
RQ_SRS_006_RBAC_User_Create_Host_Any("1.0")]):
with cleanup("user7"):
with When("I create a user with host any"):
node.query("CREATE USER user7 HOST ANY")
with Scenario("I create user with default role set to none", flags=TE, requirements=[
with Scenario("I create user with default role set to none", requirements=[
RQ_SRS_006_RBAC_User_Create_DefaultRole_None("1.0")]):
with cleanup("user8"):
with When("I create a user with no default role"):
node.query("CREATE USER user8 DEFAULT ROLE NONE")
with Scenario("I create user with default role", flags=TE, requirements=[
with Scenario("I create user with default role", requirements=[
RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]):
with Given("I have a role"):
node.query("CREATE ROLE default")
@ -197,7 +197,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the role"):
node.query("DROP ROLE default")
with Scenario("I create user default role, role doesn't exist, throws exception", flags=TE, requirements=[
with Scenario("I create user default role, role doesn't exist, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]):
with cleanup("user12"):
role = "role0"
@ -208,7 +208,7 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER user12 DEFAULT ROLE {role}",exitcode=exitcode, message=message)
del role
with Scenario("I create user default role, all except role doesn't exist, throws exception", flags=TE, requirements=[
with Scenario("I create user default role, all except role doesn't exist, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]):
with cleanup("user12"):
role = "role0"
@ -219,19 +219,19 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE USER user12 DEFAULT ROLE ALL EXCEPT {role}",exitcode=exitcode, message=message)
del role
with Scenario("I create user with all roles set to default", flags=TE, requirements=[
with Scenario("I create user with all roles set to default", requirements=[
RQ_SRS_006_RBAC_User_Create_DefaultRole_All("1.0")]):
with cleanup("user10"):
with When("I create a user with all roles as default"):
node.query("CREATE USER user10 DEFAULT ROLE ALL")
with Scenario("I create user with settings profile", flags=TE, requirements=[
with Scenario("I create user with settings profile", requirements=[
RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
with cleanup("user11"):
with When("I create a user with a settings profile"):
node.query("CREATE USER user11 SETTINGS PROFILE default, max_memory_usage=10000000 READONLY")
with Scenario("I create user settings profile, fake profile, throws exception", flags=TE, requirements=[
with Scenario("I create user settings profile, fake profile, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
with cleanup("user18a"):
profile = "profile0"
@ -242,20 +242,20 @@ def feature(self, node="clickhouse1"):
node.query("CREATE USER user18a SETTINGS PROFILE profile0", exitcode=exitcode, message=message)
del profile
with Scenario("I create user settings with a fake setting, throws exception", flags=TE, requirements=[
with Scenario("I create user settings with a fake setting, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
with cleanup("user18b"):
with When("I create settings profile using settings and nonexistent value"):
exitcode, message = errors.unknown_setting("fake_setting")
node.query("CREATE USER user18b SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message)
with Scenario("I create user with settings without profile", flags=TE, requirements=[
with Scenario("I create user with settings without profile", requirements=[
RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
with cleanup("user12"):
with When("I create a user with settings and no profile"):
node.query("CREATE USER user12 SETTINGS max_memory_usage=10000000 READONLY")
with Scenario("I create user on cluster", flags=TE, requirements=[
with Scenario("I create user on cluster", requirements=[
RQ_SRS_006_RBAC_User_Create_OnCluster("1.0")]):
try:
with When("I create user on cluster"):
@ -264,7 +264,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the user"):
node.query("DROP USER user13 ON CLUSTER sharded_cluster")
with Scenario("I create user on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I create user on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Create_OnCluster("1.0")]):
with When("I create user on fake cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -23,20 +23,20 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE QUOTA {quota}")
yield
finally:
with Finally("I drop the quota"):
with Finally("I drop the quota", flags=TE):
node.query(f"DROP QUOTA IF EXISTS {quota}")
def cleanup_quota(quota):
with Given(f"I ensure that quota {quota} does not exist"):
node.query(f"DROP QUOTA IF EXISTS {quota}")
with Scenario("I drop quota with no options", flags=TE, requirements=[
with Scenario("I drop quota with no options", requirements=[
RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
with cleanup("quota0"):
with When("I run drop quota command"):
node.query("DROP QUOTA quota0")
with Scenario("I drop quota, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I drop quota, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
quota = "quota0"
cleanup_quota(quota)
@ -45,31 +45,31 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP QUOTA {quota}", exitcode=exitcode, message=message)
del quota
with Scenario("I drop quota if exists, quota exists", flags=TE, requirements=[
with Scenario("I drop quota if exists, quota exists", requirements=[
RQ_SRS_006_RBAC_Quota_Drop_IfExists("1.0")]):
with cleanup("quota1"):
with When("I run drop quota command"):
node.query("DROP QUOTA IF EXISTS quota1")
with Scenario("I drop quota if exists, quota does not exist", flags=TE, requirements=[
with Scenario("I drop quota if exists, quota does not exist", requirements=[
RQ_SRS_006_RBAC_Quota_Drop_IfExists("1.0")]):
cleanup_quota("quota2")
with When("I run drop quota command, quota does not exist"):
node.query("DROP QUOTA IF EXISTS quota2")
with Scenario("I drop default quota, throws error", flags=TE, requirements=[
with Scenario("I drop default quota, throws error", requirements=[
RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
with When("I drop default quota"):
exitcode, message = errors.cannot_remove_quota_default()
node.query("DROP QUOTA default", exitcode=exitcode, message=message)
with Scenario("I drop multiple quotas", flags=TE, requirements=[
with Scenario("I drop multiple quotas", requirements=[
RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
with cleanup("quota2"), cleanup("quota3"):
with When("I run drop quota command"):
node.query("DROP QUOTA quota2, quota3")
with Scenario("I drop quota on cluster", flags=TE, requirements=[
with Scenario("I drop quota on cluster", requirements=[
RQ_SRS_006_RBAC_Quota_Drop_Cluster("1.0")]):
try:
with Given("I have a quota"):
@ -80,7 +80,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the quota in case it still exists"):
node.query("DROP QUOTA IF EXISTS quota4 ON CLUSTER sharded_cluster")
with Scenario("I drop quota on fake cluster", flags=TE, requirements=[
with Scenario("I drop quota on fake cluster", requirements=[
RQ_SRS_006_RBAC_Quota_Drop_Cluster("1.0")]):
with When("I run drop quota command"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -31,13 +31,13 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP ROLE IF EXISTS {role}")
with Scenario("I drop role with no options", flags=TE, requirements=[
with Scenario("I drop role with no options", requirements=[
RQ_SRS_006_RBAC_Role_Drop("1.0")]):
with setup("role0"):
with When("I drop role"):
node.query("DROP ROLE role0")
with Scenario("I drop role that doesn't exist, throws exception", flags=TE, requirements=[
with Scenario("I drop role that doesn't exist, throws exception", requirements=[
RQ_SRS_006_RBAC_Role_Drop("1.0")]):
role = "role0"
cleanup_role(role)
@ -46,38 +46,38 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP ROLE {role}", exitcode=exitcode, message=message)
del role
with Scenario("I drop multiple roles", flags=TE, requirements=[
with Scenario("I drop multiple roles", requirements=[
RQ_SRS_006_RBAC_Role_Drop("1.0")]):
with setup("role1"), setup("role2"):
with When("I drop multiple roles"):
node.query("DROP ROLE role1, role2")
with Scenario("I drop role that does not exist, using if exists", flags=TE, requirements=[
with Scenario("I drop role that does not exist, using if exists", requirements=[
RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]):
with When("I drop role if exists"):
node.query("DROP ROLE IF EXISTS role3")
with Scenario("I drop multiple roles where one does not exist", flags=TE, requirements=[
with Scenario("I drop multiple roles where one does not exist", requirements=[
RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]):
with setup("role5"):
with When("I drop multiple roles where one doesnt exist"):
node.query("DROP ROLE IF EXISTS role3, role5")
with Scenario("I drop multiple roles where both do not exist", flags = TE, requirements=[
with Scenario("I drop multiple roles where both do not exist", requirements=[
RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]):
with Given("I ensure role does not exist"):
node.query("DROP ROLE IF EXISTS role6")
with When("I drop the nonexistant roles"):
node.query("DROP USER IF EXISTS role5, role6")
with Scenario("I drop role on cluster", flags=TE, requirements=[
with Scenario("I drop role on cluster", requirements=[
RQ_SRS_006_RBAC_Role_Drop_Cluster("1.0")]):
with Given("I have a role on cluster"):
node.query("CREATE ROLE OR REPLACE role0 ON CLUSTER sharded_cluster")
with When("I drop the role from the cluster"):
node.query("DROP ROLE IF EXISTS role0 ON CLUSTER sharded_cluster")
with Scenario("I drop role on fake cluster", flags=TE, requirements=[
with Scenario("I drop role on fake cluster", requirements=[
RQ_SRS_006_RBAC_Role_Drop_Cluster("1.0")]):
with When("I run drop role command"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -39,21 +39,21 @@ def feature(self, node="clickhouse1"):
node.query(f"CREATE TABLE default.foo (x UInt64, y String) Engine=Memory")
node.query(f"CREATE TABLE default.foo2 (x UInt64, y String) Engine=Memory")
with Scenario("I drop row policy with no options", flags=TE, requirements=[
with Scenario("I drop row policy with no options", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with cleanup(["policy1"]):
with When("I drop row policy"):
node.query("DROP ROW POLICY policy1 ON default.foo")
with Scenario("I drop row policy using short syntax with no options", flags=TE, requirements=[
with Scenario("I drop row policy using short syntax with no options", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with cleanup(["policy2"]):
with When("I drop row policy short form"):
node.query("DROP POLICY policy2 ON default.foo")
with Scenario("I drop row policy, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I drop row policy, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
policy = "policy1"
@ -63,42 +63,42 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP ROW POLICY {policy} ON default.foo", exitcode=exitcode, message=message)
del policy
with Scenario("I drop row policy if exists, policy does exist", flags=TE, requirements=[
with Scenario("I drop row policy if exists, policy does exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop_IfExists("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with cleanup(["policy3"]):
with When("I drop row policy if exists"):
node.query("DROP ROW POLICY IF EXISTS policy3 ON default.foo")
with Scenario("I drop row policy if exists, policy doesn't exist", flags=TE, requirements=[
with Scenario("I drop row policy if exists, policy doesn't exist", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop_IfExists("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
cleanup_policy("policy3")
with When("I drop row policy if exists"):
node.query("DROP ROW POLICY IF EXISTS policy3 ON default.foo")
with Scenario("I drop multiple row policies", flags=TE, requirements=[
with Scenario("I drop multiple row policies", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with cleanup(["policy3", "policy4"]):
with When("I drop multiple row policies"):
node.query("DROP ROW POLICY policy3, policy4 ON default.foo")
with Scenario("I drop row policy on multiple tables", flags=TE, requirements=[
with Scenario("I drop row policy on multiple tables", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with cleanup(["policy3"], ["default.foo","default.foo2"]):
with When("I drop row policy on multiple tables"):
node.query("DROP ROW POLICY policy3 ON default.foo, default.foo2")
with Scenario("I drop multiple row policies on multiple tables", flags=TE, requirements=[
with Scenario("I drop multiple row policies on multiple tables", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with cleanup(["policy3", "policy4"], ["default.foo","default.foo2"]):
with When("I drop the row policies from the tables"):
node.query("DROP ROW POLICY policy3 ON default.foo, policy4 ON default.foo2")
with Scenario("I drop row policy on cluster", flags=TE, requirements=[
with Scenario("I drop row policy on cluster", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
try:
@ -110,7 +110,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the row policy in case it still exists"):
node.query("DROP ROW POLICY IF EXISTS policy13 ON default.foo ON CLUSTER sharded_cluster")
with Scenario("I drop row policy on cluster after table", flags=TE, requirements=[
with Scenario("I drop row policy on cluster after table", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
try:
@ -122,7 +122,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the row policy in case it still exists"):
node.query("DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster")
with Scenario("I drop row policy on fake cluster throws exception", flags=TE, requirements=[
with Scenario("I drop row policy on fake cluster throws exception", requirements=[
RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0")]):
with When("I run drop row policy command"):

View File

@ -30,13 +30,13 @@ def feature(self, node="clickhouse1"):
with Given(f"I ensure that profile {profile} does not exist"):
node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")
with Scenario("I drop settings profile with no options", flags=TE, requirements=[
with Scenario("I drop settings profile with no options", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")]):
with cleanup("profile0"):
with When("I drop settings profile"):
node.query("DROP SETTINGS PROFILE profile0")
with Scenario("I drop settings profile, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I drop settings profile, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")]):
profile = "profile0"
cleanup_profile(profile)
@ -45,19 +45,19 @@ def feature(self, node="clickhouse1"):
node.query("DROP SETTINGS PROFILE profile0", exitcode=exitcode, message=message)
del profile
with Scenario("I drop settings profile short form", flags=TE, requirements=[
with Scenario("I drop settings profile short form", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")]):
with cleanup("profile1"):
with When("I drop settings profile short form"):
node.query("DROP PROFILE profile1")
with Scenario("I drop settings profile if exists, profile does exist", flags=TE, requirements=[
with Scenario("I drop settings profile if exists, profile does exist", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop_IfExists("1.0")]):
with cleanup("profile2"):
with When("I drop settings profile if exists"):
node.query("DROP SETTINGS PROFILE IF EXISTS profile2")
with Scenario("I drop settings profile if exists, profile does not exist", flags=TE, requirements=[
with Scenario("I drop settings profile if exists, profile does not exist", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop_IfExists("1.0")]):
cleanup_profile("profile2")
with When("I drop settings profile if exists"):
@ -69,13 +69,13 @@ def feature(self, node="clickhouse1"):
exitcode, message = errors.cannot_remove_settings_profile_default()
node.query("DROP SETTINGS PROFILE default", exitcode=exitcode, message=message)
with Scenario("I drop multiple settings profiles", flags=TE, requirements=[
with Scenario("I drop multiple settings profiles", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")]):
with cleanup("profile3"), cleanup("profile4"):
with When("I drop multiple settings profiles"):
node.query("DROP SETTINGS PROFILE profile3, profile4")
with Scenario("I drop settings profile on cluster", flags=TE, requirements=[
with Scenario("I drop settings profile on cluster", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop_OnCluster("1.0")]):
try:
with Given("I have a settings profile"):
@ -86,7 +86,7 @@ def feature(self, node="clickhouse1"):
with Finally("I drop the profile in case it still exists"):
node.query("DROP SETTINGS PROFILE IF EXISTS profile5 ON CLUSTER sharded_cluster")
with Scenario("I drop settings profile on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I drop settings profile on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_SettingsProfile_Drop_OnCluster("1.0")]):
with When("I run drop settings profile command"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -30,13 +30,13 @@ def feature(self, node="clickhouse1"):
with Given(f"I ensure that user {user} does not exist"):
node.query(f"DROP USER IF EXISTS {user}")
with Scenario("I drop user with no options", flags=TE, requirements=[
with Scenario("I drop user with no options", requirements=[
RQ_SRS_006_RBAC_User_Drop("1.0")]):
with setup("user0"):
with When("I drop user"):
node.query("DROP USER user0")
with Scenario("I drop user, does not exist, throws exception", flags=TE, requirements=[
with Scenario("I drop user, does not exist, throws exception", requirements=[
RQ_SRS_006_RBAC_User_Drop("1.0")]):
user = "user0"
cleanup_user(user)
@ -45,31 +45,31 @@ def feature(self, node="clickhouse1"):
node.query(f"DROP USER {user}", exitcode=exitcode, message=message)
del user
with Scenario("I drop multiple users", flags=TE, requirements=[
with Scenario("I drop multiple users", requirements=[
RQ_SRS_006_RBAC_User_Drop("1.0")]):
with setup("user1"), setup("user2"):
with When("I drop multiple users"):
node.query("DROP USER user1, user2")
with Scenario("I drop user if exists, user does exist", flags=TE, requirements=[
with Scenario("I drop user if exists, user does exist", requirements=[
RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")]):
with setup("user3"):
with When("I drop user that exists"):
node.query("DROP USER IF EXISTS user3")
with Scenario("I drop user if exists, user does not exist", flags=TE, requirements=[
with Scenario("I drop user if exists, user does not exist", requirements=[
RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")]):
cleanup_user("user3")
with When("I drop nonexistant user"):
node.query("DROP USER IF EXISTS user3")
with Scenario("I drop default user, throws error", flags=TE, requirements=[
with Scenario("I drop default user, throws error", requirements=[
RQ_SRS_006_RBAC_User_Drop("1.0")]):
with When("I drop user"):
exitcode, message = errors.cannot_remove_user_default()
node.query("DROP USER default", exitcode=exitcode, message=message)
with Scenario("I drop multiple users where one does not exist", flags=TE, requirements=[
with Scenario("I drop multiple users where one does not exist", requirements=[
RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")]):
with setup("user3"):
with When("I drop multiple users where one does not exist"):
@ -80,7 +80,7 @@ def feature(self, node="clickhouse1"):
with When("I drop the nonexistant users"):
node.query("DROP USER IF EXISTS user5, user6")
with Scenario("I drop user from specific cluster", flags=TE, requirements=[
with Scenario("I drop user from specific cluster", requirements=[
RQ_SRS_006_RBAC_User_Drop_OnCluster("1.0")]):
try:
with Given("I have a user on cluster"):
@ -91,7 +91,7 @@ def feature(self, node="clickhouse1"):
with Finally("I make sure the user is dropped"):
node.query("DROP USER IF EXISTS user4 ON CLUSTER sharded_cluster")
with Scenario("I drop user from fake cluster", flags=TE, requirements=[
with Scenario("I drop user from fake cluster", requirements=[
RQ_SRS_006_RBAC_User_Drop_OnCluster("1.0")]):
with When("I drop a user from the fake cluster"):
exitcode, message = errors.cluster_not_found("fake_cluster")

View File

@ -3,32 +3,32 @@ from testflows.core import *
@TestFeature
@Name("syntax")
def feature(self):
Feature(run=load("rbac.tests.syntax.create_user", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.alter_user", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.drop_user", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_create_user", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.create_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.alter_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.drop_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_create_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.grant_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.grant_privilege","feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_grants", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.revoke_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.revoke_privilege","feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.create_row_policy", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.alter_row_policy", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.drop_row_policy", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_create_row_policy", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_row_policies", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.create_quota", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.alter_quota", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.drop_quota", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_create_quota", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_quotas", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.create_settings_profile", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.alter_settings_profile", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.drop_settings_profile", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.show_create_settings_profile", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.set_default_role", "feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.set_role","feature"), flags=TE)
Feature(run=load("rbac.tests.syntax.create_user", "feature"))
Feature(run=load("rbac.tests.syntax.alter_user", "feature"))
Feature(run=load("rbac.tests.syntax.drop_user", "feature"))
Feature(run=load("rbac.tests.syntax.show_create_user", "feature"))
Feature(run=load("rbac.tests.syntax.create_role", "feature"))
Feature(run=load("rbac.tests.syntax.alter_role", "feature"))
Feature(run=load("rbac.tests.syntax.drop_role", "feature"))
Feature(run=load("rbac.tests.syntax.show_create_role", "feature"))
Feature(run=load("rbac.tests.syntax.grant_role", "feature"))
Feature(run=load("rbac.tests.syntax.grant_privilege","feature"))
Feature(run=load("rbac.tests.syntax.show_grants", "feature"))
Feature(run=load("rbac.tests.syntax.revoke_role", "feature"))
Feature(run=load("rbac.tests.syntax.revoke_privilege","feature"))
Feature(run=load("rbac.tests.syntax.create_row_policy", "feature"))
Feature(run=load("rbac.tests.syntax.alter_row_policy", "feature"))
Feature(run=load("rbac.tests.syntax.drop_row_policy", "feature"))
Feature(run=load("rbac.tests.syntax.show_create_row_policy", "feature"))
Feature(run=load("rbac.tests.syntax.show_row_policies", "feature"))
Feature(run=load("rbac.tests.syntax.create_quota", "feature"))
Feature(run=load("rbac.tests.syntax.alter_quota", "feature"))
Feature(run=load("rbac.tests.syntax.drop_quota", "feature"))
Feature(run=load("rbac.tests.syntax.show_create_quota", "feature"))
Feature(run=load("rbac.tests.syntax.show_quotas", "feature"))
Feature(run=load("rbac.tests.syntax.create_settings_profile", "feature"))
Feature(run=load("rbac.tests.syntax.alter_settings_profile", "feature"))
Feature(run=load("rbac.tests.syntax.drop_settings_profile", "feature"))
Feature(run=load("rbac.tests.syntax.show_create_settings_profile", "feature"))
Feature(run=load("rbac.tests.syntax.set_default_role", "feature"))
Feature(run=load("rbac.tests.syntax.set_role","feature"))

View File

@ -82,7 +82,7 @@ def feature(self, node="clickhouse1"):
Scenario(run=grant_privileges)
# with nonexistant object name, GRANT assumes type role
with Scenario("I grant privilege to role that does not exist", flags=TE, requirements=[
with Scenario("I grant privilege to role that does not exist", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
with Given("I ensure that role does not exist"):
node.query("DROP ROLE IF EXISTS role0")
@ -90,35 +90,35 @@ def feature(self, node="clickhouse1"):
exitcode, message = errors.role_not_found_in_disk(name="role0")
node.query("GRANT NONE TO role0", exitcode=exitcode, message=message)
with Scenario("I grant privilege ON CLUSTER", flags=TE, requirements=[
with Scenario("I grant privilege ON CLUSTER", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_OnCluster("1.0"),
RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
with setup(node):
with When("I grant privilege ON CLUSTER"):
node.query("GRANT ON CLUSTER sharded_cluster NONE TO user0")
with Scenario("I grant privilege on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I grant privilege on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_OnCluster("1.0")]):
with setup(node):
with When("I grant privilege ON CLUSTER"):
exitcode, message = errors.cluster_not_found("fake_cluster")
node.query("GRANT ON CLUSTER fake_cluster NONE TO user0", exitcode=exitcode, message=message)
with Scenario("I grant privilege to multiple users and roles", flags=TE, requirements=[
with Scenario("I grant privilege to multiple users and roles", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_To("1.0"),
RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
with setup(node):
with When("I grant privilege to several users"):
node.query("GRANT NONE TO user0, user1, role1")
with Scenario("I grant privilege to current user", flags=TE, requirements=[
with Scenario("I grant privilege to current user", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_ToCurrentUser("1.0"),
RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
with setup(node):
with When("I grant privilege to current user"):
node.query("GRANT NONE TO CURRENT_USER", settings = [("user","user0")])
with Scenario("I grant privilege NONE to default user, throws exception", flags=TE, requirements=[
with Scenario("I grant privilege NONE to default user, throws exception", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_ToCurrentUser("1.0"),
RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
with setup(node):
@ -126,7 +126,7 @@ def feature(self, node="clickhouse1"):
exitcode, message = errors.cannot_update_default()
node.query("GRANT NONE TO CURRENT_USER", exitcode=exitcode, message=message)
with Scenario("I grant privilege with grant option", flags=TE, requirements=[
with Scenario("I grant privilege with grant option", requirements=[
RQ_SRS_006_RBAC_Grant_Privilege_GrantOption("1.0"),
RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
with setup(node):

View File

@ -33,7 +33,7 @@ def feature(self, node="clickhouse1"):
for j in range(roles):
node.query(f"DROP ROLE IF EXISTS role{j}")
with Scenario("I grant a role to a user",flags=TE, requirements=[
with Scenario("I grant a role to a user", requirements=[
RQ_SRS_006_RBAC_Grant_Role("1.0")]):
with setup(1,1):
with When("I grant a role"):
@ -61,19 +61,19 @@ def feature(self, node="clickhouse1"):
exitcode, message = errors.role_not_found_in_disk(name="role0")
node.query("GRANT role0 TO user0", exitcode=exitcode, message=message)
with Scenario("I grant a role to multiple users", flags=TE, requirements=[
with Scenario("I grant a role to multiple users", requirements=[
RQ_SRS_006_RBAC_Grant_Role("1.0")]):
with setup(2,1):
with When("I grant role to a multiple users"):
node.query("GRANT role0 TO user0, user1")
with Scenario("I grant multiple roles to multiple users", flags=TE, requirements=[
with Scenario("I grant multiple roles to multiple users", requirements=[
RQ_SRS_006_RBAC_Grant_Role("1.0")]):
with setup(2,2):
with When("I grant multiple roles to multiple users"):
node.query("GRANT role0, role1 TO user0, user1")
with Scenario("I grant role to current user", flags=TE, requirements=[
with Scenario("I grant role to current user", requirements=[
RQ_SRS_006_RBAC_Grant_Role_CurrentUser("1.0")]):
with setup(1,1):
with Given("I have a user with access management privilege"):
@ -81,20 +81,20 @@ def feature(self, node="clickhouse1"):
with When("I grant role to current user"):
node.query("GRANT role0 TO CURRENT_USER", settings = [("user","user0")])
with Scenario("I grant role to default user, throws exception", flags=TE, requirements=[
with Scenario("I grant role to default user, throws exception", requirements=[
RQ_SRS_006_RBAC_Grant_Role_CurrentUser("1.0")]):
with setup(1,1):
with When("I grant role to default user"):
exitcode, message = errors.cannot_update_default()
node.query("GRANT role0 TO CURRENT_USER", exitcode=exitcode, message=message)
with Scenario("I grant role to user with admin option", flags=TE, requirements=[
with Scenario("I grant role to user with admin option", requirements=[
RQ_SRS_006_RBAC_Grant_Role_AdminOption("1.0")]):
with setup(1,1):
with When("I grant role to a user with admin option"):
node.query("GRANT role0 TO user0 WITH ADMIN OPTION")
with Scenario("I grant role to user on cluster", flags=TE, requirements=[
with Scenario("I grant role to user on cluster", requirements=[
RQ_SRS_006_RBAC_Grant_Role_OnCluster("1.0")]):
try:
with Given("I have a user and a role on a cluster"):
@ -107,7 +107,7 @@ def feature(self, node="clickhouse1"):
node.query("DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster")
node.query("DROP ROLE IF EXISTS role0 ON CLUSTER sharded_cluster")
with Scenario("I grant role to user on fake cluster, throws exception", flags=TE, requirements=[
with Scenario("I grant role to user on fake cluster, throws exception", requirements=[
RQ_SRS_006_RBAC_Grant_Role_OnCluster("1.0")]):
with setup(1,1):
with When("I grant the role to the user"):

Some files were not shown because too many files have changed in this diff Show More