mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-29 02:52:13 +00:00
Add the parameter custom_settings_prefixes to the server config.
This commit is contained in:
parent
f73a4749cf
commit
7c4ae5ee65
@ -614,6 +614,9 @@ int Server::main(const std::vector<std::string> & /*args*/)
|
||||
}
|
||||
global_context->setUncompressedCache(uncompressed_cache_size);
|
||||
|
||||
if (config().has("custom_settings_prefixes"))
|
||||
global_context->getAccessControlManager().setCustomSettingsPrefixes(config().getString("custom_settings_prefixes"));
|
||||
|
||||
/// Load global settings from default_profile and system_profile.
|
||||
global_context->setDefaultProfiles(config());
|
||||
const Settings & settings = global_context->getSettingsRef();
|
||||
|
@ -262,6 +262,9 @@
|
||||
<!-- Default profile of settings. -->
|
||||
<default_profile>default</default_profile>
|
||||
|
||||
<!-- Comma-separated list of prefixes for user-defined settings. -->
|
||||
<custom_settings_prefixes></custom_settings_prefixes>
|
||||
|
||||
<!-- System profile of settings. This settings are used by internal processes (Buffer storage, Distibuted DDL worker and so on). -->
|
||||
<!-- <system_profile>default</system_profile> -->
|
||||
|
||||
|
@ -11,12 +11,19 @@
|
||||
#include <Access/SettingsProfilesCache.h>
|
||||
#include <Access/ExternalAuthenticators.h>
|
||||
#include <Core/Settings.h>
|
||||
#include <common/find_symbols.h>
|
||||
#include <Poco/ExpireCache.h>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int UNKNOWN_SETTING;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<std::unique_ptr<IAccessStorage>> createStorages()
|
||||
@ -59,6 +66,53 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class AccessControlManager::CustomSettingsPrefixes
|
||||
{
|
||||
public:
|
||||
void registerPrefixes(const Strings & prefixes_)
|
||||
{
|
||||
std::lock_guard lock{mutex};
|
||||
registered_prefixes = prefixes_;
|
||||
}
|
||||
|
||||
bool isSettingNameAllowed(const std::string_view & setting_name) const
|
||||
{
|
||||
if (Settings::hasBuiltin(setting_name))
|
||||
return true;
|
||||
|
||||
std::lock_guard lock{mutex};
|
||||
for (const auto & prefix : registered_prefixes)
|
||||
{
|
||||
if (setting_name.starts_with(prefix))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkSettingNameIsAllowed(const std::string_view & setting_name) const
|
||||
{
|
||||
if (isSettingNameAllowed(setting_name))
|
||||
return;
|
||||
|
||||
std::lock_guard lock{mutex};
|
||||
if (!registered_prefixes.empty())
|
||||
{
|
||||
throw Exception(
|
||||
"Setting " + String{setting_name} + " is neither a builtin setting nor started with the prefix '"
|
||||
+ boost::algorithm::join(registered_prefixes, "' or '") + "' registered for user-defined settings",
|
||||
ErrorCodes::UNKNOWN_SETTING);
|
||||
}
|
||||
else
|
||||
BaseSettingsHelpers::throwSettingNotFound(setting_name);
|
||||
}
|
||||
|
||||
private:
|
||||
Strings registered_prefixes;
|
||||
mutable std::mutex mutex;
|
||||
};
|
||||
|
||||
|
||||
AccessControlManager::AccessControlManager()
|
||||
: MultipleAccessStorage(createStorages()),
|
||||
context_access_cache(std::make_unique<ContextAccessCache>(*this)),
|
||||
@ -66,7 +120,8 @@ AccessControlManager::AccessControlManager()
|
||||
row_policy_cache(std::make_unique<RowPolicyCache>(*this)),
|
||||
quota_cache(std::make_unique<QuotaCache>(*this)),
|
||||
settings_profiles_cache(std::make_unique<SettingsProfilesCache>(*this)),
|
||||
external_authenticators(std::make_unique<ExternalAuthenticators>())
|
||||
external_authenticators(std::make_unique<ExternalAuthenticators>()),
|
||||
custom_settings_prefixes(std::make_unique<CustomSettingsPrefixes>())
|
||||
{
|
||||
}
|
||||
|
||||
@ -100,6 +155,29 @@ void AccessControlManager::setDefaultProfileName(const String & default_profile_
|
||||
}
|
||||
|
||||
|
||||
void AccessControlManager::setCustomSettingsPrefixes(const Strings & prefixes)
|
||||
{
|
||||
custom_settings_prefixes->registerPrefixes(prefixes);
|
||||
}
|
||||
|
||||
void AccessControlManager::setCustomSettingsPrefixes(const String & comma_separated_prefixes)
|
||||
{
|
||||
Strings prefixes;
|
||||
splitInto<','>(prefixes, comma_separated_prefixes);
|
||||
setCustomSettingsPrefixes(prefixes);
|
||||
}
|
||||
|
||||
bool AccessControlManager::isSettingNameAllowed(const std::string_view & setting_name) const
|
||||
{
|
||||
return custom_settings_prefixes->isSettingNameAllowed(setting_name);
|
||||
}
|
||||
|
||||
void AccessControlManager::checkSettingNameIsAllowed(const std::string_view & setting_name) const
|
||||
{
|
||||
custom_settings_prefixes->checkSettingNameIsAllowed(setting_name);
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<const ContextAccess> AccessControlManager::getContextAccess(
|
||||
const UUID & user_id,
|
||||
const boost::container::flat_set<UUID> & current_roles,
|
||||
|
@ -53,6 +53,13 @@ public:
|
||||
void setUsersConfig(const Poco::Util::AbstractConfiguration & users_config);
|
||||
void setDefaultProfileName(const String & default_profile_name);
|
||||
|
||||
/// Sets prefixes which should be used for custom settings.
|
||||
/// This function also enables custom prefixes to be used.
|
||||
void setCustomSettingsPrefixes(const Strings & prefixes);
|
||||
void setCustomSettingsPrefixes(const String & comma_separated_prefixes);
|
||||
bool isSettingNameAllowed(const std::string_view & name) const;
|
||||
void checkSettingNameIsAllowed(const std::string_view & name) const;
|
||||
|
||||
std::shared_ptr<const ContextAccess> getContextAccess(
|
||||
const UUID & user_id,
|
||||
const boost::container::flat_set<UUID> & current_roles,
|
||||
@ -89,14 +96,15 @@ public:
|
||||
|
||||
const ExternalAuthenticators & getExternalAuthenticators() const;
|
||||
|
||||
private:
|
||||
class ContextAccessCache;
|
||||
private: class ContextAccessCache;
|
||||
class CustomSettingsPrefixes;
|
||||
std::unique_ptr<ContextAccessCache> context_access_cache;
|
||||
std::unique_ptr<RoleCache> role_cache;
|
||||
std::unique_ptr<RowPolicyCache> row_policy_cache;
|
||||
std::unique_ptr<QuotaCache> quota_cache;
|
||||
std::unique_ptr<SettingsProfilesCache> settings_profiles_cache;
|
||||
std::unique_ptr<ExternalAuthenticators> external_authenticators;
|
||||
std::unique_ptr<CustomSettingsPrefixes> custom_settings_prefixes;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <Access/SettingsConstraints.h>
|
||||
#include <Access/AccessControlManager.h>
|
||||
#include <Core/Settings.h>
|
||||
#include <Common/FieldVisitors.h>
|
||||
#include <Common/FieldVisitorsAccurateComparison.h>
|
||||
@ -16,7 +17,11 @@ namespace ErrorCodes
|
||||
extern const int SETTING_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
SettingsConstraints::SettingsConstraints() = default;
|
||||
|
||||
SettingsConstraints::SettingsConstraints(const AccessControlManager & manager_) : manager(&manager_)
|
||||
{
|
||||
}
|
||||
|
||||
SettingsConstraints::SettingsConstraints(const SettingsConstraints & src) = default;
|
||||
SettingsConstraints & SettingsConstraints::operator=(const SettingsConstraints & src) = default;
|
||||
SettingsConstraints::SettingsConstraints(SettingsConstraints && src) = default;
|
||||
@ -191,6 +196,11 @@ bool SettingsConstraints::checkImpl(const Settings & current_settings, SettingCh
|
||||
}
|
||||
};
|
||||
|
||||
if (reaction == THROW_ON_VIOLATION)
|
||||
manager->checkSettingNameIsAllowed(setting_name);
|
||||
else if (!manager->isSettingNameAllowed(setting_name))
|
||||
return false;
|
||||
|
||||
Field current_value, new_value;
|
||||
if (current_settings.tryGet(setting_name, current_value))
|
||||
{
|
||||
@ -316,9 +326,8 @@ bool SettingsConstraints::Constraint::operator==(const Constraint & other) const
|
||||
&& (*setting_name == *other.setting_name);
|
||||
}
|
||||
|
||||
|
||||
bool operator ==(const SettingsConstraints & left, const SettingsConstraints & right)
|
||||
{
|
||||
return left.constraints == right.constraints;
|
||||
return (left.constraints == right.constraints);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace DB
|
||||
struct Settings;
|
||||
struct SettingChange;
|
||||
class SettingsChanges;
|
||||
class AccessControlManager;
|
||||
|
||||
|
||||
/** Checks if specified changes of settings are allowed or not.
|
||||
@ -50,7 +51,7 @@ class SettingsChanges;
|
||||
class SettingsConstraints
|
||||
{
|
||||
public:
|
||||
SettingsConstraints();
|
||||
SettingsConstraints(const AccessControlManager & manager_);
|
||||
SettingsConstraints(const SettingsConstraints & src);
|
||||
SettingsConstraints & operator =(const SettingsConstraints & src);
|
||||
SettingsConstraints(SettingsConstraints && src);
|
||||
@ -108,6 +109,7 @@ private:
|
||||
const Constraint * tryGetConstraint(const std::string_view & setting_name) const;
|
||||
|
||||
std::unordered_map<std::string_view, Constraint> constraints;
|
||||
const AccessControlManager * manager = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ void SettingsProfileElement::init(const ASTSettingsProfileElement & ast, const A
|
||||
min_value = Settings::castValueUtil(setting_name, min_value);
|
||||
if (!max_value.isNull())
|
||||
max_value = Settings::castValueUtil(setting_name, max_value);
|
||||
|
||||
/// Optionally check if a setting with that name is allowed.
|
||||
if (manager)
|
||||
manager->checkSettingNameIsAllowed(setting_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,9 +153,9 @@ SettingsChanges SettingsProfileElements::toSettingsChanges() const
|
||||
return res;
|
||||
}
|
||||
|
||||
SettingsConstraints SettingsProfileElements::toSettingsConstraints() const
|
||||
SettingsConstraints SettingsProfileElements::toSettingsConstraints(const AccessControlManager & manager) const
|
||||
{
|
||||
SettingsConstraints res;
|
||||
SettingsConstraints res{manager};
|
||||
for (const auto & elem : *this)
|
||||
{
|
||||
if (!elem.setting_name.empty())
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
|
||||
Settings toSettings() const;
|
||||
SettingsChanges toSettingsChanges() const;
|
||||
SettingsConstraints toSettingsConstraints() const;
|
||||
SettingsConstraints toSettingsConstraints(const AccessControlManager & manager) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ void SettingsProfilesCache::setDefaultProfileName(const String & default_profile
|
||||
default_profile_id = it->second;
|
||||
}
|
||||
|
||||
|
||||
void SettingsProfilesCache::mergeSettingsAndConstraints()
|
||||
{
|
||||
/// `mutex` is already locked.
|
||||
@ -143,9 +144,10 @@ void SettingsProfilesCache::mergeSettingsAndConstraintsFor(EnabledSettings & ena
|
||||
|
||||
substituteProfiles(merged_settings);
|
||||
|
||||
auto settings = merged_settings.toSettings();
|
||||
auto constraints = merged_settings.toSettingsConstraints(manager);
|
||||
enabled.setSettingsAndConstraints(
|
||||
std::make_shared<Settings>(merged_settings.toSettings()),
|
||||
std::make_shared<SettingsConstraints>(merged_settings.toSettingsConstraints()));
|
||||
std::make_shared<Settings>(std::move(settings)), std::make_shared<SettingsConstraints>(std::move(constraints)));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user