mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Merge pull request #11080 from vitlibar/add-authentication-type-to-system-users
Show authentication type in system.users table
This commit is contained in:
commit
d7cc703233
@ -7,8 +7,8 @@ namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int BAD_ARGUMENTS;
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@ -36,8 +36,11 @@ Authentication::Digest Authentication::getPasswordDoubleSHA1() const
|
||||
|
||||
case DOUBLE_SHA1_PASSWORD:
|
||||
return password_hash;
|
||||
|
||||
case MAX_TYPE:
|
||||
break;
|
||||
}
|
||||
throw Exception("Unknown authentication type: " + std::to_string(static_cast<int>(type)), ErrorCodes::LOGICAL_ERROR);
|
||||
throw Exception("getPasswordDoubleSHA1(): authentication type " + toString(type) + " not supported", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
|
||||
@ -71,8 +74,11 @@ bool Authentication::isCorrectPassword(const String & password_) const
|
||||
|
||||
return encodeSHA1(first_sha1) == password_hash;
|
||||
}
|
||||
|
||||
case MAX_TYPE:
|
||||
break;
|
||||
}
|
||||
throw Exception("Unknown authentication type: " + std::to_string(static_cast<int>(type)), ErrorCodes::LOGICAL_ERROR);
|
||||
throw Exception("Cannot check if the password is correct for authentication type " + toString(type), ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <Common/OpenSSLHelpers.h>
|
||||
#include <Poco/SHA1Engine.h>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -14,6 +15,7 @@ namespace ErrorCodes
|
||||
extern const int SUPPORT_IS_DISABLED;
|
||||
extern const int BAD_ARGUMENTS;
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +37,15 @@ public:
|
||||
/// SHA1(SHA1(password)).
|
||||
/// This kind of hash is used by the `mysql_native_password` authentication plugin.
|
||||
DOUBLE_SHA1_PASSWORD,
|
||||
|
||||
MAX_TYPE,
|
||||
};
|
||||
|
||||
struct TypeInfo
|
||||
{
|
||||
const char * const raw_name;
|
||||
const String name; /// Lowercased with underscores, e.g. "sha256_password".
|
||||
static const TypeInfo & get(Type type_);
|
||||
};
|
||||
|
||||
using Digest = std::vector<uint8_t>;
|
||||
@ -85,6 +96,48 @@ private:
|
||||
};
|
||||
|
||||
|
||||
inline const Authentication::TypeInfo & Authentication::TypeInfo::get(Type type_)
|
||||
{
|
||||
static constexpr auto make_info = [](const char * raw_name_)
|
||||
{
|
||||
String init_name = raw_name_;
|
||||
boost::to_lower(init_name);
|
||||
return TypeInfo{raw_name_, std::move(init_name)};
|
||||
};
|
||||
|
||||
switch (type_)
|
||||
{
|
||||
case NO_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("NO_PASSWORD");
|
||||
return info;
|
||||
}
|
||||
case PLAINTEXT_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("PLAINTEXT_PASSWORD");
|
||||
return info;
|
||||
}
|
||||
case SHA256_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("SHA256_PASSWORD");
|
||||
return info;
|
||||
}
|
||||
case DOUBLE_SHA1_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("DOUBLE_SHA1_PASSWORD");
|
||||
return info;
|
||||
}
|
||||
case MAX_TYPE: break;
|
||||
}
|
||||
throw Exception("Unknown authentication type: " + std::to_string(static_cast<int>(type_)), ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
inline String toString(Authentication::Type type_)
|
||||
{
|
||||
return Authentication::TypeInfo::get(type_).raw_name;
|
||||
}
|
||||
|
||||
|
||||
inline Authentication::Digest Authentication::encodeSHA256(const std::string_view & text [[maybe_unused]])
|
||||
{
|
||||
#if USE_SSL
|
||||
@ -122,8 +175,10 @@ inline void Authentication::setPassword(const String & password_)
|
||||
|
||||
case DOUBLE_SHA1_PASSWORD:
|
||||
return setPasswordHashBinary(encodeDoubleSHA1(password_));
|
||||
|
||||
case MAX_TYPE: break;
|
||||
}
|
||||
throw Exception("Unknown authentication type: " + std::to_string(static_cast<int>(type)), ErrorCodes::LOGICAL_ERROR);
|
||||
throw Exception("setPassword(): authentication type " + toString(type) + " not supported", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
|
||||
@ -186,8 +241,10 @@ inline void Authentication::setPasswordHashBinary(const Digest & hash)
|
||||
password_hash = hash;
|
||||
return;
|
||||
}
|
||||
|
||||
case MAX_TYPE: break;
|
||||
}
|
||||
throw Exception("Unknown authentication type: " + std::to_string(static_cast<int>(type)), ErrorCodes::LOGICAL_ERROR);
|
||||
throw Exception("setPasswordHashBinary(): authentication type " + toString(type) + " not supported", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,10 +56,10 @@ namespace
|
||||
query->default_roles = user.default_roles.toASTWithNames(*manager);
|
||||
}
|
||||
|
||||
if (attach_mode && (user.authentication.getType() != Authentication::NO_PASSWORD))
|
||||
if (user.authentication.getType() != Authentication::NO_PASSWORD)
|
||||
{
|
||||
/// We don't show password unless it's an ATTACH statement.
|
||||
query->authentication = user.authentication;
|
||||
query->show_password = attach_mode; /// We don't show password unless it's an ATTACH statement.
|
||||
}
|
||||
|
||||
if (!user.settings.empty())
|
||||
|
@ -6,6 +6,12 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
void formatRenameTo(const String & new_name, const IAST::FormatSettings & settings)
|
||||
@ -15,27 +21,51 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
void formatAuthentication(const Authentication & authentication, const IAST::FormatSettings & settings)
|
||||
void formatAuthentication(const Authentication & authentication, bool show_password, const IAST::FormatSettings & settings)
|
||||
{
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " IDENTIFIED WITH " << (settings.hilite ? IAST::hilite_none : "");
|
||||
switch (authentication.getType())
|
||||
auto authentication_type = authentication.getType();
|
||||
if (authentication_type == Authentication::NO_PASSWORD)
|
||||
{
|
||||
case Authentication::Type::NO_PASSWORD:
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << "no_password" << (settings.hilite ? IAST::hilite_none : "");
|
||||
break;
|
||||
case Authentication::Type::PLAINTEXT_PASSWORD:
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << "plaintext_password BY " << (settings.hilite ? IAST::hilite_none : "")
|
||||
<< quoteString(authentication.getPassword());
|
||||
break;
|
||||
case Authentication::Type::SHA256_PASSWORD:
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << "sha256_hash BY " << (settings.hilite ? IAST::hilite_none : "")
|
||||
<< quoteString(authentication.getPasswordHashHex());
|
||||
break;
|
||||
case Authentication::Type::DOUBLE_SHA1_PASSWORD:
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << "double_sha1_hash BY " << (settings.hilite ? IAST::hilite_none : "")
|
||||
<< quoteString(authentication.getPasswordHashHex());
|
||||
break;
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " NOT IDENTIFIED"
|
||||
<< (settings.hilite ? IAST::hilite_none : "");
|
||||
return;
|
||||
}
|
||||
|
||||
String authentication_type_name = Authentication::TypeInfo::get(authentication_type).name;
|
||||
std::optional<String> password;
|
||||
|
||||
if (show_password)
|
||||
{
|
||||
switch (authentication_type)
|
||||
{
|
||||
case Authentication::PLAINTEXT_PASSWORD:
|
||||
{
|
||||
password = authentication.getPassword();
|
||||
break;
|
||||
}
|
||||
case Authentication::SHA256_PASSWORD:
|
||||
{
|
||||
authentication_type_name = "sha256_hash";
|
||||
password = authentication.getPasswordHashHex();
|
||||
break;
|
||||
}
|
||||
case Authentication::DOUBLE_SHA1_PASSWORD:
|
||||
{
|
||||
authentication_type_name = "double_sha1_hash";
|
||||
password = authentication.getPasswordHashHex();
|
||||
break;
|
||||
}
|
||||
|
||||
case Authentication::NO_PASSWORD: [[fallthrough]];
|
||||
case Authentication::MAX_TYPE:
|
||||
throw Exception("AST: Unexpected authentication type " + toString(authentication_type), ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " IDENTIFIED WITH " << authentication_type_name
|
||||
<< (settings.hilite ? IAST::hilite_none : "");
|
||||
if (password)
|
||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " BY " << quoteString(*password);
|
||||
}
|
||||
|
||||
|
||||
@ -190,7 +220,7 @@ void ASTCreateUserQuery::formatImpl(const FormatSettings & format, FormatState &
|
||||
formatRenameTo(new_name, format);
|
||||
|
||||
if (authentication)
|
||||
formatAuthentication(*authentication, format);
|
||||
formatAuthentication(*authentication, show_password, format);
|
||||
|
||||
if (hosts)
|
||||
formatHosts(nullptr, *hosts, format);
|
||||
|
@ -12,14 +12,14 @@ class ASTExtendedRoleSet;
|
||||
class ASTSettingsProfileElements;
|
||||
|
||||
/** CREATE USER [IF NOT EXISTS | OR REPLACE] name
|
||||
* [IDENTIFIED [WITH {NO_PASSWORD|PLAINTEXT_PASSWORD|SHA256_PASSWORD|SHA256_HASH|DOUBLE_SHA1_PASSWORD|DOUBLE_SHA1_HASH}] BY {'password'|'hash'}]
|
||||
* [NOT IDENTIFIED | IDENTIFIED [WITH {no_password|plaintext_password|sha256_password|sha256_hash|double_sha1_password|double_sha1_hash}] BY {'password'|'hash'}]
|
||||
* [HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
||||
* [DEFAULT ROLE role [,...]]
|
||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
|
||||
*
|
||||
* ALTER USER [IF EXISTS] name
|
||||
* [RENAME TO new_name]
|
||||
* [IDENTIFIED [WITH {PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD}] BY {'password'|'hash'}]
|
||||
* [NOT IDENTIFIED | IDENTIFIED [WITH {no_password|plaintext_password|sha256_password|sha256_hash|double_sha1_password|double_sha1_hash}] BY {'password'|'hash'}]
|
||||
* [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
||||
* [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
|
||||
@ -38,6 +38,7 @@ public:
|
||||
String new_name;
|
||||
|
||||
std::optional<Authentication> authentication;
|
||||
bool show_password = true; /// formatImpl() will show the password or hash.
|
||||
|
||||
std::optional<AllowedClientHosts> hosts;
|
||||
std::optional<AllowedClientHosts> add_hosts;
|
||||
|
@ -35,100 +35,74 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
bool parseByPassword(IParserBase::Pos & pos, Expected & expected, String & password)
|
||||
{
|
||||
return IParserBase::wrapParseImpl(pos, [&]
|
||||
{
|
||||
if (!ParserKeyword{"BY"}.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
ASTPtr ast;
|
||||
if (!ParserStringLiteral{}.parse(pos, ast, expected))
|
||||
return false;
|
||||
|
||||
password = ast->as<const ASTLiteral &>().value.safeGet<String>();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool parseAuthentication(IParserBase::Pos & pos, Expected & expected, std::optional<Authentication> & authentication)
|
||||
{
|
||||
return IParserBase::wrapParseImpl(pos, [&]
|
||||
{
|
||||
if (ParserKeyword{"NOT IDENTIFIED"}.ignore(pos, expected))
|
||||
{
|
||||
authentication = Authentication{Authentication::NO_PASSWORD};
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ParserKeyword{"IDENTIFIED"}.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
if (!ParserKeyword{"WITH"}.ignore(pos, expected))
|
||||
std::optional<Authentication::Type> type;
|
||||
bool expect_password = false;
|
||||
bool expect_hash = false;
|
||||
|
||||
if (ParserKeyword{"WITH"}.ignore(pos, expected))
|
||||
{
|
||||
String password;
|
||||
if (!parseByPassword(pos, expected, password))
|
||||
for (auto check_type : ext::range(Authentication::MAX_TYPE))
|
||||
{
|
||||
if (ParserKeyword{Authentication::TypeInfo::get(check_type).raw_name}.ignore(pos, expected))
|
||||
{
|
||||
type = check_type;
|
||||
expect_password = (check_type != Authentication::NO_PASSWORD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type)
|
||||
{
|
||||
if (ParserKeyword{"SHA256_HASH"}.ignore(pos, expected))
|
||||
{
|
||||
type = Authentication::SHA256_PASSWORD;
|
||||
expect_hash = true;
|
||||
}
|
||||
else if (ParserKeyword{"DOUBLE_SHA1_HASH"}.ignore(pos, expected))
|
||||
{
|
||||
type = Authentication::DOUBLE_SHA1_PASSWORD;
|
||||
expect_hash = true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type)
|
||||
{
|
||||
type = Authentication::SHA256_PASSWORD;
|
||||
expect_password = true;
|
||||
}
|
||||
|
||||
String password;
|
||||
if (expect_password || expect_hash)
|
||||
{
|
||||
ASTPtr ast;
|
||||
if (!ParserKeyword{"BY"}.ignore(pos, expected) || !ParserStringLiteral{}.parse(pos, ast, expected))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::SHA256_PASSWORD};
|
||||
password = ast->as<const ASTLiteral &>().value.safeGet<String>();
|
||||
}
|
||||
|
||||
authentication = Authentication{*type};
|
||||
if (expect_password)
|
||||
authentication->setPassword(password);
|
||||
return true;
|
||||
}
|
||||
else if (expect_hash)
|
||||
authentication->setPasswordHashHex(password);
|
||||
|
||||
if (ParserKeyword{"PLAINTEXT_PASSWORD"}.ignore(pos, expected))
|
||||
{
|
||||
String password;
|
||||
if (!parseByPassword(pos, expected, password))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::PLAINTEXT_PASSWORD};
|
||||
authentication->setPassword(password);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ParserKeyword{"SHA256_PASSWORD"}.ignore(pos, expected))
|
||||
{
|
||||
String password;
|
||||
if (!parseByPassword(pos, expected, password))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::SHA256_PASSWORD};
|
||||
authentication->setPassword(password);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ParserKeyword{"SHA256_HASH"}.ignore(pos, expected))
|
||||
{
|
||||
String hash;
|
||||
if (!parseByPassword(pos, expected, hash))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::SHA256_PASSWORD};
|
||||
authentication->setPasswordHashHex(hash);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ParserKeyword{"DOUBLE_SHA1_PASSWORD"}.ignore(pos, expected))
|
||||
{
|
||||
String password;
|
||||
if (!parseByPassword(pos, expected, password))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::DOUBLE_SHA1_PASSWORD};
|
||||
authentication->setPassword(password);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ParserKeyword{"DOUBLE_SHA1_HASH"}.ignore(pos, expected))
|
||||
{
|
||||
String hash;
|
||||
if (!parseByPassword(pos, expected, hash))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::DOUBLE_SHA1_PASSWORD};
|
||||
authentication->setPasswordHashHex(hash);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ParserKeyword{"NO_PASSWORD"}.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
authentication = Authentication{Authentication::NO_PASSWORD};
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ namespace DB
|
||||
{
|
||||
/** Parses queries like
|
||||
* CREATE USER [IF NOT EXISTS | OR REPLACE] name
|
||||
* [IDENTIFIED [WITH {NO_PASSWORD|PLAINTEXT_PASSWORD|SHA256_PASSWORD|SHA256_HASH|DOUBLE_SHA1_PASSWORD|DOUBLE_SHA1_HASH}] BY {'password'|'hash'}]
|
||||
* [NOT IDENTIFIED | IDENTIFIED [WITH {no_password|plaintext_password|sha256_password|sha256_hash|double_sha1_password|double_sha1_hash}] BY {'password'|'hash'}]
|
||||
* [HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
|
||||
*
|
||||
* ALTER USER [IF EXISTS] name
|
||||
* [RENAME TO new_name]
|
||||
* [IDENTIFIED [WITH {PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD}] BY {'password'|'hash'}]
|
||||
* [NOT IDENTIFIED | IDENTIFIED [WITH {no_password|plaintext_password|sha256_password|sha256_hash|double_sha1_password|double_sha1_hash}] BY {'password'|'hash'}]
|
||||
* [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypeUUID.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeEnum.h>
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
@ -15,12 +16,26 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace
|
||||
{
|
||||
DataTypeEnum8::Values getAuthenticationTypeEnumValues()
|
||||
{
|
||||
DataTypeEnum8::Values enum_values;
|
||||
for (auto type : ext::range(Authentication::MAX_TYPE))
|
||||
enum_values.emplace_back(Authentication::TypeInfo::get(type).name, static_cast<Int8>(type));
|
||||
return enum_values;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NamesAndTypesList StorageSystemUsers::getNamesAndTypes()
|
||||
{
|
||||
NamesAndTypesList names_and_types{
|
||||
{"name", std::make_shared<DataTypeString>()},
|
||||
{"id", std::make_shared<DataTypeUUID>()},
|
||||
{"storage", std::make_shared<DataTypeString>()},
|
||||
{"auth_type", std::make_shared<DataTypeEnum8>(getAuthenticationTypeEnumValues())},
|
||||
{"auth_params", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
|
||||
{"host_ip", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
|
||||
{"host_names", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
|
||||
{"host_names_regexp", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
|
||||
@ -43,6 +58,9 @@ void StorageSystemUsers::fillData(MutableColumns & res_columns, const Context &
|
||||
auto & column_name = assert_cast<ColumnString &>(*res_columns[column_index++]);
|
||||
auto & column_id = assert_cast<ColumnUInt128 &>(*res_columns[column_index++]).getData();
|
||||
auto & column_storage = assert_cast<ColumnString &>(*res_columns[column_index++]);
|
||||
auto & column_auth_type = assert_cast<ColumnInt8 &>(*res_columns[column_index++]).getData();
|
||||
auto & column_auth_params = assert_cast<ColumnString &>(assert_cast<ColumnArray &>(*res_columns[column_index]).getData());
|
||||
auto & column_auth_params_offsets = assert_cast<ColumnArray &>(*res_columns[column_index++]).getOffsets();
|
||||
auto & column_host_ip = assert_cast<ColumnString &>(assert_cast<ColumnArray &>(*res_columns[column_index]).getData());
|
||||
auto & column_host_ip_offsets = assert_cast<ColumnArray &>(*res_columns[column_index++]).getOffsets();
|
||||
auto & column_host_names = assert_cast<ColumnString &>(assert_cast<ColumnArray &>(*res_columns[column_index]).getData());
|
||||
@ -60,12 +78,15 @@ void StorageSystemUsers::fillData(MutableColumns & res_columns, const Context &
|
||||
auto add_row = [&](const String & name,
|
||||
const UUID & id,
|
||||
const String & storage_name,
|
||||
const Authentication & authentication,
|
||||
const AllowedClientHosts & allowed_hosts,
|
||||
const ExtendedRoleSet & default_roles)
|
||||
{
|
||||
column_name.insertData(name.data(), name.length());
|
||||
column_id.push_back(id);
|
||||
column_storage.insertData(storage_name.data(), storage_name.length());
|
||||
column_auth_type.push_back(static_cast<Int8>(authentication.getType()));
|
||||
column_auth_params_offsets.push_back(column_auth_params.size());
|
||||
|
||||
if (allowed_hosts.containsAnyHost())
|
||||
{
|
||||
@ -128,7 +149,7 @@ void StorageSystemUsers::fillData(MutableColumns & res_columns, const Context &
|
||||
if (!storage)
|
||||
continue;
|
||||
|
||||
add_row(user->getName(), id, storage->getStorageName(), user->allowed_client_hosts, user->default_roles);
|
||||
add_row(user->getName(), id, storage->getStorageName(), user->authentication, user->allowed_client_hosts, user->default_roles);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ def test_create():
|
||||
|
||||
def check():
|
||||
assert instance.query("SHOW CREATE USER u1") == "CREATE USER u1 SETTINGS PROFILE s1\n"
|
||||
assert instance.query("SHOW CREATE USER u2") == "CREATE USER u2 HOST LOCAL DEFAULT ROLE rx\n"
|
||||
assert instance.query("SHOW CREATE USER u2") == "CREATE USER u2 IDENTIFIED WITH sha256_password HOST LOCAL DEFAULT ROLE rx\n"
|
||||
assert instance.query("SHOW CREATE ROW POLICY p ON mydb.mytable") == "CREATE ROW POLICY p ON mydb.mytable FOR SELECT USING a < 1000 TO u1, u2\n"
|
||||
assert instance.query("SHOW CREATE QUOTA q") == "CREATE QUOTA q KEYED BY \\'none\\' FOR INTERVAL 1 HOUR MAX QUERIES 100 TO ALL EXCEPT rx\n"
|
||||
assert instance.query("SHOW GRANTS FOR u1") == ""
|
||||
@ -69,7 +69,7 @@ def test_alter():
|
||||
|
||||
def check():
|
||||
assert instance.query("SHOW CREATE USER u1") == "CREATE USER u1 SETTINGS PROFILE s1\n"
|
||||
assert instance.query("SHOW CREATE USER u2") == "CREATE USER u2 HOST LOCAL DEFAULT ROLE ry\n"
|
||||
assert instance.query("SHOW CREATE USER u2") == "CREATE USER u2 IDENTIFIED WITH sha256_password HOST LOCAL DEFAULT ROLE ry\n"
|
||||
assert instance.query("SHOW GRANTS FOR u1") == "GRANT SELECT ON mydb.mytable TO u1\n"
|
||||
assert instance.query("SHOW GRANTS FOR u2") == "GRANT rx, ry TO u2\n"
|
||||
assert instance.query("SHOW CREATE ROLE rx") == "CREATE ROLE rx SETTINGS PROFILE s2\n"
|
||||
|
@ -155,9 +155,9 @@ def test_introspection():
|
||||
assert instance.query("SHOW ENABLED ROLES", user='A') == TSV([[ "R1", 0, 1, 1 ]])
|
||||
assert instance.query("SHOW ENABLED ROLES", user='B') == TSV([[ "R2", 1, 1, 1 ]])
|
||||
|
||||
assert instance.query("SELECT name, storage, host_ip, host_names, host_names_regexp, host_names_like, default_roles_all, default_roles_list, default_roles_except from system.users WHERE name IN ('A', 'B') ORDER BY name") ==\
|
||||
TSV([[ "A", "disk", "['::/0']", "[]", "[]", "[]", 1, "[]", "[]" ],
|
||||
[ "B", "disk", "['::/0']", "[]", "[]", "[]", 1, "[]", "[]" ]])
|
||||
assert instance.query("SELECT name, storage, auth_type, auth_params, host_ip, host_names, host_names_regexp, host_names_like, default_roles_all, default_roles_list, default_roles_except from system.users WHERE name IN ('A', 'B') ORDER BY name") ==\
|
||||
TSV([[ "A", "disk", "no_password", "[]", "['::/0']", "[]", "[]", "[]", 1, "[]", "[]" ],
|
||||
[ "B", "disk", "no_password", "[]", "['::/0']", "[]", "[]", "[]", 1, "[]", "[]" ]])
|
||||
|
||||
assert instance.query("SELECT name, storage from system.roles WHERE name IN ('R1', 'R2') ORDER BY name") ==\
|
||||
TSV([[ "R1", "disk" ],
|
||||
|
Loading…
Reference in New Issue
Block a user