Skip to content

Commit

Permalink
add separate test to check new CHECK privilege
Browse files Browse the repository at this point in the history
  • Loading branch information
alsugiliazova committed Jan 23, 2025
1 parent 0e0864c commit 73378cd
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 2 deletions.
5 changes: 5 additions & 0 deletions rbac/regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@
"multiple authentication methods were introduced in 24.12",
check_clickhouse_version("<24.12"),
),
"/rbac/privileges/check table": (
Skip,
"check privilege was introduced in 25.1",
check_clickhouse_version("<25.1"),
),
}


Expand Down
1 change: 1 addition & 0 deletions rbac/requirements/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -5120,6 +5120,7 @@ version: 1.0

[ClickHouse] SHALL successfully execute `CHECK table` statement if and only if the user has **show tables** privilege,
or any privilege on the table either directly or through a role.
From version 25.1 CHECK TABLE queries require a separate, CHECK grant (PR #74471).

#### RQ.SRS-006.RBAC.ShowDatabases.Privilege
version: 1.0
Expand Down
4 changes: 3 additions & 1 deletion rbac/requirements/requirements.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These requirements were auto generated
# from software requirements specification (SRS)
# document by TestFlows v2.0.240708.1162538.
# document by TestFlows v2.0.241127.1225014.
# Do not edit by hand but re-generate instead
# using 'tfs requirements generate' command.
from testflows.core import Specification
Expand Down Expand Up @@ -9917,6 +9917,7 @@
description=(
"[ClickHouse] SHALL successfully execute `CHECK table` statement if and only if the user has **show tables** privilege,\n"
"or any privilege on the table either directly or through a role.\n"
"From version 25.1 CHECK TABLE queries require a separate, CHECK grant (PR #74471).\n"
"\n"
),
link=None,
Expand Down Expand Up @@ -19334,6 +19335,7 @@ class targetNode target_table3;

[ClickHouse] SHALL successfully execute `CHECK table` statement if and only if the user has **show tables** privilege,
or any privilege on the table either directly or through a role.
From version 25.1 CHECK TABLE queries require a separate, CHECK grant (PR #74471).

#### RQ.SRS-006.RBAC.ShowDatabases.Privilege
version: 1.0
Expand Down
155 changes: 155 additions & 0 deletions rbac/tests/privileges/check/check_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
from testflows.core import *
from testflows.asserts import error

from rbac.requirements import *
from rbac.helper.common import *
import rbac.helper.errors as errors


@TestSuite
def table_privileges_granted_directly(self, node=None):
"""Check that a user is able to execute `CHECK TABLE` command on a table
if and only if he has CHECK privilege on that table granted directly.
"""

user_name = f"user_{getuid()}"

if node is None:
node = self.context.node

with user(node, f"{user_name}"):
table_name = f"table_name_{getuid()}"

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),
),
)


@TestSuite
def table_privileges_granted_via_role(self, node=None):
"""Check that a user is able to execute `CHECK TABLE` command on a table
if and only if he has CHECK privilege on that table granted via 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}"), role(node, f"{role_name}"):
table_name = f"table_name_{getuid()}"

with When("I grant the role to the user"):
node.query(f"GRANT {role_name} TO {user_name}")

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", "*.*"),
("CHECK", "*.*"),
("CHECK", "table"),
],
)
def check_privilege(
self, privilege, on, grant_target_name, user_name, table_name, node=None
):
"""Run checks for commands that require CHECK privilege."""

if node is None:
node = self.context.node

Suite(test=check)(
privilege=privilege,
on=on,
grant_target_name=grant_target_name,
user_name=user_name,
table_name=table_name,
)


@TestSuite
@Requirements(
RQ_SRS_006_RBAC_CheckTable_RequiredPrivilege("1.0"),
)
def check(self, privilege, on, grant_target_name, user_name, table_name, node=None):
"""Check that user is able to execute CHECK on a table if and only if the
user has CHECK TABLE privilege on that table.
"""
exitcode, message = errors.not_enough_privileges(name=user_name)

if node is None:
node = self.context.node

if on == "table":
on = f"{table_name}"

with table(node, table_name):
with Scenario("CHECK 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(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}")

with Then(f"I CHECK {table_name}"):
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}")

with And(f"I revoke {privilege} on the table"):
node.query(f"REVOKE {privilege} ON {on} FROM {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,
)


@TestFeature
@Name("check table")
def feature(self, node="clickhouse1"):
"""Check the RBAC functionality of SHOW TABLES."""
self.context.node = self.context.cluster.node(node)

Suite(run=table_privileges_granted_directly, setup=instrument_clickhouse_server_log)
Suite(run=table_privileges_granted_via_role, setup=instrument_clickhouse_server_log)
7 changes: 6 additions & 1 deletion rbac/tests/privileges/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ def feature(self):
parallel=True,
executor=pool,
)


Feature(
run=load("rbac.tests.privileges.check.check_table", "feature"),
parallel=True,
executor=pool,
)
Feature(
run=load("rbac.tests.privileges.show.show_tables", "feature"),
parallel=True,
Expand Down

0 comments on commit 73378cd

Please sign in to comment.