grpc_authz.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  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. #include <stdio.h>
  15. #include <string.h>
  16. #include <grpc/byte_buffer.h>
  17. #include <grpc/grpc_security.h>
  18. #include <grpc/support/alloc.h>
  19. #include <grpc/support/log.h>
  20. #include <grpc/support/time.h>
  21. #include "src/core/lib/channel/channel_args.h"
  22. #include "src/core/lib/gpr/string.h"
  23. #include "src/core/lib/security/authorization/grpc_authorization_policy_provider.h"
  24. #include "src/core/lib/security/credentials/credentials.h"
  25. #include "test/core/end2end/cq_verifier.h"
  26. #include "test/core/end2end/end2end_tests.h"
  27. #include "test/core/util/tls_utils.h"
  28. static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
  29. static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
  30. const char* test_name,
  31. grpc_channel_args* client_args,
  32. grpc_channel_args* server_args) {
  33. grpc_end2end_test_fixture f;
  34. gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
  35. f = config.create_fixture(client_args, server_args);
  36. config.init_server(&f, server_args);
  37. config.init_client(&f, client_args);
  38. return f;
  39. }
  40. static gpr_timespec n_seconds_from_now(int n) {
  41. return grpc_timeout_seconds_to_deadline(n);
  42. }
  43. static gpr_timespec five_seconds_from_now(void) {
  44. return n_seconds_from_now(5);
  45. }
  46. static void drain_cq(grpc_completion_queue* cq) {
  47. grpc_event ev;
  48. do {
  49. ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
  50. } while (ev.type != GRPC_QUEUE_SHUTDOWN);
  51. }
  52. static void shutdown_server(grpc_end2end_test_fixture* f) {
  53. if (!f->server) return;
  54. grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
  55. GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
  56. grpc_timeout_seconds_to_deadline(5),
  57. nullptr)
  58. .type == GRPC_OP_COMPLETE);
  59. grpc_server_destroy(f->server);
  60. f->server = nullptr;
  61. }
  62. static void shutdown_client(grpc_end2end_test_fixture* f) {
  63. if (!f->client) return;
  64. grpc_channel_destroy(f->client);
  65. f->client = nullptr;
  66. }
  67. static void end_test(grpc_end2end_test_fixture* f) {
  68. shutdown_server(f);
  69. shutdown_client(f);
  70. grpc_completion_queue_shutdown(f->cq);
  71. drain_cq(f->cq);
  72. grpc_completion_queue_destroy(f->cq);
  73. grpc_completion_queue_destroy(f->shutdown_cq);
  74. }
  75. static void test_allow_authorized_request(grpc_end2end_test_fixture f) {
  76. grpc_call* c;
  77. grpc_call* s;
  78. grpc_op ops[6];
  79. grpc_op* op;
  80. grpc_metadata_array initial_metadata_recv;
  81. grpc_metadata_array trailing_metadata_recv;
  82. grpc_metadata_array request_metadata_recv;
  83. grpc_call_details call_details;
  84. grpc_status_code status;
  85. const char* error_string = nullptr;
  86. grpc_call_error error;
  87. grpc_slice details = grpc_empty_slice();
  88. int was_cancelled = 2;
  89. cq_verifier* cqv = cq_verifier_create(f.cq);
  90. gpr_timespec deadline = five_seconds_from_now();
  91. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  92. grpc_slice_from_static_string("/foo"), nullptr,
  93. deadline, nullptr);
  94. GPR_ASSERT(c);
  95. grpc_metadata_array_init(&initial_metadata_recv);
  96. grpc_metadata_array_init(&trailing_metadata_recv);
  97. grpc_metadata_array_init(&request_metadata_recv);
  98. grpc_call_details_init(&call_details);
  99. memset(ops, 0, sizeof(ops));
  100. op = ops;
  101. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  102. op->data.send_initial_metadata.count = 0;
  103. op->flags = 0;
  104. op->reserved = nullptr;
  105. op++;
  106. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  107. op->flags = 0;
  108. op->reserved = nullptr;
  109. op++;
  110. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  111. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  112. op->flags = 0;
  113. op->reserved = nullptr;
  114. op++;
  115. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  116. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  117. op->data.recv_status_on_client.status = &status;
  118. op->data.recv_status_on_client.status_details = &details;
  119. op->data.recv_status_on_client.error_string = &error_string;
  120. op->flags = 0;
  121. op->reserved = nullptr;
  122. op++;
  123. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  124. nullptr);
  125. GPR_ASSERT(GRPC_CALL_OK == error);
  126. error =
  127. grpc_server_request_call(f.server, &s, &call_details,
  128. &request_metadata_recv, f.cq, f.cq, tag(101));
  129. GPR_ASSERT(GRPC_CALL_OK == error);
  130. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  131. cq_verify(cqv);
  132. memset(ops, 0, sizeof(ops));
  133. op = ops;
  134. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  135. op->data.send_initial_metadata.count = 0;
  136. op->flags = 0;
  137. op->reserved = nullptr;
  138. op++;
  139. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  140. op->data.send_status_from_server.trailing_metadata_count = 0;
  141. op->data.send_status_from_server.status = GRPC_STATUS_OK;
  142. grpc_slice status_details = grpc_slice_from_static_string("xyz");
  143. op->data.send_status_from_server.status_details = &status_details;
  144. op->flags = 0;
  145. op->reserved = nullptr;
  146. op++;
  147. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  148. op->data.recv_close_on_server.cancelled = &was_cancelled;
  149. op->flags = 0;
  150. op->reserved = nullptr;
  151. op++;
  152. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  153. nullptr);
  154. GPR_ASSERT(GRPC_CALL_OK == error);
  155. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  156. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  157. cq_verify(cqv);
  158. GPR_ASSERT(GRPC_STATUS_OK == status);
  159. GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
  160. grpc_slice_unref(details);
  161. gpr_free(const_cast<char*>(error_string));
  162. grpc_metadata_array_destroy(&initial_metadata_recv);
  163. grpc_metadata_array_destroy(&trailing_metadata_recv);
  164. grpc_metadata_array_destroy(&request_metadata_recv);
  165. grpc_call_details_destroy(&call_details);
  166. grpc_call_unref(c);
  167. grpc_call_unref(s);
  168. cq_verifier_destroy(cqv);
  169. }
  170. static void test_deny_unauthorized_request(grpc_end2end_test_fixture f) {
  171. grpc_call* c;
  172. grpc_op ops[6];
  173. grpc_op* op;
  174. grpc_metadata_array initial_metadata_recv;
  175. grpc_metadata_array trailing_metadata_recv;
  176. grpc_status_code status;
  177. const char* error_string = nullptr;
  178. grpc_call_error error;
  179. grpc_slice details = grpc_empty_slice();
  180. cq_verifier* cqv = cq_verifier_create(f.cq);
  181. gpr_timespec deadline = five_seconds_from_now();
  182. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  183. grpc_slice_from_static_string("/foo"), nullptr,
  184. deadline, nullptr);
  185. GPR_ASSERT(c);
  186. grpc_metadata_array_init(&initial_metadata_recv);
  187. grpc_metadata_array_init(&trailing_metadata_recv);
  188. memset(ops, 0, sizeof(ops));
  189. op = ops;
  190. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  191. op->data.send_initial_metadata.count = 0;
  192. op->flags = 0;
  193. op->reserved = nullptr;
  194. op++;
  195. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  196. op->flags = 0;
  197. op->reserved = nullptr;
  198. op++;
  199. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  200. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  201. op->flags = 0;
  202. op->reserved = nullptr;
  203. op++;
  204. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  205. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  206. op->data.recv_status_on_client.status = &status;
  207. op->data.recv_status_on_client.status_details = &details;
  208. op->data.recv_status_on_client.error_string = &error_string;
  209. op->flags = 0;
  210. op->reserved = nullptr;
  211. op++;
  212. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  213. nullptr);
  214. GPR_ASSERT(GRPC_CALL_OK == error);
  215. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  216. cq_verify(cqv);
  217. GPR_ASSERT(GRPC_STATUS_PERMISSION_DENIED == status);
  218. GPR_ASSERT(0 ==
  219. grpc_slice_str_cmp(details, "Unauthorized RPC request rejected."));
  220. grpc_slice_unref(details);
  221. gpr_free(const_cast<char*>(error_string));
  222. grpc_metadata_array_destroy(&initial_metadata_recv);
  223. grpc_metadata_array_destroy(&trailing_metadata_recv);
  224. grpc_call_unref(c);
  225. cq_verifier_destroy(cqv);
  226. }
  227. static void test_static_init_allow_authorized_request(
  228. grpc_end2end_test_config config) {
  229. const char* authz_policy =
  230. "{"
  231. " \"name\": \"authz\","
  232. " \"allow_rules\": ["
  233. " {"
  234. " \"name\": \"allow_foo\","
  235. " \"request\": {"
  236. " \"paths\": ["
  237. " \"*/foo\""
  238. " ]"
  239. " }"
  240. " }"
  241. " ]"
  242. "}";
  243. grpc_status_code code = GRPC_STATUS_OK;
  244. const char* error_details;
  245. grpc_authorization_policy_provider* provider =
  246. grpc_authorization_policy_provider_static_data_create(authz_policy, &code,
  247. &error_details);
  248. GPR_ASSERT(GRPC_STATUS_OK == code);
  249. grpc_arg args[] = {
  250. grpc_channel_arg_pointer_create(
  251. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  252. grpc_authorization_policy_provider_arg_vtable()),
  253. };
  254. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  255. grpc_end2end_test_fixture f =
  256. begin_test(config, "test_static_init_allow_authorized_request", nullptr,
  257. &server_args);
  258. grpc_authorization_policy_provider_release(provider);
  259. test_allow_authorized_request(f);
  260. end_test(&f);
  261. config.tear_down_data(&f);
  262. }
  263. static void test_static_init_deny_unauthorized_request(
  264. grpc_end2end_test_config config) {
  265. const char* authz_policy =
  266. "{"
  267. " \"name\": \"authz\","
  268. " \"allow_rules\": ["
  269. " {"
  270. " \"name\": \"allow_bar\","
  271. " \"request\": {"
  272. " \"paths\": ["
  273. " \"*/bar\""
  274. " ]"
  275. " }"
  276. " }"
  277. " ],"
  278. " \"deny_rules\": ["
  279. " {"
  280. " \"name\": \"deny_foo\","
  281. " \"request\": {"
  282. " \"paths\": ["
  283. " \"*/foo\""
  284. " ]"
  285. " }"
  286. " }"
  287. " ]"
  288. "}";
  289. grpc_status_code code = GRPC_STATUS_OK;
  290. const char* error_details;
  291. grpc_authorization_policy_provider* provider =
  292. grpc_authorization_policy_provider_static_data_create(authz_policy, &code,
  293. &error_details);
  294. GPR_ASSERT(GRPC_STATUS_OK == code);
  295. grpc_arg args[] = {
  296. grpc_channel_arg_pointer_create(
  297. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  298. grpc_authorization_policy_provider_arg_vtable()),
  299. };
  300. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  301. grpc_end2end_test_fixture f =
  302. begin_test(config, "test_static_init_deny_unauthorized_request", nullptr,
  303. &server_args);
  304. grpc_authorization_policy_provider_release(provider);
  305. test_deny_unauthorized_request(f);
  306. end_test(&f);
  307. config.tear_down_data(&f);
  308. }
  309. static void test_static_init_deny_request_no_match_in_policy(
  310. grpc_end2end_test_config config) {
  311. const char* authz_policy =
  312. "{"
  313. " \"name\": \"authz\","
  314. " \"allow_rules\": ["
  315. " {"
  316. " \"name\": \"allow_bar\","
  317. " \"request\": {"
  318. " \"paths\": ["
  319. " \"*/bar\""
  320. " ]"
  321. " }"
  322. " }"
  323. " ]"
  324. "}";
  325. grpc_status_code code = GRPC_STATUS_OK;
  326. const char* error_details;
  327. grpc_authorization_policy_provider* provider =
  328. grpc_authorization_policy_provider_static_data_create(authz_policy, &code,
  329. &error_details);
  330. GPR_ASSERT(GRPC_STATUS_OK == code);
  331. grpc_arg args[] = {
  332. grpc_channel_arg_pointer_create(
  333. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  334. grpc_authorization_policy_provider_arg_vtable()),
  335. };
  336. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  337. grpc_end2end_test_fixture f =
  338. begin_test(config, "test_static_init_deny_request_no_match_in_policy",
  339. nullptr, &server_args);
  340. grpc_authorization_policy_provider_release(provider);
  341. test_deny_unauthorized_request(f);
  342. end_test(&f);
  343. config.tear_down_data(&f);
  344. }
  345. static void test_file_watcher_init_allow_authorized_request(
  346. grpc_end2end_test_config config) {
  347. const char* authz_policy =
  348. "{"
  349. " \"name\": \"authz\","
  350. " \"allow_rules\": ["
  351. " {"
  352. " \"name\": \"allow_foo\","
  353. " \"request\": {"
  354. " \"paths\": ["
  355. " \"*/foo\""
  356. " ]"
  357. " }"
  358. " }"
  359. " ]"
  360. "}";
  361. grpc_core::testing::TmpFile tmp_policy(authz_policy);
  362. grpc_status_code code = GRPC_STATUS_OK;
  363. const char* error_details;
  364. grpc_authorization_policy_provider* provider =
  365. grpc_authorization_policy_provider_file_watcher_create(
  366. tmp_policy.name().c_str(), /*refresh_interval_sec=*/1, &code,
  367. &error_details);
  368. GPR_ASSERT(GRPC_STATUS_OK == code);
  369. grpc_arg args[] = {
  370. grpc_channel_arg_pointer_create(
  371. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  372. grpc_authorization_policy_provider_arg_vtable()),
  373. };
  374. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  375. grpc_end2end_test_fixture f =
  376. begin_test(config, "test_file_watcher_init_allow_authorized_request",
  377. nullptr, &server_args);
  378. grpc_authorization_policy_provider_release(provider);
  379. test_allow_authorized_request(f);
  380. end_test(&f);
  381. config.tear_down_data(&f);
  382. }
  383. static void test_file_watcher_init_deny_unauthorized_request(
  384. grpc_end2end_test_config config) {
  385. const char* authz_policy =
  386. "{"
  387. " \"name\": \"authz\","
  388. " \"allow_rules\": ["
  389. " {"
  390. " \"name\": \"allow_bar\","
  391. " \"request\": {"
  392. " \"paths\": ["
  393. " \"*/bar\""
  394. " ]"
  395. " }"
  396. " }"
  397. " ],"
  398. " \"deny_rules\": ["
  399. " {"
  400. " \"name\": \"deny_foo\","
  401. " \"request\": {"
  402. " \"paths\": ["
  403. " \"*/foo\""
  404. " ]"
  405. " }"
  406. " }"
  407. " ]"
  408. "}";
  409. grpc_core::testing::TmpFile tmp_policy(authz_policy);
  410. grpc_status_code code = GRPC_STATUS_OK;
  411. const char* error_details;
  412. grpc_authorization_policy_provider* provider =
  413. grpc_authorization_policy_provider_file_watcher_create(
  414. tmp_policy.name().c_str(), /*refresh_interval_sec=*/1, &code,
  415. &error_details);
  416. GPR_ASSERT(GRPC_STATUS_OK == code);
  417. grpc_arg args[] = {
  418. grpc_channel_arg_pointer_create(
  419. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  420. grpc_authorization_policy_provider_arg_vtable()),
  421. };
  422. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  423. grpc_end2end_test_fixture f =
  424. begin_test(config, "test_file_watcher_init_deny_unauthorized_request",
  425. nullptr, &server_args);
  426. grpc_authorization_policy_provider_release(provider);
  427. test_deny_unauthorized_request(f);
  428. end_test(&f);
  429. config.tear_down_data(&f);
  430. }
  431. static void test_file_watcher_init_deny_request_no_match_in_policy(
  432. grpc_end2end_test_config config) {
  433. const char* authz_policy =
  434. "{"
  435. " \"name\": \"authz\","
  436. " \"allow_rules\": ["
  437. " {"
  438. " \"name\": \"allow_bar\","
  439. " \"request\": {"
  440. " \"paths\": ["
  441. " \"*/bar\""
  442. " ]"
  443. " }"
  444. " }"
  445. " ]"
  446. "}";
  447. grpc_core::testing::TmpFile tmp_policy(authz_policy);
  448. grpc_status_code code = GRPC_STATUS_OK;
  449. const char* error_details;
  450. grpc_authorization_policy_provider* provider =
  451. grpc_authorization_policy_provider_file_watcher_create(
  452. tmp_policy.name().c_str(), /*refresh_interval_sec=*/1, &code,
  453. &error_details);
  454. GPR_ASSERT(GRPC_STATUS_OK == code);
  455. grpc_arg args[] = {
  456. grpc_channel_arg_pointer_create(
  457. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  458. grpc_authorization_policy_provider_arg_vtable()),
  459. };
  460. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  461. grpc_end2end_test_fixture f = begin_test(
  462. config, "test_file_watcher_init_deny_request_no_match_in_policy", nullptr,
  463. &server_args);
  464. grpc_authorization_policy_provider_release(provider);
  465. test_deny_unauthorized_request(f);
  466. end_test(&f);
  467. config.tear_down_data(&f);
  468. }
  469. static void test_file_watcher_valid_policy_reload(
  470. grpc_end2end_test_config config) {
  471. const char* authz_policy =
  472. "{"
  473. " \"name\": \"authz\","
  474. " \"allow_rules\": ["
  475. " {"
  476. " \"name\": \"allow_foo\","
  477. " \"request\": {"
  478. " \"paths\": ["
  479. " \"*/foo\""
  480. " ]"
  481. " }"
  482. " }"
  483. " ]"
  484. "}";
  485. grpc_core::testing::TmpFile tmp_policy(authz_policy);
  486. grpc_status_code code = GRPC_STATUS_OK;
  487. const char* error_details;
  488. grpc_authorization_policy_provider* provider =
  489. grpc_authorization_policy_provider_file_watcher_create(
  490. tmp_policy.name().c_str(), /*refresh_interval_sec=*/1, &code,
  491. &error_details);
  492. GPR_ASSERT(GRPC_STATUS_OK == code);
  493. grpc_arg args[] = {
  494. grpc_channel_arg_pointer_create(
  495. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  496. grpc_authorization_policy_provider_arg_vtable()),
  497. };
  498. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  499. grpc_end2end_test_fixture f = begin_test(
  500. config, "test_file_watcher_valid_policy_reload", nullptr, &server_args);
  501. grpc_authorization_policy_provider_release(provider);
  502. test_allow_authorized_request(f);
  503. // Replace existing policy in file with a different authorization policy.
  504. authz_policy =
  505. "{"
  506. " \"name\": \"authz\","
  507. " \"allow_rules\": ["
  508. " {"
  509. " \"name\": \"allow_bar\","
  510. " \"request\": {"
  511. " \"paths\": ["
  512. " \"*/bar\""
  513. " ]"
  514. " }"
  515. " }"
  516. " ],"
  517. " \"deny_rules\": ["
  518. " {"
  519. " \"name\": \"deny_foo\","
  520. " \"request\": {"
  521. " \"paths\": ["
  522. " \"*/foo\""
  523. " ]"
  524. " }"
  525. " }"
  526. " ]"
  527. "}";
  528. tmp_policy.RewriteFile(authz_policy);
  529. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  530. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  531. test_deny_unauthorized_request(f);
  532. end_test(&f);
  533. config.tear_down_data(&f);
  534. }
  535. static void test_file_watcher_invalid_policy_skip_reload(
  536. grpc_end2end_test_config config) {
  537. const char* authz_policy =
  538. "{"
  539. " \"name\": \"authz\","
  540. " \"allow_rules\": ["
  541. " {"
  542. " \"name\": \"allow_foo\","
  543. " \"request\": {"
  544. " \"paths\": ["
  545. " \"*/foo\""
  546. " ]"
  547. " }"
  548. " }"
  549. " ]"
  550. "}";
  551. grpc_core::testing::TmpFile tmp_policy(authz_policy);
  552. grpc_status_code code = GRPC_STATUS_OK;
  553. const char* error_details;
  554. grpc_authorization_policy_provider* provider =
  555. grpc_authorization_policy_provider_file_watcher_create(
  556. tmp_policy.name().c_str(), /*refresh_interval_sec=*/1, &code,
  557. &error_details);
  558. GPR_ASSERT(GRPC_STATUS_OK == code);
  559. grpc_arg args[] = {
  560. grpc_channel_arg_pointer_create(
  561. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  562. grpc_authorization_policy_provider_arg_vtable()),
  563. };
  564. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  565. grpc_end2end_test_fixture f =
  566. begin_test(config, "test_file_watcher_invalid_policy_skip_reload",
  567. nullptr, &server_args);
  568. grpc_authorization_policy_provider_release(provider);
  569. test_allow_authorized_request(f);
  570. // Replace exisiting policy in file with an invalid policy.
  571. authz_policy = "{}";
  572. tmp_policy.RewriteFile(authz_policy);
  573. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  574. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  575. test_allow_authorized_request(f);
  576. end_test(&f);
  577. config.tear_down_data(&f);
  578. }
  579. static void test_file_watcher_recovers_from_failure(
  580. grpc_end2end_test_config config) {
  581. const char* authz_policy =
  582. "{"
  583. " \"name\": \"authz\","
  584. " \"allow_rules\": ["
  585. " {"
  586. " \"name\": \"allow_foo\","
  587. " \"request\": {"
  588. " \"paths\": ["
  589. " \"*/foo\""
  590. " ]"
  591. " }"
  592. " }"
  593. " ]"
  594. "}";
  595. grpc_core::testing::TmpFile tmp_policy(authz_policy);
  596. grpc_status_code code = GRPC_STATUS_OK;
  597. const char* error_details;
  598. grpc_authorization_policy_provider* provider =
  599. grpc_authorization_policy_provider_file_watcher_create(
  600. tmp_policy.name().c_str(), /*refresh_interval_sec=*/1, &code,
  601. &error_details);
  602. GPR_ASSERT(GRPC_STATUS_OK == code);
  603. grpc_arg args[] = {
  604. grpc_channel_arg_pointer_create(
  605. const_cast<char*>(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER), provider,
  606. grpc_authorization_policy_provider_arg_vtable()),
  607. };
  608. grpc_channel_args server_args = {GPR_ARRAY_SIZE(args), args};
  609. grpc_end2end_test_fixture f = begin_test(
  610. config, "test_file_watcher_valid_policy_reload", nullptr, &server_args);
  611. grpc_authorization_policy_provider_release(provider);
  612. test_allow_authorized_request(f);
  613. // Replace exisiting policy in file with an invalid policy.
  614. authz_policy = "{}";
  615. tmp_policy.RewriteFile(authz_policy);
  616. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  617. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  618. test_allow_authorized_request(f);
  619. // Recover from reload errors, by replacing invalid policy in file with a
  620. // valid policy.
  621. authz_policy =
  622. "{"
  623. " \"name\": \"authz\","
  624. " \"allow_rules\": ["
  625. " {"
  626. " \"name\": \"allow_bar\","
  627. " \"request\": {"
  628. " \"paths\": ["
  629. " \"*/bar\""
  630. " ]"
  631. " }"
  632. " }"
  633. " ],"
  634. " \"deny_rules\": ["
  635. " {"
  636. " \"name\": \"deny_foo\","
  637. " \"request\": {"
  638. " \"paths\": ["
  639. " \"*/foo\""
  640. " ]"
  641. " }"
  642. " }"
  643. " ]"
  644. "}";
  645. tmp_policy.RewriteFile(authz_policy);
  646. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  647. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  648. test_deny_unauthorized_request(f);
  649. end_test(&f);
  650. config.tear_down_data(&f);
  651. }
  652. void grpc_authz(grpc_end2end_test_config config) {
  653. test_static_init_allow_authorized_request(config);
  654. test_static_init_deny_unauthorized_request(config);
  655. test_static_init_deny_request_no_match_in_policy(config);
  656. test_file_watcher_init_allow_authorized_request(config);
  657. test_file_watcher_init_deny_unauthorized_request(config);
  658. test_file_watcher_init_deny_request_no_match_in_policy(config);
  659. test_file_watcher_valid_policy_reload(config);
  660. test_file_watcher_invalid_policy_skip_reload(config);
  661. test_file_watcher_recovers_from_failure(config);
  662. }
  663. void grpc_authz_pre_init(void) {}