Skip to content

Commit 439a651

Browse files
Merge pull request ClickHouse#79842 from ClickHouse/pufit/enable_user_name_access_type
Add `enable_user_name_access_type` setting for compatibility.
2 parents cf0e9f2 + 90592e1 commit 439a651

File tree

6 files changed

+81
-4
lines changed

6 files changed

+81
-4
lines changed

src/Access/AccessControl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ void AccessControl::setupFromMainConfig(const Poco::Util::AbstractConfiguration
306306
setSettingsConstraintsReplacePrevious(config_.getBool("access_control_improvements.settings_constraints_replace_previous", true));
307307
setTableEnginesRequireGrant(config_.getBool("access_control_improvements.table_engines_require_grant", false));
308308

309+
/// Set `true` by default because the feature is backward incompatible only when older version replicas are in the same cluster.
310+
setEnableUserNameAccessType(config_.getBool("access_control_improvements.enable_user_name_access_type", true));
311+
309312
addStoragesFromMainConfig(config_, config_path_, get_zookeeper_function_);
310313

311314
role_cache = std::make_unique<RoleCache>(*this, config_.getInt("access_control_improvements.role_cache_expiration_time_seconds", 600));
@@ -771,6 +774,15 @@ int AccessControl::getBcryptWorkfactor() const
771774
return bcrypt_workfactor;
772775
}
773776

777+
void AccessControl::setEnableUserNameAccessType(bool enable_user_name_access_type_)
778+
{
779+
enable_user_name_access_type = enable_user_name_access_type_;
780+
}
781+
782+
bool AccessControl::isEnabledUserNameAccessType() const
783+
{
784+
return enable_user_name_access_type;
785+
}
774786

775787
std::shared_ptr<const ContextAccess> AccessControl::getContextAccess(const ContextAccessParams & params) const
776788
{

src/Access/AccessControl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ class AccessControl : public MultipleAccessStorage
173173
void setBcryptWorkfactor(int workfactor_);
174174
int getBcryptWorkfactor() const;
175175

176+
/// Compatibility setting
177+
void setEnableUserNameAccessType(bool enable_user_name_access_type_);
178+
bool isEnabledUserNameAccessType() const;
179+
176180
/// Enables logic that users without permissive row policies can still read rows using a SELECT query.
177181
/// For example, if there are two users A, B and a row policy is defined only for A, then
178182
/// if this setting is true the user B will see all rows, and if this setting is false the user B will see no rows.
@@ -284,6 +288,7 @@ class AccessControl : public MultipleAccessStorage
284288
std::atomic<AuthenticationType> default_password_type = AuthenticationType::SHA256_PASSWORD;
285289
std::atomic_bool allow_experimental_tier_settings = true;
286290
std::atomic_bool allow_beta_tier_settings = true;
291+
std::atomic_bool enable_user_name_access_type = true;
287292
};
288293

289294
}

src/Access/Common/AccessRightsElement.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
#include <Access/AccessControl.h>
12
#include <Access/Common/AccessRightsElement.h>
3+
#include <Common/logger_useful.h>
24
#include <Common/quoteString.h>
35
#include <IO/Operators.h>
46
#include <IO/WriteBufferFromString.h>
7+
#include <Interpreters/Context.h>
58
#include <Parsers/IAST.h>
69

710

@@ -139,16 +142,40 @@ void AccessRightsElement::formatColumnNames(WriteBuffer & buffer) const
139142

140143
void AccessRightsElement::formatONClause(WriteBuffer & buffer, bool hilite) const
141144
{
145+
auto is_enabled_user_name_access_type = true;
146+
if (const auto context = Context::getGlobalContextInstance())
147+
{
148+
const auto & access_control = context->getAccessControl();
149+
is_enabled_user_name_access_type = access_control.isEnabledUserNameAccessType();
150+
}
151+
142152
buffer << (hilite ? IAST::hilite_keyword : "") << "ON " << (hilite ? IAST::hilite_none : "");
143153
if (isGlobalWithParameter())
144154
{
145-
if (anyParameter())
146-
buffer << "*";
155+
/// Special check for backward compatibility.
156+
/// If `enable_user_name_access_type` is set to false, we will dump `GRANT CREATE USER ON *` as `GRANT CREATE USER ON *.*`.
157+
/// This will allow us to run old replicas in the same cluster.
158+
if (access_flags.getParameterType() == AccessFlags::USER_NAME
159+
&& !is_enabled_user_name_access_type)
160+
{
161+
if (!anyParameter())
162+
LOG_WARNING(getLogger("AccessRightsElement"),
163+
"Converting {} to *.* because the setting `enable_user_name_access_type` is `false`. "
164+
"Consider turning this setting on, if your cluster contains no replicas older than 25.1",
165+
parameter);
166+
167+
buffer << "*.*";
168+
}
147169
else
148170
{
149-
buffer << backQuoteIfNeed(parameter);
150-
if (wildcard)
171+
if (anyParameter())
151172
buffer << "*";
173+
else
174+
{
175+
buffer << backQuoteIfNeed(parameter);
176+
if (wildcard)
177+
buffer << "*";
178+
}
152179
}
153180
}
154181
else if (anyDatabase())

tests/integration/test_enable_user_name_access_type/__init__.py

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<clickhouse>
2+
<access_control_improvements>
3+
<enable_user_name_access_type>0</enable_user_name_access_type>
4+
</access_control_improvements>
5+
</clickhouse>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from helpers.cluster import ClickHouseCluster
2+
3+
4+
def test_startup_scripts():
5+
cluster = ClickHouseCluster(__file__)
6+
7+
node = cluster.add_instance(
8+
"node",
9+
main_configs=[
10+
"configs/access_control_settings.xml",
11+
],
12+
macros={"replica": "node", "shard": "node"},
13+
with_zookeeper=True,
14+
)
15+
16+
try:
17+
cluster.start()
18+
node.query("CREATE USER foobar")
19+
node.query("GRANT CREATE USER ON * TO foobar")
20+
assert (
21+
node.query(
22+
"SHOW GRANTS FOR foobar"
23+
)
24+
== "GRANT CREATE USER ON *.* TO foobar\n"
25+
)
26+
node.query("DROP USER foobar")
27+
finally:
28+
cluster.shutdown()

0 commit comments

Comments
 (0)