YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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