1 | #include <Interpreters/InterpreterCreateRowPolicyQuery.h> |
2 | #include <Parsers/ASTCreateRowPolicyQuery.h> |
3 | #include <Parsers/ASTRoleList.h> |
4 | #include <Parsers/formatAST.h> |
5 | #include <Interpreters/Context.h> |
6 | #include <Access/AccessControlManager.h> |
7 | #include <boost/range/algorithm/sort.hpp> |
8 | |
9 | |
10 | namespace DB |
11 | { |
12 | BlockIO InterpreterCreateRowPolicyQuery::execute() |
13 | { |
14 | context.checkRowPolicyManagementIsAllowed(); |
15 | const auto & query = query_ptr->as<const ASTCreateRowPolicyQuery &>(); |
16 | auto & access_control = context.getAccessControlManager(); |
17 | |
18 | if (query.alter) |
19 | { |
20 | auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr |
21 | { |
22 | auto updated_policy = typeid_cast<std::shared_ptr<RowPolicy>>(entity->clone()); |
23 | updateRowPolicyFromQuery(*updated_policy, query); |
24 | return updated_policy; |
25 | }; |
26 | String full_name = query.name_parts.getFullName(context); |
27 | if (query.if_exists) |
28 | { |
29 | if (auto id = access_control.find<RowPolicy>(full_name)) |
30 | access_control.tryUpdate(*id, update_func); |
31 | } |
32 | else |
33 | access_control.update(access_control.getID<RowPolicy>(full_name), update_func); |
34 | } |
35 | else |
36 | { |
37 | auto new_policy = std::make_shared<RowPolicy>(); |
38 | updateRowPolicyFromQuery(*new_policy, query); |
39 | |
40 | if (query.if_not_exists) |
41 | access_control.tryInsert(new_policy); |
42 | else if (query.or_replace) |
43 | access_control.insertOrReplace(new_policy); |
44 | else |
45 | access_control.insert(new_policy); |
46 | } |
47 | |
48 | return {}; |
49 | } |
50 | |
51 | |
52 | void InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(RowPolicy & policy, const ASTCreateRowPolicyQuery & query) |
53 | { |
54 | if (query.alter) |
55 | { |
56 | if (!query.new_policy_name.empty()) |
57 | policy.setName(query.new_policy_name); |
58 | } |
59 | else |
60 | { |
61 | policy.setDatabase(query.name_parts.database.empty() ? context.getCurrentDatabase() : query.name_parts.database); |
62 | policy.setTableName(query.name_parts.table_name); |
63 | policy.setName(query.name_parts.policy_name); |
64 | } |
65 | |
66 | if (query.is_restrictive) |
67 | policy.setRestrictive(*query.is_restrictive); |
68 | |
69 | for (const auto & [index, condition] : query.conditions) |
70 | policy.conditions[index] = condition ? serializeAST(*condition) : String{}; |
71 | |
72 | if (query.roles) |
73 | { |
74 | const auto & query_roles = *query.roles; |
75 | |
76 | /// We keep `roles` sorted. |
77 | policy.roles = query_roles.roles; |
78 | if (query_roles.current_user) |
79 | policy.roles.push_back(context.getClientInfo().current_user); |
80 | boost::range::sort(policy.roles); |
81 | policy.roles.erase(std::unique(policy.roles.begin(), policy.roles.end()), policy.roles.end()); |
82 | |
83 | policy.all_roles = query_roles.all_roles; |
84 | |
85 | /// We keep `except_roles` sorted. |
86 | policy.except_roles = query_roles.except_roles; |
87 | if (query_roles.except_current_user) |
88 | policy.except_roles.push_back(context.getClientInfo().current_user); |
89 | boost::range::sort(policy.except_roles); |
90 | policy.except_roles.erase(std::unique(policy.except_roles.begin(), policy.except_roles.end()), policy.except_roles.end()); |
91 | } |
92 | } |
93 | } |
94 | |