• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <grpc/support/port_platform.h>
16 
17 #include "src/core/lib/security/authorization/rbac_policy.h"
18 
19 #include "absl/strings/str_format.h"
20 #include "absl/strings/str_join.h"
21 
22 namespace grpc_core {
23 
24 //
25 // Rbac
26 //
27 
Rbac(Rbac::Action action,std::map<std::string,Policy> policies)28 Rbac::Rbac(Rbac::Action action, std::map<std::string, Policy> policies)
29     : action(action), policies(std::move(policies)) {}
30 
Rbac(Rbac && other)31 Rbac::Rbac(Rbac&& other) noexcept
32     : action(other.action), policies(std::move(other.policies)) {}
33 
operator =(Rbac && other)34 Rbac& Rbac::operator=(Rbac&& other) noexcept {
35   action = other.action;
36   policies = std::move(other.policies);
37   return *this;
38 }
39 
ToString() const40 std::string Rbac::ToString() const {
41   std::vector<std::string> contents;
42   contents.push_back(absl::StrFormat(
43       "Rbac action=%s{", action == Rbac::Action::kAllow ? "Allow" : "Deny"));
44   for (const auto& p : policies) {
45     contents.push_back(absl::StrFormat("{\n  policy_name=%s\n%s\n}", p.first,
46                                        p.second.ToString()));
47   }
48   contents.push_back("}");
49   return absl::StrJoin(contents, "\n");
50 }
51 
52 //
53 // CidrRange
54 //
55 
CidrRange(std::string address_prefix,uint32_t prefix_len)56 Rbac::CidrRange::CidrRange(std::string address_prefix, uint32_t prefix_len)
57     : address_prefix(std::move(address_prefix)), prefix_len(prefix_len) {}
58 
CidrRange(Rbac::CidrRange && other)59 Rbac::CidrRange::CidrRange(Rbac::CidrRange&& other) noexcept
60     : address_prefix(std::move(other.address_prefix)),
61       prefix_len(other.prefix_len) {}
62 
operator =(Rbac::CidrRange && other)63 Rbac::CidrRange& Rbac::CidrRange::operator=(Rbac::CidrRange&& other) noexcept {
64   address_prefix = std::move(other.address_prefix);
65   prefix_len = other.prefix_len;
66   return *this;
67 }
68 
ToString() const69 std::string Rbac::CidrRange::ToString() const {
70   return absl::StrFormat("CidrRange{address_prefix=%s,prefix_len=%d}",
71                          address_prefix, prefix_len);
72 }
73 
74 //
75 // Permission
76 //
77 
Permission(Permission::RuleType type,std::vector<std::unique_ptr<Permission>> permissions,bool not_rule)78 Rbac::Permission::Permission(
79     Permission::RuleType type,
80     std::vector<std::unique_ptr<Permission>> permissions, bool not_rule)
81     : type(type), permissions(std::move(permissions)), not_rule(not_rule) {}
Permission(Permission::RuleType type,bool not_rule)82 Rbac::Permission::Permission(Permission::RuleType type, bool not_rule)
83     : type(type), not_rule(not_rule) {}
Permission(Permission::RuleType type,HeaderMatcher header_matcher,bool not_rule)84 Rbac::Permission::Permission(Permission::RuleType type,
85                              HeaderMatcher header_matcher, bool not_rule)
86     : type(type),
87       header_matcher(std::move(header_matcher)),
88       not_rule(not_rule) {}
Permission(Permission::RuleType type,StringMatcher string_matcher,bool not_rule)89 Rbac::Permission::Permission(Permission::RuleType type,
90                              StringMatcher string_matcher, bool not_rule)
91     : type(type),
92       string_matcher(std::move(string_matcher)),
93       not_rule(not_rule) {}
Permission(Permission::RuleType type,CidrRange ip,bool not_rule)94 Rbac::Permission::Permission(Permission::RuleType type, CidrRange ip,
95                              bool not_rule)
96     : type(type), ip(std::move(ip)), not_rule(not_rule) {}
Permission(Permission::RuleType type,int port,bool not_rule)97 Rbac::Permission::Permission(Permission::RuleType type, int port, bool not_rule)
98     : type(type), port(port), not_rule(not_rule) {}
99 
Permission(Rbac::Permission && other)100 Rbac::Permission::Permission(Rbac::Permission&& other) noexcept
101     : type(other.type), not_rule(other.not_rule) {
102   switch (type) {
103     case RuleType::kAnd:
104     case RuleType::kOr:
105       permissions = std::move(other.permissions);
106       break;
107     case RuleType::kAny:
108       break;
109     case RuleType::kHeader:
110       header_matcher = std::move(other.header_matcher);
111       break;
112     case RuleType::kPath:
113     case RuleType::kReqServerName:
114       string_matcher = std::move(other.string_matcher);
115       break;
116     case RuleType::kDestIp:
117       ip = std::move(other.ip);
118       break;
119     default:
120       port = other.port;
121   }
122 }
123 
operator =(Rbac::Permission && other)124 Rbac::Permission& Rbac::Permission::operator=(
125     Rbac::Permission&& other) noexcept {
126   type = other.type;
127   not_rule = other.not_rule;
128   switch (type) {
129     case RuleType::kAnd:
130     case RuleType::kOr:
131       permissions = std::move(other.permissions);
132       break;
133     case RuleType::kAny:
134       break;
135     case RuleType::kHeader:
136       header_matcher = std::move(other.header_matcher);
137       break;
138     case RuleType::kPath:
139     case RuleType::kReqServerName:
140       string_matcher = std::move(other.string_matcher);
141       break;
142     case RuleType::kDestIp:
143       ip = std::move(other.ip);
144       break;
145     default:
146       port = other.port;
147   }
148   return *this;
149 }
150 
ToString() const151 std::string Rbac::Permission::ToString() const {
152   switch (type) {
153     case RuleType::kAnd: {
154       std::vector<std::string> contents;
155       contents.reserve(permissions.size());
156       for (const auto& permission : permissions) {
157         contents.push_back(permission->ToString());
158       }
159       return absl::StrFormat("%sand=[%s]", not_rule ? "not " : "",
160                              absl::StrJoin(contents, ","));
161     }
162     case RuleType::kOr: {
163       std::vector<std::string> contents;
164       contents.reserve(permissions.size());
165       for (const auto& permission : permissions) {
166         contents.push_back(permission->ToString());
167       }
168       return absl::StrFormat("%sor=[%s]", not_rule ? "not " : "",
169                              absl::StrJoin(contents, ","));
170     }
171     case RuleType::kAny:
172       return absl::StrFormat("%sany", not_rule ? "not " : "");
173     case RuleType::kHeader:
174       return absl::StrFormat("%sheader=%s", not_rule ? "not " : "",
175                              header_matcher.ToString());
176     case RuleType::kPath:
177       return absl::StrFormat("%spath=%s", not_rule ? "not " : "",
178                              string_matcher.ToString());
179     case RuleType::kDestIp:
180       return absl::StrFormat("%sdest_ip=%s", not_rule ? "not " : "",
181                              ip.ToString());
182     case RuleType::kDestPort:
183       return absl::StrFormat("%sdest_port=%d", not_rule ? "not " : "", port);
184     case RuleType::kReqServerName:
185       return absl::StrFormat("%srequested_server_name=%s",
186                              not_rule ? "not " : "", string_matcher.ToString());
187     default:
188       return "";
189   }
190 }
191 
192 //
193 // Principal
194 //
195 
Principal(Principal::RuleType type,std::vector<std::unique_ptr<Principal>> principals,bool not_rule)196 Rbac::Principal::Principal(Principal::RuleType type,
197                            std::vector<std::unique_ptr<Principal>> principals,
198                            bool not_rule)
199     : type(type), principals(std::move(principals)), not_rule(not_rule) {}
Principal(Principal::RuleType type,bool not_rule)200 Rbac::Principal::Principal(Principal::RuleType type, bool not_rule)
201     : type(type), not_rule(not_rule) {}
Principal(Principal::RuleType type,StringMatcher string_matcher,bool not_rule)202 Rbac::Principal::Principal(Principal::RuleType type,
203                            StringMatcher string_matcher, bool not_rule)
204     : type(type),
205       string_matcher(std::move(string_matcher)),
206       not_rule(not_rule) {}
Principal(Principal::RuleType type,CidrRange ip,bool not_rule)207 Rbac::Principal::Principal(Principal::RuleType type, CidrRange ip,
208                            bool not_rule)
209     : type(type), ip(std::move(ip)), not_rule(not_rule) {}
Principal(Principal::RuleType type,HeaderMatcher header_matcher,bool not_rule)210 Rbac::Principal::Principal(Principal::RuleType type,
211                            HeaderMatcher header_matcher, bool not_rule)
212     : type(type),
213       header_matcher(std::move(header_matcher)),
214       not_rule(not_rule) {}
215 
Principal(Rbac::Principal && other)216 Rbac::Principal::Principal(Rbac::Principal&& other) noexcept
217     : type(other.type), not_rule(other.not_rule) {
218   switch (type) {
219     case RuleType::kAnd:
220     case RuleType::kOr:
221       principals = std::move(other.principals);
222       break;
223     case RuleType::kAny:
224       break;
225     case RuleType::kHeader:
226       header_matcher = std::move(other.header_matcher);
227       break;
228     case RuleType::kPrincipalName:
229     case RuleType::kPath:
230       string_matcher = std::move(other.string_matcher);
231       break;
232     default:
233       ip = std::move(other.ip);
234   }
235 }
236 
operator =(Rbac::Principal && other)237 Rbac::Principal& Rbac::Principal::operator=(Rbac::Principal&& other) noexcept {
238   type = other.type;
239   not_rule = other.not_rule;
240   switch (type) {
241     case RuleType::kAnd:
242     case RuleType::kOr:
243       principals = std::move(other.principals);
244       break;
245     case RuleType::kAny:
246       break;
247     case RuleType::kHeader:
248       header_matcher = std::move(other.header_matcher);
249       break;
250     case RuleType::kPrincipalName:
251     case RuleType::kPath:
252       string_matcher = std::move(other.string_matcher);
253       break;
254     default:
255       ip = std::move(other.ip);
256   }
257   return *this;
258 }
259 
ToString() const260 std::string Rbac::Principal::ToString() const {
261   switch (type) {
262     case RuleType::kAnd: {
263       std::vector<std::string> contents;
264       contents.reserve(principals.size());
265       for (const auto& principal : principals) {
266         contents.push_back(principal->ToString());
267       }
268       return absl::StrFormat("%sand=[%s]", not_rule ? "not " : "",
269                              absl::StrJoin(contents, ","));
270     }
271     case RuleType::kOr: {
272       std::vector<std::string> contents;
273       contents.reserve(principals.size());
274       for (const auto& principal : principals) {
275         contents.push_back(principal->ToString());
276       }
277       return absl::StrFormat("%sor=[%s]", not_rule ? "not " : "",
278                              absl::StrJoin(contents, ","));
279     }
280     case RuleType::kAny:
281       return absl::StrFormat("%sany", not_rule ? "not " : "");
282     case RuleType::kPrincipalName:
283       return absl::StrFormat("%sprincipal_name=%s", not_rule ? "not " : "",
284                              string_matcher.ToString());
285     case RuleType::kSourceIp:
286       return absl::StrFormat("%ssource_ip=%s", not_rule ? "not " : "",
287                              ip.ToString());
288     case RuleType::kDirectRemoteIp:
289       return absl::StrFormat("%sdirect_remote_ip=%s", not_rule ? "not " : "",
290                              ip.ToString());
291     case RuleType::kRemoteIp:
292       return absl::StrFormat("%sremote_ip=%s", not_rule ? "not " : "",
293                              ip.ToString());
294     case RuleType::kHeader:
295       return absl::StrFormat("%sheader=%s", not_rule ? "not " : "",
296                              header_matcher.ToString());
297     case RuleType::kPath:
298       return absl::StrFormat("%spath=%s", not_rule ? "not " : "",
299                              string_matcher.ToString());
300     default:
301       return "";
302   }
303 }
304 
305 //
306 // Policy
307 //
308 
Policy(Permission permissions,Principal principals)309 Rbac::Policy::Policy(Permission permissions, Principal principals)
310     : permissions(std::move(permissions)), principals(std::move(principals)) {}
311 
Policy(Rbac::Policy && other)312 Rbac::Policy::Policy(Rbac::Policy&& other) noexcept
313     : permissions(std::move(other.permissions)),
314       principals(std::move(other.principals)) {}
315 
operator =(Rbac::Policy && other)316 Rbac::Policy& Rbac::Policy::operator=(Rbac::Policy&& other) noexcept {
317   permissions = std::move(other.permissions);
318   principals = std::move(other.principals);
319   return *this;
320 }
321 
ToString() const322 std::string Rbac::Policy::ToString() const {
323   return absl::StrFormat(
324       "  Policy  {\n    Permissions{%s}\n    Principals{%s}\n  }",
325       permissions.ToString(), principals.ToString());
326 }
327 
328 }  // namespace grpc_core
329