2021-07-20 15:07:54 +00:00
|
|
|
#include <Access/AccessEntityIO.h>
|
|
|
|
#include <Access/IAccessEntity.h>
|
|
|
|
#include <Access/IAccessStorage.h>
|
|
|
|
#include <Access/Quota.h>
|
|
|
|
#include <Access/Role.h>
|
|
|
|
#include <Access/RowPolicy.h>
|
|
|
|
#include <Access/SettingsProfile.h>
|
|
|
|
#include <Access/User.h>
|
|
|
|
#include <Core/Defines.h>
|
2021-11-26 16:19:47 +00:00
|
|
|
#include <IO/WriteHelpers.h>
|
2021-10-31 08:51:20 +00:00
|
|
|
#include <Interpreters/Access/InterpreterCreateQuotaQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterCreateRoleQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterCreateRowPolicyQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterCreateSettingsProfileQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterCreateUserQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterGrantQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterShowCreateAccessEntityQuery.h>
|
|
|
|
#include <Interpreters/Access/InterpreterShowGrantsQuery.h>
|
2022-04-21 02:57:44 +00:00
|
|
|
#include <Parsers/Access/ASTCreateQuotaQuery.h>
|
|
|
|
#include <Parsers/Access/ASTCreateRoleQuery.h>
|
|
|
|
#include <Parsers/Access/ASTCreateRowPolicyQuery.h>
|
|
|
|
#include <Parsers/Access/ASTCreateSettingsProfileQuery.h>
|
|
|
|
#include <Parsers/Access/ASTCreateUserQuery.h>
|
|
|
|
#include <Parsers/Access/ASTGrantQuery.h>
|
|
|
|
#include <Parsers/ParserAttachAccessEntity.h>
|
2021-07-20 15:07:54 +00:00
|
|
|
#include <Parsers/formatAST.h>
|
|
|
|
#include <Parsers/parseQuery.h>
|
|
|
|
#include <boost/range/algorithm/copy.hpp>
|
|
|
|
#include <boost/range/algorithm_ext/push_back.hpp>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int INCORRECT_ACCESS_ENTITY_DEFINITION;
|
|
|
|
}
|
|
|
|
|
|
|
|
String serializeAccessEntity(const IAccessEntity & entity)
|
|
|
|
{
|
2022-03-16 13:21:52 +00:00
|
|
|
/// Build list of ATTACH queries.
|
2022-03-21 05:41:33 +00:00
|
|
|
ASTs queries;
|
2021-07-20 15:07:54 +00:00
|
|
|
queries.push_back(InterpreterShowCreateAccessEntityQuery::getAttachQuery(entity));
|
2021-11-18 20:54:18 +00:00
|
|
|
if ((entity.getType() == AccessEntityType::USER) || (entity.getType() == AccessEntityType::ROLE))
|
2021-07-20 15:07:54 +00:00
|
|
|
boost::range::push_back(queries, InterpreterShowGrantsQuery::getAttachGrantQueries(entity));
|
|
|
|
|
|
|
|
/// Serialize the list of ATTACH queries to a string.
|
|
|
|
WriteBufferFromOwnString buf;
|
|
|
|
for (const ASTPtr & query : queries)
|
|
|
|
{
|
|
|
|
formatAST(*query, buf, false, true);
|
|
|
|
buf.write(";\n", 2);
|
|
|
|
}
|
|
|
|
return buf.str();
|
|
|
|
}
|
|
|
|
|
2022-02-23 21:41:16 +00:00
|
|
|
AccessEntityPtr deserializeAccessEntityImpl(const String & definition)
|
2021-07-20 15:07:54 +00:00
|
|
|
{
|
|
|
|
ASTs queries;
|
|
|
|
ParserAttachAccessEntity parser;
|
|
|
|
const char * begin = definition.data(); /// begin of current query
|
|
|
|
const char * pos = begin; /// parser moves pos from begin to the end of current query
|
|
|
|
const char * end = begin + definition.size();
|
|
|
|
while (pos < end)
|
|
|
|
{
|
2024-03-17 18:53:58 +00:00
|
|
|
queries.emplace_back(parseQueryAndMovePosition(parser, pos, end, "", true, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS));
|
2021-07-20 15:07:54 +00:00
|
|
|
while (isWhitespaceASCII(*pos) || *pos == ';')
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Interpret the AST to build an access entity.
|
|
|
|
std::shared_ptr<User> user;
|
|
|
|
std::shared_ptr<Role> role;
|
|
|
|
std::shared_ptr<RowPolicy> policy;
|
|
|
|
std::shared_ptr<Quota> quota;
|
|
|
|
std::shared_ptr<SettingsProfile> profile;
|
|
|
|
AccessEntityPtr res;
|
|
|
|
|
|
|
|
for (const auto & query : queries)
|
|
|
|
{
|
2022-03-21 05:41:33 +00:00
|
|
|
if (auto * create_user_query = query->as<ASTCreateUserQuery>())
|
2021-07-20 15:07:54 +00:00
|
|
|
{
|
|
|
|
if (res)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "Two access entities attached in the same file");
|
2021-07-20 15:07:54 +00:00
|
|
|
res = user = std::make_unique<User>();
|
2022-03-21 05:41:33 +00:00
|
|
|
InterpreterCreateUserQuery::updateUserFromQuery(*user, *create_user_query, /* allow_no_password = */ true, /* allow_plaintext_password = */ true);
|
2021-07-20 15:07:54 +00:00
|
|
|
}
|
|
|
|
else if (auto * create_role_query = query->as<ASTCreateRoleQuery>())
|
|
|
|
{
|
|
|
|
if (res)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "Two access entities attached in the same file");
|
2021-07-20 15:07:54 +00:00
|
|
|
res = role = std::make_unique<Role>();
|
|
|
|
InterpreterCreateRoleQuery::updateRoleFromQuery(*role, *create_role_query);
|
|
|
|
}
|
|
|
|
else if (auto * create_policy_query = query->as<ASTCreateRowPolicyQuery>())
|
|
|
|
{
|
|
|
|
if (res)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "Two access entities attached in the same file");
|
2021-07-20 15:07:54 +00:00
|
|
|
res = policy = std::make_unique<RowPolicy>();
|
2022-03-21 05:41:33 +00:00
|
|
|
InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(*policy, *create_policy_query);
|
2021-07-20 15:07:54 +00:00
|
|
|
}
|
|
|
|
else if (auto * create_quota_query = query->as<ASTCreateQuotaQuery>())
|
|
|
|
{
|
|
|
|
if (res)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "Two access entities attached in the same file");
|
2021-07-20 15:07:54 +00:00
|
|
|
res = quota = std::make_unique<Quota>();
|
|
|
|
InterpreterCreateQuotaQuery::updateQuotaFromQuery(*quota, *create_quota_query);
|
|
|
|
}
|
|
|
|
else if (auto * create_profile_query = query->as<ASTCreateSettingsProfileQuery>())
|
|
|
|
{
|
|
|
|
if (res)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "Two access entities attached in the same file");
|
2021-07-20 15:07:54 +00:00
|
|
|
res = profile = std::make_unique<SettingsProfile>();
|
|
|
|
InterpreterCreateSettingsProfileQuery::updateSettingsProfileFromQuery(*profile, *create_profile_query);
|
|
|
|
}
|
|
|
|
else if (auto * grant_query = query->as<ASTGrantQuery>())
|
|
|
|
{
|
|
|
|
if (!user && !role)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "A user or role should be attached before grant");
|
2021-07-20 15:07:54 +00:00
|
|
|
if (user)
|
|
|
|
InterpreterGrantQuery::updateUserFromQuery(*user, *grant_query);
|
|
|
|
else
|
|
|
|
InterpreterGrantQuery::updateRoleFromQuery(*role, *grant_query);
|
|
|
|
}
|
|
|
|
else
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "No interpreter found for query {}", query->getID());
|
2021-07-20 15:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!res)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "No access entities attached");
|
2021-07-20 15:07:54 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-02-23 21:41:16 +00:00
|
|
|
|
|
|
|
AccessEntityPtr deserializeAccessEntity(const String & definition, const String & file_path)
|
|
|
|
{
|
|
|
|
if (file_path.empty())
|
|
|
|
return deserializeAccessEntityImpl(definition);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return deserializeAccessEntityImpl(definition);
|
|
|
|
}
|
|
|
|
catch (Exception & e)
|
|
|
|
{
|
|
|
|
e.addMessage("Could not parse " + file_path);
|
|
|
|
e.rethrow();
|
2022-10-07 19:20:14 +00:00
|
|
|
UNREACHABLE();
|
2022-02-23 21:41:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-20 15:07:54 +00:00
|
|
|
}
|