/Users/deen/code/yugabyte-db/src/yb/client/permissions.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_CLIENT_PERMISSIONS_H |
15 | | #define YB_CLIENT_PERMISSIONS_H |
16 | | |
17 | | #include <shared_mutex> |
18 | | |
19 | | #include <boost/optional.hpp> |
20 | | |
21 | | #include "yb/common/entity_ids_types.h" |
22 | | #include "yb/common/roles_permissions.h" |
23 | | |
24 | | #include "yb/master/master_dcl.fwd.h" |
25 | | |
26 | | #include "yb/rpc/io_thread_pool.h" |
27 | | |
28 | | #include "yb/util/locks.h" |
29 | | #include "yb/util/monotime.h" |
30 | | |
31 | | #include "yb/yql/cql/ql/ptree/pt_option.h" |
32 | | |
33 | | namespace yb { |
34 | | |
35 | | namespace client { |
36 | | |
37 | | class YBClient; |
38 | | |
39 | | namespace internal { |
40 | | |
41 | | class RolePermissions { |
42 | | public: |
43 | | explicit RolePermissions(const master::RolePermissionInfoPB& role_permission_info_pb); |
44 | | |
45 | | bool HasCanonicalResourcePermission(const std::string &canonical_resource, |
46 | | PermissionType permission) const; |
47 | | |
48 | | bool HasAllKeyspacesPermission(PermissionType permission) const; |
49 | | |
50 | | bool HasAllRolesPermission(PermissionType permission) const; |
51 | | |
52 | 0 | const Permissions& all_keyspaces_permissions() const { |
53 | 0 | return all_keyspaces_permissions_; |
54 | 0 | } |
55 | | |
56 | 0 | const Permissions& all_roles_permissions() const { |
57 | 0 | return all_roles_permissions_; |
58 | 0 | } |
59 | | |
60 | 0 | const std::unordered_map<std::string, Permissions>& resource_permissions() const { |
61 | 0 | return resource_permissions_; |
62 | 0 | } |
63 | | |
64 | | private: |
65 | | |
66 | | // Permissions for resources "ALL KEYSPACES" ('data') and "ALL ROLES" ('roles'). |
67 | | // Special case to avoid hashing canonical resources 'data' and 'roles' and doing a hashmap |
68 | | // lookup. |
69 | | Permissions all_keyspaces_permissions_; |
70 | | Permissions all_roles_permissions_; |
71 | | // canonical resource -> permission bitmap. |
72 | | std::unordered_map<std::string, Permissions> resource_permissions_; |
73 | | }; |
74 | | |
75 | | struct RoleAuthInfo { |
76 | | std::string salted_hash; |
77 | | bool can_login; |
78 | | }; |
79 | | |
80 | | using RolesPermissionsMap = std::unordered_map<RoleName, RolePermissions>; |
81 | | using RolesAuthInfoMap = std::unordered_map<RoleName, RoleAuthInfo>; |
82 | | |
83 | | class PermissionsCache { |
84 | | public: |
85 | | explicit PermissionsCache(client::YBClient* client, |
86 | | bool automatically_update_cache = true); |
87 | | |
88 | | ~PermissionsCache(); |
89 | | |
90 | | void UpdateRolesPermissions(const master::GetPermissionsResponsePB& resp); |
91 | | |
92 | 0 | std::shared_ptr<RolesPermissionsMap> get_roles_permissions_map() { |
93 | 0 | std::unique_lock<simple_spinlock> l(permissions_cache_lock_); |
94 | 0 | return roles_permissions_map_; |
95 | 0 | } |
96 | | |
97 | 14.5k | bool ready() { |
98 | 14.5k | return ready_.load(std::memory_order_acquire); |
99 | 14.5k | } |
100 | | |
101 | | // Wait until the cache is ready (it has received at least one update from the master). Returns |
102 | | // false if the cache is not ready after waiting for the specified time. Returns true otherwise. |
103 | | bool WaitUntilReady(MonoDelta wait_for); |
104 | | |
105 | 118k | boost::optional<uint64_t> version() { |
106 | 118k | std::unique_lock<simple_spinlock> l(permissions_cache_lock_); |
107 | 118k | return version_; |
108 | 118k | } |
109 | | |
110 | | bool HasCanonicalResourcePermission(const std::string &canonical_resource, |
111 | | const ql::ObjectType &object_type, |
112 | | const RoleName &role_name, |
113 | | const PermissionType &permission); |
114 | | |
115 | | Result<std::string> salted_hash(const RoleName& role_name); |
116 | | Result<bool> can_login(const RoleName& role_name); |
117 | | |
118 | | private: |
119 | | void ScheduleGetPermissionsFromMaster(bool now); |
120 | | |
121 | | void GetPermissionsFromMaster(); |
122 | | |
123 | | // Passed to the master whenever we want to update our cache. The master will only send a new |
124 | | // cache if its version number is greater than this version number. |
125 | | boost::optional<uint64_t> version_; |
126 | | |
127 | | // Client used to send the request to the master. |
128 | | client::YBClient* const client_; |
129 | | |
130 | | // role name -> RolePermissions. |
131 | | std::shared_ptr<RolesPermissionsMap> roles_permissions_map_; |
132 | | std::shared_ptr<RolesAuthInfoMap> roles_auth_info_map_; |
133 | | |
134 | | // Used to modify the internal state. |
135 | | mutable simple_spinlock permissions_cache_lock_; |
136 | | |
137 | | // Used to wait until the cache is ready. |
138 | | std::mutex mtx_; |
139 | | std::condition_variable cond_; |
140 | | |
141 | | // Thread pool used by the scheduler. |
142 | | std::unique_ptr<yb::rpc::IoThreadPool> pool_; |
143 | | // The scheduler used to refresh the permissions. |
144 | | std::unique_ptr<yb::rpc::Scheduler> scheduler_; |
145 | | |
146 | | // Whether we have received the permissions from the master. |
147 | | std::atomic<bool> ready_{false}; |
148 | | }; |
149 | | |
150 | | } // namespace namespace internal |
151 | | } // namespace client |
152 | | } // namespace yb |
153 | | |
154 | | #endif // YB_CLIENT_PERMISSIONS_H |