mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Revert "[WIP] New row policies"
This commit is contained in:
parent
cf6c4e4e56
commit
0ce4696c49
@ -28,8 +28,6 @@
|
|||||||
#include <Parsers/Access/ParserCreateSettingsProfileQuery.h>
|
#include <Parsers/Access/ParserCreateSettingsProfileQuery.h>
|
||||||
#include <Parsers/Access/ParserCreateUserQuery.h>
|
#include <Parsers/Access/ParserCreateUserQuery.h>
|
||||||
#include <Parsers/Access/ParserGrantQuery.h>
|
#include <Parsers/Access/ParserGrantQuery.h>
|
||||||
#include <Parsers/ASTSetQuery.h>
|
|
||||||
#include <Parsers/ParserSetQuery.h>
|
|
||||||
#include <Parsers/formatAST.h>
|
#include <Parsers/formatAST.h>
|
||||||
#include <Parsers/parseQuery.h>
|
#include <Parsers/parseQuery.h>
|
||||||
#include <boost/range/algorithm/copy.hpp>
|
#include <boost/range/algorithm/copy.hpp>
|
||||||
@ -40,16 +38,10 @@ namespace DB
|
|||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
extern const int INCORRECT_ACCESS_ENTITY_DEFINITION;
|
extern const int INCORRECT_ACCESS_ENTITY_DEFINITION;
|
||||||
extern const int RBAC_VERSION_IS_TOO_NEW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const UInt64 RBAC_INITIAL_VERSION;
|
|
||||||
extern const UInt64 RBAC_LATEST_VERSION;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr const char RBAC_VERSION_SETTING_NAME[] = "rbac_version";
|
|
||||||
|
|
||||||
/// Special parser for the 'ATTACH access entity' queries.
|
/// Special parser for the 'ATTACH access entity' queries.
|
||||||
class ParserAttachAccessEntity : public IParserBase
|
class ParserAttachAccessEntity : public IParserBase
|
||||||
{
|
{
|
||||||
@ -64,7 +56,6 @@ namespace
|
|||||||
ParserCreateQuotaQuery create_quota_p;
|
ParserCreateQuotaQuery create_quota_p;
|
||||||
ParserCreateSettingsProfileQuery create_profile_p;
|
ParserCreateSettingsProfileQuery create_profile_p;
|
||||||
ParserGrantQuery grant_p;
|
ParserGrantQuery grant_p;
|
||||||
ParserSetQuery set_p;
|
|
||||||
|
|
||||||
create_user_p.useAttachMode();
|
create_user_p.useAttachMode();
|
||||||
create_role_p.useAttachMode();
|
create_role_p.useAttachMode();
|
||||||
@ -75,8 +66,7 @@ namespace
|
|||||||
|
|
||||||
return create_user_p.parse(pos, node, expected) || create_role_p.parse(pos, node, expected)
|
return create_user_p.parse(pos, node, expected) || create_role_p.parse(pos, node, expected)
|
||||||
|| create_policy_p.parse(pos, node, expected) || create_quota_p.parse(pos, node, expected)
|
|| create_policy_p.parse(pos, node, expected) || create_quota_p.parse(pos, node, expected)
|
||||||
|| create_profile_p.parse(pos, node, expected) || grant_p.parse(pos, node, expected)
|
|| create_profile_p.parse(pos, node, expected) || grant_p.parse(pos, node, expected);
|
||||||
|| set_p.parse(pos, node, expected);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,15 +75,8 @@ namespace
|
|||||||
|
|
||||||
String serializeAccessEntity(const IAccessEntity & entity)
|
String serializeAccessEntity(const IAccessEntity & entity)
|
||||||
{
|
{
|
||||||
ASTs queries;
|
|
||||||
{
|
|
||||||
/// Prepend the list with "SET rbac_version = ..." query.
|
|
||||||
auto set_rbac_version_query = std::make_shared<ASTSetQuery>();
|
|
||||||
set_rbac_version_query->changes.emplace_back(RBAC_VERSION_SETTING_NAME, RBAC_LATEST_VERSION);
|
|
||||||
queries.push_back(set_rbac_version_query);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build list of ATTACH queries.
|
/// Build list of ATTACH queries.
|
||||||
|
ASTs queries;
|
||||||
queries.push_back(InterpreterShowCreateAccessEntityQuery::getAttachQuery(entity));
|
queries.push_back(InterpreterShowCreateAccessEntityQuery::getAttachQuery(entity));
|
||||||
if ((entity.getType() == AccessEntityType::USER) || (entity.getType() == AccessEntityType::ROLE))
|
if ((entity.getType() == AccessEntityType::USER) || (entity.getType() == AccessEntityType::ROLE))
|
||||||
boost::range::push_back(queries, InterpreterShowGrantsQuery::getAttachGrantQueries(entity));
|
boost::range::push_back(queries, InterpreterShowGrantsQuery::getAttachGrantQueries(entity));
|
||||||
@ -122,12 +105,6 @@ AccessEntityPtr deserializeAccessEntityImpl(const String & definition)
|
|||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Number of queries interpreted.
|
|
||||||
size_t query_index = 0;
|
|
||||||
|
|
||||||
/// If there is no "SET rbac_version = ..." query we assume that it's the initial version.
|
|
||||||
UInt64 rbac_version = RBAC_INITIAL_VERSION;
|
|
||||||
|
|
||||||
/// Interpret the AST to build an access entity.
|
/// Interpret the AST to build an access entity.
|
||||||
std::shared_ptr<User> user;
|
std::shared_ptr<User> user;
|
||||||
std::shared_ptr<Role> role;
|
std::shared_ptr<Role> role;
|
||||||
@ -138,24 +115,12 @@ AccessEntityPtr deserializeAccessEntityImpl(const String & definition)
|
|||||||
|
|
||||||
for (const auto & query : queries)
|
for (const auto & query : queries)
|
||||||
{
|
{
|
||||||
if (auto * set_query = query->as<ASTSetQuery>())
|
if (auto * create_user_query = query->as<ASTCreateUserQuery>())
|
||||||
{
|
|
||||||
if ((set_query->changes.size() != 1) || (set_query->changes[0].name != RBAC_VERSION_SETTING_NAME))
|
|
||||||
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "SET query in this file is only allowed to set {}", RBAC_VERSION_SETTING_NAME);
|
|
||||||
if (query_index != 0)
|
|
||||||
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "SET {} should be the first query in the file", RBAC_VERSION_SETTING_NAME);
|
|
||||||
rbac_version = set_query->changes[0].value.safeGet<UInt64>();
|
|
||||||
if (rbac_version < RBAC_INITIAL_VERSION)
|
|
||||||
throw Exception(ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION, "{} must be >= {}", RBAC_VERSION_SETTING_NAME, RBAC_INITIAL_VERSION);
|
|
||||||
if (rbac_version > RBAC_LATEST_VERSION)
|
|
||||||
throw Exception(ErrorCodes::RBAC_VERSION_IS_TOO_NEW, "{} must be <= {}, {} {} is too new", RBAC_VERSION_SETTING_NAME, RBAC_LATEST_VERSION, RBAC_VERSION_SETTING_NAME, rbac_version);
|
|
||||||
}
|
|
||||||
else if (auto * create_user_query = query->as<ASTCreateUserQuery>())
|
|
||||||
{
|
{
|
||||||
if (res)
|
if (res)
|
||||||
throw Exception("Two access entities attached in the same file", ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION);
|
throw Exception("Two access entities attached in the same file", ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION);
|
||||||
res = user = std::make_unique<User>();
|
res = user = std::make_unique<User>();
|
||||||
InterpreterCreateUserQuery::updateUserFromQuery(*user, *create_user_query);
|
InterpreterCreateUserQuery::updateUserFromQuery(*user, *create_user_query, /* allow_no_password = */ true, /* allow_plaintext_password = */ true);
|
||||||
}
|
}
|
||||||
else if (auto * create_role_query = query->as<ASTCreateRoleQuery>())
|
else if (auto * create_role_query = query->as<ASTCreateRoleQuery>())
|
||||||
{
|
{
|
||||||
@ -169,7 +134,7 @@ AccessEntityPtr deserializeAccessEntityImpl(const String & definition)
|
|||||||
if (res)
|
if (res)
|
||||||
throw Exception("Two access entities attached in the same file", ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION);
|
throw Exception("Two access entities attached in the same file", ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION);
|
||||||
res = policy = std::make_unique<RowPolicy>();
|
res = policy = std::make_unique<RowPolicy>();
|
||||||
InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(*policy, *create_policy_query, rbac_version);
|
InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(*policy, *create_policy_query);
|
||||||
}
|
}
|
||||||
else if (auto * create_quota_query = query->as<ASTCreateQuotaQuery>())
|
else if (auto * create_quota_query = query->as<ASTCreateQuotaQuery>())
|
||||||
{
|
{
|
||||||
@ -196,8 +161,6 @@ AccessEntityPtr deserializeAccessEntityImpl(const String & definition)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Exception("No interpreter found for query " + query->getID(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION);
|
throw Exception("No interpreter found for query " + query->getID(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION);
|
||||||
|
|
||||||
++query_index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -78,40 +78,4 @@ const RowPolicyFilterTypeInfo & RowPolicyFilterTypeInfo::get(RowPolicyFilterType
|
|||||||
throw Exception("Unknown type: " + std::to_string(static_cast<size_t>(type_)), ErrorCodes::LOGICAL_ERROR);
|
throw Exception("Unknown type: " + std::to_string(static_cast<size_t>(type_)), ErrorCodes::LOGICAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
String toString(RowPolicyKind type)
|
|
||||||
{
|
|
||||||
return RowPolicyKindInfo::get(type).raw_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RowPolicyKindInfo & RowPolicyKindInfo::get(RowPolicyKind kind_)
|
|
||||||
{
|
|
||||||
static constexpr auto make_info = [](const char * raw_name_)
|
|
||||||
{
|
|
||||||
String nam = raw_name_;
|
|
||||||
boost::to_lower(nam);
|
|
||||||
return RowPolicyKindInfo{raw_name_, std::move(nam)};
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (kind_)
|
|
||||||
{
|
|
||||||
case RowPolicyKind::PERMISSIVE:
|
|
||||||
{
|
|
||||||
static const auto info = make_info("PERMISSIVE");
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
case RowPolicyKind::RESTRICTIVE:
|
|
||||||
{
|
|
||||||
static const auto info = make_info("RESTRICTIVE");
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
case RowPolicyKind::SIMPLE:
|
|
||||||
{
|
|
||||||
static const auto info = make_info("SIMPLE");
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
case RowPolicyKind::MAX: break;
|
|
||||||
}
|
|
||||||
throw Exception("Unknown kind: " + std::to_string(static_cast<size_t>(kind_)), ErrorCodes::LOGICAL_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,26 +54,4 @@ struct RowPolicyFilterTypeInfo
|
|||||||
static const RowPolicyFilterTypeInfo & get(RowPolicyFilterType type);
|
static const RowPolicyFilterTypeInfo & get(RowPolicyFilterType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Kinds of row policies. It affects how row policies are applied.
|
|
||||||
/// A row is only accessible if at least one of the permissive policies passes,
|
|
||||||
/// in addition to all the restrictive policies.
|
|
||||||
enum class RowPolicyKind
|
|
||||||
{
|
|
||||||
PERMISSIVE,
|
|
||||||
RESTRICTIVE,
|
|
||||||
SIMPLE,
|
|
||||||
|
|
||||||
MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
String toString(RowPolicyKind kind);
|
|
||||||
|
|
||||||
struct RowPolicyKindInfo
|
|
||||||
{
|
|
||||||
const char * const raw_name;
|
|
||||||
const String name; /// Lowercased with underscores, e.g. "permissive".
|
|
||||||
static const RowPolicyKindInfo & get(RowPolicyKind kind);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
#include <base/types.h>
|
|
||||||
|
|
||||||
namespace DB
|
|
||||||
{
|
|
||||||
|
|
||||||
extern const UInt64 RBAC_INITIAL_VERSION = 1;
|
|
||||||
|
|
||||||
/// rbac_version < 2:
|
|
||||||
/// row policies are permissive by default
|
|
||||||
///
|
|
||||||
/// rbac_version >= 2:
|
|
||||||
/// row policies are simple by default
|
|
||||||
extern const UInt64 RBAC_VERSION_ROW_POLICIES_ARE_SIMPLE_BY_DEFAULT = 2;
|
|
||||||
|
|
||||||
extern const UInt64 RBAC_LATEST_VERSION = 2;
|
|
||||||
|
|
||||||
}
|
|
@ -55,7 +55,7 @@ bool RowPolicy::equal(const IAccessEntity & other) const
|
|||||||
return false;
|
return false;
|
||||||
const auto & other_policy = typeid_cast<const RowPolicy &>(other);
|
const auto & other_policy = typeid_cast<const RowPolicy &>(other);
|
||||||
return (full_name == other_policy.full_name) && boost::range::equal(filters, other_policy.filters)
|
return (full_name == other_policy.full_name) && boost::range::equal(filters, other_policy.filters)
|
||||||
&& (kind == other_policy.kind) && (to_roles == other_policy.to_roles);
|
&& restrictive == other_policy.restrictive && (to_roles == other_policy.to_roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,17 @@ struct RowPolicy : public IAccessEntity
|
|||||||
/// for user or available for modification.
|
/// for user or available for modification.
|
||||||
std::array<String, static_cast<size_t>(RowPolicyFilterType::MAX)> filters;
|
std::array<String, static_cast<size_t>(RowPolicyFilterType::MAX)> filters;
|
||||||
|
|
||||||
/// Sets the kind of the policy, it affects how row policies are applied.
|
/// Sets that the policy is permissive.
|
||||||
void setKind(RowPolicyKind kind_) { kind = kind_; }
|
/// A row is only accessible if at least one of the permissive policies passes,
|
||||||
RowPolicyKind getKind() const { return kind; }
|
/// in addition to all the restrictive policies.
|
||||||
|
void setPermissive(bool permissive_ = true) { setRestrictive(!permissive_); }
|
||||||
|
bool isPermissive() const { return !isRestrictive(); }
|
||||||
|
|
||||||
|
/// Sets that the policy is restrictive.
|
||||||
|
/// A row is only accessible if at least one of the permissive policies passes,
|
||||||
|
/// in addition to all the restrictive policies.
|
||||||
|
void setRestrictive(bool restrictive_ = true) { restrictive = restrictive_; }
|
||||||
|
bool isRestrictive() const { return restrictive; }
|
||||||
|
|
||||||
bool equal(const IAccessEntity & other) const override;
|
bool equal(const IAccessEntity & other) const override;
|
||||||
std::shared_ptr<IAccessEntity> clone() const override { return cloneImpl<RowPolicy>(); }
|
std::shared_ptr<IAccessEntity> clone() const override { return cloneImpl<RowPolicy>(); }
|
||||||
@ -45,7 +53,7 @@ private:
|
|||||||
void setName(const String &) override;
|
void setName(const String &) override;
|
||||||
|
|
||||||
RowPolicyName full_name;
|
RowPolicyName full_name;
|
||||||
RowPolicyKind kind = RowPolicyKind::PERMISSIVE;
|
bool restrictive = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
using RowPolicyPtr = std::shared_ptr<const RowPolicy>;
|
using RowPolicyPtr = std::shared_ptr<const RowPolicy>;
|
||||||
|
@ -20,21 +20,18 @@ namespace
|
|||||||
class FiltersMixer
|
class FiltersMixer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void add(const ASTPtr & filter, RowPolicyKind kind)
|
void add(const ASTPtr & filter, bool is_restrictive)
|
||||||
{
|
{
|
||||||
if (kind == RowPolicyKind::PERMISSIVE)
|
if (is_restrictive)
|
||||||
permissions.push_back(filter);
|
|
||||||
else if ((kind == RowPolicyKind::RESTRICTIVE) || (kind == RowPolicyKind::SIMPLE))
|
|
||||||
restrictions.push_back(filter);
|
restrictions.push_back(filter);
|
||||||
if ((kind == RowPolicyKind::PERMISSIVE) || (kind == RowPolicyKind::RESTRICTIVE))
|
else
|
||||||
setUsePermissiveFilters(true);
|
permissions.push_back(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPtr getResult() &&
|
ASTPtr getResult() &&
|
||||||
{
|
{
|
||||||
/// Process permissive filters.
|
/// Process permissive filters.
|
||||||
if (use_permissive_filters)
|
restrictions.push_back(makeASTForLogicalOr(std::move(permissions)));
|
||||||
restrictions.push_back(makeASTForLogicalOr(std::move(permissions)));
|
|
||||||
|
|
||||||
/// Process restrictive filters.
|
/// Process restrictive filters.
|
||||||
auto result = makeASTForLogicalAnd(std::move(restrictions));
|
auto result = makeASTForLogicalAnd(std::move(restrictions));
|
||||||
@ -46,17 +43,9 @@ namespace
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If permissive filters are enabled then but no filters have been added then getResult() returns zero (i.e. no rows allowed).
|
|
||||||
/// It can happen if permissive or restrictive row policies have been added for some other users.
|
|
||||||
/// For example if the following is an only row policy for table1:
|
|
||||||
/// CREATE ROW POLICY policy1 ON table1 USING id=1 AS permissive TO user1
|
|
||||||
/// then user1 will see rows with id=1 and user2 will see no rows at all.
|
|
||||||
void setUsePermissiveFilters(bool use_permissive_filters_) { use_permissive_filters = use_permissive_filters_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ASTs permissions;
|
ASTs permissions;
|
||||||
ASTs restrictions;
|
ASTs restrictions;
|
||||||
bool use_permissive_filters = false;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,10 +223,8 @@ void RowPolicyCache::mixFiltersFor(EnabledRowPolicies & enabled)
|
|||||||
key.filter_type = filter_type;
|
key.filter_type = filter_type;
|
||||||
auto & mixer = mixers[key];
|
auto & mixer = mixers[key];
|
||||||
mixer.database_and_table_name = info.database_and_table_name;
|
mixer.database_and_table_name = info.database_and_table_name;
|
||||||
if ((policy.getKind() == RowPolicyKind::PERMISSIVE) || (policy.getKind() == RowPolicyKind::RESTRICTIVE))
|
|
||||||
mixer.mixer.setUsePermissiveFilters(true);
|
|
||||||
if (match)
|
if (match)
|
||||||
mixer.mixer.add(info.parsed_filters[filter_type_i], policy.getKind());
|
mixer.mixer.add(info.parsed_filters[filter_type_i], policy.isRestrictive());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,7 +614,6 @@
|
|||||||
M(643, CANNOT_UNPACK_ARCHIVE) \
|
M(643, CANNOT_UNPACK_ARCHIVE) \
|
||||||
M(644, REMOTE_FS_OBJECT_CACHE_ERROR) \
|
M(644, REMOTE_FS_OBJECT_CACHE_ERROR) \
|
||||||
M(645, NUMBER_OF_DIMENSIONS_MISMATHED) \
|
M(645, NUMBER_OF_DIMENSIONS_MISMATHED) \
|
||||||
M(646, RBAC_VERSION_IS_TOO_NEW) \
|
|
||||||
\
|
\
|
||||||
M(999, KEEPER_EXCEPTION) \
|
M(999, KEEPER_EXCEPTION) \
|
||||||
M(1000, POCO_EXCEPTION) \
|
M(1000, POCO_EXCEPTION) \
|
||||||
|
@ -693,8 +693,7 @@ class IColumn;
|
|||||||
\
|
\
|
||||||
M(Bool, output_format_arrow_low_cardinality_as_dictionary, false, "Enable output LowCardinality type as Dictionary Arrow type", 0) \
|
M(Bool, output_format_arrow_low_cardinality_as_dictionary, false, "Enable output LowCardinality type as Dictionary Arrow type", 0) \
|
||||||
\
|
\
|
||||||
M(EnumComparingMode, format_capn_proto_enum_comparising_mode, FormatSettings::EnumComparingMode::BY_VALUES, "How to map ClickHouse Enum and CapnProto Enum", 0) \
|
M(EnumComparingMode, format_capn_proto_enum_comparising_mode, FormatSettings::EnumComparingMode::BY_VALUES, "How to map ClickHouse Enum and CapnProto Enum", 0)\
|
||||||
M(UInt64, rbac_version, 1, "RBAC version", 0)\
|
|
||||||
|
|
||||||
// End of FORMAT_FACTORY_SETTINGS
|
// End of FORMAT_FACTORY_SETTINGS
|
||||||
// Please add settings non-related to formats into the COMMON_SETTINGS above.
|
// Please add settings non-related to formats into the COMMON_SETTINGS above.
|
||||||
|
@ -14,14 +14,11 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
extern const UInt64 RBAC_VERSION_ROW_POLICIES_ARE_SIMPLE_BY_DEFAULT;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
void updateRowPolicyFromQueryImpl(
|
void updateRowPolicyFromQueryImpl(
|
||||||
RowPolicy & policy,
|
RowPolicy & policy,
|
||||||
const ASTCreateRowPolicyQuery & query,
|
const ASTCreateRowPolicyQuery & query,
|
||||||
UInt64 rbac_version,
|
|
||||||
const RowPolicyName & override_name,
|
const RowPolicyName & override_name,
|
||||||
const std::optional<RolesOrUsersSet> & override_to_roles)
|
const std::optional<RolesOrUsersSet> & override_to_roles)
|
||||||
{
|
{
|
||||||
@ -32,25 +29,16 @@ namespace
|
|||||||
else if (query.names->full_names.size() == 1)
|
else if (query.names->full_names.size() == 1)
|
||||||
policy.setFullName(query.names->full_names.front());
|
policy.setFullName(query.names->full_names.front());
|
||||||
|
|
||||||
std::optional<RowPolicyKind> new_kind = query.kind;
|
if (query.is_restrictive)
|
||||||
if (!query.alter && !new_kind)
|
policy.setRestrictive(*query.is_restrictive);
|
||||||
{
|
|
||||||
if (rbac_version < RBAC_VERSION_ROW_POLICIES_ARE_SIMPLE_BY_DEFAULT)
|
|
||||||
new_kind = RowPolicyKind::PERMISSIVE;
|
|
||||||
else
|
|
||||||
new_kind = RowPolicyKind::SIMPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_kind)
|
|
||||||
policy.setKind(*new_kind);
|
|
||||||
|
|
||||||
for (const auto & [filter_type, filter] : query.filters)
|
for (const auto & [filter_type, filter] : query.filters)
|
||||||
policy.filters[static_cast<size_t>(filter_type)] = filter ? serializeAST(*filter) : String{};
|
policy.filters[static_cast<size_t>(filter_type)] = filter ? serializeAST(*filter) : String{};
|
||||||
|
|
||||||
if (override_to_roles)
|
if (override_to_roles)
|
||||||
policy.to_roles = *override_to_roles;
|
policy.to_roles = *override_to_roles;
|
||||||
else if (query.to_roles)
|
else if (query.roles)
|
||||||
policy.to_roles = *query.to_roles;
|
policy.to_roles = *query.roles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,21 +56,20 @@ BlockIO InterpreterCreateRowPolicyQuery::execute()
|
|||||||
|
|
||||||
assert(query.names->cluster.empty());
|
assert(query.names->cluster.empty());
|
||||||
auto & access_control = getContext()->getAccessControl();
|
auto & access_control = getContext()->getAccessControl();
|
||||||
UInt64 rbac_version = getContext()->getSettingsRef().rbac_version;
|
|
||||||
getContext()->checkAccess(required_access);
|
getContext()->checkAccess(required_access);
|
||||||
|
|
||||||
query.replaceEmptyDatabase(getContext()->getCurrentDatabase());
|
query.replaceEmptyDatabase(getContext()->getCurrentDatabase());
|
||||||
|
|
||||||
std::optional<RolesOrUsersSet> roles_from_query;
|
std::optional<RolesOrUsersSet> roles_from_query;
|
||||||
if (query.to_roles)
|
if (query.roles)
|
||||||
roles_from_query = RolesOrUsersSet{*query.to_roles, access_control, getContext()->getUserID()};
|
roles_from_query = RolesOrUsersSet{*query.roles, access_control, getContext()->getUserID()};
|
||||||
|
|
||||||
if (query.alter)
|
if (query.alter)
|
||||||
{
|
{
|
||||||
auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr
|
auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr
|
||||||
{
|
{
|
||||||
auto updated_policy = typeid_cast<std::shared_ptr<RowPolicy>>(entity->clone());
|
auto updated_policy = typeid_cast<std::shared_ptr<RowPolicy>>(entity->clone());
|
||||||
updateRowPolicyFromQueryImpl(*updated_policy, query, rbac_version, {}, roles_from_query);
|
updateRowPolicyFromQueryImpl(*updated_policy, query, {}, roles_from_query);
|
||||||
return updated_policy;
|
return updated_policy;
|
||||||
};
|
};
|
||||||
Strings names = query.names->toStrings();
|
Strings names = query.names->toStrings();
|
||||||
@ -100,7 +87,7 @@ BlockIO InterpreterCreateRowPolicyQuery::execute()
|
|||||||
for (const auto & full_name : query.names->full_names)
|
for (const auto & full_name : query.names->full_names)
|
||||||
{
|
{
|
||||||
auto new_policy = std::make_shared<RowPolicy>();
|
auto new_policy = std::make_shared<RowPolicy>();
|
||||||
updateRowPolicyFromQueryImpl(*new_policy, query, rbac_version, full_name, roles_from_query);
|
updateRowPolicyFromQueryImpl(*new_policy, query, full_name, roles_from_query);
|
||||||
new_policies.emplace_back(std::move(new_policy));
|
new_policies.emplace_back(std::move(new_policy));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +103,9 @@ BlockIO InterpreterCreateRowPolicyQuery::execute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(RowPolicy & policy, const ASTCreateRowPolicyQuery & query, UInt64 rbac_version)
|
void InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(RowPolicy & policy, const ASTCreateRowPolicyQuery & query)
|
||||||
{
|
{
|
||||||
updateRowPolicyFromQueryImpl(policy, query, rbac_version, {}, {});
|
updateRowPolicyFromQueryImpl(policy, query, {}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
|
|
||||||
BlockIO execute() override;
|
BlockIO execute() override;
|
||||||
|
|
||||||
static void updateRowPolicyFromQuery(RowPolicy & policy, const ASTCreateRowPolicyQuery & query, UInt64 rbac_version);
|
static void updateRowPolicyFromQuery(RowPolicy & policy, const ASTCreateRowPolicyQuery & query);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AccessRightsElements getRequiredAccess() const;
|
AccessRightsElements getRequiredAccess() const;
|
||||||
|
@ -129,8 +129,7 @@ BlockIO InterpreterCreateUserQuery::execute()
|
|||||||
auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr
|
auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr
|
||||||
{
|
{
|
||||||
auto updated_user = typeid_cast<std::shared_ptr<User>>(entity->clone());
|
auto updated_user = typeid_cast<std::shared_ptr<User>>(entity->clone());
|
||||||
updateUserFromQueryImpl(*updated_user, query, {}, default_roles_from_query, settings_from_query,
|
updateUserFromQueryImpl(*updated_user, query, {}, default_roles_from_query, settings_from_query, grantees_from_query, no_password_allowed, plaintext_password_allowed);
|
||||||
grantees_from_query, no_password_allowed, plaintext_password_allowed);
|
|
||||||
return updated_user;
|
return updated_user;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -149,8 +148,7 @@ BlockIO InterpreterCreateUserQuery::execute()
|
|||||||
for (const auto & name : *query.names)
|
for (const auto & name : *query.names)
|
||||||
{
|
{
|
||||||
auto new_user = std::make_shared<User>();
|
auto new_user = std::make_shared<User>();
|
||||||
updateUserFromQueryImpl(*new_user, query, name, default_roles_from_query, settings_from_query,
|
updateUserFromQueryImpl(*new_user, query, name, default_roles_from_query, settings_from_query, RolesOrUsersSet::AllTag{}, no_password_allowed, plaintext_password_allowed);
|
||||||
RolesOrUsersSet::AllTag{}, no_password_allowed, plaintext_password_allowed);
|
|
||||||
new_users.emplace_back(std::move(new_user));
|
new_users.emplace_back(std::move(new_user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,9 +176,9 @@ BlockIO InterpreterCreateUserQuery::execute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterpreterCreateUserQuery::updateUserFromQuery(User & user, const ASTCreateUserQuery & query)
|
void InterpreterCreateUserQuery::updateUserFromQuery(User & user, const ASTCreateUserQuery & query, bool allow_no_password, bool allow_plaintext_password)
|
||||||
{
|
{
|
||||||
updateUserFromQueryImpl(user, query, {}, {}, {}, {}, true, true);
|
updateUserFromQueryImpl(user, query, {}, {}, {}, {}, allow_no_password, allow_plaintext_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
|
|
||||||
BlockIO execute() override;
|
BlockIO execute() override;
|
||||||
|
|
||||||
static void updateUserFromQuery(User & user, const ASTCreateUserQuery & query);
|
static void updateUserFromQuery(User & user, const ASTCreateUserQuery & query, bool allow_no_password, bool allow_plaintext_password);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ASTPtr query_ptr;
|
ASTPtr query_ptr;
|
||||||
|
@ -70,12 +70,11 @@ ASTs InterpreterShowAccessQuery::getCreateAndGrantQueries() const
|
|||||||
{
|
{
|
||||||
auto entities = getEntities();
|
auto entities = getEntities();
|
||||||
const auto & access_control = getContext()->getAccessControl();
|
const auto & access_control = getContext()->getAccessControl();
|
||||||
UInt64 rbac_version = getContext()->getSettingsRef().rbac_version;
|
|
||||||
|
|
||||||
ASTs create_queries, grant_queries;
|
ASTs create_queries, grant_queries;
|
||||||
for (const auto & entity : entities)
|
for (const auto & entity : entities)
|
||||||
{
|
{
|
||||||
create_queries.push_back(InterpreterShowCreateAccessEntityQuery::getCreateQuery(*entity, access_control, rbac_version));
|
create_queries.push_back(InterpreterShowCreateAccessEntityQuery::getCreateQuery(*entity, access_control));
|
||||||
if (entity->isTypeOf(AccessEntityType::USER) || entity->isTypeOf(AccessEntityType::ROLE))
|
if (entity->isTypeOf(AccessEntityType::USER) || entity->isTypeOf(AccessEntityType::ROLE))
|
||||||
insertAtEnd(grant_queries, InterpreterShowGrantsQuery::getGrantQueries(*entity, access_control));
|
insertAtEnd(grant_queries, InterpreterShowGrantsQuery::getGrantQueries(*entity, access_control));
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,6 @@ namespace ErrorCodes
|
|||||||
extern const int NOT_IMPLEMENTED;
|
extern const int NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const UInt64 RBAC_LATEST_VERSION;
|
|
||||||
extern const UInt64 RBAC_VERSION_ROW_POLICIES_ARE_SIMPLE_BY_DEFAULT;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -185,7 +183,6 @@ namespace
|
|||||||
ASTPtr getCreateQueryImpl(
|
ASTPtr getCreateQueryImpl(
|
||||||
const RowPolicy & policy,
|
const RowPolicy & policy,
|
||||||
const AccessControl * access_control /* not used if attach_mode == true */,
|
const AccessControl * access_control /* not used if attach_mode == true */,
|
||||||
UInt64 rbac_version,
|
|
||||||
bool attach_mode)
|
bool attach_mode)
|
||||||
{
|
{
|
||||||
auto query = std::make_shared<ASTCreateRowPolicyQuery>();
|
auto query = std::make_shared<ASTCreateRowPolicyQuery>();
|
||||||
@ -193,6 +190,9 @@ namespace
|
|||||||
query->names->full_names.emplace_back(policy.getFullName());
|
query->names->full_names.emplace_back(policy.getFullName());
|
||||||
query->attach = attach_mode;
|
query->attach = attach_mode;
|
||||||
|
|
||||||
|
if (policy.isRestrictive())
|
||||||
|
query->is_restrictive = policy.isRestrictive();
|
||||||
|
|
||||||
for (auto type : collections::range(RowPolicyFilterType::MAX))
|
for (auto type : collections::range(RowPolicyFilterType::MAX))
|
||||||
{
|
{
|
||||||
const auto & filter = policy.filters[static_cast<size_t>(type)];
|
const auto & filter = policy.filters[static_cast<size_t>(type)];
|
||||||
@ -204,15 +204,12 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attach_mode || (rbac_version < RBAC_VERSION_ROW_POLICIES_ARE_SIMPLE_BY_DEFAULT) || (policy.getKind() != RowPolicyKind::SIMPLE))
|
|
||||||
query->kind = policy.getKind();
|
|
||||||
|
|
||||||
if (!policy.to_roles.empty())
|
if (!policy.to_roles.empty())
|
||||||
{
|
{
|
||||||
if (attach_mode)
|
if (attach_mode)
|
||||||
query->to_roles = policy.to_roles.toAST();
|
query->roles = policy.to_roles.toAST();
|
||||||
else
|
else
|
||||||
query->to_roles = policy.to_roles.toASTWithNames(*access_control);
|
query->roles = policy.to_roles.toASTWithNames(*access_control);
|
||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
@ -221,7 +218,6 @@ namespace
|
|||||||
ASTPtr getCreateQueryImpl(
|
ASTPtr getCreateQueryImpl(
|
||||||
const IAccessEntity & entity,
|
const IAccessEntity & entity,
|
||||||
const AccessControl * access_control /* not used if attach_mode == true */,
|
const AccessControl * access_control /* not used if attach_mode == true */,
|
||||||
UInt64 rbac_version,
|
|
||||||
bool attach_mode)
|
bool attach_mode)
|
||||||
{
|
{
|
||||||
if (const User * user = typeid_cast<const User *>(&entity))
|
if (const User * user = typeid_cast<const User *>(&entity))
|
||||||
@ -229,7 +225,7 @@ namespace
|
|||||||
if (const Role * role = typeid_cast<const Role *>(&entity))
|
if (const Role * role = typeid_cast<const Role *>(&entity))
|
||||||
return getCreateQueryImpl(*role, access_control, attach_mode);
|
return getCreateQueryImpl(*role, access_control, attach_mode);
|
||||||
if (const RowPolicy * policy = typeid_cast<const RowPolicy *>(&entity))
|
if (const RowPolicy * policy = typeid_cast<const RowPolicy *>(&entity))
|
||||||
return getCreateQueryImpl(*policy, access_control, rbac_version, attach_mode);
|
return getCreateQueryImpl(*policy, access_control, attach_mode);
|
||||||
if (const Quota * quota = typeid_cast<const Quota *>(&entity))
|
if (const Quota * quota = typeid_cast<const Quota *>(&entity))
|
||||||
return getCreateQueryImpl(*quota, access_control, attach_mode);
|
return getCreateQueryImpl(*quota, access_control, attach_mode);
|
||||||
if (const SettingsProfile * profile = typeid_cast<const SettingsProfile *>(&entity))
|
if (const SettingsProfile * profile = typeid_cast<const SettingsProfile *>(&entity))
|
||||||
@ -356,23 +352,22 @@ ASTs InterpreterShowCreateAccessEntityQuery::getCreateQueries() const
|
|||||||
|
|
||||||
ASTs list;
|
ASTs list;
|
||||||
const auto & access_control = getContext()->getAccessControl();
|
const auto & access_control = getContext()->getAccessControl();
|
||||||
UInt64 rbac_version = getContext()->getSettingsRef().rbac_version;
|
|
||||||
for (const auto & entity : entities)
|
for (const auto & entity : entities)
|
||||||
list.push_back(getCreateQuery(*entity, access_control, rbac_version));
|
list.push_back(getCreateQuery(*entity, access_control));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ASTPtr InterpreterShowCreateAccessEntityQuery::getCreateQuery(const IAccessEntity & entity, const AccessControl & access_control, UInt64 rbac_version)
|
ASTPtr InterpreterShowCreateAccessEntityQuery::getCreateQuery(const IAccessEntity & entity, const AccessControl & access_control)
|
||||||
{
|
{
|
||||||
return getCreateQueryImpl(entity, &access_control, rbac_version, false);
|
return getCreateQueryImpl(entity, &access_control, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ASTPtr InterpreterShowCreateAccessEntityQuery::getAttachQuery(const IAccessEntity & entity)
|
ASTPtr InterpreterShowCreateAccessEntityQuery::getAttachQuery(const IAccessEntity & entity)
|
||||||
{
|
{
|
||||||
return getCreateQueryImpl(entity, nullptr, RBAC_LATEST_VERSION, true);
|
return getCreateQueryImpl(entity, nullptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public:
|
|||||||
bool ignoreQuota() const override { return true; }
|
bool ignoreQuota() const override { return true; }
|
||||||
bool ignoreLimits() const override { return true; }
|
bool ignoreLimits() const override { return true; }
|
||||||
|
|
||||||
static ASTPtr getCreateQuery(const IAccessEntity & entity, const AccessControl & access_control, UInt64 rbac_version);
|
static ASTPtr getCreateQuery(const IAccessEntity & entity, const AccessControl & access_control);
|
||||||
static ASTPtr getAttachQuery(const IAccessEntity & entity);
|
static ASTPtr getAttachQuery(const IAccessEntity & entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -20,10 +20,10 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void formatAsKind(RowPolicyKind kind, const IAST::FormatSettings & settings)
|
void formatAsRestrictiveOrPermissive(bool is_restrictive, const IAST::FormatSettings & settings)
|
||||||
{
|
{
|
||||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " AS " << (settings.hilite ? IAST::hilite_none : "")
|
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " AS " << (settings.hilite ? IAST::hilite_none : "")
|
||||||
<< RowPolicyKindInfo::get(kind).name;
|
<< (is_restrictive ? "restrictive" : "permissive");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,20 +156,20 @@ void ASTCreateRowPolicyQuery::formatImpl(const FormatSettings & settings, Format
|
|||||||
if (!new_short_name.empty())
|
if (!new_short_name.empty())
|
||||||
formatRenameTo(new_short_name, settings);
|
formatRenameTo(new_short_name, settings);
|
||||||
|
|
||||||
|
if (is_restrictive)
|
||||||
|
formatAsRestrictiveOrPermissive(*is_restrictive, settings);
|
||||||
|
|
||||||
formatForClauses(filters, alter, settings);
|
formatForClauses(filters, alter, settings);
|
||||||
|
|
||||||
if (kind)
|
if (roles && (!roles->empty() || alter))
|
||||||
formatAsKind(*kind, settings);
|
formatToRoles(*roles, settings);
|
||||||
|
|
||||||
if (to_roles)
|
|
||||||
formatToRoles(*to_roles, settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ASTCreateRowPolicyQuery::replaceCurrentUserTag(const String & current_user_name) const
|
void ASTCreateRowPolicyQuery::replaceCurrentUserTag(const String & current_user_name) const
|
||||||
{
|
{
|
||||||
if (to_roles)
|
if (roles)
|
||||||
to_roles->replaceCurrentUserTag(current_user_name);
|
roles->replaceCurrentUserTag(current_user_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTCreateRowPolicyQuery::replaceEmptyDatabase(const String & current_database) const
|
void ASTCreateRowPolicyQuery::replaceEmptyDatabase(const String & current_database) const
|
||||||
|
@ -39,10 +39,10 @@ public:
|
|||||||
std::shared_ptr<ASTRowPolicyNames> names;
|
std::shared_ptr<ASTRowPolicyNames> names;
|
||||||
String new_short_name;
|
String new_short_name;
|
||||||
|
|
||||||
|
std::optional<bool> is_restrictive;
|
||||||
std::vector<std::pair<RowPolicyFilterType, ASTPtr>> filters; /// `nullptr` means set to NONE.
|
std::vector<std::pair<RowPolicyFilterType, ASTPtr>> filters; /// `nullptr` means set to NONE.
|
||||||
|
|
||||||
std::optional<RowPolicyKind> kind;
|
std::shared_ptr<ASTRolesOrUsersSet> roles;
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> to_roles;
|
|
||||||
|
|
||||||
String getID(char) const override;
|
String getID(char) const override;
|
||||||
ASTPtr clone() const override;
|
ASTPtr clone() const override;
|
||||||
|
@ -29,24 +29,24 @@ namespace
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseAsKind(IParserBase::Pos & pos, Expected & expected, RowPolicyKind & kind)
|
bool parseAsRestrictiveOrPermissive(IParserBase::Pos & pos, Expected & expected, bool & is_restrictive)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
if (!ParserKeyword{"AS"}.ignore(pos, expected))
|
if (!ParserKeyword{"AS"}.ignore(pos, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto current_kind : collections::range(RowPolicyKind::MAX))
|
if (ParserKeyword{"RESTRICTIVE"}.ignore(pos, expected))
|
||||||
{
|
{
|
||||||
const std::string_view & kind_name = RowPolicyKindInfo::get(current_kind).name;
|
is_restrictive = true;
|
||||||
if (ParserKeyword{kind_name.data()}.ignore(pos, expected))
|
return true;
|
||||||
{
|
|
||||||
kind = current_kind;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!ParserKeyword{"PERMISSIVE"}.ignore(pos, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
is_restrictive = false;
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ bool ParserCreateRowPolicyQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
|
|||||||
String cluster = std::exchange(names->cluster, "");
|
String cluster = std::exchange(names->cluster, "");
|
||||||
|
|
||||||
String new_short_name;
|
String new_short_name;
|
||||||
std::optional<RowPolicyKind> kind;
|
std::optional<bool> is_restrictive;
|
||||||
std::vector<std::pair<RowPolicyFilterType, ASTPtr>> filters;
|
std::vector<std::pair<RowPolicyFilterType, ASTPtr>> filters;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@ -251,12 +251,12 @@ bool ParserCreateRowPolicyQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
|
|||||||
if (alter && (names->full_names.size() == 1) && new_short_name.empty() && parseRenameTo(pos, expected, new_short_name))
|
if (alter && (names->full_names.size() == 1) && new_short_name.empty() && parseRenameTo(pos, expected, new_short_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!kind)
|
if (!is_restrictive)
|
||||||
{
|
{
|
||||||
RowPolicyKind new_kind;
|
bool new_is_restrictive;
|
||||||
if (parseAsKind(pos, expected, new_kind))
|
if (parseAsRestrictiveOrPermissive(pos, expected, new_is_restrictive))
|
||||||
{
|
{
|
||||||
kind = new_kind;
|
is_restrictive = new_is_restrictive;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,8 +274,8 @@ bool ParserCreateRowPolicyQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> to_roles;
|
std::shared_ptr<ASTRolesOrUsersSet> roles;
|
||||||
parseToRoles(pos, expected, attach_mode, to_roles);
|
parseToRoles(pos, expected, attach_mode, roles);
|
||||||
|
|
||||||
if (cluster.empty())
|
if (cluster.empty())
|
||||||
parseOnCluster(pos, expected, cluster);
|
parseOnCluster(pos, expected, cluster);
|
||||||
@ -291,9 +291,9 @@ bool ParserCreateRowPolicyQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
|
|||||||
query->cluster = std::move(cluster);
|
query->cluster = std::move(cluster);
|
||||||
query->names = std::move(names);
|
query->names = std::move(names);
|
||||||
query->new_short_name = std::move(new_short_name);
|
query->new_short_name = std::move(new_short_name);
|
||||||
query->kind = kind;
|
query->is_restrictive = is_restrictive;
|
||||||
query->filters = std::move(filters);
|
query->filters = std::move(filters);
|
||||||
query->to_roles = std::move(to_roles);
|
query->roles = std::move(roles);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
#include <DataTypes/DataTypeUUID.h>
|
#include <DataTypes/DataTypeUUID.h>
|
||||||
#include <DataTypes/DataTypeNullable.h>
|
#include <DataTypes/DataTypeNullable.h>
|
||||||
#include <DataTypes/DataTypeEnum.h>
|
|
||||||
#include <DataTypes/DataTypeArray.h>
|
#include <DataTypes/DataTypeArray.h>
|
||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <Parsers/Access/ASTRolesOrUsersSet.h>
|
#include <Parsers/Access/ASTRolesOrUsersSet.h>
|
||||||
@ -20,26 +19,6 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const std::vector<std::pair<String, Int8>> & getRowPolicyKindEnumValues()
|
|
||||||
{
|
|
||||||
static const std::vector<std::pair<String, Int8>> values = []
|
|
||||||
{
|
|
||||||
std::vector<std::pair<String, Int8>> res;
|
|
||||||
for (auto kind : collections::range(RowPolicyKind::MAX))
|
|
||||||
{
|
|
||||||
const std::string_view & kind_name = RowPolicyKindInfo::get(kind).name;
|
|
||||||
res.emplace_back(kind_name, static_cast<Int8>(kind));
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}();
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NamesAndTypesList StorageSystemRowPolicies::getNamesAndTypes()
|
NamesAndTypesList StorageSystemRowPolicies::getNamesAndTypes()
|
||||||
{
|
{
|
||||||
NamesAndTypesList names_and_types{
|
NamesAndTypesList names_and_types{
|
||||||
@ -58,7 +37,7 @@ NamesAndTypesList StorageSystemRowPolicies::getNamesAndTypes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
NamesAndTypesList extra_names_and_types{
|
NamesAndTypesList extra_names_and_types{
|
||||||
{"kind", std::make_shared<DataTypeEnum8>(getRowPolicyKindEnumValues())},
|
{"is_restrictive", std::make_shared<DataTypeUInt8>()},
|
||||||
{"apply_to_all", std::make_shared<DataTypeUInt8>()},
|
{"apply_to_all", std::make_shared<DataTypeUInt8>()},
|
||||||
{"apply_to_list", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
|
{"apply_to_list", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())},
|
||||||
{"apply_to_except", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())}
|
{"apply_to_except", std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>())}
|
||||||
@ -93,7 +72,7 @@ void StorageSystemRowPolicies::fillData(MutableColumns & res_columns, ContextPtr
|
|||||||
column_filter_null_map[filter_type_i] = &assert_cast<ColumnNullable &>(*res_columns[column_index++]).getNullMapData();
|
column_filter_null_map[filter_type_i] = &assert_cast<ColumnNullable &>(*res_columns[column_index++]).getNullMapData();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & column_kind = assert_cast<ColumnInt8 &>(*res_columns[column_index++]).getData();
|
auto & column_is_restrictive = assert_cast<ColumnUInt8 &>(*res_columns[column_index++]).getData();
|
||||||
auto & column_apply_to_all = assert_cast<ColumnUInt8 &>(*res_columns[column_index++]).getData();
|
auto & column_apply_to_all = assert_cast<ColumnUInt8 &>(*res_columns[column_index++]).getData();
|
||||||
auto & column_apply_to_list = assert_cast<ColumnString &>(assert_cast<ColumnArray &>(*res_columns[column_index]).getData());
|
auto & column_apply_to_list = assert_cast<ColumnString &>(assert_cast<ColumnArray &>(*res_columns[column_index]).getData());
|
||||||
auto & column_apply_to_list_offsets = assert_cast<ColumnArray &>(*res_columns[column_index++]).getOffsets();
|
auto & column_apply_to_list_offsets = assert_cast<ColumnArray &>(*res_columns[column_index++]).getOffsets();
|
||||||
@ -105,7 +84,7 @@ void StorageSystemRowPolicies::fillData(MutableColumns & res_columns, ContextPtr
|
|||||||
const UUID & id,
|
const UUID & id,
|
||||||
const String & storage_name,
|
const String & storage_name,
|
||||||
const std::array<String, static_cast<size_t>(RowPolicyFilterType::MAX)> & filters,
|
const std::array<String, static_cast<size_t>(RowPolicyFilterType::MAX)> & filters,
|
||||||
RowPolicyKind kind,
|
bool is_restrictive,
|
||||||
const RolesOrUsersSet & apply_to)
|
const RolesOrUsersSet & apply_to)
|
||||||
{
|
{
|
||||||
column_name.insertData(name.data(), name.length());
|
column_name.insertData(name.data(), name.length());
|
||||||
@ -131,7 +110,7 @@ void StorageSystemRowPolicies::fillData(MutableColumns & res_columns, ContextPtr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
column_kind.push_back(static_cast<Int8>(kind));
|
column_is_restrictive.push_back(is_restrictive);
|
||||||
|
|
||||||
auto apply_to_ast = apply_to.toASTWithNames(access_control);
|
auto apply_to_ast = apply_to.toASTWithNames(access_control);
|
||||||
column_apply_to_all.push_back(apply_to_ast->all);
|
column_apply_to_all.push_back(apply_to_ast->all);
|
||||||
@ -154,7 +133,7 @@ void StorageSystemRowPolicies::fillData(MutableColumns & res_columns, ContextPtr
|
|||||||
if (!storage)
|
if (!storage)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
add_row(policy->getName(), policy->getFullName(), id, storage->getStorageName(), policy->filters, policy->getKind(), policy->to_roles);
|
add_row(policy->getName(), policy->getFullName(), id, storage->getStorageName(), policy->filters, policy->isRestrictive(), policy->to_roles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2287,16 +2287,6 @@ class ClickHouseInstance:
|
|||||||
def copy_file_to_container(self, local_path, dest_path):
|
def copy_file_to_container(self, local_path, dest_path):
|
||||||
return self.cluster.copy_file_to_container(self.docker_id, local_path, dest_path)
|
return self.cluster.copy_file_to_container(self.docker_id, local_path, dest_path)
|
||||||
|
|
||||||
def copy_dir_to_container(self, local_path, dest_path):
|
|
||||||
for file_name in os.listdir(local_path):
|
|
||||||
self.copy_file_to_container(os.path.join(local_path, file_name), os.path.join(dest_path, file_name))
|
|
||||||
|
|
||||||
def clear_dir_in_container(self, path):
|
|
||||||
return self.exec_in_container(['bash', '-c', f'rm -rf {os.path.join(path, "*")}'])
|
|
||||||
|
|
||||||
def read_file(node, path):
|
|
||||||
return node.exec_in_container(['bash', '-c', f'cat {path}'])
|
|
||||||
|
|
||||||
def get_process_pid(self, process_name):
|
def get_process_pid(self, process_name):
|
||||||
output = self.exec_in_container(["bash", "-c",
|
output = self.exec_in_container(["bash", "-c",
|
||||||
"ps ax | grep '{}' | grep -v 'grep' | grep -v 'coproc' | grep -v 'bash -c' | awk '{{print $1}}'".format(
|
"ps ax | grep '{}' | grep -v 'grep' | grep -v 'coproc' | grep -v 'bash -c' | awk '{{print $1}}'".format(
|
||||||
|
@ -42,7 +42,7 @@ def test_create():
|
|||||||
assert instance.query(
|
assert instance.query(
|
||||||
"SHOW CREATE USER u2") == "CREATE USER u2 IDENTIFIED WITH sha256_password HOST LOCAL DEFAULT ROLE rx\n"
|
"SHOW CREATE USER u2") == "CREATE USER u2 IDENTIFIED WITH sha256_password HOST LOCAL DEFAULT ROLE rx\n"
|
||||||
assert instance.query(
|
assert instance.query(
|
||||||
"SHOW CREATE ROW POLICY p ON mydb.mytable") == "CREATE ROW POLICY p ON mydb.mytable FOR SELECT USING a < 1000 AS permissive TO u1, u2\n"
|
"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(
|
assert instance.query(
|
||||||
"SHOW CREATE QUOTA q") == "CREATE QUOTA q FOR INTERVAL 1 hour MAX queries = 100 TO ALL EXCEPT rx\n"
|
"SHOW CREATE QUOTA q") == "CREATE QUOTA q FOR INTERVAL 1 hour MAX queries = 100 TO ALL EXCEPT rx\n"
|
||||||
assert instance.query("SHOW GRANTS FOR u1") == ""
|
assert instance.query("SHOW GRANTS FOR u1") == ""
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
import pytest
|
|
||||||
from helpers.cluster import ClickHouseCluster
|
|
||||||
from helpers.test_tools import TSV
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
|
|
||||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
||||||
cluster = ClickHouseCluster(__file__)
|
|
||||||
node = cluster.add_instance('instance', stay_alive=True)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module", autouse=True)
|
|
||||||
def started_cluster():
|
|
||||||
try:
|
|
||||||
cluster.start()
|
|
||||||
yield cluster
|
|
||||||
|
|
||||||
finally:
|
|
||||||
cluster.shutdown()
|
|
||||||
|
|
||||||
|
|
||||||
def test_version_1():
|
|
||||||
node.stop_clickhouse()
|
|
||||||
node.clear_dir_in_container("/var/lib/clickhouse/access")
|
|
||||||
node.copy_dir_to_container(os.path.join(SCRIPT_DIR, "version_1"), "/var/lib/clickhouse/access")
|
|
||||||
node.start_clickhouse()
|
|
||||||
|
|
||||||
assert node.query("SELECT name, select_filter, kind FROM system.row_policies ORDER BY name") == TSV([['p0 ON mydb.mytable', 'a = 0', 'permissive'],
|
|
||||||
['p1 ON mydb.mytable', 'a = 1000', 'permissive'],
|
|
||||||
['p2 ON mydb.mytable', 'a = 2000', 'restrictive'],
|
|
||||||
['p3 ON mydb.mytable', 'a = 3000', 'simple']])
|
|
||||||
|
|
||||||
u0_id = node.query("SELECT id FROM system.users WHERE name='u0'").rstrip()
|
|
||||||
p0_id = node.query("SELECT id FROM system.row_policies WHERE name='p0 ON mydb.mytable'").rstrip()
|
|
||||||
|
|
||||||
assert node.read_file(os.path.join("/var/lib/clickhouse/access", p0_id + ".sql")) == \
|
|
||||||
f"ATTACH ROW POLICY p0 ON mydb.mytable FOR SELECT USING a = 0 TO ID('{u0_id}');\n"
|
|
||||||
|
|
||||||
node.query("ALTER ROW POLICY p0 ON mydb.mytable FOR SELECT USING a=1")
|
|
||||||
assert node.read_file(os.path.join("/var/lib/clickhouse/access", p0_id + ".sql")) == \
|
|
||||||
f"SET rbac_version = 2;\n"\
|
|
||||||
f"ATTACH ROW POLICY p0 ON mydb.mytable FOR SELECT USING a = 1 AS permissive TO ID('{u0_id}');\n"
|
|
||||||
|
|
||||||
node.query("CREATE ROW POLICY p4 ON mydb.mytable FOR SELECT USING a=4000")
|
|
||||||
p4_id = node.query("SELECT id FROM system.row_policies WHERE name='p4 ON mydb.mytable'").rstrip()
|
|
||||||
assert node.read_file(os.path.join("/var/lib/clickhouse/access", p4_id + ".sql")) == \
|
|
||||||
f"SET rbac_version = 2;\n"\
|
|
||||||
f"ATTACH ROW POLICY p4 ON mydb.mytable FOR SELECT USING a = 4000 AS permissive;\n"
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH USER u3;
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH ROW POLICY p0 ON mydb.mytable FOR SELECT USING a = 0 TO ID('a44bf717-218f-09e8-e1cd-f101f5b7cbbb');
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH USER u2;
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH USER u1;
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH ROW POLICY p1 ON mydb.mytable FOR SELECT USING a = 1000 AS permissive TO ID('964a717c-05cd-2ba0-d398-6624e778e99a');
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH ROW POLICY p3 ON mydb.mytable FOR SELECT USING a = 3000 AS simple TO ID('004ba500-8a3d-5746-7d4a-f37172faa69e');
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH USER u0;
|
|
@ -1 +0,0 @@
|
|||||||
ATTACH ROW POLICY p2 ON mydb.mytable FOR SELECT USING a = 2000 AS restrictive TO ID('48494a8a-aad1-4cd3-1f17-af53613e85be');
|
|
@ -256,21 +256,21 @@ def test_reload_users_xml_by_timer():
|
|||||||
def test_introspection():
|
def test_introspection():
|
||||||
policies = [
|
policies = [
|
||||||
["another ON mydb.filtered_table1", "another", "mydb", "filtered_table1",
|
["another ON mydb.filtered_table1", "another", "mydb", "filtered_table1",
|
||||||
"6068883a-0e9d-f802-7e22-0144f8e66d3c", "users.xml", "1", "permissive", 0, "['another']", "[]"],
|
"6068883a-0e9d-f802-7e22-0144f8e66d3c", "users.xml", "1", 0, 0, "['another']", "[]"],
|
||||||
["another ON mydb.filtered_table2", "another", "mydb", "filtered_table2",
|
["another ON mydb.filtered_table2", "another", "mydb", "filtered_table2",
|
||||||
"c019e957-c60b-d54e-cc52-7c90dac5fb01", "users.xml", "1", "permissive", 0, "['another']", "[]"],
|
"c019e957-c60b-d54e-cc52-7c90dac5fb01", "users.xml", "1", 0, 0, "['another']", "[]"],
|
||||||
["another ON mydb.filtered_table3", "another", "mydb", "filtered_table3",
|
["another ON mydb.filtered_table3", "another", "mydb", "filtered_table3",
|
||||||
"4cb080d0-44e8-dbef-6026-346655143628", "users.xml", "1", "permissive", 0, "['another']", "[]"],
|
"4cb080d0-44e8-dbef-6026-346655143628", "users.xml", "1", 0, 0, "['another']", "[]"],
|
||||||
["another ON mydb.local", "another", "mydb", "local", "5b23c389-7e18-06bf-a6bc-dd1afbbc0a97", "users.xml",
|
["another ON mydb.local", "another", "mydb", "local", "5b23c389-7e18-06bf-a6bc-dd1afbbc0a97", "users.xml",
|
||||||
"a = 1", "permissive", 0, "['another']", "[]"],
|
"a = 1", 0, 0, "['another']", "[]"],
|
||||||
["default ON mydb.filtered_table1", "default", "mydb", "filtered_table1",
|
["default ON mydb.filtered_table1", "default", "mydb", "filtered_table1",
|
||||||
"9e8a8f62-4965-2b5e-8599-57c7b99b3549", "users.xml", "a = 1", "permissive", 0, "['default']", "[]"],
|
"9e8a8f62-4965-2b5e-8599-57c7b99b3549", "users.xml", "a = 1", 0, 0, "['default']", "[]"],
|
||||||
["default ON mydb.filtered_table2", "default", "mydb", "filtered_table2",
|
["default ON mydb.filtered_table2", "default", "mydb", "filtered_table2",
|
||||||
"cffae79d-b9bf-a2ef-b798-019c18470b25", "users.xml", "a + b < 1 or c - d > 5", "permissive", 0, "['default']", "[]"],
|
"cffae79d-b9bf-a2ef-b798-019c18470b25", "users.xml", "a + b < 1 or c - d > 5", 0, 0, "['default']", "[]"],
|
||||||
["default ON mydb.filtered_table3", "default", "mydb", "filtered_table3",
|
["default ON mydb.filtered_table3", "default", "mydb", "filtered_table3",
|
||||||
"12fc5cef-e3da-3940-ec79-d8be3911f42b", "users.xml", "c = 1", "permissive", 0, "['default']", "[]"],
|
"12fc5cef-e3da-3940-ec79-d8be3911f42b", "users.xml", "c = 1", 0, 0, "['default']", "[]"],
|
||||||
["default ON mydb.local", "default", "mydb", "local", "cdacaeb5-1d97-f99d-2bb0-4574f290629c", "users.xml", "1",
|
["default ON mydb.local", "default", "mydb", "local", "cdacaeb5-1d97-f99d-2bb0-4574f290629c", "users.xml", "1",
|
||||||
"permissive", 0, "['default']", "[]"]
|
0, 0, "['default']", "[]"]
|
||||||
]
|
]
|
||||||
assert node.query("SELECT * from system.row_policies ORDER BY short_name, database, table") == TSV(policies)
|
assert node.query("SELECT * from system.row_policies ORDER BY short_name, database, table") == TSV(policies)
|
||||||
|
|
||||||
@ -292,49 +292,49 @@ def test_dcl_introspection():
|
|||||||
"default ON mydb.local"])
|
"default ON mydb.local"])
|
||||||
|
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table1") == "CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table1") == "CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table2") == "CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table2") == "CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table3") == "CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table3") == "CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.local") == "CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.local") == "CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 TO default\n"
|
||||||
|
|
||||||
assert node.query("SHOW CREATE POLICY default") == TSV(
|
assert node.query("SHOW CREATE POLICY default") == TSV(
|
||||||
["CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 AS permissive TO default",
|
["CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 AS permissive TO default"])
|
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 TO default"])
|
||||||
assert node.query("SHOW CREATE POLICIES ON mydb.filtered_table1") == TSV(
|
assert node.query("SHOW CREATE POLICIES ON mydb.filtered_table1") == TSV(
|
||||||
["CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 AS permissive TO another",
|
["CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 AS permissive TO default"])
|
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 TO default"])
|
||||||
assert node.query("SHOW CREATE POLICIES ON mydb.*") == TSV(
|
assert node.query("SHOW CREATE POLICIES ON mydb.*") == TSV(
|
||||||
["CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 AS permissive TO another",
|
["CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY another ON mydb.filtered_table2 FOR SELECT USING 1 AS permissive TO another",
|
"CREATE ROW POLICY another ON mydb.filtered_table2 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY another ON mydb.filtered_table3 FOR SELECT USING 1 AS permissive TO another",
|
"CREATE ROW POLICY another ON mydb.filtered_table3 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY another ON mydb.local FOR SELECT USING a = 1 AS permissive TO another",
|
"CREATE ROW POLICY another ON mydb.local FOR SELECT USING a = 1 TO another",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 AS permissive TO default"])
|
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 TO default"])
|
||||||
assert node.query("SHOW CREATE POLICIES") == TSV(
|
assert node.query("SHOW CREATE POLICIES") == TSV(
|
||||||
["CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 AS permissive TO another",
|
["CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY another ON mydb.filtered_table2 FOR SELECT USING 1 AS permissive TO another",
|
"CREATE ROW POLICY another ON mydb.filtered_table2 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY another ON mydb.filtered_table3 FOR SELECT USING 1 AS permissive TO another",
|
"CREATE ROW POLICY another ON mydb.filtered_table3 FOR SELECT USING 1 TO another",
|
||||||
"CREATE ROW POLICY another ON mydb.local FOR SELECT USING a = 1 AS permissive TO another",
|
"CREATE ROW POLICY another ON mydb.local FOR SELECT USING a = 1 TO another",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 AS permissive TO default"])
|
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 TO default"])
|
||||||
|
|
||||||
expected_access = "CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 AS permissive TO another\n" \
|
expected_access = "CREATE ROW POLICY another ON mydb.filtered_table1 FOR SELECT USING 1 TO another\n" \
|
||||||
"CREATE ROW POLICY another ON mydb.filtered_table2 FOR SELECT USING 1 AS permissive TO another\n" \
|
"CREATE ROW POLICY another ON mydb.filtered_table2 FOR SELECT USING 1 TO another\n" \
|
||||||
"CREATE ROW POLICY another ON mydb.filtered_table3 FOR SELECT USING 1 AS permissive TO another\n" \
|
"CREATE ROW POLICY another ON mydb.filtered_table3 FOR SELECT USING 1 TO another\n" \
|
||||||
"CREATE ROW POLICY another ON mydb.local FOR SELECT USING a = 1 AS permissive TO another\n" \
|
"CREATE ROW POLICY another ON mydb.local FOR SELECT USING a = 1 TO another\n" \
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 AS permissive TO default\n" \
|
"CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING a = 1 TO default\n" \
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) AS permissive TO default\n" \
|
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING ((a + b) < 1) OR ((c - d) > 5) TO default\n" \
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 AS permissive TO default\n" \
|
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 1 TO default\n" \
|
||||||
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 AS permissive TO default\n"
|
"CREATE ROW POLICY default ON mydb.local FOR SELECT USING 1 TO default\n"
|
||||||
assert expected_access in node.query("SHOW ACCESS")
|
assert expected_access in node.query("SHOW ACCESS")
|
||||||
|
|
||||||
copy_policy_xml('all_rows.xml')
|
copy_policy_xml('all_rows.xml')
|
||||||
@ -342,22 +342,22 @@ def test_dcl_introspection():
|
|||||||
["another ON mydb.filtered_table1", "another ON mydb.filtered_table2", "another ON mydb.filtered_table3",
|
["another ON mydb.filtered_table1", "another ON mydb.filtered_table2", "another ON mydb.filtered_table3",
|
||||||
"default ON mydb.filtered_table1", "default ON mydb.filtered_table2", "default ON mydb.filtered_table3"])
|
"default ON mydb.filtered_table1", "default ON mydb.filtered_table2", "default ON mydb.filtered_table3"])
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table1") == "CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING 1 AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table1") == "CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING 1 TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table2") == "CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING 1 AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table2") == "CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING 1 TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table3") == "CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING 1 AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table3") == "CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING 1 TO default\n"
|
||||||
|
|
||||||
copy_policy_xml('no_rows.xml')
|
copy_policy_xml('no_rows.xml')
|
||||||
assert node.query("SHOW POLICIES") == TSV(
|
assert node.query("SHOW POLICIES") == TSV(
|
||||||
["another ON mydb.filtered_table1", "another ON mydb.filtered_table2", "another ON mydb.filtered_table3",
|
["another ON mydb.filtered_table1", "another ON mydb.filtered_table2", "another ON mydb.filtered_table3",
|
||||||
"default ON mydb.filtered_table1", "default ON mydb.filtered_table2", "default ON mydb.filtered_table3"])
|
"default ON mydb.filtered_table1", "default ON mydb.filtered_table2", "default ON mydb.filtered_table3"])
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table1") == "CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING NULL AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table1") == "CREATE ROW POLICY default ON mydb.filtered_table1 FOR SELECT USING NULL TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table2") == "CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING NULL AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table2") == "CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING NULL TO default\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY default ON mydb.filtered_table3") == "CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING NULL AS permissive TO default\n"
|
"SHOW CREATE POLICY default ON mydb.filtered_table3") == "CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING NULL TO default\n"
|
||||||
|
|
||||||
copy_policy_xml('no_filters.xml')
|
copy_policy_xml('no_filters.xml')
|
||||||
assert node.query("SHOW POLICIES") == ""
|
assert node.query("SHOW POLICIES") == ""
|
||||||
@ -382,7 +382,7 @@ def test_dcl_management():
|
|||||||
assert node.query("SELECT * FROM mydb.filtered_table1") == TSV([[1, 0]])
|
assert node.query("SELECT * FROM mydb.filtered_table1") == TSV([[1, 0]])
|
||||||
assert node.query("SHOW POLICIES ON mydb.filtered_table1") == "pB\n"
|
assert node.query("SHOW POLICIES ON mydb.filtered_table1") == "pB\n"
|
||||||
assert node.query(
|
assert node.query(
|
||||||
"SHOW CREATE POLICY pB ON mydb.filtered_table1") == "CREATE ROW POLICY pB ON mydb.filtered_table1 FOR SELECT USING a > b AS permissive TO default\n"
|
"SHOW CREATE POLICY pB ON mydb.filtered_table1") == "CREATE ROW POLICY pB ON mydb.filtered_table1 FOR SELECT USING a > b TO default\n"
|
||||||
|
|
||||||
node.query("DROP POLICY pB ON mydb.filtered_table1")
|
node.query("DROP POLICY pB ON mydb.filtered_table1")
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1") == TSV([[0, 0], [0, 1], [1, 0], [1, 1]])
|
assert node.query("SELECT * FROM mydb.filtered_table1") == TSV([[0, 0], [0, 1], [1, 0], [1, 1]])
|
||||||
@ -439,34 +439,6 @@ def test_users_xml_is_readonly():
|
|||||||
assert re.search("storage is readonly", node.query_and_get_error("DROP POLICY default ON mydb.filtered_table1"))
|
assert re.search("storage is readonly", node.query_and_get_error("DROP POLICY default ON mydb.filtered_table1"))
|
||||||
|
|
||||||
|
|
||||||
def test_some_users_without_policies():
|
|
||||||
copy_policy_xml('no_filters.xml')
|
|
||||||
assert node.query("SHOW POLICIES") == ""
|
|
||||||
node.query("CREATE USER X, Y")
|
|
||||||
node.query("GRANT SELECT ON mydb.filtered_table1 TO X, Y")
|
|
||||||
|
|
||||||
node.query("CREATE POLICY pA ON mydb.filtered_table1 FOR SELECT USING a < b AS permissive TO X")
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == TSV([[0, 1]])
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == ""
|
|
||||||
|
|
||||||
node.query("ALTER POLICY pA ON mydb.filtered_table1 AS restrictive")
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == ""
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == ""
|
|
||||||
node.query("CREATE POLICY pB ON mydb.filtered_table1 FOR SELECT USING 1 AS permissive TO X")
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == TSV([[0, 1]])
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == ""
|
|
||||||
node.query("ALTER POLICY pB ON mydb.filtered_table1 TO X, Y")
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == TSV([[0, 1]])
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == TSV([[0, 0], [0, 1], [1, 0], [1, 1]])
|
|
||||||
node.query("DROP POLICY pB ON mydb.filtered_table1")
|
|
||||||
|
|
||||||
node.query("ALTER POLICY pA ON mydb.filtered_table1 AS simple")
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == TSV([[0, 1]])
|
|
||||||
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == TSV([[0, 0], [0, 1], [1, 0], [1, 1]])
|
|
||||||
|
|
||||||
node.query("DROP USER X, Y")
|
|
||||||
|
|
||||||
|
|
||||||
def test_tags_with_db_and_table_names():
|
def test_tags_with_db_and_table_names():
|
||||||
copy_policy_xml('tags_with_db_and_table_names.xml')
|
copy_policy_xml('tags_with_db_and_table_names.xml')
|
||||||
|
|
||||||
@ -476,10 +448,10 @@ def test_tags_with_db_and_table_names():
|
|||||||
assert node.query("SELECT * FROM mydb.`.filtered_table4`") == TSV([[1, 1]])
|
assert node.query("SELECT * FROM mydb.`.filtered_table4`") == TSV([[1, 1]])
|
||||||
|
|
||||||
assert node.query("SHOW CREATE POLICIES default") == TSV(
|
assert node.query("SHOW CREATE POLICIES default") == TSV(
|
||||||
["CREATE ROW POLICY default ON mydb.`.filtered_table4` FOR SELECT USING c = 2 AS permissive TO default",
|
["CREATE ROW POLICY default ON mydb.`.filtered_table4` FOR SELECT USING c = 2 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING c > (d + 5) AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table2 FOR SELECT USING c > (d + 5) TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 0 AS permissive TO default",
|
"CREATE ROW POLICY default ON mydb.filtered_table3 FOR SELECT USING c = 0 TO default",
|
||||||
"CREATE ROW POLICY default ON mydb.table FOR SELECT USING a = 0 AS permissive TO default"])
|
"CREATE ROW POLICY default ON mydb.table FOR SELECT USING a = 0 TO default"])
|
||||||
|
|
||||||
|
|
||||||
def test_miscellaneous_engines():
|
def test_miscellaneous_engines():
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
-- default
|
-- default
|
||||||
CREATE ROW POLICY p1_01295 ON db.table AS permissive
|
CREATE ROW POLICY p1_01295 ON db.table
|
||||||
-- same as default
|
-- same as default
|
||||||
CREATE ROW POLICY p2_01295 ON db.table AS permissive
|
CREATE ROW POLICY p2_01295 ON db.table
|
||||||
CREATE ROW POLICY p3_01295 ON db.table AS permissive
|
CREATE ROW POLICY p3_01295 ON db.table
|
||||||
-- rename
|
-- rename
|
||||||
CREATE ROW POLICY p2_01295_renamed ON db.table AS permissive
|
CREATE ROW POLICY p2_01295_renamed ON db.table
|
||||||
-- filter
|
-- filter
|
||||||
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING (a < b) AND (c > d) AS permissive
|
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING (a < b) AND (c > d)
|
||||||
CREATE ROW POLICY p2_01295 ON db.table FOR SELECT USING id = currentUser() AS restrictive
|
CREATE ROW POLICY p2_01295 ON db.table AS restrictive FOR SELECT USING id = currentUser()
|
||||||
CREATE ROW POLICY p3_01295 ON db.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p3_01295 ON db.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING 0 AS restrictive
|
CREATE ROW POLICY p1_01295 ON db.table AS restrictive FOR SELECT USING 0
|
||||||
-- to roles
|
-- to roles
|
||||||
CREATE ROW POLICY p1_01295 ON db.table AS permissive
|
CREATE ROW POLICY p1_01295 ON db.table
|
||||||
CREATE ROW POLICY p2_01295 ON db.table AS permissive TO ALL
|
CREATE ROW POLICY p2_01295 ON db.table TO ALL
|
||||||
CREATE ROW POLICY p3_01295 ON db.table AS permissive TO r1_01295
|
CREATE ROW POLICY p3_01295 ON db.table TO r1_01295
|
||||||
CREATE ROW POLICY p4_01295 ON db.table AS permissive TO u1_01295
|
CREATE ROW POLICY p4_01295 ON db.table TO u1_01295
|
||||||
CREATE ROW POLICY p5_01295 ON db.table AS permissive TO r1_01295, u1_01295
|
CREATE ROW POLICY p5_01295 ON db.table TO r1_01295, u1_01295
|
||||||
CREATE ROW POLICY p6_01295 ON db.table AS permissive TO ALL EXCEPT r1_01295
|
CREATE ROW POLICY p6_01295 ON db.table TO ALL EXCEPT r1_01295
|
||||||
CREATE ROW POLICY p7_01295 ON db.table AS permissive TO ALL EXCEPT r1_01295, u1_01295
|
CREATE ROW POLICY p7_01295 ON db.table TO ALL EXCEPT r1_01295, u1_01295
|
||||||
CREATE ROW POLICY p1_01295 ON db.table AS permissive TO u1_01295
|
CREATE ROW POLICY p1_01295 ON db.table TO u1_01295
|
||||||
CREATE ROW POLICY p2_01295 ON db.table AS permissive
|
CREATE ROW POLICY p2_01295 ON db.table
|
||||||
-- multiple policies in one command
|
-- multiple policies in one command
|
||||||
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p2_01295 ON db.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p2_01295 ON db.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p3_01295 ON db.table AS permissive TO u1_01295
|
CREATE ROW POLICY p3_01295 ON db.table TO u1_01295
|
||||||
CREATE ROW POLICY p3_01295 ON db2.table2 AS permissive TO u1_01295
|
CREATE ROW POLICY p3_01295 ON db2.table2 TO u1_01295
|
||||||
CREATE ROW POLICY p4_01295 ON db.table FOR SELECT USING a = b AS permissive
|
CREATE ROW POLICY p4_01295 ON db.table FOR SELECT USING a = b
|
||||||
CREATE ROW POLICY p5_01295 ON db2.table2 FOR SELECT USING a = b AS permissive
|
CREATE ROW POLICY p5_01295 ON db2.table2 FOR SELECT USING a = b
|
||||||
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING 1 AS permissive TO ALL
|
CREATE ROW POLICY p1_01295 ON db.table FOR SELECT USING 1 TO ALL
|
||||||
CREATE ROW POLICY p2_01295 ON db.table FOR SELECT USING 1 AS permissive TO ALL
|
CREATE ROW POLICY p2_01295 ON db.table FOR SELECT USING 1 TO ALL
|
||||||
-- system.row_policies
|
-- system.row_policies
|
||||||
p1_01295 ON db.table p1_01295 db table local directory (a < b) AND (c > d) permissive 0 [] []
|
p1_01295 ON db.table p1_01295 db table local directory (a < b) AND (c > d) 0 0 [] []
|
||||||
p2_01295 ON db.table p2_01295 db table local directory id = currentUser() restrictive 0 ['u1_01295'] []
|
p2_01295 ON db.table p2_01295 db table local directory id = currentUser() 1 0 ['u1_01295'] []
|
||||||
p3_01295 ON db.table p3_01295 db table local directory 1 permissive 1 [] ['r1_01295']
|
p3_01295 ON db.table p3_01295 db table local directory 1 0 1 [] ['r1_01295']
|
||||||
|
@ -72,7 +72,7 @@ SELECT '-- system.row_policies';
|
|||||||
CREATE ROW POLICY p1_01295 ON db.table USING a<b AND c>d;
|
CREATE ROW POLICY p1_01295 ON db.table USING a<b AND c>d;
|
||||||
CREATE ROW POLICY p2_01295 ON db.table USING id=currentUser() AS RESTRICTIVE TO u1_01295;
|
CREATE ROW POLICY p2_01295 ON db.table USING id=currentUser() AS RESTRICTIVE TO u1_01295;
|
||||||
CREATE ROW POLICY p3_01295 ON db.table USING 1 AS PERMISSIVE TO ALL EXCEPT r1_01295;
|
CREATE ROW POLICY p3_01295 ON db.table USING 1 AS PERMISSIVE TO ALL EXCEPT r1_01295;
|
||||||
SELECT name, short_name, database, table, storage, select_filter, kind, apply_to_all, apply_to_list, apply_to_except from system.row_policies WHERE short_name LIKE 'p%\_01295' ORDER BY name;
|
SELECT name, short_name, database, table, storage, select_filter, is_restrictive, apply_to_all, apply_to_list, apply_to_except from system.row_policies WHERE short_name LIKE 'p%\_01295' ORDER BY name;
|
||||||
DROP ROW POLICY p1_01295, p2_01295, p3_01295 ON db.table;
|
DROP ROW POLICY p1_01295, p2_01295, p3_01295 ON db.table;
|
||||||
|
|
||||||
DROP ROLE r1_01295;
|
DROP ROLE r1_01295;
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
-- one policy
|
-- one policy
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table AS permissive
|
CREATE ROW POLICY p1_01296 ON db_01296.table
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table AS permissive
|
CREATE ROW POLICY p1_01296 ON db_01296.table
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1
|
||||||
-- multiple policies
|
-- multiple policies
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p2_01296 ON db_01296.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p2_01296 ON db_01296.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p3_01296 ON db_01296.table AS permissive TO u1_01296
|
CREATE ROW POLICY p3_01296 ON db_01296.table TO u1_01296
|
||||||
CREATE ROW POLICY p3_01296 ON db_01296.table2 AS permissive TO u1_01296
|
CREATE ROW POLICY p3_01296 ON db_01296.table2 TO u1_01296
|
||||||
CREATE ROW POLICY p4_01296 ON db_01296.table FOR SELECT USING a = b AS permissive
|
CREATE ROW POLICY p4_01296 ON db_01296.table FOR SELECT USING a = b
|
||||||
CREATE ROW POLICY p5_01296 ON db_01296.table2 FOR SELECT USING a = b AS permissive
|
CREATE ROW POLICY p5_01296 ON db_01296.table2 FOR SELECT USING a = b
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p2_01296 ON db_01296.table FOR SELECT USING 1 AS permissive
|
CREATE ROW POLICY p2_01296 ON db_01296.table FOR SELECT USING 1
|
||||||
CREATE ROW POLICY p3_01296 ON db_01296.table AS permissive TO u1_01296
|
CREATE ROW POLICY p3_01296 ON db_01296.table TO u1_01296
|
||||||
CREATE ROW POLICY p3_01296 ON db_01296.table2 AS permissive TO u1_01296
|
CREATE ROW POLICY p3_01296 ON db_01296.table2 TO u1_01296
|
||||||
CREATE ROW POLICY p4_01296 ON db_01296.table FOR SELECT USING a = b AS permissive
|
CREATE ROW POLICY p4_01296 ON db_01296.table FOR SELECT USING a = b
|
||||||
CREATE ROW POLICY p5_01296 ON db_01296.table2 FOR SELECT USING a = b AS permissive
|
CREATE ROW POLICY p5_01296 ON db_01296.table2 FOR SELECT USING a = b
|
||||||
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1 AS permissive TO ALL
|
CREATE ROW POLICY p1_01296 ON db_01296.table FOR SELECT USING 1 TO ALL
|
||||||
CREATE ROW POLICY p2_01296 ON db_01296.table FOR SELECT USING 1 AS permissive TO ALL
|
CREATE ROW POLICY p2_01296 ON db_01296.table FOR SELECT USING 1 TO ALL
|
||||||
|
@ -49,7 +49,7 @@ CREATE TABLE system.replicated_merge_tree_settings\n(\n `name` String,\n `
|
|||||||
CREATE TABLE system.replication_queue\n(\n `database` String,\n `table` String,\n `replica_name` String,\n `position` UInt32,\n `node_name` String,\n `type` String,\n `create_time` DateTime,\n `required_quorum` UInt32,\n `source_replica` String,\n `new_part_name` String,\n `parts_to_merge` Array(String),\n `is_detach` UInt8,\n `is_currently_executing` UInt8,\n `num_tries` UInt32,\n `last_exception` String,\n `last_attempt_time` DateTime,\n `num_postponed` UInt32,\n `postpone_reason` String,\n `last_postpone_time` DateTime,\n `merge_type` String\n)\nENGINE = SystemReplicationQueue()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.replication_queue\n(\n `database` String,\n `table` String,\n `replica_name` String,\n `position` UInt32,\n `node_name` String,\n `type` String,\n `create_time` DateTime,\n `required_quorum` UInt32,\n `source_replica` String,\n `new_part_name` String,\n `parts_to_merge` Array(String),\n `is_detach` UInt8,\n `is_currently_executing` UInt8,\n `num_tries` UInt32,\n `last_exception` String,\n `last_attempt_time` DateTime,\n `num_postponed` UInt32,\n `postpone_reason` String,\n `last_postpone_time` DateTime,\n `merge_type` String\n)\nENGINE = SystemReplicationQueue()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
CREATE TABLE system.role_grants\n(\n `user_name` Nullable(String),\n `role_name` Nullable(String),\n `granted_role_name` String,\n `granted_role_is_default` UInt8,\n `with_admin_option` UInt8\n)\nENGINE = SystemRoleGrants()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.role_grants\n(\n `user_name` Nullable(String),\n `role_name` Nullable(String),\n `granted_role_name` String,\n `granted_role_is_default` UInt8,\n `with_admin_option` UInt8\n)\nENGINE = SystemRoleGrants()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
CREATE TABLE system.roles\n(\n `name` String,\n `id` UUID,\n `storage` String\n)\nENGINE = SystemRoles()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.roles\n(\n `name` String,\n `id` UUID,\n `storage` String\n)\nENGINE = SystemRoles()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
CREATE TABLE system.row_policies\n(\n `name` String,\n `short_name` String,\n `database` String,\n `table` String,\n `id` UUID,\n `storage` String,\n `select_filter` Nullable(String),\n `kind` Enum8(\'permissive\' = 0, \'restrictive\' = 1, \'simple\' = 2),\n `apply_to_all` UInt8,\n `apply_to_list` Array(String),\n `apply_to_except` Array(String)\n)\nENGINE = SystemRowPolicies()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.row_policies\n(\n `name` String,\n `short_name` String,\n `database` String,\n `table` String,\n `id` UUID,\n `storage` String,\n `select_filter` Nullable(String),\n `is_restrictive` UInt8,\n `apply_to_all` UInt8,\n `apply_to_list` Array(String),\n `apply_to_except` Array(String)\n)\nENGINE = SystemRowPolicies()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
CREATE TABLE system.settings\n(\n `name` String,\n `value` String,\n `changed` UInt8,\n `description` String,\n `min` Nullable(String),\n `max` Nullable(String),\n `readonly` UInt8,\n `type` String\n)\nENGINE = SystemSettings()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.settings\n(\n `name` String,\n `value` String,\n `changed` UInt8,\n `description` String,\n `min` Nullable(String),\n `max` Nullable(String),\n `readonly` UInt8,\n `type` String\n)\nENGINE = SystemSettings()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
CREATE TABLE system.settings_profile_elements\n(\n `profile_name` Nullable(String),\n `user_name` Nullable(String),\n `role_name` Nullable(String),\n `index` UInt64,\n `setting_name` Nullable(String),\n `value` Nullable(String),\n `min` Nullable(String),\n `max` Nullable(String),\n `readonly` Nullable(UInt8),\n `inherit_profile` Nullable(String)\n)\nENGINE = SystemSettingsProfileElements()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.settings_profile_elements\n(\n `profile_name` Nullable(String),\n `user_name` Nullable(String),\n `role_name` Nullable(String),\n `index` UInt64,\n `setting_name` Nullable(String),\n `value` Nullable(String),\n `min` Nullable(String),\n `max` Nullable(String),\n `readonly` Nullable(UInt8),\n `inherit_profile` Nullable(String)\n)\nENGINE = SystemSettingsProfileElements()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
CREATE TABLE system.settings_profiles\n(\n `name` String,\n `id` UUID,\n `storage` String,\n `num_elements` UInt64,\n `apply_to_all` UInt8,\n `apply_to_list` Array(String),\n `apply_to_except` Array(String)\n)\nENGINE = SystemSettingsProfiles()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
CREATE TABLE system.settings_profiles\n(\n `name` String,\n `id` UUID,\n `storage` String,\n `num_elements` UInt64,\n `apply_to_all` UInt8,\n `apply_to_list` Array(String),\n `apply_to_except` Array(String)\n)\nENGINE = SystemSettingsProfiles()\nCOMMENT \'SYSTEM TABLE is built on the fly.\'
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
None
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
4
|
|
||||||
R1: x == 1
|
|
||||||
1
|
|
||||||
R1, R2: (x == 1) OR (x == 2)
|
|
||||||
1
|
|
||||||
2
|
|
||||||
R1, R2, R3: (x == 1) OR (x == 2) OR (x == 3)
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
R1, R2, R3, R4: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2)
|
|
||||||
1
|
|
||||||
2
|
|
||||||
R1, R2, R3, R4, R5: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)
|
|
||||||
2
|
|
||||||
R2, R3, R4, R5: ((x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)
|
|
||||||
2
|
|
||||||
R3, R4, R5: (x == 3) AND (x <= 2) AND (x >= 2)
|
|
||||||
R4, R5: FALSE(no permissive filters) AND (x <= 2) AND (x >= 2)
|
|
||||||
R5: (x >= 2)
|
|
||||||
2
|
|
||||||
3
|
|
||||||
4
|
|
||||||
None
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
4
|
|
@ -1,54 +0,0 @@
|
|||||||
DROP TABLE IF EXISTS 02131_multiple_row_policies_on_same_column;
|
|
||||||
CREATE TABLE 02131_multiple_row_policies_on_same_column (x UInt8) ENGINE = MergeTree ORDER BY x;
|
|
||||||
INSERT INTO 02131_multiple_row_policies_on_same_column VALUES (1), (2), (3), (4);
|
|
||||||
|
|
||||||
DROP ROW POLICY IF EXISTS 02131_filter_1 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
DROP ROW POLICY IF EXISTS 02131_filter_2 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
DROP ROW POLICY IF EXISTS 02131_filter_3 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
DROP ROW POLICY IF EXISTS 02131_filter_4 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
DROP ROW POLICY IF EXISTS 02131_filter_5 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
SELECT 'None';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
CREATE ROW POLICY 02131_filter_1 ON 02131_multiple_row_policies_on_same_column USING x=1 AS permissive TO ALL;
|
|
||||||
SELECT 'R1: x == 1';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
CREATE ROW POLICY 02131_filter_2 ON 02131_multiple_row_policies_on_same_column USING x=2 AS permissive TO ALL;
|
|
||||||
SELECT 'R1, R2: (x == 1) OR (x == 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
CREATE ROW POLICY 02131_filter_3 ON 02131_multiple_row_policies_on_same_column USING x=3 AS permissive TO ALL;
|
|
||||||
SELECT 'R1, R2, R3: (x == 1) OR (x == 2) OR (x == 3)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
CREATE ROW POLICY 02131_filter_4 ON 02131_multiple_row_policies_on_same_column USING x<=2 AS restrictive TO ALL;
|
|
||||||
SELECT 'R1, R2, R3, R4: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
CREATE ROW POLICY 02131_filter_5 ON 02131_multiple_row_policies_on_same_column USING x>=2 AS simple TO ALL;
|
|
||||||
SELECT 'R1, R2, R3, R4, R5: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
DROP ROW POLICY 02131_filter_1 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
SELECT 'R2, R3, R4, R5: ((x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
DROP ROW POLICY 02131_filter_2 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
SELECT 'R3, R4, R5: (x == 3) AND (x <= 2) AND (x >= 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
DROP ROW POLICY 02131_filter_3 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
SELECT 'R4, R5: FALSE(no permissive filters) AND (x <= 2) AND (x >= 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
DROP ROW POLICY 02131_filter_4 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
SELECT 'R5: (x >= 2)';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
DROP ROW POLICY 02131_filter_5 ON 02131_multiple_row_policies_on_same_column;
|
|
||||||
SELECT 'None';
|
|
||||||
SELECT * FROM 02131_multiple_row_policies_on_same_column;
|
|
||||||
|
|
||||||
DROP TABLE 02131_multiple_row_policies_on_same_column;
|
|
@ -0,0 +1,8 @@
|
|||||||
|
4
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
3
|
||||||
|
3
|
||||||
|
4
|
@ -0,0 +1,32 @@
|
|||||||
|
SET optimize_move_to_prewhere = 1;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS 02131_multiply_row_policies_on_same_column;
|
||||||
|
CREATE TABLE 02131_multiply_row_policies_on_same_column (x UInt8) ENGINE = MergeTree ORDER BY x;
|
||||||
|
INSERT INTO 02131_multiply_row_policies_on_same_column VALUES (1), (2), (3), (4);
|
||||||
|
|
||||||
|
|
||||||
|
DROP ROW POLICY IF EXISTS 02131_filter_1 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
DROP ROW POLICY IF EXISTS 02131_filter_2 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
DROP ROW POLICY IF EXISTS 02131_filter_3 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE ROW POLICY 02131_filter_1 ON 02131_multiply_row_policies_on_same_column USING x=1 TO ALL;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
CREATE ROW POLICY 02131_filter_2 ON 02131_multiply_row_policies_on_same_column USING x=2 TO ALL;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
CREATE ROW POLICY 02131_filter_3 ON 02131_multiply_row_policies_on_same_column USING x=3 TO ALL;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE ROW POLICY 02131_filter_4 ON 02131_multiply_row_policies_on_same_column USING x<4 AS RESTRICTIVE TO ALL;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
|
||||||
|
DROP ROW POLICY 02131_filter_1 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
DROP ROW POLICY 02131_filter_2 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
DROP ROW POLICY 02131_filter_3 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
DROP ROW POLICY 02131_filter_4 ON 02131_multiply_row_policies_on_same_column;
|
||||||
|
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
|
||||||
|
DROP TABLE 02131_multiply_row_policies_on_same_column;
|
@ -1,18 +0,0 @@
|
|||||||
rbac_version=1
|
|
||||||
CREATE ROW POLICY `02240_r1` ON db1.table1 AS permissive
|
|
||||||
CREATE ROW POLICY `02240_r2` ON db1.table1 AS permissive
|
|
||||||
CREATE ROW POLICY `02240_r3` ON db1.table1 AS restrictive
|
|
||||||
CREATE ROW POLICY `02240_r4` ON db1.table1 AS simple
|
|
||||||
02240_r1 permissive
|
|
||||||
02240_r2 permissive
|
|
||||||
02240_r3 restrictive
|
|
||||||
02240_r4 simple
|
|
||||||
rbac_version=2
|
|
||||||
CREATE ROW POLICY `02240_r1` ON db1.table1
|
|
||||||
CREATE ROW POLICY `02240_r2` ON db1.table1 AS permissive
|
|
||||||
CREATE ROW POLICY `02240_r3` ON db1.table1 AS restrictive
|
|
||||||
CREATE ROW POLICY `02240_r4` ON db1.table1
|
|
||||||
02240_r1 simple
|
|
||||||
02240_r2 permissive
|
|
||||||
02240_r3 restrictive
|
|
||||||
02240_r4 simple
|
|
@ -1,22 +0,0 @@
|
|||||||
DROP ROW POLICY IF EXISTS 02240_r1, 02240_r2, 02240_r3, 02240_r4 ON db1.table1;
|
|
||||||
|
|
||||||
SELECT concat('rbac_version=', toString(getSetting('rbac_version')));
|
|
||||||
CREATE ROW POLICY 02240_r1 ON db1.table1;
|
|
||||||
CREATE ROW POLICY 02240_r2 ON db1.table1 AS permissive;
|
|
||||||
CREATE ROW POLICY 02240_r3 ON db1.table1 AS restrictive;
|
|
||||||
CREATE ROW POLICY 02240_r4 ON db1.table1 AS simple;
|
|
||||||
SHOW CREATE ROW POLICY 02240_r1, 02240_r2, 02240_r3, 02240_r4 ON db1.table1;
|
|
||||||
SELECT short_name, kind FROM system.row_policies WHERE short_name LIKE '02240%' ORDER BY short_name;
|
|
||||||
DROP ROW POLICY 02240_r1, 02240_r2, 02240_r3, 02240_r4 ON db1.table1;
|
|
||||||
|
|
||||||
SET rbac_version=2;
|
|
||||||
SELECT concat('rbac_version=', toString(getSetting('rbac_version')));
|
|
||||||
CREATE ROW POLICY 02240_r1 ON db1.table1;
|
|
||||||
CREATE ROW POLICY 02240_r2 ON db1.table1 AS permissive;
|
|
||||||
CREATE ROW POLICY 02240_r3 ON db1.table1 AS restrictive;
|
|
||||||
CREATE ROW POLICY 02240_r4 ON db1.table1 AS simple;
|
|
||||||
SHOW CREATE ROW POLICY 02240_r1, 02240_r2, 02240_r3, 02240_r4 ON db1.table1;
|
|
||||||
SELECT short_name, kind FROM system.row_policies WHERE short_name LIKE '02240%' ORDER BY short_name;
|
|
||||||
DROP ROW POLICY 02240_r1, 02240_r2, 02240_r3, 02240_r4 ON db1.table1;
|
|
||||||
|
|
||||||
SET rbac_version=1;
|
|
Loading…
Reference in New Issue
Block a user