Merge pull request #38024 from nvartolomei/nv/error-if-profile-does-not-exist

Throw exception when xml user profile does not exist
This commit is contained in:
Vitaly Baranov 2022-07-03 11:26:08 +02:00 committed by GitHub
commit 1a71e44b28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 8 deletions

View File

@ -20,6 +20,7 @@ class AccessControl;
struct SettingsProfileElement
{
std::optional<UUID> parent_profile;
String setting_name;
Field value;
Field min_value;

View File

@ -26,6 +26,7 @@ namespace ErrorCodes
{
extern const int BAD_ARGUMENTS;
extern const int UNKNOWN_ADDRESS_PATTERN_TYPE;
extern const int THERE_IS_NO_PROFILE;
extern const int NOT_IMPLEMENTED;
}
@ -47,7 +48,7 @@ namespace
UUID generateID(const IAccessEntity & entity) { return generateID(entity.getType(), entity.getName()); }
UserPtr parseUser(const Poco::Util::AbstractConfiguration & config, const String & user_name, bool allow_no_password, bool allow_plaintext_password)
UserPtr parseUser(const Poco::Util::AbstractConfiguration & config, const String & user_name, const std::unordered_set<UUID> & allowed_profile_ids, bool allow_no_password, bool allow_plaintext_password)
{
auto user = std::make_shared<User>();
user->setName(user_name);
@ -140,8 +141,11 @@ namespace
if (config.has(profile_name_config))
{
auto profile_name = config.getString(profile_name_config);
auto profile_id = generateID(AccessEntityType::SETTINGS_PROFILE, profile_name);
if (!allowed_profile_ids.contains(profile_id))
throw Exception(ErrorCodes::THERE_IS_NO_PROFILE, "Profile {} was not found", profile_name);
SettingsProfileElement profile_element;
profile_element.parent_profile = generateID(AccessEntityType::SETTINGS_PROFILE, profile_name);
profile_element.parent_profile = profile_id;
user->settings.push_back(std::move(profile_element));
}
@ -231,7 +235,7 @@ namespace
}
std::vector<AccessEntityPtr> parseUsers(const Poco::Util::AbstractConfiguration & config, bool allow_no_password, bool allow_plaintext_password)
std::vector<AccessEntityPtr> parseUsers(const Poco::Util::AbstractConfiguration & config, const std::unordered_set<UUID> & allowed_profile_ids, bool allow_no_password, bool allow_plaintext_password)
{
Poco::Util::AbstractConfiguration::Keys user_names;
config.keys("users", user_names);
@ -242,7 +246,7 @@ namespace
{
try
{
users.push_back(parseUser(config, user_name, allow_no_password, allow_plaintext_password));
users.push_back(parseUser(config, user_name, allowed_profile_ids, allow_no_password, allow_plaintext_password));
}
catch (Exception & e)
{
@ -457,6 +461,7 @@ namespace
std::shared_ptr<SettingsProfile> parseSettingsProfile(
const Poco::Util::AbstractConfiguration & config,
const String & profile_name,
const std::unordered_set<UUID> & allowed_parent_profile_ids,
const AccessControl & access_control)
{
auto profile = std::make_shared<SettingsProfile>();
@ -471,8 +476,11 @@ namespace
if (key == "profile" || key.starts_with("profile["))
{
String parent_profile_name = config.getString(profile_config + "." + key);
auto parent_profile_id = generateID(AccessEntityType::SETTINGS_PROFILE, parent_profile_name);
if (!allowed_parent_profile_ids.contains(parent_profile_id))
throw Exception(ErrorCodes::THERE_IS_NO_PROFILE, "Parent profile '{}' was not found", parent_profile_name);
SettingsProfileElement profile_element;
profile_element.parent_profile = generateID(AccessEntityType::SETTINGS_PROFILE, parent_profile_name);
profile_element.parent_profile = parent_profile_id;
profile->elements.emplace_back(std::move(profile_element));
continue;
}
@ -498,6 +506,7 @@ namespace
std::vector<AccessEntityPtr> parseSettingsProfiles(
const Poco::Util::AbstractConfiguration & config,
const std::unordered_set<UUID> & allowed_parent_profile_ids,
const AccessControl & access_control)
{
Poco::Util::AbstractConfiguration::Keys profile_names;
@ -510,7 +519,7 @@ namespace
{
try
{
profiles.push_back(parseSettingsProfile(config, profile_name, access_control));
profiles.push_back(parseSettingsProfile(config, profile_name, allowed_parent_profile_ids, access_control));
}
catch (Exception & e)
{
@ -521,6 +530,17 @@ namespace
return profiles;
}
std::unordered_set<UUID> getAllowedSettingsProfileIDs(const Poco::Util::AbstractConfiguration & config)
{
Poco::Util::AbstractConfiguration::Keys profile_names;
config.keys("profiles", profile_names);
std::unordered_set<UUID> ids;
for (const auto & profile_name : profile_names)
ids.emplace(generateID(AccessEntityType::SETTINGS_PROFILE, profile_name));
return ids;
}
}
UsersConfigAccessStorage::UsersConfigAccessStorage(const String & storage_name_, AccessControl & access_control_, bool allow_backup_)
@ -569,16 +589,18 @@ void UsersConfigAccessStorage::parseFromConfig(const Poco::Util::AbstractConfigu
{
try
{
auto allowed_profile_ids = getAllowedSettingsProfileIDs(config);
bool no_password_allowed = access_control.isNoPasswordAllowed();
bool plaintext_password_allowed = access_control.isPlaintextPasswordAllowed();
std::vector<std::pair<UUID, AccessEntityPtr>> all_entities;
for (const auto & entity : parseUsers(config, no_password_allowed, plaintext_password_allowed))
for (const auto & entity : parseUsers(config, allowed_profile_ids, no_password_allowed, plaintext_password_allowed))
all_entities.emplace_back(generateID(*entity), entity);
for (const auto & entity : parseQuotas(config))
all_entities.emplace_back(generateID(*entity), entity);
for (const auto & entity : parseRowPolicies(config, access_control.isEnabledUsersWithoutRowPoliciesCanReadRows()))
all_entities.emplace_back(generateID(*entity), entity);
for (const auto & entity : parseSettingsProfiles(config, access_control))
for (const auto & entity : parseSettingsProfiles(config, allowed_profile_ids, access_control))
all_entities.emplace_back(generateID(*entity), entity);
memory_storage.setAll(all_entities);
}