InterpreterCreateUserQuery.cpp 5.6 KB
Newer Older
1 2
#include <Interpreters/InterpreterCreateUserQuery.h>
#include <Interpreters/Context.h>
3
#include <Interpreters/InterpreterSetRoleQuery.h>
A
Alexander Tokmakov 已提交
4
#include <Interpreters/executeDDLQueryOnCluster.h>
5
#include <Parsers/ASTCreateUserQuery.h>
6
#include <Parsers/ASTUserNameWithHost.h>
7
#include <Parsers/ASTRolesOrUsersSet.h>
8 9
#include <Access/AccessControlManager.h>
#include <Access/User.h>
10
#include <Access/ContextAccess.h>
11
#include <boost/range/algorithm/copy.hpp>
12 13 14 15


namespace DB
{
16
namespace
17
{
18 19 20
    void updateUserFromQueryImpl(
        User & user,
        const ASTCreateUserQuery & query,
21
        const std::shared_ptr<ASTUserNameWithHost> & override_name,
22
        const std::optional<RolesOrUsersSet> & override_default_roles,
23 24
        const std::optional<SettingsProfileElements> & override_settings,
        const std::optional<RolesOrUsersSet> & override_grantees)
25
    {
26 27 28 29 30 31
        if (override_name)
            user.setName(override_name->toString());
        else if (!query.new_name.empty())
            user.setName(query.new_name);
        else if (query.names->size() == 1)
            user.setName(query.names->front()->toString());
32 33 34 35

        if (query.authentication)
            user.authentication = *query.authentication;

36 37 38 39 40 41
        if (override_name && !override_name->host_pattern.empty())
        {
            user.allowed_client_hosts = AllowedClientHosts{};
            user.allowed_client_hosts.addLikePattern(override_name->host_pattern);
        }
        else if (query.hosts)
42
            user.allowed_client_hosts = *query.hosts;
43

44 45 46 47 48
        if (query.remove_hosts)
            user.allowed_client_hosts.remove(*query.remove_hosts);
        if (query.add_hosts)
            user.allowed_client_hosts.add(*query.add_hosts);

49
        auto set_default_roles = [&](const RolesOrUsersSet & default_roles_)
50
        {
51 52
            if (!query.alter && !default_roles_.all)
                user.granted_roles.grant(default_roles_.getMatchingIDs());
53

54 55
            InterpreterSetRoleQuery::updateUserSetDefaultRoles(user, default_roles_);
        };
56

57 58 59 60
        if (override_default_roles)
            set_default_roles(*override_default_roles);
        else if (query.default_roles)
            set_default_roles(*query.default_roles);
61

62 63 64 65
        if (override_settings)
            user.settings = *override_settings;
        else if (query.settings)
            user.settings = *query.settings;
66 67 68 69 70

        if (override_grantees)
            user.grantees = *override_grantees;
        else if (query.grantees)
            user.grantees = *query.grantees;
71
    }
72 73 74
}


75 76
BlockIO InterpreterCreateUserQuery::execute()
{
A
Alexey Milovidov 已提交
77
    const auto & query = query_ptr->as<const ASTCreateUserQuery &>();
78
    auto & access_control = context.getAccessControlManager();
79 80
    auto access = context.getAccess();
    access->checkAccess(query.alter ? AccessType::ALTER_USER : AccessType::CREATE_USER);
81

82
    std::optional<RolesOrUsersSet> default_roles_from_query;
83 84
    if (query.default_roles)
    {
85
        default_roles_from_query = RolesOrUsersSet{*query.default_roles, access_control};
86 87 88
        if (!query.alter && !default_roles_from_query->all)
        {
            for (const UUID & role : default_roles_from_query->getMatchingIDs())
89
                access->checkAdminOption(role);
90 91 92
        }
    }

93 94 95
    if (!query.cluster.empty())
        return executeDDLQueryOnCluster(query_ptr, context);

96 97 98 99
    std::optional<SettingsProfileElements> settings_from_query;
    if (query.settings)
        settings_from_query = SettingsProfileElements{*query.settings, access_control};

100 101
    if (query.alter)
    {
102 103 104 105
        std::optional<RolesOrUsersSet> grantees_from_query;
        if (query.grantees)
            grantees_from_query = RolesOrUsersSet{*query.grantees, access_control};

106 107 108
        auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr
        {
            auto updated_user = typeid_cast<std::shared_ptr<User>>(entity->clone());
109
            updateUserFromQueryImpl(*updated_user, query, {}, default_roles_from_query, settings_from_query, grantees_from_query);
110 111
            return updated_user;
        };
112

113
        Strings names = query.names->toStrings();
114 115
        if (query.if_exists)
        {
116 117
            auto ids = access_control.find<User>(names);
            access_control.tryUpdate(ids, update_func);
118 119
        }
        else
120
            access_control.update(access_control.getIDs<User>(names), update_func);
121 122 123
    }
    else
    {
124 125 126 127
        std::vector<AccessEntityPtr> new_users;
        for (const auto & name : *query.names)
        {
            auto new_user = std::make_shared<User>();
128
            updateUserFromQueryImpl(*new_user, query, name, default_roles_from_query, settings_from_query, RolesOrUsersSet::AllTag{});
129 130
            new_users.emplace_back(std::move(new_user));
        }
131

132
        std::vector<UUID> ids;
133
        if (query.if_not_exists)
134
            ids = access_control.tryInsert(new_users);
135
        else if (query.or_replace)
136
            ids = access_control.insertOrReplace(new_users);
137
        else
138 139 140 141 142 143 144 145 146 147 148 149
            ids = access_control.insert(new_users);

        if (query.grantees)
        {
            RolesOrUsersSet grantees_from_query = RolesOrUsersSet{*query.grantees, access_control};
            access_control.update(ids, [&](const AccessEntityPtr & entity) -> AccessEntityPtr
            {
                auto updated_user = typeid_cast<std::shared_ptr<User>>(entity->clone());
                updated_user->grantees = grantees_from_query;
                return updated_user;
            });
        }
150 151 152 153 154 155
    }

    return {};
}


156
void InterpreterCreateUserQuery::updateUserFromQuery(User & user, const ASTCreateUserQuery & query)
157
{
158
    updateUserFromQueryImpl(user, query, {}, {}, {}, {});
159
}
160

161
}