Exemple #1
0
def user_column_privileges(self, grant_columns, insert_columns_pass, data_fail, data_pass, table_type,
    revoke_columns=None, insert_columns_fail=None, node=None):
    """Check that user is able to insert on columns where insert privilege is granted
    and unable to insert on columns where insert privilege has not been granted or has been revoked.
    """
    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})",
                        settings=[("user",user_name)], exitcode=exitcode, message=message)
Exemple #2
0
def user_column_privileges(self, grant_columns, select_columns_pass, data_pass, table_type, revoke_columns=None, select_columns_fail=None, node=None):
    """Check that user is able to select on granted columns
    and unable to select on not granted or revoked columns.
    """
    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)
Exemple #3
0
def check_ttl_when_privilege_is_not_granted(table, user, node):
    """Ensures ALTER TTL errors as expected without the required privilege for the specified user
    """
    with When("I try to use privilege that has not been granted"):
        exitcode, message = errors.not_enough_privileges(user)
        node.query(f"ALTER TABLE {table} MODIFY TTL d + INTERVAL 1 DAY;",
                    settings = [("user", user)], exitcode=exitcode, message=message)
Exemple #4
0
def start_merges(self, privilege, on, grant_target_name, user_name, table_name, node=None):
    """Check that user is only able to execute `SYSTEM START MERGES` when they have privilege.
    """
    exitcode, message = errors.not_enough_privileges(name=user_name)

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

    on = on.replace("table", f"{table_name}")

    with table(node, table_name):

        with Scenario("SYSTEM START MERGES without privilege"):
            with When("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}")

            with Then("I check the user can start merges"):
                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}")

            with And(f"I revoke {privilege} on the table"):
                node.query(f"REVOKE {privilege} ON {on} FROM {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)
Exemple #5
0
def create_as_numbers(self, node=None):
    """Check that user is able to create a table as numbers table function.
    """
    user_name = f"user_{getuid()}"
    table_name = f"table_{getuid()}"
    exitcode, message = errors.not_enough_privileges(name=f"{user_name}")

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

    with user(node, f"{user_name}"):

        try:
            with When("I grant CREATE TABLE privilege to a user"):
                node.query(
                    f"GRANT CREATE TABLE ON {table_name} TO {user_name}")

            with And("I grant INSERT privilege"):
                node.query(f"GRANT INSERT ON {table_name} TO {user_name}")

            with Then(
                    "I try to create a table without select privilege on the table"
            ):
                node.query(f"CREATE TABLE {table_name} AS numbers(5)",
                           settings=[("user", f"{user_name}")])

        finally:
            with Finally("I drop the tables"):
                node.query(f"DROP TABLE IF EXISTS {table_name}")
Exemple #6
0
def create_as_another_table(self, node=None):
    """Check that user is able to create a table as another table with only CREATE TABLE privilege.
    """
    user_name = f"user_{getuid()}"
    table_name = f"table_{getuid()}"
    source_table_name = f"source_table_{getuid()}"
    exitcode, message = errors.not_enough_privileges(name=f"{user_name}")

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

    with table(node, f"{source_table_name}"):
        with user(node, f"{user_name}"):

            try:
                with When("I grant CREATE TABLE privilege to a user"):
                    node.query(
                        f"GRANT CREATE TABLE ON {table_name} TO {user_name}")

                with Then("I try to create a table as another table"):
                    node.query(
                        f"CREATE TABLE {table_name} AS {source_table_name}",
                        settings=[("user", f"{user_name}")])

            finally:
                with Finally("I drop the tables"):
                    node.query(f"DROP TABLE IF EXISTS {table_name}")
Exemple #7
0
def create_with_revoked_create_table_privilege(self,
                                               grant_target_name,
                                               user_name,
                                               node=None):
    """Revoke CREATE TABLE 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 CREATE TABLE privilege"):
            node.query(
                f"REVOKE CREATE TABLE ON {table_name} 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}")
Exemple #8
0
def revoke_privileges_from_user_via_role_with_grant_option(self, privilege, table_type, node=None):
    """Check that user with a role is unable to revoke a privilege they don't have access to from a user.
    """
    if node is None:
        node = self.context.node

    table_name = f"merge_tree_{getuid()}"
    user0_name = f"user0_{getuid()}"
    user1_name = f"user1_{getuid()}"
    role_name = f"role_{getuid()}"

    with table(node, table_name, table_type), user(node, user0_name), user(node, user1_name):
        with role(node, role_name):
            with Given(f"I grant privileges with grant option to user0"):
                node.query(f"GRANT {privilege} ON {table_name} TO {user0_name} WITH GRANT OPTION")

            with And(f"I grant privileges with grant option to role1"):
                node.query(f"GRANT {privilege} ON {table_name} TO {role_name} WITH GRANT OPTION",
                    settings=[("user", user0_name)])

            with When("I grant role1 to user1"):
                node.query(f"GRANT {role_name} TO {user1_name}")

            with And("I revoke privilege from user0 using role1(user1)"):
                node.query(f"REVOKE {privilege} ON {table_name} FROM {user0_name}",
                    settings=[("user" ,user1_name)])

            with Then("I verify that user0 has privileges revoked"):
                exitcode, message = errors.not_enough_privileges(user0_name)
                node.query(f"GRANT {privilege} ON {table_name} TO {role_name}",
                    settings=[("user", user0_name)], exitcode=exitcode, message=message)
                node.query(f"REVOKE {privilege} ON {table_name} FROM {role_name}",
                    settings=[("user", user0_name)], exitcode=exitcode, message=message)
def check_add_column_when_privilege_is_not_granted(table,
                                                   user,
                                                   node,
                                                   column=None):
    """Ensures ADD COLUMN errors as expected without the required privilege
    for the specified user.
    """
    if column is None:
        column = "add"

    with When("I try to use privilege that has not been granted"):
        exitcode, message = errors.not_enough_privileges(user)
        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 insert_with_table_on_distributed_table(self, user_name, grant_target_name, node=None):
    """Grant INSERT privilege seperately on the distributed table, the distributed table it is using and the table that the second distributed table is using,
    check that user is unable to insert into the distributed table, grant privilege on all three and check the user is able to insert.
    """
    table0_name = f"table0_{getuid()}"
    table1_name = f"table1_{getuid()}"
    table2_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 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}")])

    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}")
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:
        node = self.context.node

    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 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)
    finally:
        with Finally("I drop the distributed table"):
            node.query(f"DROP TABLE IF EXISTS {table1_name}")
Exemple #12
0
def privilege_check(grant_target_name, user_name, table_type, privilege, node=None):
    """Run scenarios to check the user's access with different privileges.
    """
    exitcode, message = errors.not_enough_privileges(name=f"{user_name}")

    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"):
                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"):
                node.query(f"GRANT {privilege} ON {table_name} TO {grant_target_name}")

            with Then("I attempt to freeze partitions"):
                node.query(f"ALTER TABLE {table_name} FREEZE", 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 freeze privilege"):
                node.query(f"GRANT {privilege} ON {table_name} TO {grant_target_name}")
            with And("I revoke the freeze privilege"):
                node.query(f"REVOKE {privilege} ON {table_name} FROM {grant_target_name}")

            with Then("I attempt to freeze partitions"):
                node.query(f"ALTER TABLE {table_name} FREEZE", settings = [("user", user_name)],
                    exitcode=exitcode, message=message)
Exemple #13
0
def revoke_privilege_from_role_via_role_with_grant_option(
        self, table_type, node=None):
    """Check that user with a role is unable to revoke a column they dont have acces to from a role.
    """
    user_name = f"user_{getuid()}"
    role0_name = f"role0_{getuid()}"
    role1_name = f"role1_{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, f"{role0_name},{role1_name}"):
            with When("I grant privilege with grant option to a role"):
                node.query(
                    f"GRANT SELECT(d) ON {table_name} TO {role0_name} WITH GRANT OPTION"
                )
            with And("I grant the role to a user"):
                node.query(f"GRANT {role0_name} TO {user_name}")
            with Then(
                    "I revoke privilege on a column the user with grant option does not have access to"
            ):
                exitcode, message = errors.not_enough_privileges(
                    name=user_name)
                node.query(
                    f"REVOKE SELECT(b) ON {table_name} FROM {role1_name}",
                    settings=[("user", user_name)],
                    exitcode=exitcode,
                    message=message)
Exemple #14
0
def stop_replicated_sends(self,
                          privilege,
                          on,
                          grant_target_name,
                          user_name,
                          node=None):
    """Check that user is only able to execute `SYSTEM STOP REPLICATED SENDS` when they have privilege."""
    exitcode, message = errors.not_enough_privileges(name=user_name)
    table_name = f"table_name_{getuid()}"

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

    on = on.replace("table", f"{table_name}")

    with table(node, table_name, "ReplicatedMergeTree-sharded_cluster"):

        with Scenario("SYSTEM STOP REPLICATED SENDS 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 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}")

            with Then("I check the user can stop sends"):
                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}")

            with And(f"I revoke {privilege} on the table"):
                node.query(
                    f"REVOKE {privilege} ON {on} FROM {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,
                )
Exemple #15
0
def embedded_dictionaries(self,
                          privilege,
                          grant_target_name,
                          user_name,
                          node=None):
    """Run checks for `SYSTEM RELOAD EMBEDDED DICTIONARIES` privilege."""
    exitcode, message = errors.not_enough_privileges(name=user_name)

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

    with Scenario("SYSTEM RELOAD EMBEDDED DICTIONARIES 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 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}")

        with Then(
                "I check the user is bale to execute SYSTEM RELOAD EMBEDDED DICTIONARIES"
        ):
            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}")

        with And(f"I revoke {privilege} on the table"):
            node.query(f"REVOKE {privilege} ON *.* FROM {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,
            )
Exemple #16
0
def user_with_revoked_role(self, table_type, node=None):
    """Check that user with a role that has insert privilege on a table
    is unable to insert into that table after the role has been revoked from the user.
    """
    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')",
                    settings=[("user", user_name)],
                    exitcode=exitcode,
                    message=message,
                )
Exemple #17
0
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"):
        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)
Exemple #18
0
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.
    """
    if column is None:
        column = "drop"

    with When("I try to use privilege that has not been granted"):
        exitcode, message = errors.not_enough_privileges(user)
        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,
        )
Exemple #19
0
def show_quotas(self, privilege, grant_target_name, user_name, node=None):
    """Check that user is only able to execute `SHOW QUOTAS` when they have the necessary privilege.
    """
    exitcode, message = errors.not_enough_privileges(name=user_name)

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

    with Scenario("SHOW QUOTAS without privilege"):

        with When("I check the user can't use SHOW QUOTAS"):
            node.query(f"SHOW QUOTAS", settings=[("user",user_name)],
                exitcode=exitcode, message=message)

    with Scenario("SHOW QUOTAS with privilege"):

        with When(f"I grant {privilege}"):
            node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")

        with Then("I check the user can use SHOW QUOTAS"):
            node.query(f"SHOW QUOTAS", settings = [("user", f"{user_name}")])

    with Scenario("SHOW QUOTAS with revoked privilege"):

        with When(f"I grant {privilege}"):
            node.query(f"GRANT {privilege} ON *.* TO {grant_target_name}")

        with And(f"I revoke {privilege}"):
            node.query(f"REVOKE {privilege} ON *.* FROM {grant_target_name}")

        with Then("I check the user cannot use SHOW QUOTAS"):
            node.query(f"SHOW QUOTAS", settings=[("user",user_name)],
                exitcode=exitcode, message=message)
Exemple #20
0
def flush_logs(self, privilege, on, grant_target_name, user_name, node=None):
    """Check that user is only able to execute `SYSTEM START REPLICATED FLUSH` when they have privilege.
    """
    exitcode, message = errors.not_enough_privileges(name=user_name)

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

    with Scenario("SYSTEM FLUSH LOGS without privilege"):
        with When("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}")

        with Then("I check the user can flush logs"):
            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}")

        with And(f"I revoke {privilege} on the table"):
            node.query(f"REVOKE {privilege} ON {on} FROM {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)
Exemple #21
0
def create_without_insert_privilege(self, node=None):
    """Check that user is unable to create a table without insert
    privilege on that table.
    """
    user_name = f"user_{getuid()}"
    table_name = f"table_{getuid()}"
    source_table_name = f"source_table_{getuid()}"
    exitcode, message = errors.not_enough_privileges(name=f"{user_name}")

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

    with table(node, f"{source_table_name}"):
        with user(node, f"{user_name}"):

            try:
                with When("I grant CREATE TABLE privilege to a user"):
                    node.query(
                        f"GRANT CREATE TABLE ON {table_name} TO {user_name}")

                with And("I grant SELECT privilege"):
                    node.query(
                        f"GRANT SELECT ON {source_table_name} TO {user_name}")

                with Then(
                        "I try to create a table without select privilege on the table"
                ):
                    node.query(
                        f"CREATE TABLE {table_name} ENGINE = Memory AS SELECT * FROM {source_table_name}",
                        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}")
def use(self, privilege, on, grant_target_name, user_name, db_name, node=None):
    """Check that user is able to execute EXISTS on a database if and only if the user has SHOW DATABASE privilege
    on that database.
    """
    exitcode, message = errors.not_enough_privileges(name=user_name)

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

    try:
        with Given("I have a database"):
            node.query(f"CREATE DATABASE {db_name}")

        with Scenario("USE 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 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}")

            with Then(f"I attempt to USE {db_name}"):
                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}")

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

    finally:
        with Finally("I drop the database"):
            node.query(f"DROP DATABASE IF EXISTS {db_name}")
Exemple #23
0
def create_without_create_table_privilege(self, node=None):
    """Check that user is unable to create a table without CREATE TABLE privilege.
    """
    user_name = f"user_{getuid()}"
    table_name = f"table_{getuid()}"
    exitcode, message = errors.not_enough_privileges(name=f"{user_name}")

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

    with user(node, f"{user_name}"):
        try:
            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"
            ):
                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}")
Exemple #24
0
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)
Exemple #25
0
def create_as_merge(self, node=None):
    """Check that user is able to create a table as merge table function.
    """
    user_name = f"user_{getuid()}"
    table_name = f"table_{getuid()}"
    source_table_name = f"source_table_{getuid()}"
    exitcode, message = errors.not_enough_privileges(name=f"{user_name}")

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

    with table(node, f"{source_table_name}"):
        with user(node, f"{user_name}"):

            try:
                with When("I grant CREATE TABLE privilege to a user"):
                    node.query(
                        f"GRANT CREATE TABLE ON {table_name} TO {user_name}")

                with And(
                        "I grant SELECT privilege to a user to allow executing the table function merge()"
                ):
                    node.query(
                        f"GRANT SELECT ON {source_table_name} TO {user_name}")

                with Then("I try to create a table as another table"):
                    node.query(
                        f"CREATE TABLE {table_name} AS merge(default,'{source_table_name}')",
                        settings=[("user", f"{user_name}")])

            finally:
                with Finally("I drop the tables"):
                    node.query(f"DROP TABLE IF EXISTS {table_name}")
Exemple #26
0
def role_with_revoked_privilege(self, table_type, node=None):
    """Check that user with a role that has select privilege on a table is unable
    to select from that table after select privilege has been revoked from the role.
    """
    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)],
                           exitcode=exitcode,
                           message=message)
Exemple #27
0
def check_drop_column_when_privilege_is_granted(table, user, node, column=None):
    """Ensures DROP COLUMN runs as expected when the privilege is granted
    to the specified user.
    """
    with When("I try to drop nonexistent column, throws exception"):
        # if user has privilege for all columns, error is 'wrong column name'
        if column:
            exitcode, message = errors.not_enough_privileges(user)
        else:
            exitcode, message = errors.wrong_column_name("fake_column")

        node.query(f"ALTER TABLE {table} DROP COLUMN fake_column",
            settings = [("user", user)], exitcode=exitcode, message=message)

    if column is None:
        column = 'drop'

    with Given(f"I add the column {column}"):
        node.query(f"ALTER TABLE {table} ADD COLUMN {column} String")

    with Then(f"I drop column {column} which exists"):
        node.query(f"ALTER TABLE {table} DROP COLUMN {column}",
            settings = [("user", user)])

    with And(f"I verify that {column} has been dropped"):
        exitcode, message = errors.wrong_column_name(column)
        node.query(f"ALTER TABLE {table} DROP COLUMN {column}",
            settings = [("user", user)], exitcode=exitcode, message=message)
Exemple #28
0
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,
                )
Exemple #29
0
def check_materialize_ttl_when_privilege_is_not_granted(table, user, node):
    """Ensures MATERIALIZE TTL errors as expected without the required privilege for the specified user
    """
    with When("I try to use privilege that has not been granted"):
        exitcode, message = errors.not_enough_privileges(user)
        node.query(f"ALTER TABLE {table} MATERIALIZE TTL IN PARTITION 4",
                    settings = [("user", user)], exitcode=exitcode, message=message)
Exemple #30
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."""
    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 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)],
                    exitcode=exitcode,
                    message=message,
                )