orphaned role - tests only

This commit is contained in:
Ilya Golshtein 2023-03-08 17:13:35 +01:00
parent 329a762ded
commit e1d1ead941
6 changed files with 70 additions and 4 deletions

View File

@ -703,6 +703,9 @@
actions of previous constraint (defined in other profiles) for the same specific setting, including fields that are not set by new constraint.
It also enables 'changeable_in_readonly' constraint type -->
<settings_constraints_replace_previous>false</settings_constraints_replace_previous>
<!-- Number of seconds since last access a role is stored in the Role Cache -->
<role_cache_expiration_time>600</role_cache_expiration_time>
</access_control_improvements>
<!-- Default profile of settings. -->

View File

@ -247,7 +247,6 @@ private:
AccessControl::AccessControl()
: MultipleAccessStorage("user directories"),
context_access_cache(std::make_unique<ContextAccessCache>(*this)),
role_cache(std::make_unique<RoleCache>(*this)),
row_policy_cache(std::make_unique<RowPolicyCache>(*this)),
quota_cache(std::make_unique<QuotaCache>(*this)),
settings_profiles_cache(std::make_unique<SettingsProfilesCache>(*this)),
@ -282,6 +281,8 @@ void AccessControl::setUpFromMainConfig(const Poco::Util::AbstractConfiguration
setSettingsConstraintsReplacePrevious(config_.getBool("access_control_improvements.settings_constraints_replace_previous", false));
addStoragesFromMainConfig(config_, config_path_, get_zookeeper_function_);
role_cache = std::make_unique<RoleCache>(*this, config_.getInt("access_control_improvements.role_cache_expiration_time", 600));
}

View File

@ -56,8 +56,8 @@ namespace
}
RoleCache::RoleCache(const AccessControl & access_control_)
: access_control(access_control_), cache(600000 /* 10 minutes */)
RoleCache::RoleCache(const AccessControl & access_control_, int expiration_time)
: access_control(access_control_), cache(expiration_time * 1000 /* 10 minutes by default*/)
{
}

View File

@ -16,7 +16,7 @@ using RolePtr = std::shared_ptr<const Role>;
class RoleCache
{
public:
explicit RoleCache(const AccessControl & access_control_);
explicit RoleCache(const AccessControl & access_control_, int expiration_time);
~RoleCache();
std::shared_ptr<const EnabledRoles> getEnabledRoles(

View File

@ -25,5 +25,6 @@
<select_from_system_db_requires_grant>true</select_from_system_db_requires_grant>
<select_from_information_schema_requires_grant>true</select_from_information_schema_requires_grant>
<settings_constraints_replace_previous>true</settings_constraints_replace_previous>
<role_cache_expiration_time>6</role_cache_expiration_time>
</access_control_improvements>
</clickhouse>

View File

@ -1,3 +1,4 @@
import time
import pytest
from helpers.client import QueryRuntimeException
from helpers.cluster import ClickHouseCluster
@ -412,3 +413,63 @@ def test_function_current_roles():
)
== "['R1']\t['R1']\t['R1']\n"
)
def test_role_expiration():
instance.query("CREATE USER ure")
instance.query("CREATE ROLE rre")
instance.query("GRANT rre TO ure")
instance.query("CREATE TABLE IF NOT EXISTS tre (id Int) Engine=Log")
instance.query("INSERT INTO tre VALUES (0)")
assert "Not enough privileges" in instance.query_and_get_error(
"SELECT * FROM tre", user="ure"
)
instance.query("GRANT SELECT ON tre TO rre")
assert instance.query("SELECT * FROM tre", user="ure") == "0\n"
time.sleep(10) # wait for role expiration
instance.query("CREATE TABLE IF NOT EXISTS tre1 (id Int) Engine=Log")
instance.query("INSERT INTO tre1 VALUES (0)")
instance.query("GRANT SELECT ON tre1 TO rre")
assert instance.query("SELECT * from tre1", user="ure") == "0\n"
instance.query("DROP USER ure")
instance.query("DROP ROLE rre")
instance.query("DROP TABLE tre")
instance.query("DROP TABLE tre1")
def test_two_roles_expiration():
instance.query("CREATE USER ure")
instance.query("CREATE ROLE rre")
instance.query("GRANT rre TO ure")
instance.query("CREATE ROLE rre_second")
instance.query("CREATE TABLE IF NOT EXISTS tre (id Int) Engine=Log")
instance.query("INSERT INTO tre VALUES (0)")
assert "Not enough privileges" in instance.query_and_get_error(
"SELECT * FROM tre", user="ure"
)
instance.query("GRANT SELECT ON tre TO rre")
assert instance.query("SELECT * FROM tre", user="ure") == "0\n"
time.sleep(10) # wait for role expiration
instance.query("GRANT SELECT ON tre1 TO rre_second") # we expect that both rre and rre_second are gone from cache
instance.query("CREATE TABLE IF NOT EXISTS tre1 (id Int) Engine=Log")
instance.query("INSERT INTO tre1 VALUES (0)")
instance.query("GRANT SELECT ON tre1 TO rre")
assert instance.query("SELECT * from tre1", user="ure") == "0\n"
instance.query("DROP USER ure")
instance.query("DROP ROLE rre")
instance.query("DROP ROLE rre_second")
instance.query("DROP TABLE tre")
instance.query("DROP TABLE tre1")