aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Access/Common/AccessRightsElement.h
blob: ba625fc43df2a11a4ef14519be5b0753d068724f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#pragma once

#include <Access/Common/AccessFlags.h>
#include <tuple>


namespace DB
{
/// An element of access rights which can be represented by single line
/// GRANT ... ON ...
struct AccessRightsElement
{
    AccessFlags access_flags;

    String database;
    String table;
    Strings columns;
    String parameter;

    bool any_database = true;
    bool any_table = true;
    bool any_column = true;
    bool any_parameter = false;

    bool grant_option = false;
    bool is_partial_revoke = false;

    AccessRightsElement() = default;
    AccessRightsElement(const AccessRightsElement &) = default;
    AccessRightsElement & operator=(const AccessRightsElement &) = default;
    AccessRightsElement(AccessRightsElement &&) = default;
    AccessRightsElement & operator=(AccessRightsElement &&) = default;

    explicit AccessRightsElement(AccessFlags access_flags_) : access_flags(access_flags_) {}

    AccessRightsElement(AccessFlags access_flags_, std::string_view database_);
    AccessRightsElement(AccessFlags access_flags_, std::string_view database_, std::string_view table_);
    AccessRightsElement(
        AccessFlags access_flags_, std::string_view database_, std::string_view table_, std::string_view column_);

    AccessRightsElement(
        AccessFlags access_flags_,
        std::string_view database_,
        std::string_view table_,
        const std::vector<std::string_view> & columns_);

    AccessRightsElement(
        AccessFlags access_flags_, std::string_view database_, std::string_view table_, const Strings & columns_);

    bool empty() const { return !access_flags || (!any_column && columns.empty()); }

    auto toTuple() const { return std::tie(access_flags, any_database, database, any_table, table, any_column, columns, any_parameter, parameter, grant_option, is_partial_revoke); }
    friend bool operator==(const AccessRightsElement & left, const AccessRightsElement & right) { return left.toTuple() == right.toTuple(); }
    friend bool operator!=(const AccessRightsElement & left, const AccessRightsElement & right) { return !(left == right); }

    bool sameDatabaseAndTableAndParameter(const AccessRightsElement & other) const
    {
        return sameDatabaseAndTable(other) && sameParameter(other);
    }

    bool sameParameter(const AccessRightsElement & other) const
    {
        return (parameter == other.parameter) && (any_parameter == other.any_parameter)
            && (access_flags.getParameterType() == other.access_flags.getParameterType())
            && (isGlobalWithParameter() == other.isGlobalWithParameter());
    }

    bool sameDatabaseAndTable(const AccessRightsElement & other) const
    {
        return (database == other.database) && (any_database == other.any_database)
            && (table == other.table) && (any_table == other.any_table);
    }

    bool sameOptions(const AccessRightsElement & other) const
    {
        return (grant_option == other.grant_option) && (is_partial_revoke == other.is_partial_revoke);
    }

    /// Resets flags which cannot be granted.
    void eraseNonGrantable();

    bool isEmptyDatabase() const { return !any_database && database.empty(); }

    /// If the database is empty, replaces it with `current_database`. Otherwise does nothing.
    void replaceEmptyDatabase(const String & current_database);

    bool isGlobalWithParameter() const { return access_flags.isGlobalWithParameter(); }

    /// Returns a human-readable representation like "GRANT SELECT, UPDATE(x, y) ON db.table".
    String toString() const;
    String toStringWithoutOptions() const;
};


/// Multiple elements of access rights.
class AccessRightsElements : public std::vector<AccessRightsElement>
{
public:
    using Base = std::vector<AccessRightsElement>;
    using Base::Base;

    bool empty() const;
    bool sameDatabaseAndTableAndParameter() const;
    bool sameDatabaseAndTable() const;
    bool sameOptions() const;

    /// Resets flags which cannot be granted.
    void eraseNonGrantable();

    /// If the database is empty, replaces it with `current_database`. Otherwise does nothing.
    void replaceEmptyDatabase(const String & current_database);

    /// Returns a human-readable representation like "GRANT SELECT, UPDATE(x, y) ON db.table".
    String toString() const;
    String toStringWithoutOptions() const;
};

}