ClickHouse/src/Interpreters/InterserverCredentials.cpp

89 lines
3.0 KiB
C++
Raw Normal View History

#include <Interpreters/InterserverCredentials.h>
2022-04-27 15:05:45 +00:00
#include <Common/logger_useful.h>
2021-04-07 13:52:11 +00:00
#include <Common/StringUtils/StringUtils.h>
namespace DB
{
2021-04-07 13:52:11 +00:00
namespace ErrorCodes
{
extern const int NO_ELEMENTS_IN_CONFIG;
}
2021-04-07 13:52:11 +00:00
std::unique_ptr<InterserverCredentials>
InterserverCredentials::make(const Poco::Util::AbstractConfiguration & config, const std::string & root_tag)
{
2021-04-07 13:52:11 +00:00
if (config.has("user") && !config.has("password"))
throw Exception(ErrorCodes::NO_ELEMENTS_IN_CONFIG, "Configuration parameter interserver_http_credentials.password can't be empty");
2021-04-07 13:52:11 +00:00
if (!config.has("user") && config.has("password"))
throw Exception(ErrorCodes::NO_ELEMENTS_IN_CONFIG,
"Configuration parameter interserver_http_credentials.user can't be empty if user specified");
2021-04-07 13:52:11 +00:00
/// They both can be empty
auto user = config.getString(root_tag + ".user", "");
auto password = config.getString(root_tag + ".password", "");
2021-04-07 13:52:11 +00:00
auto store = parseCredentialsFromConfig(user, password, config, root_tag);
2021-04-07 13:52:11 +00:00
return std::make_unique<InterserverCredentials>(user, password, store);
}
2021-04-07 13:52:11 +00:00
InterserverCredentials::CurrentCredentials InterserverCredentials::parseCredentialsFromConfig(
const std::string & current_user_,
const std::string & current_password_,
const Poco::Util::AbstractConfiguration & config,
2021-04-07 13:52:11 +00:00
const std::string & root_tag)
{
2021-04-07 13:52:11 +00:00
auto * log = &Poco::Logger::get("InterserverCredentials");
CurrentCredentials store;
store.emplace_back(current_user_, current_password_);
if (config.getBool(root_tag + ".allow_empty", false))
{
2021-04-07 13:52:11 +00:00
LOG_DEBUG(log, "Allowing empty credentials");
/// Allow empty credential to support migrating from no auth
2021-04-07 13:52:11 +00:00
store.emplace_back("", "");
}
2021-04-07 13:52:11 +00:00
Poco::Util::AbstractConfiguration::Keys old_users;
config.keys(root_tag, old_users);
2021-04-07 13:52:11 +00:00
for (const auto & user_key : old_users)
{
2021-04-07 13:52:11 +00:00
if (startsWith(user_key, "old"))
{
std::string full_prefix = root_tag + "." + user_key;
std::string old_user_name = config.getString(full_prefix + ".user");
LOG_DEBUG(log, "Adding credentials for old user {}", old_user_name);
std::string old_user_password = config.getString(full_prefix + ".password");
store.emplace_back(old_user_name, old_user_password);
}
}
return store;
}
2021-04-07 13:52:11 +00:00
InterserverCredentials::CheckResult InterserverCredentials::isValidUser(const UserWithPassword & credentials) const
{
2021-04-07 13:52:11 +00:00
auto itr = std::find(all_users_store.begin(), all_users_store.end(), credentials);
if (itr == all_users_store.end())
2021-04-07 14:05:40 +00:00
{
if (credentials.first.empty())
return {"Server requires HTTP Basic authentication, but client doesn't provide it", false};
2021-04-06 13:56:14 +00:00
return {"Incorrect user or password in HTTP basic authentication: " + credentials.first, false};
2021-04-07 14:05:40 +00:00
}
2021-04-07 13:52:11 +00:00
return {"", true};
}
2021-04-07 13:59:18 +00:00
InterserverCredentials::CheckResult InterserverCredentials::isValidUser(const std::string & user, const std::string & password) const
{
return isValidUser(std::make_pair(user, password));
}
}