mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 09:02:00 +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);
|
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.
|
/// Load global settings from default_profile and system_profile.
|
||||||
global_context->setDefaultProfiles(config());
|
global_context->setDefaultProfiles(config());
|
||||||
const Settings & settings = global_context->getSettingsRef();
|
const Settings & settings = global_context->getSettingsRef();
|
||||||
|
@ -262,6 +262,9 @@
|
|||||||
<!-- Default profile of settings. -->
|
<!-- Default profile of settings. -->
|
||||||
<default_profile>default</default_profile>
|
<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 of settings. This settings are used by internal processes (Buffer storage, Distibuted DDL worker and so on). -->
|
||||||
<!-- <system_profile>default</system_profile> -->
|
<!-- <system_profile>default</system_profile> -->
|
||||||
|
|
||||||
|
@ -11,12 +11,19 @@
|
|||||||
#include <Access/SettingsProfilesCache.h>
|
#include <Access/SettingsProfilesCache.h>
|
||||||
#include <Access/ExternalAuthenticators.h>
|
#include <Access/ExternalAuthenticators.h>
|
||||||
#include <Core/Settings.h>
|
#include <Core/Settings.h>
|
||||||
|
#include <common/find_symbols.h>
|
||||||
#include <Poco/ExpireCache.h>
|
#include <Poco/ExpireCache.h>
|
||||||
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int UNKNOWN_SETTING;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<IAccessStorage>> createStorages()
|
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()
|
AccessControlManager::AccessControlManager()
|
||||||
: MultipleAccessStorage(createStorages()),
|
: MultipleAccessStorage(createStorages()),
|
||||||
context_access_cache(std::make_unique<ContextAccessCache>(*this)),
|
context_access_cache(std::make_unique<ContextAccessCache>(*this)),
|
||||||
@ -66,7 +120,8 @@ AccessControlManager::AccessControlManager()
|
|||||||
row_policy_cache(std::make_unique<RowPolicyCache>(*this)),
|
row_policy_cache(std::make_unique<RowPolicyCache>(*this)),
|
||||||
quota_cache(std::make_unique<QuotaCache>(*this)),
|
quota_cache(std::make_unique<QuotaCache>(*this)),
|
||||||
settings_profiles_cache(std::make_unique<SettingsProfilesCache>(*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(
|
std::shared_ptr<const ContextAccess> AccessControlManager::getContextAccess(
|
||||||
const UUID & user_id,
|
const UUID & user_id,
|
||||||
const boost::container::flat_set<UUID> & current_roles,
|
const boost::container::flat_set<UUID> & current_roles,
|
||||||
|
@ -53,6 +53,13 @@ public:
|
|||||||
void setUsersConfig(const Poco::Util::AbstractConfiguration & users_config);
|
void setUsersConfig(const Poco::Util::AbstractConfiguration & users_config);
|
||||||
void setDefaultProfileName(const String & default_profile_name);
|
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(
|
std::shared_ptr<const ContextAccess> getContextAccess(
|
||||||
const UUID & user_id,
|
const UUID & user_id,
|
||||||
const boost::container::flat_set<UUID> & current_roles,
|
const boost::container::flat_set<UUID> & current_roles,
|
||||||
@ -89,14 +96,15 @@ public:
|
|||||||
|
|
||||||
const ExternalAuthenticators & getExternalAuthenticators() const;
|
const ExternalAuthenticators & getExternalAuthenticators() const;
|
||||||
|
|
||||||
private:
|
private: class ContextAccessCache;
|
||||||
class ContextAccessCache;
|
class CustomSettingsPrefixes;
|
||||||
std::unique_ptr<ContextAccessCache> context_access_cache;
|
std::unique_ptr<ContextAccessCache> context_access_cache;
|
||||||
std::unique_ptr<RoleCache> role_cache;
|
std::unique_ptr<RoleCache> role_cache;
|
||||||
std::unique_ptr<RowPolicyCache> row_policy_cache;
|
std::unique_ptr<RowPolicyCache> row_policy_cache;
|
||||||
std::unique_ptr<QuotaCache> quota_cache;
|
std::unique_ptr<QuotaCache> quota_cache;
|
||||||
std::unique_ptr<SettingsProfilesCache> settings_profiles_cache;
|
std::unique_ptr<SettingsProfilesCache> settings_profiles_cache;
|
||||||
std::unique_ptr<ExternalAuthenticators> external_authenticators;
|
std::unique_ptr<ExternalAuthenticators> external_authenticators;
|
||||||
|
std::unique_ptr<CustomSettingsPrefixes> custom_settings_prefixes;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <Access/SettingsConstraints.h>
|
#include <Access/SettingsConstraints.h>
|
||||||
|
#include <Access/AccessControlManager.h>
|
||||||
#include <Core/Settings.h>
|
#include <Core/Settings.h>
|
||||||
#include <Common/FieldVisitors.h>
|
#include <Common/FieldVisitors.h>
|
||||||
#include <Common/FieldVisitorsAccurateComparison.h>
|
#include <Common/FieldVisitorsAccurateComparison.h>
|
||||||
@ -16,7 +17,11 @@ namespace ErrorCodes
|
|||||||
extern const int SETTING_CONSTRAINT_VIOLATION;
|
extern const int SETTING_CONSTRAINT_VIOLATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsConstraints::SettingsConstraints() = default;
|
|
||||||
|
SettingsConstraints::SettingsConstraints(const AccessControlManager & manager_) : manager(&manager_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SettingsConstraints::SettingsConstraints(const SettingsConstraints & src) = default;
|
SettingsConstraints::SettingsConstraints(const SettingsConstraints & src) = default;
|
||||||
SettingsConstraints & SettingsConstraints::operator=(const SettingsConstraints & src) = default;
|
SettingsConstraints & SettingsConstraints::operator=(const SettingsConstraints & src) = default;
|
||||||
SettingsConstraints::SettingsConstraints(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;
|
Field current_value, new_value;
|
||||||
if (current_settings.tryGet(setting_name, current_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);
|
&& (*setting_name == *other.setting_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool operator ==(const SettingsConstraints & left, const SettingsConstraints & right)
|
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 Settings;
|
||||||
struct SettingChange;
|
struct SettingChange;
|
||||||
class SettingsChanges;
|
class SettingsChanges;
|
||||||
|
class AccessControlManager;
|
||||||
|
|
||||||
|
|
||||||
/** Checks if specified changes of settings are allowed or not.
|
/** Checks if specified changes of settings are allowed or not.
|
||||||
@ -50,7 +51,7 @@ class SettingsChanges;
|
|||||||
class SettingsConstraints
|
class SettingsConstraints
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SettingsConstraints();
|
SettingsConstraints(const AccessControlManager & manager_);
|
||||||
SettingsConstraints(const SettingsConstraints & src);
|
SettingsConstraints(const SettingsConstraints & src);
|
||||||
SettingsConstraints & operator =(const SettingsConstraints & src);
|
SettingsConstraints & operator =(const SettingsConstraints & src);
|
||||||
SettingsConstraints(SettingsConstraints && src);
|
SettingsConstraints(SettingsConstraints && src);
|
||||||
@ -108,6 +109,7 @@ private:
|
|||||||
const Constraint * tryGetConstraint(const std::string_view & setting_name) const;
|
const Constraint * tryGetConstraint(const std::string_view & setting_name) const;
|
||||||
|
|
||||||
std::unordered_map<std::string_view, Constraint> constraints;
|
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);
|
min_value = Settings::castValueUtil(setting_name, min_value);
|
||||||
if (!max_value.isNull())
|
if (!max_value.isNull())
|
||||||
max_value = Settings::castValueUtil(setting_name, max_value);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsConstraints SettingsProfileElements::toSettingsConstraints() const
|
SettingsConstraints SettingsProfileElements::toSettingsConstraints(const AccessControlManager & manager) const
|
||||||
{
|
{
|
||||||
SettingsConstraints res;
|
SettingsConstraints res{manager};
|
||||||
for (const auto & elem : *this)
|
for (const auto & elem : *this)
|
||||||
{
|
{
|
||||||
if (!elem.setting_name.empty())
|
if (!elem.setting_name.empty())
|
||||||
|
@ -61,7 +61,7 @@ public:
|
|||||||
|
|
||||||
Settings toSettings() const;
|
Settings toSettings() const;
|
||||||
SettingsChanges toSettingsChanges() 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;
|
default_profile_id = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SettingsProfilesCache::mergeSettingsAndConstraints()
|
void SettingsProfilesCache::mergeSettingsAndConstraints()
|
||||||
{
|
{
|
||||||
/// `mutex` is already locked.
|
/// `mutex` is already locked.
|
||||||
@ -143,9 +144,10 @@ void SettingsProfilesCache::mergeSettingsAndConstraintsFor(EnabledSettings & ena
|
|||||||
|
|
||||||
substituteProfiles(merged_settings);
|
substituteProfiles(merged_settings);
|
||||||
|
|
||||||
|
auto settings = merged_settings.toSettings();
|
||||||
|
auto constraints = merged_settings.toSettingsConstraints(manager);
|
||||||
enabled.setSettingsAndConstraints(
|
enabled.setSettingsAndConstraints(
|
||||||
std::make_shared<Settings>(merged_settings.toSettings()),
|
std::make_shared<Settings>(std::move(settings)), std::make_shared<SettingsConstraints>(std::move(constraints)));
|
||||||
std::make_shared<SettingsConstraints>(merged_settings.toSettingsConstraints()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user