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 "src/core/lib/security/authorization/rbac_translator.h"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 namespace grpc_core {
21
22 namespace {
23
24 MATCHER_P2(EqualsPrincipalName, expected_matcher_type, expected_matcher_value,
25 "") {
26 return arg->type == Rbac::Principal::RuleType::kPrincipalName &&
27 arg->string_matcher.type() == expected_matcher_type &&
28 arg->string_matcher.string_matcher() == expected_matcher_value;
29 }
30
31 MATCHER_P2(EqualsPath, expected_matcher_type, expected_matcher_value, "") {
32 return arg->type == Rbac::Permission::RuleType::kPath &&
33 arg->string_matcher.type() == expected_matcher_type &&
34 arg->string_matcher.string_matcher() == expected_matcher_value;
35 }
36
37 MATCHER_P3(EqualsHeader, expected_name, expected_matcher_type,
38 expected_matcher_value, "") {
39 return arg->type == Rbac::Permission::RuleType::kHeader &&
40 arg->header_matcher.name() == expected_name &&
41 arg->header_matcher.type() == expected_matcher_type &&
42 arg->header_matcher.string_matcher() == expected_matcher_value;
43 }
44
45 } // namespace
46
TEST(GenerateRbacPoliciesTest,InvalidPolicy)47 TEST(GenerateRbacPoliciesTest, InvalidPolicy) {
48 const char* authz_policy =
49 "{"
50 " \"name\": \"authz-policy\",,"
51 "}";
52 auto rbac_policies = GenerateRbacPolicies(authz_policy);
53 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
54 EXPECT_THAT(
55 std::string(rbac_policies.status().message()),
56 ::testing::StartsWith("Failed to parse SDK authorization policy."));
57 }
58
TEST(GenerateRbacPoliciesTest,MissingAuthorizationPolicyName)59 TEST(GenerateRbacPoliciesTest, MissingAuthorizationPolicyName) {
60 const char* authz_policy = "{}";
61 auto rbac_policies = GenerateRbacPolicies(authz_policy);
62 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
63 EXPECT_EQ(rbac_policies.status().message(), "\"name\" field is not present.");
64 }
65
TEST(GenerateRbacPoliciesTest,IncorrectAuthorizationPolicyNameType)66 TEST(GenerateRbacPoliciesTest, IncorrectAuthorizationPolicyNameType) {
67 const char* authz_policy =
68 "{"
69 " \"name\": [\"authz_policy\"]"
70 "}";
71 auto rbac_policies = GenerateRbacPolicies(authz_policy);
72 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
73 EXPECT_EQ(rbac_policies.status().message(), "\"name\" is not a string.");
74 }
75
TEST(GenerateRbacPoliciesTest,MissingAllowRules)76 TEST(GenerateRbacPoliciesTest, MissingAllowRules) {
77 const char* authz_policy =
78 "{"
79 " \"name\": \"authz_policy\""
80 "}";
81 auto rbac_policies = GenerateRbacPolicies(authz_policy);
82 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
83 EXPECT_EQ(rbac_policies.status().message(),
84 "\"allow_rules\" is not present.");
85 }
86
TEST(GenerateRbacPoliciesTest,MissingDenyRules)87 TEST(GenerateRbacPoliciesTest, MissingDenyRules) {
88 const char* authz_policy =
89 "{"
90 " \"name\": \"authz\","
91 " \"allow_rules\": ["
92 " {"
93 " \"name\": \"allow_policy\""
94 " }"
95 " ]"
96 "}";
97 auto rbac_policies = GenerateRbacPolicies(authz_policy);
98 ASSERT_TRUE(rbac_policies.ok());
99 EXPECT_EQ(rbac_policies.value().deny_policy.action, Rbac::Action::kDeny);
100 EXPECT_TRUE(rbac_policies.value().deny_policy.policies.empty());
101 }
102
TEST(GenerateRbacPoliciesTest,IncorrectAllowRulesType)103 TEST(GenerateRbacPoliciesTest, IncorrectAllowRulesType) {
104 const char* authz_policy =
105 "{"
106 " \"name\": \"authz\","
107 " \"allow_rules\": {}"
108 "}";
109 auto rbac_policies = GenerateRbacPolicies(authz_policy);
110 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
111 EXPECT_EQ(rbac_policies.status().message(),
112 "\"allow_rules\" is not an array.");
113 }
114
TEST(GenerateRbacPoliciesTest,IncorrectDenyRulesType)115 TEST(GenerateRbacPoliciesTest, IncorrectDenyRulesType) {
116 const char* authz_policy =
117 "{"
118 " \"name\": \"authz\","
119 " \"deny_rules\": 123"
120 "}";
121 auto rbac_policies = GenerateRbacPolicies(authz_policy);
122 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
123 EXPECT_EQ(rbac_policies.status().message(),
124 "\"deny_rules\" is not an array.");
125 }
126
TEST(GenerateRbacPoliciesTest,IncorrectRuleType)127 TEST(GenerateRbacPoliciesTest, IncorrectRuleType) {
128 const char* authz_policy =
129 "{"
130 " \"name\": \"authz\","
131 " \"allow_rules\": [\"rule-a\"]"
132 "}";
133 auto rbac_policies = GenerateRbacPolicies(authz_policy);
134 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
135 EXPECT_EQ(rbac_policies.status().message(),
136 "allow_rules 0: is not an object.");
137 }
138
TEST(GenerateRbacPoliciesTest,MissingRuleNameField)139 TEST(GenerateRbacPoliciesTest, MissingRuleNameField) {
140 const char* authz_policy =
141 "{"
142 " \"name\": \"authz\","
143 " \"allow_rules\": [{}]"
144 "}";
145 auto rbac_policies = GenerateRbacPolicies(authz_policy);
146 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
147 EXPECT_EQ(rbac_policies.status().message(),
148 "allow_rules 0: \"name\" is not present.");
149 }
150
TEST(GenerateRbacPoliciesTest,IncorrectRuleNameType)151 TEST(GenerateRbacPoliciesTest, IncorrectRuleNameType) {
152 const char* authz_policy =
153 "{"
154 " \"name\": \"authz\","
155 " \"allow_rules\": ["
156 " {"
157 " \"name\": 123"
158 " }"
159 " ]"
160 "}";
161 auto rbac_policies = GenerateRbacPolicies(authz_policy);
162 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
163 EXPECT_EQ(rbac_policies.status().message(),
164 "allow_rules 0: \"name\" is not a string.");
165 }
166
TEST(GenerateRbacPoliciesTest,MissingSourceAndRequest)167 TEST(GenerateRbacPoliciesTest, MissingSourceAndRequest) {
168 const char* authz_policy =
169 "{"
170 " \"name\": \"authz\","
171 " \"allow_rules\": ["
172 " {"
173 " \"name\": \"allow_policy\""
174 " }"
175 " ]"
176 "}";
177 auto rbac_policies = GenerateRbacPolicies(authz_policy);
178 ASSERT_TRUE(rbac_policies.ok());
179 EXPECT_EQ(rbac_policies.value().allow_policy.action, Rbac::Action::kAllow);
180 EXPECT_THAT(
181 rbac_policies.value().allow_policy.policies,
182 ::testing::ElementsAre(::testing::Pair(
183 "authz_allow_policy",
184 ::testing::AllOf(
185 ::testing::Field(
186 &Rbac::Policy::permissions,
187 ::testing::Field(&Rbac::Permission::type,
188 Rbac::Permission::RuleType::kAny)),
189 ::testing::Field(
190 &Rbac::Policy::principals,
191 ::testing::Field(&Rbac::Principal::type,
192 Rbac::Principal::RuleType::kAny))))));
193 }
194
TEST(GenerateRbacPoliciesTest,EmptySourceAndRequest)195 TEST(GenerateRbacPoliciesTest, EmptySourceAndRequest) {
196 const char* authz_policy =
197 "{"
198 " \"name\": \"authz\","
199 " \"allow_rules\": ["
200 " {"
201 " \"name\": \"allow_policy\","
202 " \"source\": {},"
203 " \"request\": {}"
204 " }"
205 " ]"
206 "}";
207 auto rbac_policies = GenerateRbacPolicies(authz_policy);
208 ASSERT_TRUE(rbac_policies.ok());
209 EXPECT_EQ(rbac_policies.value().allow_policy.action, Rbac::Action::kAllow);
210 EXPECT_THAT(
211 rbac_policies.value().allow_policy.policies,
212 ::testing::ElementsAre(::testing::Pair(
213 "authz_allow_policy",
214 ::testing::AllOf(
215 ::testing::Field(
216 &Rbac::Policy::permissions,
217 ::testing::Field(&Rbac::Permission::type,
218 Rbac::Permission::RuleType::kAny)),
219 ::testing::Field(
220 &Rbac::Policy::principals,
221 ::testing::Field(&Rbac::Principal::type,
222 Rbac::Principal::RuleType::kAny))))));
223 }
224
TEST(GenerateRbacPoliciesTest,IncorrectSourceType)225 TEST(GenerateRbacPoliciesTest, IncorrectSourceType) {
226 const char* authz_policy =
227 "{"
228 " \"name\": \"authz\","
229 " \"allow_rules\": ["
230 " {"
231 " \"name\": \"allow_policy\","
232 " \"source\": 111"
233 " }"
234 " ]"
235 "}";
236 auto rbac_policies = GenerateRbacPolicies(authz_policy);
237 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
238 EXPECT_EQ(rbac_policies.status().message(),
239 "allow_rules 0: \"source\" is not an object.");
240 }
241
TEST(GenerateRbacPoliciesTest,IncorrectPrincipalsType)242 TEST(GenerateRbacPoliciesTest, IncorrectPrincipalsType) {
243 const char* authz_policy =
244 "{"
245 " \"name\": \"authz\","
246 " \"allow_rules\": ["
247 " {"
248 " \"name\": \"allow_policy\","
249 " \"source\": {"
250 " \"principals\": ["
251 " \"*\","
252 " 123"
253 " ]"
254 " }"
255 " }"
256 " ]"
257 "}";
258 auto rbac_policies = GenerateRbacPolicies(authz_policy);
259 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
260 EXPECT_EQ(rbac_policies.status().message(),
261 "allow_rules 0: \"principals\" 1: is not a string.");
262 }
263
TEST(GenerateRbacPoliciesTest,ParseSourceSuccess)264 TEST(GenerateRbacPoliciesTest, ParseSourceSuccess) {
265 const char* authz_policy =
266 "{"
267 " \"name\": \"authz\","
268 " \"allow_rules\": ["
269 " {"
270 " \"name\": \"allow_policy\","
271 " \"source\": {"
272 " \"principals\": ["
273 " \"spiffe://foo.abc\","
274 " \"spiffe://bar*\","
275 " \"*baz\","
276 " \"spiffe://abc.*.com\""
277 " ]"
278 " }"
279 " }"
280 " ],"
281 " \"deny_rules\": ["
282 " {"
283 " \"name\": \"deny_policy\","
284 " \"source\": {"
285 " \"principals\": ["
286 " \"*\""
287 " ]"
288 " }"
289 " }"
290 " ]"
291 "}";
292 auto rbac_policies = GenerateRbacPolicies(authz_policy);
293 ASSERT_TRUE(rbac_policies.ok());
294 EXPECT_EQ(rbac_policies.value().allow_policy.action, Rbac::Action::kAllow);
295 EXPECT_THAT(
296 rbac_policies.value().allow_policy.policies,
297 ::testing::ElementsAre(::testing::Pair(
298 "authz_allow_policy",
299 ::testing::AllOf(
300 ::testing::Field(
301 &Rbac::Policy::permissions,
302 ::testing::Field(&Rbac::Permission::type,
303 Rbac::Permission::RuleType::kAny)),
304 ::testing::Field(
305 &Rbac::Policy::principals,
306 ::testing::AllOf(
307 ::testing::Field(&Rbac::Principal::type,
308 Rbac::Principal::RuleType::kAnd),
309 ::testing::Field(
310 &Rbac::Principal::principals,
311 ::testing::ElementsAre(::testing::AllOf(
312 ::testing::Pointee(::testing::Field(
313 &Rbac::Principal::type,
314 Rbac::Principal::RuleType::kOr)),
315 ::testing::Pointee(::testing::Field(
316 &Rbac::Principal::principals,
317 ::testing::ElementsAre(
318 EqualsPrincipalName(
319 StringMatcher::Type::kExact,
320 "spiffe://foo.abc"),
321 EqualsPrincipalName(
322 StringMatcher::Type::kPrefix,
323 "spiffe://bar"),
324 EqualsPrincipalName(
325 StringMatcher::Type::kSuffix, "baz"),
326 EqualsPrincipalName(
327 StringMatcher::Type::kExact,
328 "spiffe://abc.*.com")))))))))))));
329 EXPECT_EQ(rbac_policies.value().deny_policy.action, Rbac::Action::kDeny);
330 EXPECT_THAT(
331 rbac_policies.value().deny_policy.policies,
332 ::testing::ElementsAre(::testing::Pair(
333 "authz_deny_policy",
334 ::testing::AllOf(
335 ::testing::Field(
336 &Rbac::Policy::permissions,
337 ::testing::Field(&Rbac::Permission::type,
338 Rbac::Permission::RuleType::kAny)),
339 ::testing::Field(
340 &Rbac::Policy::principals,
341 ::testing::AllOf(
342 ::testing::Field(&Rbac::Principal::type,
343 Rbac::Principal::RuleType::kAnd),
344 ::testing::Field(
345 &Rbac::Principal::principals,
346 ::testing::ElementsAre(::testing::AllOf(
347 ::testing::Pointee(::testing::Field(
348 &Rbac::Principal::type,
349 Rbac::Principal::RuleType::kOr)),
350 ::testing::Pointee(::testing::Field(
351 &Rbac::Principal::principals,
352 ::testing::ElementsAre(EqualsPrincipalName(
353 StringMatcher::Type::kPrefix,
354 "")))))))))))));
355 }
356
TEST(GenerateRbacPoliciesTest,IncorrectRequestType)357 TEST(GenerateRbacPoliciesTest, IncorrectRequestType) {
358 const char* authz_policy =
359 "{"
360 " \"name\": \"authz\","
361 " \"deny_rules\": ["
362 " {"
363 " \"name\": \"deny_policy\","
364 " \"request\": 111"
365 " }"
366 " ]"
367 "}";
368 auto rbac_policies = GenerateRbacPolicies(authz_policy);
369 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
370 EXPECT_EQ(rbac_policies.status().message(),
371 "deny_rules 0: \"request\" is not an object.");
372 }
373
TEST(GenerateRbacPoliciesTest,IncorrectPathType)374 TEST(GenerateRbacPoliciesTest, IncorrectPathType) {
375 const char* authz_policy =
376 "{"
377 " \"name\": \"authz\","
378 " \"deny_rules\": ["
379 " {"
380 " \"name\": \"allow_policy\","
381 " \"request\": {"
382 " \"paths\": ["
383 " \"path-a\","
384 " 123"
385 " ]"
386 " }"
387 " }"
388 " ]"
389 "}";
390 auto rbac_policies = GenerateRbacPolicies(authz_policy);
391 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
392 EXPECT_EQ(rbac_policies.status().message(),
393 "deny_rules 0: \"paths\" 1: is not a string.");
394 }
395
TEST(GenerateRbacPoliciesTest,ParseRequestPathsSuccess)396 TEST(GenerateRbacPoliciesTest, ParseRequestPathsSuccess) {
397 const char* authz_policy =
398 "{"
399 " \"name\": \"authz\","
400 " \"allow_rules\": ["
401 " {"
402 " \"name\": \"allow_policy\","
403 " \"request\": {"
404 " \"paths\": ["
405 " \"*\""
406 " ]"
407 " }"
408 " }"
409 " ],"
410 " \"deny_rules\": ["
411 " {"
412 " \"name\": \"deny_policy\","
413 " \"request\": {"
414 " \"paths\": ["
415 " \"path-foo\","
416 " \"path-bar*\","
417 " \"*baz\""
418 " ]"
419 " }"
420 " }"
421 " ]"
422 "}";
423 auto rbac_policies = GenerateRbacPolicies(authz_policy);
424 ASSERT_TRUE(rbac_policies.ok());
425 EXPECT_EQ(rbac_policies.value().deny_policy.action, Rbac::Action::kDeny);
426 EXPECT_THAT(
427 rbac_policies.value().deny_policy.policies,
428 ::testing::ElementsAre(::testing::Pair(
429 "authz_deny_policy",
430 ::testing::AllOf(
431 ::testing::Field(
432 &Rbac::Policy::principals,
433 ::testing::Field(&Rbac::Principal::type,
434 Rbac::Principal::RuleType::kAny)),
435 ::testing::Field(
436 &Rbac::Policy::permissions,
437 ::testing::AllOf(
438 ::testing::Field(&Rbac::Permission::type,
439 Rbac::Permission::RuleType::kAnd),
440 ::testing::Field(
441 &Rbac::Permission::permissions,
442 ::testing::ElementsAre(::testing::AllOf(
443 ::testing::Pointee(::testing::Field(
444 &Rbac::Permission::type,
445 Rbac::Permission::RuleType::kOr)),
446 ::testing::Pointee(::testing::Field(
447 &Rbac::Permission::permissions,
448 ::testing::ElementsAre(
449 EqualsPath(StringMatcher::Type::kExact,
450 "path-foo"),
451 EqualsPath(StringMatcher::Type::kPrefix,
452 "path-bar"),
453 EqualsPath(StringMatcher::Type::kSuffix,
454 "baz")))))))))))));
455 EXPECT_EQ(rbac_policies.value().allow_policy.action, Rbac::Action::kAllow);
456 EXPECT_THAT(
457 rbac_policies.value().allow_policy.policies,
458 ::testing::ElementsAre(::testing::Pair(
459 "authz_allow_policy",
460 ::testing::AllOf(
461 ::testing::Field(
462 &Rbac::Policy::principals,
463 ::testing::Field(&Rbac::Principal::type,
464 Rbac::Principal::RuleType::kAny)),
465 ::testing::Field(
466 &Rbac::Policy::permissions,
467 ::testing::AllOf(
468 ::testing::Field(&Rbac::Permission::type,
469 Rbac::Permission::RuleType::kAnd),
470 ::testing::Field(
471 &Rbac::Permission::permissions,
472 ::testing::ElementsAre(::testing::AllOf(
473 ::testing::Pointee(::testing::Field(
474 &Rbac::Permission::type,
475 Rbac::Permission::RuleType::kOr)),
476 ::testing::Pointee(::testing::Field(
477 &Rbac::Permission::permissions,
478 ::testing::ElementsAre(
479 EqualsPath(StringMatcher::Type::kPrefix,
480 "")))))))))))));
481 }
482
TEST(GenerateRbacPoliciesTest,IncorrectHeaderType)483 TEST(GenerateRbacPoliciesTest, IncorrectHeaderType) {
484 const char* authz_policy =
485 "{"
486 " \"name\": \"authz\","
487 " \"deny_rules\": ["
488 " {"
489 " \"name\": \"allow_policy\","
490 " \"request\": {"
491 " \"headers\": ["
492 " \"header-a\""
493 " ]"
494 " }"
495 " }"
496 " ]"
497 "}";
498 auto rbac_policies = GenerateRbacPolicies(authz_policy);
499 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
500 EXPECT_EQ(rbac_policies.status().message(),
501 "deny_rules 0: \"headers\" 0: is not an object.");
502 }
503
TEST(GenerateRbacPoliciesTest,UnsupportedGrpcHeaders)504 TEST(GenerateRbacPoliciesTest, UnsupportedGrpcHeaders) {
505 const char* authz_policy =
506 "{"
507 " \"name\": \"authz\","
508 " \"deny_rules\": ["
509 " {"
510 " \"name\": \"policy\","
511 " \"request\": {"
512 " \"headers\": ["
513 " {"
514 " \"key\": \"grpc-xxx\","
515 " \"values\": ["
516 " \"*\""
517 " ]"
518 " }"
519 " ]"
520 " }"
521 " }"
522 " ]"
523 "}";
524 auto rbac_policies = GenerateRbacPolicies(authz_policy);
525 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
526 EXPECT_EQ(rbac_policies.status().message(),
527 "deny_rules 0: \"headers\" 0: Unsupported \"key\" grpc-xxx.");
528 }
529
TEST(GenerateRbacPoliciesTest,UnsupportedPseudoHeaders)530 TEST(GenerateRbacPoliciesTest, UnsupportedPseudoHeaders) {
531 const char* authz_policy =
532 "{"
533 " \"name\": \"authz\","
534 " \"allow_rules\": ["
535 " {"
536 " \"name\": \"policy\","
537 " \"request\": {"
538 " \"headers\": ["
539 " {"
540 " \"key\": \":method\","
541 " \"values\": ["
542 " \"*\""
543 " ]"
544 " }"
545 " ]"
546 " }"
547 " }"
548 " ]"
549 "}";
550 auto rbac_policies = GenerateRbacPolicies(authz_policy);
551 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
552 EXPECT_EQ(rbac_policies.status().message(),
553 "allow_rules 0: \"headers\" 0: Unsupported \"key\" :method.");
554 }
555
TEST(GenerateRbacPoliciesTest,UnsupportedhostHeader)556 TEST(GenerateRbacPoliciesTest, UnsupportedhostHeader) {
557 const char* authz_policy =
558 "{"
559 " \"name\": \"authz\","
560 " \"deny_rules\": ["
561 " {"
562 " \"name\": \"policy\","
563 " \"request\": {"
564 " \"headers\": ["
565 " {"
566 " \"key\": \"host\","
567 " \"values\": ["
568 " \"*\""
569 " ]"
570 " }"
571 " ]"
572 " }"
573 " }"
574 " ]"
575 "}";
576 auto rbac_policies = GenerateRbacPolicies(authz_policy);
577 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
578 EXPECT_EQ(rbac_policies.status().message(),
579 "deny_rules 0: \"headers\" 0: Unsupported \"key\" host.");
580 }
581
TEST(GenerateRbacPoliciesTest,UnsupportedHostHeader)582 TEST(GenerateRbacPoliciesTest, UnsupportedHostHeader) {
583 const char* authz_policy =
584 "{"
585 " \"name\": \"authz\","
586 " \"allow_rules\": ["
587 " {"
588 " \"name\": \"policy\","
589 " \"request\": {"
590 " \"headers\": ["
591 " {"
592 " \"key\": \"Host\","
593 " \"values\": ["
594 " \"*\""
595 " ]"
596 " }"
597 " ]"
598 " }"
599 " }"
600 " ]"
601 "}";
602 auto rbac_policies = GenerateRbacPolicies(authz_policy);
603 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
604 EXPECT_EQ(rbac_policies.status().message(),
605 "allow_rules 0: \"headers\" 0: Unsupported \"key\" Host.");
606 }
607
TEST(GenerateRbacPoliciesTest,EmptyHeaderValuesList)608 TEST(GenerateRbacPoliciesTest, EmptyHeaderValuesList) {
609 const char* authz_policy =
610 "{"
611 " \"name\": \"authz\","
612 " \"allow_rules\": ["
613 " {"
614 " \"name\": \"allow_policy_1\","
615 " \"request\": {"
616 " \"headers\": ["
617 " {"
618 " \"key\": \"key-a\","
619 " \"values\": ["
620 " ]"
621 " }"
622 " ]"
623 " }"
624 " }"
625 " ]"
626 "}";
627 auto rbac_policies = GenerateRbacPolicies(authz_policy);
628 EXPECT_EQ(rbac_policies.status().code(), absl::StatusCode::kInvalidArgument);
629 EXPECT_EQ(rbac_policies.status().message(),
630 "allow_rules 0: \"headers\" 0: \"values\" list is empty.");
631 }
632
TEST(GenerateRbacPoliciesTest,ParseRequestHeadersSuccess)633 TEST(GenerateRbacPoliciesTest, ParseRequestHeadersSuccess) {
634 const char* authz_policy =
635 "{"
636 " \"name\": \"authz\","
637 " \"allow_rules\": ["
638 " {"
639 " \"name\": \"allow_policy\","
640 " \"request\": {"
641 " \"headers\": ["
642 " {"
643 " \"key\": \"key-1\","
644 " \"values\": ["
645 " \"*\""
646 " ]"
647 " },"
648 " {"
649 " \"key\": \"key-2\","
650 " \"values\": ["
651 " \"foo\","
652 " \"bar*\","
653 " \"*baz\""
654 " ]"
655 " }"
656 " ]"
657 " }"
658 " }"
659 " ]"
660 "}";
661 auto rbac_policies = GenerateRbacPolicies(authz_policy);
662 ASSERT_TRUE(rbac_policies.ok());
663 EXPECT_EQ(rbac_policies.value().deny_policy.action, Rbac::Action::kDeny);
664 EXPECT_TRUE(rbac_policies.value().deny_policy.policies.empty());
665 EXPECT_EQ(rbac_policies.value().allow_policy.action, Rbac::Action::kAllow);
666 EXPECT_THAT(
667 rbac_policies.value().allow_policy.policies,
668 ::testing::ElementsAre(::testing::Pair(
669 "authz_allow_policy",
670 ::testing::AllOf(
671 ::testing::Field(
672 &Rbac::Policy::principals,
673 ::testing::Field(&Rbac::Principal::type,
674 Rbac::Principal::RuleType::kAny)),
675 ::testing::Field(
676 &Rbac::Policy::permissions,
677 ::testing::AllOf(
678 ::testing::Field(&Rbac::Permission::type,
679 Rbac::Permission::RuleType::kAnd),
680 ::testing::Field(
681 &Rbac::Permission::permissions,
682 ::testing::ElementsAre(::testing::AllOf(
683 ::testing::Pointee(::testing::Field(
684 &Rbac::Permission::type,
685 Rbac::Permission::RuleType::kAnd)),
686 ::testing::Pointee(::testing::Field(
687 &Rbac::Permission::permissions,
688 ::testing::ElementsAre(
689 ::testing::AllOf(
690 ::testing::Pointee(::testing::Field(
691 &Rbac::Permission::type,
692 Rbac::Permission::RuleType::kOr)),
693 ::testing::Pointee(::testing::Field(
694 &Rbac::Permission::permissions,
695 ::testing::ElementsAre(
696 EqualsHeader(
697 "key-1",
698 HeaderMatcher::Type::
699 kPrefix,
700 ""))))),
701 ::testing::AllOf(
702 ::testing::Pointee(::testing::Field(
703 &Rbac::Permission::type,
704 Rbac::Permission::RuleType::kOr)),
705 ::testing::Pointee(::testing::Field(
706 &Rbac::Permission::permissions,
707 ::testing::ElementsAre(
708 EqualsHeader("key-2",
709 HeaderMatcher::
710 Type::kExact,
711 "foo"),
712 EqualsHeader(
713 "key-2",
714 HeaderMatcher::Type::
715 kPrefix,
716 "bar"),
717 EqualsHeader(
718 "key-2",
719 HeaderMatcher::Type::
720 kSuffix,
721 "baz")))))))))))))))));
722 }
723
TEST(GenerateRbacPoliciesTest,ParseRulesArraySuccess)724 TEST(GenerateRbacPoliciesTest, ParseRulesArraySuccess) {
725 const char* authz_policy =
726 "{"
727 " \"name\": \"authz\","
728 " \"allow_rules\": ["
729 " {"
730 " \"name\": \"allow_policy_1\","
731 " \"source\": {"
732 " \"principals\": ["
733 " \"spiffe://foo.abc\""
734 " ]"
735 " },"
736 " \"request\": {"
737 " \"paths\": ["
738 " \"foo\""
739 " ]"
740 " }"
741 " },"
742 " {"
743 " \"name\": \"allow_policy_2\""
744 " }"
745 " ]"
746 "}";
747 auto rbac_policies = GenerateRbacPolicies(authz_policy);
748 ASSERT_TRUE(rbac_policies.ok());
749 EXPECT_EQ(rbac_policies.value().deny_policy.action, Rbac::Action::kDeny);
750 EXPECT_TRUE(rbac_policies.value().deny_policy.policies.empty());
751 EXPECT_EQ(rbac_policies.value().allow_policy.action, Rbac::Action::kAllow);
752 EXPECT_THAT(
753 rbac_policies.value().allow_policy.policies,
754 ::testing::ElementsAre(
755 ::testing::Pair(
756 "authz_allow_policy_1",
757 ::testing::AllOf(
758 ::testing::Field(
759 &Rbac::Policy::permissions,
760 ::testing::AllOf(
761 ::testing::Field(&Rbac::Permission::type,
762 Rbac::Permission::RuleType::kAnd),
763 ::testing::Field(
764 &Rbac::Permission::permissions,
765 ::testing::ElementsAre(::testing::AllOf(
766 ::testing::Pointee(::testing::Field(
767 &Rbac::Permission::type,
768 Rbac::Permission::RuleType::kOr)),
769 ::testing::Pointee(::testing::Field(
770 &Rbac::Permission::permissions,
771 ::testing::ElementsAre(EqualsPath(
772 StringMatcher::Type::kExact,
773 "foo"))))))))),
774 ::testing::Field(
775 &Rbac::Policy::principals,
776 ::testing::AllOf(
777 ::testing::Field(&Rbac::Principal::type,
778 Rbac::Principal::RuleType::kAnd),
779 ::testing::Field(
780 &Rbac::Principal::principals,
781 ::testing::ElementsAre(::testing::AllOf(
782 ::testing::Pointee(::testing::Field(
783 &Rbac::Principal::type,
784 Rbac::Principal::RuleType::kOr)),
785 ::testing::Pointee(::testing::Field(
786 &Rbac::Principal::principals,
787 ::testing::ElementsAre(
788 EqualsPrincipalName(
789 StringMatcher::Type::kExact,
790 "spiffe://foo.abc"))))))))))),
791 ::testing::Pair(
792 "authz_allow_policy_2",
793 ::testing::AllOf(
794 ::testing::Field(
795 &Rbac::Policy::permissions,
796 ::testing::Field(&Rbac::Permission::type,
797 Rbac::Permission::RuleType::kAny)),
798 ::testing::Field(
799 &Rbac::Policy::principals,
800 ::testing::Field(&Rbac::Principal::type,
801 Rbac::Principal::RuleType::kAny))))));
802 }
803
804 } // namespace grpc_core
805
main(int argc,char ** argv)806 int main(int argc, char** argv) {
807 ::testing::InitGoogleTest(&argc, argv);
808 return RUN_ALL_TESTS();
809 }
810