| 51 | { |
| 52 | template <typename T> |
| 53 | void parseGrant(T & entity, const String & string_query, const std::unordered_set<UUID> & role_ids_from_users_config, const AccessControl & access_control, LoggerPtr log) |
| 54 | { |
| 55 | ParserGrantQuery parser; |
| 56 | parser.setParseWithoutGrantees(); |
| 57 | |
| 58 | String error_message; |
| 59 | const char * pos = string_query.data(); |
| 60 | auto ast = tryParseQuery(parser, pos, pos + string_query.size(), error_message, false, "", false, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS, true); |
| 61 | |
| 62 | if (!ast) |
| 63 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Failed to parse grant query. Error: {}", error_message); |
| 64 | |
| 65 | auto & query = ast->as<ASTGrantQuery &>(); |
| 66 | |
| 67 | if (query.roles && query.is_revoke) |
| 68 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Roles can't be revoked in config file"); |
| 69 | |
| 70 | if (!query.cluster.empty()) |
| 71 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Can't grant on cluster using config file"); |
| 72 | |
| 73 | if (query.grantees) |
| 74 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "You can't specify grantees in query using config file"); |
| 75 | |
| 76 | for (auto & element : query.access_rights_elements) |
| 77 | { |
| 78 | if (query.is_revoke) |
| 79 | entity.access.revoke(element); |
| 80 | else |
| 81 | entity.access.grant(element); |
| 82 | } |
| 83 | |
| 84 | if (query.roles) |
| 85 | { |
| 86 | std::vector<UUID> roles_to_grant; |
| 87 | roles_to_grant.reserve(query.roles->size()); |
| 88 | |
| 89 | for (const auto & role_name : query.roles->names) |
| 90 | { |
| 91 | auto role_id = UsersConfigParser::generateID(AccessEntityType::ROLE, role_name); |
| 92 | if (!role_ids_from_users_config.contains(role_id)) |
| 93 | { |
| 94 | if (const auto role = access_control.find<Role>(role_name)) |
| 95 | role_id = *role; |
| 96 | else |
| 97 | LOG_WARNING(log, "Role {} is not defined and will be ignored for grant query '{}'.", role_name, string_query); |
| 98 | } |
| 99 | |
| 100 | roles_to_grant.push_back(role_id); |
| 101 | } |
| 102 | |
| 103 | if (query.admin_option) |
| 104 | entity.granted_roles.grantWithAdminOption(roles_to_grant); |
| 105 | else |
| 106 | entity.granted_roles.grant(roles_to_grant); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | /// Throws if any user-level/flat authentication fields (password, ldap, etc.) coexist |