1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include "test/cpp/interop/client_helper.h"
20
21 #include <grpc/credentials.h>
22 #include <grpc/grpc.h>
23 #include <grpc/support/alloc.h>
24 #include <grpcpp/channel.h>
25 #include <grpcpp/create_channel.h>
26 #include <grpcpp/security/credentials.h>
27
28 #include <fstream>
29 #include <memory>
30 #include <sstream>
31
32 #include "absl/flags/declare.h"
33 #include "absl/flags/flag.h"
34 #include "absl/log/check.h"
35 #include "absl/log/log.h"
36 #include "absl/strings/escaping.h"
37 #include "absl/strings/match.h"
38 #include "test/core/security/oauth2_utils.h"
39 #include "test/cpp/util/create_test_channel.h"
40 #include "test/cpp/util/test_credentials_provider.h"
41
42 ABSL_DECLARE_FLAG(std::string, custom_credentials_type);
43 ABSL_DECLARE_FLAG(std::string, default_service_account);
44 ABSL_DECLARE_FLAG(std::string, oauth_scope);
45 ABSL_DECLARE_FLAG(std::string, service_account_key_file);
46 ABSL_DECLARE_FLAG(std::string, server_host);
47 ABSL_DECLARE_FLAG(std::string, server_host_override);
48 ABSL_DECLARE_FLAG(int32_t, server_port);
49 ABSL_DECLARE_FLAG(std::string, test_case);
50 ABSL_DECLARE_FLAG(bool, use_alts);
51 ABSL_DECLARE_FLAG(bool, use_test_ca);
52 ABSL_DECLARE_FLAG(bool, use_tls);
53
54 namespace grpc {
55 namespace testing {
56
GetServiceAccountJsonKey()57 std::string GetServiceAccountJsonKey() {
58 static std::string json_key;
59 if (json_key.empty()) {
60 std::ifstream json_key_file(absl::GetFlag(FLAGS_service_account_key_file));
61 std::stringstream key_stream;
62 key_stream << json_key_file.rdbuf();
63 json_key = key_stream.str();
64 }
65 return json_key;
66 }
67
GetOauth2AccessToken()68 std::string GetOauth2AccessToken() {
69 std::shared_ptr<CallCredentials> creds = GoogleComputeEngineCredentials();
70 char* token = grpc_test_fetch_oauth2_token_with_credentials(creds->c_creds_);
71 CHECK_NE(token, nullptr);
72 LOG(INFO) << "Get raw oauth2 access token: " << token;
73 std::string access_token(token + sizeof("Bearer ") - 1);
74 gpr_free(token);
75 return access_token;
76 }
77
UpdateActions(std::unordered_map<std::string,std::function<bool ()>> *)78 void UpdateActions(
79 std::unordered_map<std::string, std::function<bool()>>* /*actions*/) {}
80
CreateChannelForTestCase(const std::string & test_case,std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> interceptor_creators,ChannelArguments channel_args)81 std::shared_ptr<Channel> CreateChannelForTestCase(
82 const std::string& test_case,
83 std::vector<
84 std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
85 interceptor_creators,
86 ChannelArguments channel_args) {
87 std::string server_uri = absl::GetFlag(FLAGS_server_host);
88 int32_t port = absl::GetFlag(FLAGS_server_port);
89 if (port != 0) {
90 absl::StrAppend(&server_uri, ":", std::to_string(port));
91 }
92 std::shared_ptr<CallCredentials> creds;
93 if (test_case == "compute_engine_creds") {
94 creds = absl::GetFlag(FLAGS_custom_credentials_type) ==
95 "google_default_credentials"
96 ? nullptr
97 : GoogleComputeEngineCredentials();
98 } else if (test_case == "jwt_token_creds") {
99 std::string json_key = GetServiceAccountJsonKey();
100 std::chrono::seconds token_lifetime = std::chrono::hours(1);
101 creds = absl::GetFlag(FLAGS_custom_credentials_type) ==
102 "google_default_credentials"
103 ? nullptr
104 : ServiceAccountJWTAccessCredentials(json_key,
105 token_lifetime.count());
106 } else if (test_case == "oauth2_auth_token") {
107 creds = absl::GetFlag(FLAGS_custom_credentials_type) ==
108 "google_default_credentials"
109 ? nullptr
110 : AccessTokenCredentials(GetOauth2AccessToken());
111 } else if (test_case == "pick_first_unary") {
112 // allow the LB policy to be configured with service config
113 channel_args.SetInt(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, 0);
114 return CreateTestChannel(
115 server_uri, absl::GetFlag(FLAGS_custom_credentials_type),
116 absl::GetFlag(FLAGS_server_host_override),
117 !absl::GetFlag(FLAGS_use_test_ca), creds, channel_args);
118 }
119 if (absl::GetFlag(FLAGS_custom_credentials_type).empty()) {
120 transport_security security_type =
121 absl::GetFlag(FLAGS_use_alts)
122 ? ALTS
123 : (absl::GetFlag(FLAGS_use_tls) ? TLS : INSECURE);
124 return CreateTestChannel(
125 server_uri, absl::GetFlag(FLAGS_server_host_override), security_type,
126 !absl::GetFlag(FLAGS_use_test_ca), creds, channel_args,
127 std::move(interceptor_creators));
128 } else {
129 if (interceptor_creators.empty()) {
130 return CreateTestChannel(server_uri,
131 absl::GetFlag(FLAGS_custom_credentials_type), "",
132 false, creds, channel_args);
133 } else {
134 return CreateTestChannel(
135 server_uri, absl::GetFlag(FLAGS_custom_credentials_type), creds,
136 std::move(interceptor_creators), channel_args);
137 }
138 }
139 }
140
log_metadata_entry(const std::string & prefix,const grpc::string_ref & key,const grpc::string_ref & value)141 static void log_metadata_entry(const std::string& prefix,
142 const grpc::string_ref& key,
143 const grpc::string_ref& value) {
144 std::string key_str(key.begin(), key.end());
145 std::string value_str(value.begin(), value.end());
146 if (absl::EndsWith(key_str, "-bin")) {
147 value_str = absl::Base64Escape(value_str);
148 }
149 LOG(ERROR) << prefix << " " << key_str << ": " << value_str;
150 }
151
Intercept(experimental::InterceptorBatchMethods * methods)152 void MetadataAndStatusLoggerInterceptor::Intercept(
153 experimental::InterceptorBatchMethods* methods) {
154 if (methods->QueryInterceptionHookPoint(
155 experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) {
156 auto initial_metadata = methods->GetRecvInitialMetadata();
157
158 for (const auto& entry : *initial_metadata) {
159 log_metadata_entry("GRPC_INITIAL_METADATA", entry.first, entry.second);
160 }
161 }
162
163 if (methods->QueryInterceptionHookPoint(
164 experimental::InterceptionHookPoints::POST_RECV_STATUS)) {
165 auto trailing_metadata = methods->GetRecvTrailingMetadata();
166 for (const auto& entry : *trailing_metadata) {
167 log_metadata_entry("GRPC_TRAILING_METADATA", entry.first, entry.second);
168 }
169
170 auto status = methods->GetRecvStatus();
171 LOG(ERROR) << "GRPC_STATUS " << status->error_code();
172 LOG(ERROR) << "GRPC_ERROR_MESSAGE " << status->error_message();
173 }
174
175 methods->Proceed();
176 }
177
178 } // namespace testing
179 } // namespace grpc
180