]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_rgw_iam_policy.cc
update sources to v12.1.3
[ceph.git] / ceph / src / test / rgw / test_rgw_iam_policy.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 Red Hat
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #include <string>
16
17 #include <boost/intrusive_ptr.hpp>
18 #include <boost/optional.hpp>
19
20 #include <gtest/gtest.h>
21
22 #include "common/code_environment.h"
23 #include "common/ceph_context.h"
24 #include "global/global_init.h"
25 #include "rgw/rgw_auth.h"
26 #include "rgw/rgw_iam_policy.h"
27
28
29 using std::string;
30 using std::vector;
31
32 using boost::container::flat_set;
33 using boost::intrusive_ptr;
34 using boost::make_optional;
35 using boost::none;
36 using boost::optional;
37
38 using rgw::auth::Identity;
39 using rgw::auth::Principal;
40
41 using rgw::IAM::ARN;
42 using rgw::IAM::Effect;
43 using rgw::IAM::Environment;
44 using rgw::IAM::Partition;
45 using rgw::IAM::Policy;
46 using rgw::IAM::s3All;
47 using rgw::IAM::s3Count;
48 using rgw::IAM::s3GetAccelerateConfiguration;
49 using rgw::IAM::s3GetBucketAcl;
50 using rgw::IAM::s3GetBucketCORS;
51 using rgw::IAM::s3GetBucketLocation;
52 using rgw::IAM::s3GetBucketLogging;
53 using rgw::IAM::s3GetBucketNotification;
54 using rgw::IAM::s3GetBucketPolicy;
55 using rgw::IAM::s3GetBucketRequestPayment;
56 using rgw::IAM::s3GetBucketTagging;
57 using rgw::IAM::s3GetBucketVersioning;
58 using rgw::IAM::s3GetBucketWebsite;
59 using rgw::IAM::s3GetLifecycleConfiguration;
60 using rgw::IAM::s3GetObject;
61 using rgw::IAM::s3GetObjectAcl;
62 using rgw::IAM::s3GetObjectVersionAcl;
63 using rgw::IAM::s3GetObjectTorrent;
64 using rgw::IAM::s3GetObjectTagging;
65 using rgw::IAM::s3GetObjectVersion;
66 using rgw::IAM::s3GetObjectVersionTagging;
67 using rgw::IAM::s3GetObjectVersionTorrent;
68 using rgw::IAM::s3GetReplicationConfiguration;
69 using rgw::IAM::s3ListAllMyBuckets;
70 using rgw::IAM::s3ListBucket;
71 using rgw::IAM::s3ListBucket;
72 using rgw::IAM::s3ListBucketMultiPartUploads;
73 using rgw::IAM::s3ListBucketVersions;
74 using rgw::IAM::s3ListMultipartUploadParts;
75 using rgw::IAM::s3None;
76 using rgw::IAM::s3PutBucketAcl;
77 using rgw::IAM::s3PutBucketPolicy;
78 using rgw::IAM::Service;
79 using rgw::IAM::TokenID;
80 using rgw::IAM::Version;
81
82 class FakeIdentity : public Identity {
83 const Principal id;
84 public:
85
86 FakeIdentity(Principal&& id) : id(std::move(id)) {}
87 uint32_t get_perms_from_aclspec(const aclspec_t& aclspec) const override {
88 abort();
89 return 0;
90 };
91
92 bool is_admin_of(const rgw_user& uid) const override {
93 abort();
94 return false;
95 }
96
97 bool is_owner_of(const rgw_user& uid) const override {
98 abort();
99 return false;
100 }
101
102 virtual uint32_t get_perm_mask() const override {
103 abort();
104 return 0;
105 }
106
107 void to_str(std::ostream& out) const override {
108 abort();
109 }
110
111 bool is_identity(const flat_set<Principal>& ids) const override {
112 return ids.find(id) != ids.end();
113 }
114 };
115
116 class PolicyTest : public ::testing::Test {
117 protected:
118 intrusive_ptr<CephContext> cct;
119 static const string arbitrary_tenant;
120 static string example1;
121 static string example2;
122 static string example3;
123 public:
124 PolicyTest() {
125 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
126 }
127 };
128
129 TEST_F(PolicyTest, Parse1) {
130 optional<Policy> p;
131
132 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
133 bufferlist::static_from_string(example1)));
134 ASSERT_TRUE(p);
135
136 EXPECT_EQ(p->text, example1);
137 EXPECT_EQ(p->version, Version::v2012_10_17);
138 EXPECT_FALSE(p->id);
139 EXPECT_FALSE(p->statements[0].sid);
140 EXPECT_FALSE(p->statements.empty());
141 EXPECT_EQ(p->statements.size(), 1U);
142 EXPECT_TRUE(p->statements[0].princ.empty());
143 EXPECT_TRUE(p->statements[0].noprinc.empty());
144 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
145 EXPECT_EQ(p->statements[0].action, s3ListBucket);
146 EXPECT_EQ(p->statements[0].notaction, s3None);
147 ASSERT_FALSE(p->statements[0].resource.empty());
148 ASSERT_EQ(p->statements[0].resource.size(), 1U);
149 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
150 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
151 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
152 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
153 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
154 EXPECT_TRUE(p->statements[0].notresource.empty());
155 EXPECT_TRUE(p->statements[0].conditions.empty());
156 }
157
158 TEST_F(PolicyTest, Eval1) {
159 auto p = Policy(cct.get(), arbitrary_tenant,
160 bufferlist::static_from_string(example1));
161 Environment e;
162
163 EXPECT_EQ(p.eval(e, none, s3ListBucket,
164 ARN(Partition::aws, Service::s3,
165 "", arbitrary_tenant, "example_bucket")),
166 Effect::Allow);
167
168 EXPECT_EQ(p.eval(e, none, s3PutBucketAcl,
169 ARN(Partition::aws, Service::s3,
170 "", arbitrary_tenant, "example_bucket")),
171 Effect::Pass);
172
173 EXPECT_EQ(p.eval(e, none, s3ListBucket,
174 ARN(Partition::aws, Service::s3,
175 "", arbitrary_tenant, "erroneous_bucket")),
176 Effect::Pass);
177
178 }
179
180 TEST_F(PolicyTest, Parse2) {
181 optional<Policy> p;
182
183 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
184 bufferlist::static_from_string(example2)));
185 ASSERT_TRUE(p);
186
187 EXPECT_EQ(p->text, example2);
188 EXPECT_EQ(p->version, Version::v2012_10_17);
189 EXPECT_EQ(*p->id, "S3-Account-Permissions");
190 ASSERT_FALSE(p->statements.empty());
191 EXPECT_EQ(p->statements.size(), 1U);
192 EXPECT_EQ(*p->statements[0].sid, "1");
193 EXPECT_FALSE(p->statements[0].princ.empty());
194 EXPECT_EQ(p->statements[0].princ.size(), 1U);
195 EXPECT_EQ(*p->statements[0].princ.begin(),
196 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
197 EXPECT_TRUE(p->statements[0].noprinc.empty());
198 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
199 EXPECT_EQ(p->statements[0].action, s3All);
200 EXPECT_EQ(p->statements[0].notaction, s3None);
201 ASSERT_FALSE(p->statements[0].resource.empty());
202 ASSERT_EQ(p->statements[0].resource.size(), 2U);
203 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
204 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
205 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
206 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
207 EXPECT_EQ(p->statements[0].resource.begin()->resource, "mybucket");
208 EXPECT_EQ((p->statements[0].resource.begin() + 1)->partition,
209 Partition::aws);
210 EXPECT_EQ((p->statements[0].resource.begin() + 1)->service,
211 Service::s3);
212 EXPECT_TRUE((p->statements[0].resource.begin() + 1)->region.empty());
213 EXPECT_EQ((p->statements[0].resource.begin() + 1)->account,
214 arbitrary_tenant);
215 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "mybucket/*");
216 EXPECT_TRUE(p->statements[0].notresource.empty());
217 EXPECT_TRUE(p->statements[0].conditions.empty());
218 }
219
220 TEST_F(PolicyTest, Eval2) {
221 auto p = Policy(cct.get(), arbitrary_tenant,
222 bufferlist::static_from_string(example2));
223 Environment e;
224
225 auto trueacct = FakeIdentity(
226 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
227
228 auto notacct = FakeIdentity(
229 Principal::tenant("some-other-account"));
230 for (auto i = 0ULL; i < s3Count; ++i) {
231 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
232 ARN(Partition::aws, Service::s3,
233 "", arbitrary_tenant, "mybucket")),
234 Effect::Allow);
235 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
236 ARN(Partition::aws, Service::s3,
237 "", arbitrary_tenant, "mybucket/myobject")),
238 Effect::Allow);
239
240 EXPECT_EQ(p.eval(e, notacct, 1ULL << i,
241 ARN(Partition::aws, Service::s3,
242 "", arbitrary_tenant, "mybucket")),
243 Effect::Pass);
244 EXPECT_EQ(p.eval(e, notacct, 1ULL << i,
245 ARN(Partition::aws, Service::s3,
246 "", arbitrary_tenant, "mybucket/myobject")),
247 Effect::Pass);
248
249 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
250 ARN(Partition::aws, Service::s3,
251 "", arbitrary_tenant, "notyourbucket")),
252 Effect::Pass);
253 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
254 ARN(Partition::aws, Service::s3,
255 "", arbitrary_tenant, "notyourbucket/notyourobject")),
256 Effect::Pass);
257
258 }
259 }
260
261 TEST_F(PolicyTest, Parse3) {
262 optional<Policy> p;
263
264 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
265 bufferlist::static_from_string(example3)));
266 ASSERT_TRUE(p);
267
268 EXPECT_EQ(p->text, example3);
269 EXPECT_EQ(p->version, Version::v2012_10_17);
270 EXPECT_FALSE(p->id);
271 ASSERT_FALSE(p->statements.empty());
272 EXPECT_EQ(p->statements.size(), 3U);
273
274 EXPECT_EQ(*p->statements[0].sid, "FirstStatement");
275 EXPECT_TRUE(p->statements[0].princ.empty());
276 EXPECT_TRUE(p->statements[0].noprinc.empty());
277 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
278 EXPECT_EQ(p->statements[0].action, s3PutBucketPolicy);
279 EXPECT_EQ(p->statements[0].notaction, s3None);
280 ASSERT_FALSE(p->statements[0].resource.empty());
281 ASSERT_EQ(p->statements[0].resource.size(), 1U);
282 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::wildcard);
283 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::wildcard);
284 EXPECT_EQ(p->statements[0].resource.begin()->region, "*");
285 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
286 EXPECT_EQ(p->statements[0].resource.begin()->resource, "*");
287 EXPECT_TRUE(p->statements[0].notresource.empty());
288 EXPECT_TRUE(p->statements[0].conditions.empty());
289
290 EXPECT_EQ(*p->statements[1].sid, "SecondStatement");
291 EXPECT_TRUE(p->statements[1].princ.empty());
292 EXPECT_TRUE(p->statements[1].noprinc.empty());
293 EXPECT_EQ(p->statements[1].effect, Effect::Allow);
294 EXPECT_EQ(p->statements[1].action, s3ListAllMyBuckets);
295 EXPECT_EQ(p->statements[1].notaction, s3None);
296 ASSERT_FALSE(p->statements[1].resource.empty());
297 ASSERT_EQ(p->statements[1].resource.size(), 1U);
298 EXPECT_EQ(p->statements[1].resource.begin()->partition, Partition::wildcard);
299 EXPECT_EQ(p->statements[1].resource.begin()->service, Service::wildcard);
300 EXPECT_EQ(p->statements[1].resource.begin()->region, "*");
301 EXPECT_EQ(p->statements[1].resource.begin()->account, arbitrary_tenant);
302 EXPECT_EQ(p->statements[1].resource.begin()->resource, "*");
303 EXPECT_TRUE(p->statements[1].notresource.empty());
304 EXPECT_TRUE(p->statements[1].conditions.empty());
305
306 EXPECT_EQ(*p->statements[2].sid, "ThirdStatement");
307 EXPECT_TRUE(p->statements[2].princ.empty());
308 EXPECT_TRUE(p->statements[2].noprinc.empty());
309 EXPECT_EQ(p->statements[2].effect, Effect::Allow);
310 EXPECT_EQ(p->statements[2].action, (s3ListMultipartUploadParts |
311 s3ListBucket | s3ListBucketVersions |
312 s3ListAllMyBuckets |
313 s3ListBucketMultiPartUploads |
314 s3GetObject | s3GetObjectVersion |
315 s3GetObjectAcl | s3GetObjectVersionAcl |
316 s3GetObjectTorrent |
317 s3GetObjectVersionTorrent |
318 s3GetAccelerateConfiguration |
319 s3GetBucketAcl | s3GetBucketCORS |
320 s3GetBucketVersioning |
321 s3GetBucketRequestPayment |
322 s3GetBucketLocation |
323 s3GetBucketPolicy |
324 s3GetBucketNotification |
325 s3GetBucketLogging |
326 s3GetBucketTagging |
327 s3GetBucketWebsite |
328 s3GetLifecycleConfiguration |
329 s3GetReplicationConfiguration |
330 s3GetObjectTagging |
331 s3GetObjectVersionTagging));
332 EXPECT_EQ(p->statements[2].notaction, s3None);
333 ASSERT_FALSE(p->statements[2].resource.empty());
334 ASSERT_EQ(p->statements[2].resource.size(), 2U);
335 EXPECT_EQ(p->statements[2].resource.begin()->partition, Partition::aws);
336 EXPECT_EQ(p->statements[2].resource.begin()->service, Service::s3);
337 EXPECT_TRUE(p->statements[2].resource.begin()->region.empty());
338 EXPECT_EQ(p->statements[2].resource.begin()->account, arbitrary_tenant);
339 EXPECT_EQ(p->statements[2].resource.begin()->resource, "confidential-data");
340 EXPECT_EQ((p->statements[2].resource.begin() + 1)->partition,
341 Partition::aws);
342 EXPECT_EQ((p->statements[2].resource.begin() + 1)->service, Service::s3);
343 EXPECT_TRUE((p->statements[2].resource.begin() + 1)->region.empty());
344 EXPECT_EQ((p->statements[2].resource.begin() + 1)->account,
345 arbitrary_tenant);
346 EXPECT_EQ((p->statements[2].resource.begin() + 1)->resource,
347 "confidential-data/*");
348 EXPECT_TRUE(p->statements[2].notresource.empty());
349 ASSERT_FALSE(p->statements[2].conditions.empty());
350 ASSERT_EQ(p->statements[2].conditions.size(), 1U);
351 EXPECT_EQ(p->statements[2].conditions[0].op, TokenID::Bool);
352 EXPECT_EQ(p->statements[2].conditions[0].key, "aws:MultiFactorAuthPresent");
353 EXPECT_FALSE(p->statements[2].conditions[0].ifexists);
354 ASSERT_FALSE(p->statements[2].conditions[0].vals.empty());
355 EXPECT_EQ(p->statements[2].conditions[0].vals.size(), 1U);
356 EXPECT_EQ(p->statements[2].conditions[0].vals[0], "true");
357 }
358
359 TEST_F(PolicyTest, Eval3) {
360 auto p = Policy(cct.get(), arbitrary_tenant,
361 bufferlist::static_from_string(example3));
362 Environment em;
363 Environment tr = { { "aws:MultiFactorAuthPresent", "true" } };
364 Environment fa = { { "aws:MultiFactorAuthPresent", "false" } };
365
366 auto s3allow = (s3ListMultipartUploadParts | s3ListBucket |
367 s3ListBucketVersions | s3ListAllMyBuckets |
368 s3ListBucketMultiPartUploads | s3GetObject |
369 s3GetObjectVersion | s3GetObjectAcl | s3GetObjectVersionAcl |
370 s3GetObjectTorrent | s3GetObjectVersionTorrent |
371 s3GetAccelerateConfiguration | s3GetBucketAcl |
372 s3GetBucketCORS | s3GetBucketVersioning |
373 s3GetBucketRequestPayment | s3GetBucketLocation |
374 s3GetBucketPolicy | s3GetBucketNotification |
375 s3GetBucketLogging | s3GetBucketTagging |
376 s3GetBucketWebsite | s3GetLifecycleConfiguration |
377 s3GetReplicationConfiguration |
378 s3GetObjectTagging | s3GetObjectVersionTagging);
379
380 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
381 ARN(Partition::aws, Service::s3,
382 "", arbitrary_tenant, "mybucket")),
383 Effect::Allow);
384
385 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
386 ARN(Partition::aws, Service::s3,
387 "", arbitrary_tenant, "mybucket")),
388 Effect::Allow);
389
390
391 for (auto i = 0ULL; i < s3Count; ++i) {
392 auto op = 1ULL << i;
393 if ((op == s3ListAllMyBuckets) || (op == s3PutBucketPolicy)) {
394 continue;
395 }
396
397 EXPECT_EQ(p.eval(em, none, op,
398 ARN(Partition::aws, Service::s3,
399 "", arbitrary_tenant, "confidential-data")),
400 Effect::Pass);
401 EXPECT_EQ(p.eval(tr, none, op,
402 ARN(Partition::aws, Service::s3,
403 "", arbitrary_tenant, "confidential-data")),
404 op & s3allow ? Effect::Allow : Effect::Pass);
405 EXPECT_EQ(p.eval(fa, none, op,
406 ARN(Partition::aws, Service::s3,
407 "", arbitrary_tenant, "confidential-data")),
408 Effect::Pass);
409
410 EXPECT_EQ(p.eval(em, none, op,
411 ARN(Partition::aws, Service::s3,
412 "", arbitrary_tenant, "confidential-data/moo")),
413 Effect::Pass);
414 EXPECT_EQ(p.eval(tr, none, op,
415 ARN(Partition::aws, Service::s3,
416 "", arbitrary_tenant, "confidential-data/moo")),
417 op & s3allow ? Effect::Allow : Effect::Pass);
418 EXPECT_EQ(p.eval(fa, none, op,
419 ARN(Partition::aws, Service::s3,
420 "", arbitrary_tenant, "confidential-data/moo")),
421 Effect::Pass);
422
423 EXPECT_EQ(p.eval(em, none, op,
424 ARN(Partition::aws, Service::s3,
425 "", arbitrary_tenant, "really-confidential-data")),
426 Effect::Pass);
427 EXPECT_EQ(p.eval(tr, none, op,
428 ARN(Partition::aws, Service::s3,
429 "", arbitrary_tenant, "really-confidential-data")),
430 Effect::Pass);
431 EXPECT_EQ(p.eval(fa, none, op,
432 ARN(Partition::aws, Service::s3,
433 "", arbitrary_tenant, "really-confidential-data")),
434 Effect::Pass);
435
436 EXPECT_EQ(p.eval(em, none, op,
437 ARN(Partition::aws, Service::s3,
438 "", arbitrary_tenant,
439 "really-confidential-data/moo")), Effect::Pass);
440 EXPECT_EQ(p.eval(tr, none, op,
441 ARN(Partition::aws, Service::s3,
442 "", arbitrary_tenant,
443 "really-confidential-data/moo")), Effect::Pass);
444 EXPECT_EQ(p.eval(fa, none, op,
445 ARN(Partition::aws, Service::s3,
446 "", arbitrary_tenant,
447 "really-confidential-data/moo")), Effect::Pass);
448
449 }
450 }
451
452 const string PolicyTest::arbitrary_tenant = "arbitrary_tenant";
453 string PolicyTest::example1 = R"(
454 {
455 "Version": "2012-10-17",
456 "Statement": {
457 "Effect": "Allow",
458 "Action": "s3:ListBucket",
459 "Resource": "arn:aws:s3:::example_bucket"
460 }
461 }
462 )";
463
464 string PolicyTest::example2 = R"(
465 {
466 "Version": "2012-10-17",
467 "Id": "S3-Account-Permissions",
468 "Statement": [{
469 "Sid": "1",
470 "Effect": "Allow",
471 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
472 "Action": "s3:*",
473 "Resource": [
474 "arn:aws:s3:::mybucket",
475 "arn:aws:s3:::mybucket/*"
476 ]
477 }]
478 }
479 )";
480
481 string PolicyTest::example3 = R"(
482 {
483 "Version": "2012-10-17",
484 "Statement": [
485 {
486 "Sid": "FirstStatement",
487 "Effect": "Allow",
488 "Action": ["s3:PutBucketPolicy"],
489 "Resource": "*"
490 },
491 {
492 "Sid": "SecondStatement",
493 "Effect": "Allow",
494 "Action": "s3:ListAllMyBuckets",
495 "Resource": "*"
496 },
497 {
498 "Sid": "ThirdStatement",
499 "Effect": "Allow",
500 "Action": [
501 "s3:List*",
502 "s3:Get*"
503 ],
504 "Resource": [
505 "arn:aws:s3:::confidential-data",
506 "arn:aws:s3:::confidential-data/*"
507 ],
508 "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
509 }
510 ]
511 }
512 )";
513
514 TEST(MatchWildcards, Simple)
515 {
516 EXPECT_TRUE(match_wildcards("", ""));
517 EXPECT_TRUE(match_wildcards("", "", MATCH_CASE_INSENSITIVE));
518 EXPECT_FALSE(match_wildcards("", "abc"));
519 EXPECT_FALSE(match_wildcards("", "abc", MATCH_CASE_INSENSITIVE));
520 EXPECT_FALSE(match_wildcards("abc", ""));
521 EXPECT_FALSE(match_wildcards("abc", "", MATCH_CASE_INSENSITIVE));
522 EXPECT_TRUE(match_wildcards("abc", "abc"));
523 EXPECT_TRUE(match_wildcards("abc", "abc", MATCH_CASE_INSENSITIVE));
524 EXPECT_FALSE(match_wildcards("abc", "abC"));
525 EXPECT_TRUE(match_wildcards("abc", "abC", MATCH_CASE_INSENSITIVE));
526 EXPECT_FALSE(match_wildcards("abC", "abc"));
527 EXPECT_TRUE(match_wildcards("abC", "abc", MATCH_CASE_INSENSITIVE));
528 EXPECT_FALSE(match_wildcards("abc", "abcd"));
529 EXPECT_FALSE(match_wildcards("abc", "abcd", MATCH_CASE_INSENSITIVE));
530 EXPECT_FALSE(match_wildcards("abcd", "abc"));
531 EXPECT_FALSE(match_wildcards("abcd", "abc", MATCH_CASE_INSENSITIVE));
532 }
533
534 TEST(MatchWildcards, QuestionMark)
535 {
536 EXPECT_FALSE(match_wildcards("?", ""));
537 EXPECT_FALSE(match_wildcards("?", "", MATCH_CASE_INSENSITIVE));
538 EXPECT_TRUE(match_wildcards("?", "a"));
539 EXPECT_TRUE(match_wildcards("?", "a", MATCH_CASE_INSENSITIVE));
540 EXPECT_TRUE(match_wildcards("?bc", "abc"));
541 EXPECT_TRUE(match_wildcards("?bc", "abc", MATCH_CASE_INSENSITIVE));
542 EXPECT_TRUE(match_wildcards("a?c", "abc"));
543 EXPECT_TRUE(match_wildcards("a?c", "abc", MATCH_CASE_INSENSITIVE));
544 EXPECT_FALSE(match_wildcards("abc", "a?c"));
545 EXPECT_FALSE(match_wildcards("abc", "a?c", MATCH_CASE_INSENSITIVE));
546 EXPECT_FALSE(match_wildcards("a?c", "abC"));
547 EXPECT_TRUE(match_wildcards("a?c", "abC", MATCH_CASE_INSENSITIVE));
548 EXPECT_TRUE(match_wildcards("ab?", "abc"));
549 EXPECT_TRUE(match_wildcards("ab?", "abc", MATCH_CASE_INSENSITIVE));
550 EXPECT_TRUE(match_wildcards("a?c?e", "abcde"));
551 EXPECT_TRUE(match_wildcards("a?c?e", "abcde", MATCH_CASE_INSENSITIVE));
552 EXPECT_TRUE(match_wildcards("???", "abc"));
553 EXPECT_TRUE(match_wildcards("???", "abc", MATCH_CASE_INSENSITIVE));
554 EXPECT_FALSE(match_wildcards("???", "abcd"));
555 EXPECT_FALSE(match_wildcards("???", "abcd", MATCH_CASE_INSENSITIVE));
556 }
557
558 TEST(MatchWildcards, Asterisk)
559 {
560 EXPECT_TRUE(match_wildcards("*", ""));
561 EXPECT_TRUE(match_wildcards("*", "", MATCH_CASE_INSENSITIVE));
562 EXPECT_FALSE(match_wildcards("", "*"));
563 EXPECT_FALSE(match_wildcards("", "*", MATCH_CASE_INSENSITIVE));
564 EXPECT_FALSE(match_wildcards("*a", ""));
565 EXPECT_FALSE(match_wildcards("*a", "", MATCH_CASE_INSENSITIVE));
566 EXPECT_TRUE(match_wildcards("*a", "a"));
567 EXPECT_TRUE(match_wildcards("*a", "a", MATCH_CASE_INSENSITIVE));
568 EXPECT_TRUE(match_wildcards("a*", "a"));
569 EXPECT_TRUE(match_wildcards("a*", "a", MATCH_CASE_INSENSITIVE));
570 EXPECT_TRUE(match_wildcards("a*c", "ac"));
571 EXPECT_TRUE(match_wildcards("a*c", "ac", MATCH_CASE_INSENSITIVE));
572 EXPECT_TRUE(match_wildcards("a*c", "abbc"));
573 EXPECT_TRUE(match_wildcards("a*c", "abbc", MATCH_CASE_INSENSITIVE));
574 EXPECT_FALSE(match_wildcards("a*c", "abbC"));
575 EXPECT_TRUE(match_wildcards("a*c", "abbC", MATCH_CASE_INSENSITIVE));
576 EXPECT_TRUE(match_wildcards("a*c*e", "abBce"));
577 EXPECT_TRUE(match_wildcards("a*c*e", "abBce", MATCH_CASE_INSENSITIVE));
578 EXPECT_TRUE(match_wildcards("http://*.example.com",
579 "http://www.example.com"));
580 EXPECT_TRUE(match_wildcards("http://*.example.com",
581 "http://www.example.com", MATCH_CASE_INSENSITIVE));
582 EXPECT_FALSE(match_wildcards("http://*.example.com",
583 "http://www.Example.com"));
584 EXPECT_TRUE(match_wildcards("http://*.example.com",
585 "http://www.Example.com", MATCH_CASE_INSENSITIVE));
586 EXPECT_TRUE(match_wildcards("http://example.com/*",
587 "http://example.com/index.html"));
588 EXPECT_TRUE(match_wildcards("http://example.com/*/*.jpg",
589 "http://example.com/fun/smiley.jpg"));
590 // note: parsing of * is not greedy, so * does not match 'bc' here
591 EXPECT_FALSE(match_wildcards("a*c", "abcc"));
592 EXPECT_FALSE(match_wildcards("a*c", "abcc", MATCH_CASE_INSENSITIVE));
593 }
594
595 TEST(MatchPolicy, Action)
596 {
597 constexpr auto flag = MATCH_POLICY_ACTION;
598 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
599 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
600 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
601 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
602 }
603
604 TEST(MatchPolicy, Resource)
605 {
606 constexpr auto flag = MATCH_POLICY_RESOURCE;
607 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
608 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
609 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
610 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
611 }
612
613 TEST(MatchPolicy, ARN)
614 {
615 constexpr auto flag = MATCH_POLICY_ARN;
616 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
617 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
618 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
619 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
620 }
621
622 TEST(MatchPolicy, String)
623 {
624 constexpr auto flag = MATCH_POLICY_STRING;
625 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
626 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
627 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
628 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
629 }