grpc_authz_end2end_test.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  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 <gmock/gmock.h>
  15. #include <gtest/gtest.h>
  16. #include <grpcpp/channel.h>
  17. #include <grpcpp/client_context.h>
  18. #include <grpcpp/create_channel.h>
  19. #include <grpcpp/security/authorization_policy_provider.h>
  20. #include <grpcpp/server.h>
  21. #include <grpcpp/server_builder.h>
  22. #include "src/core/lib/iomgr/load_file.h"
  23. #include "src/core/lib/security/credentials/fake/fake_credentials.h"
  24. #include "src/cpp/client/secure_credentials.h"
  25. #include "src/cpp/server/secure_server_credentials.h"
  26. #include "src/proto/grpc/testing/echo.grpc.pb.h"
  27. #include "test/core/util/port.h"
  28. #include "test/core/util/test_config.h"
  29. #include "test/core/util/tls_utils.h"
  30. #include "test/cpp/end2end/test_service_impl.h"
  31. namespace grpc {
  32. namespace testing {
  33. namespace {
  34. constexpr char kCaCertPath[] = "src/core/tsi/test_creds/ca.pem";
  35. constexpr char kServerCertPath[] = "src/core/tsi/test_creds/server1.pem";
  36. constexpr char kServerKeyPath[] = "src/core/tsi/test_creds/server1.key";
  37. constexpr char kClientCertPath[] = "src/core/tsi/test_creds/client.pem";
  38. constexpr char kClientKeyPath[] = "src/core/tsi/test_creds/client.key";
  39. constexpr char kMessage[] = "Hello";
  40. std::string ReadFile(const char* file_path) {
  41. grpc_slice slice;
  42. GPR_ASSERT(
  43. GRPC_LOG_IF_ERROR("load_file", grpc_load_file(file_path, 0, &slice)));
  44. std::string file_contents(grpc_core::StringViewFromSlice(slice));
  45. grpc_slice_unref(slice);
  46. return file_contents;
  47. }
  48. class GrpcAuthzEnd2EndTest : public ::testing::Test {
  49. protected:
  50. GrpcAuthzEnd2EndTest()
  51. : server_address_(
  52. absl::StrCat("localhost:", grpc_pick_unused_port_or_die())) {
  53. std::string root_cert = ReadFile(kCaCertPath);
  54. std::string identity_cert = ReadFile(kServerCertPath);
  55. std::string private_key = ReadFile(kServerKeyPath);
  56. std::vector<experimental::IdentityKeyCertPair>
  57. server_identity_key_cert_pairs = {{private_key, identity_cert}};
  58. grpc::experimental::TlsServerCredentialsOptions server_options(
  59. std::make_shared<grpc::experimental::StaticDataCertificateProvider>(
  60. root_cert, server_identity_key_cert_pairs));
  61. server_options.watch_root_certs();
  62. server_options.watch_identity_key_cert_pairs();
  63. server_options.set_cert_request_type(
  64. GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY);
  65. server_creds_ = grpc::experimental::TlsServerCredentials(server_options);
  66. std::vector<experimental::IdentityKeyCertPair>
  67. channel_identity_key_cert_pairs = {
  68. {ReadFile(kClientKeyPath), ReadFile(kClientCertPath)}};
  69. grpc::experimental::TlsChannelCredentialsOptions channel_options;
  70. channel_options.set_certificate_provider(
  71. std::make_shared<grpc::experimental::StaticDataCertificateProvider>(
  72. ReadFile(kCaCertPath), channel_identity_key_cert_pairs));
  73. channel_options.watch_identity_key_cert_pairs();
  74. channel_options.watch_root_certs();
  75. channel_creds_ = grpc::experimental::TlsCredentials(channel_options);
  76. }
  77. ~GrpcAuthzEnd2EndTest() override { server_->Shutdown(); }
  78. // Replaces existing credentials with insecure credentials.
  79. void UseInsecureCredentials() {
  80. server_creds_ = InsecureServerCredentials();
  81. channel_creds_ = InsecureChannelCredentials();
  82. }
  83. // Creates server with gRPC authorization enabled when provider is not null.
  84. void InitServer(
  85. std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
  86. provider) {
  87. ServerBuilder builder;
  88. builder.AddListeningPort(server_address_, std::move(server_creds_));
  89. builder.experimental().SetAuthorizationPolicyProvider(std::move(provider));
  90. builder.RegisterService(&service_);
  91. server_ = builder.BuildAndStart();
  92. }
  93. std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
  94. CreateStaticAuthzPolicyProvider(const std::string& policy) {
  95. grpc::Status status;
  96. auto provider = experimental::StaticDataAuthorizationPolicyProvider::Create(
  97. policy, &status);
  98. EXPECT_TRUE(status.ok());
  99. return provider;
  100. }
  101. std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
  102. CreateFileWatcherAuthzPolicyProvider(const std::string& policy_path,
  103. unsigned int refresh_interval_sec) {
  104. grpc::Status status;
  105. auto provider =
  106. experimental::FileWatcherAuthorizationPolicyProvider::Create(
  107. policy_path, refresh_interval_sec, &status);
  108. EXPECT_TRUE(status.ok());
  109. return provider;
  110. }
  111. std::shared_ptr<Channel> BuildChannel() {
  112. ChannelArguments args;
  113. // Override target name for host name check
  114. args.SetSslTargetNameOverride("foo.test.google.fr");
  115. return grpc::CreateCustomChannel(server_address_, channel_creds_, args);
  116. }
  117. grpc::Status SendRpc(const std::shared_ptr<Channel>& channel,
  118. ClientContext* context,
  119. grpc::testing::EchoResponse* response = nullptr) {
  120. auto stub = grpc::testing::EchoTestService::NewStub(channel);
  121. grpc::testing::EchoRequest request;
  122. request.set_message(kMessage);
  123. return stub->Echo(context, request, response);
  124. }
  125. std::string server_address_;
  126. TestServiceImpl service_;
  127. std::unique_ptr<Server> server_;
  128. std::shared_ptr<ServerCredentials> server_creds_;
  129. std::shared_ptr<ChannelCredentials> channel_creds_;
  130. };
  131. TEST_F(GrpcAuthzEnd2EndTest,
  132. StaticInitAllowsRpcRequestNoMatchInDenyMatchInAllow) {
  133. std::string policy =
  134. "{"
  135. " \"name\": \"authz\","
  136. " \"allow_rules\": ["
  137. " {"
  138. " \"name\": \"allow_echo\","
  139. " \"request\": {"
  140. " \"paths\": ["
  141. " \"*/Echo\""
  142. " ],"
  143. " \"headers\": ["
  144. " {"
  145. " \"key\": \"key-foo\","
  146. " \"values\": [\"foo1\", \"foo2\"]"
  147. " },"
  148. " {"
  149. " \"key\": \"key-bar\","
  150. " \"values\": [\"bar1\"]"
  151. " }"
  152. " ]"
  153. " }"
  154. " }"
  155. " ],"
  156. " \"deny_rules\": ["
  157. " {"
  158. " \"name\": \"deny_clientstreamingecho\","
  159. " \"request\": {"
  160. " \"paths\": ["
  161. " \"*/ClientStreamingEcho\""
  162. " ]"
  163. " }"
  164. " }"
  165. " ]"
  166. "}";
  167. InitServer(CreateStaticAuthzPolicyProvider(policy));
  168. auto channel = BuildChannel();
  169. ClientContext context;
  170. context.AddMetadata("key-foo", "foo2");
  171. context.AddMetadata("key-bar", "bar1");
  172. context.AddMetadata("key-baz", "baz1");
  173. grpc::testing::EchoResponse resp;
  174. grpc::Status status = SendRpc(channel, &context, &resp);
  175. EXPECT_TRUE(status.ok());
  176. EXPECT_EQ(resp.message(), kMessage);
  177. }
  178. TEST_F(GrpcAuthzEnd2EndTest, StaticInitDeniesRpcRequestNoMatchInAllowAndDeny) {
  179. std::string policy =
  180. "{"
  181. " \"name\": \"authz\","
  182. " \"allow_rules\": ["
  183. " {"
  184. " \"name\": \"allow_foo\","
  185. " \"request\": {"
  186. " \"paths\": ["
  187. " \"*/foo\""
  188. " ]"
  189. " }"
  190. " }"
  191. " ],"
  192. " \"deny_rules\": ["
  193. " {"
  194. " \"name\": \"deny_bar\","
  195. " \"source\": {"
  196. " \"principals\": ["
  197. " \"bar\""
  198. " ]"
  199. " }"
  200. " }"
  201. " ]"
  202. "}";
  203. InitServer(CreateStaticAuthzPolicyProvider(policy));
  204. auto channel = BuildChannel();
  205. ClientContext context;
  206. grpc::testing::EchoResponse resp;
  207. grpc::Status status = SendRpc(channel, &context, &resp);
  208. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  209. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  210. EXPECT_TRUE(resp.message().empty());
  211. }
  212. TEST_F(GrpcAuthzEnd2EndTest,
  213. StaticInitDeniesRpcRequestMatchInDenyMatchInAllow) {
  214. std::string policy =
  215. "{"
  216. " \"name\": \"authz\","
  217. " \"allow_rules\": ["
  218. " {"
  219. " \"name\": \"allow_all\""
  220. " }"
  221. " ],"
  222. " \"deny_rules\": ["
  223. " {"
  224. " \"name\": \"deny_echo\","
  225. " \"request\": {"
  226. " \"paths\": ["
  227. " \"*/Echo\""
  228. " ]"
  229. " }"
  230. " }"
  231. " ]"
  232. "}";
  233. InitServer(CreateStaticAuthzPolicyProvider(policy));
  234. auto channel = BuildChannel();
  235. ClientContext context;
  236. grpc::testing::EchoResponse resp;
  237. grpc::Status status = SendRpc(channel, &context, &resp);
  238. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  239. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  240. EXPECT_TRUE(resp.message().empty());
  241. }
  242. TEST_F(GrpcAuthzEnd2EndTest,
  243. StaticInitDeniesRpcRequestMatchInDenyNoMatchInAllow) {
  244. std::string policy =
  245. "{"
  246. " \"name\": \"authz\","
  247. " \"allow_rules\": ["
  248. " {"
  249. " \"name\": \"allow_clientstreamingecho\","
  250. " \"request\": {"
  251. " \"paths\": ["
  252. " \"*/ClientStreamingEcho\""
  253. " ]"
  254. " }"
  255. " }"
  256. " ],"
  257. " \"deny_rules\": ["
  258. " {"
  259. " \"name\": \"deny_echo\","
  260. " \"request\": {"
  261. " \"paths\": ["
  262. " \"*/Echo\""
  263. " ]"
  264. " }"
  265. " }"
  266. " ]"
  267. "}";
  268. InitServer(CreateStaticAuthzPolicyProvider(policy));
  269. auto channel = BuildChannel();
  270. ClientContext context;
  271. grpc::testing::EchoResponse resp;
  272. grpc::Status status = SendRpc(channel, &context, &resp);
  273. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  274. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  275. EXPECT_TRUE(resp.message().empty());
  276. }
  277. TEST_F(GrpcAuthzEnd2EndTest, StaticInitAllowsRpcRequestEmptyDenyMatchInAllow) {
  278. std::string policy =
  279. "{"
  280. " \"name\": \"authz\","
  281. " \"allow_rules\": ["
  282. " {"
  283. " \"name\": \"allow_echo\","
  284. " \"request\": {"
  285. " \"paths\": ["
  286. " \"*\""
  287. " ],"
  288. " \"headers\": ["
  289. " {"
  290. " \"key\": \"key-foo\","
  291. " \"values\": [\"foo1\", \"foo2\"]"
  292. " },"
  293. " {"
  294. " \"key\": \"key-bar\","
  295. " \"values\": [\"bar1\"]"
  296. " }"
  297. " ]"
  298. " }"
  299. " }"
  300. " ]"
  301. "}";
  302. InitServer(CreateStaticAuthzPolicyProvider(policy));
  303. auto channel = BuildChannel();
  304. ClientContext context;
  305. context.AddMetadata("key-foo", "foo2");
  306. context.AddMetadata("key-bar", "bar1");
  307. context.AddMetadata("key-baz", "baz1");
  308. grpc::testing::EchoResponse resp;
  309. grpc::Status status = SendRpc(channel, &context, &resp);
  310. EXPECT_TRUE(status.ok());
  311. EXPECT_EQ(resp.message(), kMessage);
  312. }
  313. TEST_F(GrpcAuthzEnd2EndTest,
  314. StaticInitDeniesRpcRequestEmptyDenyNoMatchInAllow) {
  315. std::string policy =
  316. "{"
  317. " \"name\": \"authz\","
  318. " \"allow_rules\": ["
  319. " {"
  320. " \"name\": \"allow_echo\","
  321. " \"request\": {"
  322. " \"paths\": ["
  323. " \"*/Echo\""
  324. " ],"
  325. " \"headers\": ["
  326. " {"
  327. " \"key\": \"key-foo\","
  328. " \"values\": [\"foo1\"]"
  329. " }"
  330. " ]"
  331. " }"
  332. " }"
  333. " ]"
  334. "}";
  335. InitServer(CreateStaticAuthzPolicyProvider(policy));
  336. auto channel = BuildChannel();
  337. ClientContext context;
  338. context.AddMetadata("key-bar", "bar1");
  339. grpc::testing::EchoResponse resp;
  340. grpc::Status status = SendRpc(channel, &context, &resp);
  341. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  342. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  343. EXPECT_TRUE(resp.message().empty());
  344. }
  345. TEST_F(
  346. GrpcAuthzEnd2EndTest,
  347. StaticInitDeniesRpcRequestWithPrincipalsFieldOnUnauthenticatedConnection) {
  348. std::string policy =
  349. "{"
  350. " \"name\": \"authz\","
  351. " \"allow_rules\": ["
  352. " {"
  353. " \"name\": \"allow_mtls\","
  354. " \"source\": {"
  355. " \"principals\": [\"*\"]"
  356. " }"
  357. " }"
  358. " ]"
  359. "}";
  360. UseInsecureCredentials();
  361. InitServer(CreateStaticAuthzPolicyProvider(policy));
  362. auto channel = BuildChannel();
  363. ClientContext context;
  364. grpc::testing::EchoResponse resp;
  365. grpc::Status status = SendRpc(channel, &context, &resp);
  366. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  367. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  368. EXPECT_TRUE(resp.message().empty());
  369. }
  370. TEST_F(GrpcAuthzEnd2EndTest,
  371. StaticInitAllowsRpcRequestWithPrincipalsFieldOnAuthenticatedConnection) {
  372. std::string policy =
  373. "{"
  374. " \"name\": \"authz\","
  375. " \"allow_rules\": ["
  376. " {"
  377. " \"name\": \"allow_mtls\","
  378. " \"source\": {"
  379. " \"principals\": [\"*\"]"
  380. " }"
  381. " }"
  382. " ]"
  383. "}";
  384. InitServer(CreateStaticAuthzPolicyProvider(policy));
  385. auto channel = BuildChannel();
  386. ClientContext context;
  387. grpc::testing::EchoResponse resp;
  388. grpc::Status status = SendRpc(channel, &context, &resp);
  389. EXPECT_TRUE(status.ok());
  390. EXPECT_EQ(resp.message(), kMessage);
  391. }
  392. TEST_F(GrpcAuthzEnd2EndTest,
  393. FileWatcherInitAllowsRpcRequestNoMatchInDenyMatchInAllow) {
  394. std::string policy =
  395. "{"
  396. " \"name\": \"authz\","
  397. " \"allow_rules\": ["
  398. " {"
  399. " \"name\": \"allow_echo\","
  400. " \"request\": {"
  401. " \"paths\": ["
  402. " \"*/Echo\""
  403. " ],"
  404. " \"headers\": ["
  405. " {"
  406. " \"key\": \"key-foo\","
  407. " \"values\": [\"foo1\", \"foo2\"]"
  408. " },"
  409. " {"
  410. " \"key\": \"key-bar\","
  411. " \"values\": [\"bar1\"]"
  412. " }"
  413. " ]"
  414. " }"
  415. " }"
  416. " ],"
  417. " \"deny_rules\": ["
  418. " {"
  419. " \"name\": \"deny_clientstreamingecho\","
  420. " \"request\": {"
  421. " \"paths\": ["
  422. " \"*/ClientStreamingEcho\""
  423. " ]"
  424. " }"
  425. " }"
  426. " ]"
  427. "}";
  428. grpc_core::testing::TmpFile tmp_policy(policy);
  429. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5));
  430. auto channel = BuildChannel();
  431. ClientContext context;
  432. context.AddMetadata("key-foo", "foo2");
  433. context.AddMetadata("key-bar", "bar1");
  434. context.AddMetadata("key-baz", "baz1");
  435. grpc::testing::EchoResponse resp;
  436. grpc::Status status = SendRpc(channel, &context, &resp);
  437. EXPECT_TRUE(status.ok());
  438. EXPECT_EQ(resp.message(), kMessage);
  439. }
  440. TEST_F(GrpcAuthzEnd2EndTest,
  441. FileWatcherInitDeniesRpcRequestNoMatchInAllowAndDeny) {
  442. std::string policy =
  443. "{"
  444. " \"name\": \"authz\","
  445. " \"allow_rules\": ["
  446. " {"
  447. " \"name\": \"allow_foo\","
  448. " \"request\": {"
  449. " \"paths\": ["
  450. " \"*/foo\""
  451. " ]"
  452. " }"
  453. " }"
  454. " ],"
  455. " \"deny_rules\": ["
  456. " {"
  457. " \"name\": \"deny_bar\","
  458. " \"source\": {"
  459. " \"principals\": ["
  460. " \"bar\""
  461. " ]"
  462. " }"
  463. " }"
  464. " ]"
  465. "}";
  466. grpc_core::testing::TmpFile tmp_policy(policy);
  467. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5));
  468. auto channel = BuildChannel();
  469. ClientContext context;
  470. grpc::testing::EchoResponse resp;
  471. grpc::Status status = SendRpc(channel, &context, &resp);
  472. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  473. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  474. EXPECT_TRUE(resp.message().empty());
  475. }
  476. TEST_F(GrpcAuthzEnd2EndTest,
  477. FileWatcherInitDeniesRpcRequestMatchInDenyMatchInAllow) {
  478. std::string policy =
  479. "{"
  480. " \"name\": \"authz\","
  481. " \"allow_rules\": ["
  482. " {"
  483. " \"name\": \"allow_all\""
  484. " }"
  485. " ],"
  486. " \"deny_rules\": ["
  487. " {"
  488. " \"name\": \"deny_echo\","
  489. " \"request\": {"
  490. " \"paths\": ["
  491. " \"*/Echo\""
  492. " ]"
  493. " }"
  494. " }"
  495. " ]"
  496. "}";
  497. grpc_core::testing::TmpFile tmp_policy(policy);
  498. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5));
  499. auto channel = BuildChannel();
  500. ClientContext context;
  501. grpc::testing::EchoResponse resp;
  502. grpc::Status status = SendRpc(channel, &context, &resp);
  503. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  504. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  505. EXPECT_TRUE(resp.message().empty());
  506. }
  507. TEST_F(GrpcAuthzEnd2EndTest,
  508. FileWatcherInitDeniesRpcRequestMatchInDenyNoMatchInAllow) {
  509. std::string policy =
  510. "{"
  511. " \"name\": \"authz\","
  512. " \"allow_rules\": ["
  513. " {"
  514. " \"name\": \"allow_clientstreamingecho\","
  515. " \"request\": {"
  516. " \"paths\": ["
  517. " \"*/ClientStreamingEcho\""
  518. " ]"
  519. " }"
  520. " }"
  521. " ],"
  522. " \"deny_rules\": ["
  523. " {"
  524. " \"name\": \"deny_echo\","
  525. " \"request\": {"
  526. " \"paths\": ["
  527. " \"*/Echo\""
  528. " ]"
  529. " }"
  530. " }"
  531. " ]"
  532. "}";
  533. grpc_core::testing::TmpFile tmp_policy(policy);
  534. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5));
  535. auto channel = BuildChannel();
  536. ClientContext context;
  537. grpc::testing::EchoResponse resp;
  538. grpc::Status status = SendRpc(channel, &context, &resp);
  539. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  540. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  541. EXPECT_TRUE(resp.message().empty());
  542. }
  543. TEST_F(GrpcAuthzEnd2EndTest,
  544. FileWatcherInitAllowsRpcRequestEmptyDenyMatchInAllow) {
  545. std::string policy =
  546. "{"
  547. " \"name\": \"authz\","
  548. " \"allow_rules\": ["
  549. " {"
  550. " \"name\": \"allow_echo\","
  551. " \"request\": {"
  552. " \"paths\": ["
  553. " \"*/Echo\""
  554. " ],"
  555. " \"headers\": ["
  556. " {"
  557. " \"key\": \"key-foo\","
  558. " \"values\": [\"foo1\", \"foo2\"]"
  559. " },"
  560. " {"
  561. " \"key\": \"key-bar\","
  562. " \"values\": [\"bar1\"]"
  563. " }"
  564. " ]"
  565. " }"
  566. " }"
  567. " ]"
  568. "}";
  569. grpc_core::testing::TmpFile tmp_policy(policy);
  570. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5));
  571. auto channel = BuildChannel();
  572. ClientContext context;
  573. context.AddMetadata("key-foo", "foo2");
  574. context.AddMetadata("key-bar", "bar1");
  575. context.AddMetadata("key-baz", "baz1");
  576. grpc::testing::EchoResponse resp;
  577. grpc::Status status = SendRpc(channel, &context, &resp);
  578. EXPECT_TRUE(status.ok());
  579. EXPECT_EQ(resp.message(), kMessage);
  580. }
  581. TEST_F(GrpcAuthzEnd2EndTest,
  582. FileWatcherInitDeniesRpcRequestEmptyDenyNoMatchInAllow) {
  583. std::string policy =
  584. "{"
  585. " \"name\": \"authz\","
  586. " \"allow_rules\": ["
  587. " {"
  588. " \"name\": \"allow_echo\","
  589. " \"request\": {"
  590. " \"paths\": ["
  591. " \"*/Echo\""
  592. " ],"
  593. " \"headers\": ["
  594. " {"
  595. " \"key\": \"key-foo\","
  596. " \"values\": [\"foo1\"]"
  597. " }"
  598. " ]"
  599. " }"
  600. " }"
  601. " ]"
  602. "}";
  603. grpc_core::testing::TmpFile tmp_policy(policy);
  604. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5));
  605. auto channel = BuildChannel();
  606. ClientContext context;
  607. context.AddMetadata("key-bar", "bar1");
  608. grpc::testing::EchoResponse resp;
  609. grpc::Status status = SendRpc(channel, &context, &resp);
  610. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  611. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  612. EXPECT_TRUE(resp.message().empty());
  613. }
  614. TEST_F(GrpcAuthzEnd2EndTest, FileWatcherValidPolicyRefresh) {
  615. std::string policy =
  616. "{"
  617. " \"name\": \"authz\","
  618. " \"allow_rules\": ["
  619. " {"
  620. " \"name\": \"allow_echo\","
  621. " \"request\": {"
  622. " \"paths\": ["
  623. " \"*/Echo\""
  624. " ]"
  625. " }"
  626. " }"
  627. " ]"
  628. "}";
  629. grpc_core::testing::TmpFile tmp_policy(policy);
  630. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 1));
  631. auto channel = BuildChannel();
  632. ClientContext context1;
  633. grpc::testing::EchoResponse resp1;
  634. grpc::Status status = SendRpc(channel, &context1, &resp1);
  635. EXPECT_TRUE(status.ok());
  636. EXPECT_EQ(resp1.message(), kMessage);
  637. // Replace the existing policy with a new authorization policy.
  638. policy =
  639. "{"
  640. " \"name\": \"authz\","
  641. " \"allow_rules\": ["
  642. " {"
  643. " \"name\": \"allow_foo\","
  644. " \"request\": {"
  645. " \"paths\": ["
  646. " \"*/foo\""
  647. " ]"
  648. " }"
  649. " }"
  650. " ],"
  651. " \"deny_rules\": ["
  652. " {"
  653. " \"name\": \"deny_echo\","
  654. " \"request\": {"
  655. " \"paths\": ["
  656. " \"*/Echo\""
  657. " ]"
  658. " }"
  659. " }"
  660. " ]"
  661. "}";
  662. tmp_policy.RewriteFile(policy);
  663. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  664. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  665. ClientContext context2;
  666. grpc::testing::EchoResponse resp2;
  667. status = SendRpc(channel, &context2, &resp2);
  668. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  669. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  670. EXPECT_TRUE(resp2.message().empty());
  671. }
  672. TEST_F(GrpcAuthzEnd2EndTest, FileWatcherInvalidPolicyRefreshSkipsReload) {
  673. std::string policy =
  674. "{"
  675. " \"name\": \"authz\","
  676. " \"allow_rules\": ["
  677. " {"
  678. " \"name\": \"allow_echo\","
  679. " \"request\": {"
  680. " \"paths\": ["
  681. " \"*/Echo\""
  682. " ]"
  683. " }"
  684. " }"
  685. " ]"
  686. "}";
  687. grpc_core::testing::TmpFile tmp_policy(policy);
  688. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 1));
  689. auto channel = BuildChannel();
  690. ClientContext context1;
  691. grpc::testing::EchoResponse resp1;
  692. grpc::Status status = SendRpc(channel, &context1, &resp1);
  693. EXPECT_TRUE(status.ok());
  694. EXPECT_EQ(resp1.message(), kMessage);
  695. // Replaces existing policy with an invalid authorization policy.
  696. policy = "{}";
  697. tmp_policy.RewriteFile(policy);
  698. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  699. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  700. ClientContext context2;
  701. grpc::testing::EchoResponse resp2;
  702. status = SendRpc(channel, &context2, &resp2);
  703. EXPECT_TRUE(status.ok());
  704. EXPECT_EQ(resp2.message(), kMessage);
  705. }
  706. TEST_F(GrpcAuthzEnd2EndTest, FileWatcherRecoversFromFailure) {
  707. std::string policy =
  708. "{"
  709. " \"name\": \"authz\","
  710. " \"allow_rules\": ["
  711. " {"
  712. " \"name\": \"allow_echo\","
  713. " \"request\": {"
  714. " \"paths\": ["
  715. " \"*/Echo\""
  716. " ]"
  717. " }"
  718. " }"
  719. " ]"
  720. "}";
  721. grpc_core::testing::TmpFile tmp_policy(policy);
  722. InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 1));
  723. auto channel = BuildChannel();
  724. ClientContext context1;
  725. grpc::testing::EchoResponse resp1;
  726. grpc::Status status = SendRpc(channel, &context1, &resp1);
  727. EXPECT_TRUE(status.ok());
  728. EXPECT_EQ(resp1.message(), kMessage);
  729. // Replaces existing policy with an invalid authorization policy.
  730. policy = "{}";
  731. tmp_policy.RewriteFile(policy);
  732. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  733. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  734. ClientContext context2;
  735. grpc::testing::EchoResponse resp2;
  736. status = SendRpc(channel, &context2, &resp2);
  737. EXPECT_TRUE(status.ok());
  738. EXPECT_EQ(resp2.message(), kMessage);
  739. // Replace the existing invalid policy with a valid authorization policy.
  740. policy =
  741. "{"
  742. " \"name\": \"authz\","
  743. " \"allow_rules\": ["
  744. " {"
  745. " \"name\": \"allow_foo\","
  746. " \"request\": {"
  747. " \"paths\": ["
  748. " \"*/foo\""
  749. " ]"
  750. " }"
  751. " }"
  752. " ],"
  753. " \"deny_rules\": ["
  754. " {"
  755. " \"name\": \"deny_echo\","
  756. " \"request\": {"
  757. " \"paths\": ["
  758. " \"*/Echo\""
  759. " ]"
  760. " }"
  761. " }"
  762. " ]"
  763. "}";
  764. tmp_policy.RewriteFile(policy);
  765. // Wait 2 seconds for the provider's refresh thread to read the updated files.
  766. gpr_sleep_until(grpc_timeout_seconds_to_deadline(2));
  767. ClientContext context3;
  768. grpc::testing::EchoResponse resp3;
  769. status = SendRpc(channel, &context3, &resp3);
  770. EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED);
  771. EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected.");
  772. EXPECT_TRUE(resp3.message().empty());
  773. }
  774. } // namespace
  775. } // namespace testing
  776. } // namespace grpc
  777. int main(int argc, char** argv) {
  778. ::testing::InitGoogleTest(&argc, argv);
  779. grpc::testing::TestEnvironment env(argc, argv);
  780. const auto result = RUN_ALL_TESTS();
  781. return result;
  782. }