url_external_account_credentials.cc
Go to the documentation of this file.
1 //
2 // Copyright 2020 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
17 
19 
20 #include <string.h>
21 
22 #include <memory>
23 #include <utility>
24 
25 #include "absl/status/status.h"
26 #include "absl/status/statusor.h"
27 #include "absl/strings/str_cat.h"
28 #include "absl/strings/str_format.h"
29 #include "absl/strings/str_split.h"
30 #include "absl/strings/string_view.h"
31 
32 #include <grpc/grpc.h>
33 #include <grpc/grpc_security.h>
34 #include <grpc/support/alloc.h>
35 #include <grpc/support/log.h>
37 
41 #include "src/core/lib/json/json.h"
44 
45 namespace grpc_core {
46 
47 RefCountedPtr<UrlExternalAccountCredentials>
49  std::vector<std::string> scopes,
51  auto creds = MakeRefCounted<UrlExternalAccountCredentials>(
52  std::move(options), std::move(scopes), error);
53  if (GRPC_ERROR_IS_NONE(*error)) {
54  return creds;
55  } else {
56  return nullptr;
57  }
58 }
59 
61  Options options, std::vector<std::string> scopes, grpc_error_handle* error)
63  auto it = options.credential_source.object_value().find("url");
64  if (it == options.credential_source.object_value().end()) {
65  *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("url field not present.");
66  return;
67  }
68  if (it->second.type() != Json::Type::STRING) {
69  *error =
70  GRPC_ERROR_CREATE_FROM_STATIC_STRING("url field must be a string.");
71  return;
72  }
73  absl::StatusOr<URI> tmp_url = URI::Parse(it->second.string_value());
74  if (!tmp_url.ok()) {
76  absl::StrFormat("Invalid credential source url. Error: %s",
77  tmp_url.status().ToString()));
78  return;
79  }
80  url_ = *tmp_url;
81  // The url must follow the format of <scheme>://<authority>/<path>
82  std::vector<absl::string_view> v =
83  absl::StrSplit(it->second.string_value(), absl::MaxSplits('/', 3));
84  url_full_path_ = absl::StrCat("/", v[3]);
85  it = options.credential_source.object_value().find("headers");
86  if (it != options.credential_source.object_value().end()) {
87  if (it->second.type() != Json::Type::OBJECT) {
89  "The JSON value of credential source headers is not an object.");
90  return;
91  }
92  for (auto const& header : it->second.object_value()) {
93  headers_[header.first] = header.second.string_value();
94  }
95  }
96  it = options.credential_source.object_value().find("format");
97  if (it != options.credential_source.object_value().end()) {
98  const Json& format_json = it->second;
99  if (format_json.type() != Json::Type::OBJECT) {
101  "The JSON value of credential source format is not an object.");
102  return;
103  }
104  auto format_it = format_json.object_value().find("type");
105  if (format_it == format_json.object_value().end()) {
107  "format.type field not present.");
108  return;
109  }
110  if (format_it->second.type() != Json::Type::STRING) {
112  "format.type field must be a string.");
113  return;
114  }
115  format_type_ = format_it->second.string_value();
116  if (format_type_ == "json") {
117  format_it = format_json.object_value().find("subject_token_field_name");
118  if (format_it == format_json.object_value().end()) {
120  "format.subject_token_field_name field must be present if the "
121  "format is in Json.");
122  return;
123  }
124  if (format_it->second.type() != Json::Type::STRING) {
126  "format.subject_token_field_name field must be a string.");
127  return;
128  }
129  format_subject_token_field_name_ = format_it->second.string_value();
130  }
131  }
132 }
133 
135  HTTPRequestContext* ctx, const Options& /*options*/,
137  if (ctx == nullptr) {
139  "",
141  "Missing HTTPRequestContext to start subject token retrieval."));
142  return;
143  }
144  auto url_for_request =
146  {} /* query params */, "" /* fragment */);
147  if (!url_for_request.ok()) {
149  "", absl_status_to_grpc_error(url_for_request.status()));
150  return;
151  }
152  ctx_ = ctx;
153  cb_ = cb;
155  memset(&request, 0, sizeof(grpc_http_request));
156  request.path = gpr_strdup(url_full_path_.c_str());
157  grpc_http_header* headers = nullptr;
158  request.hdr_count = headers_.size();
159  headers = static_cast<grpc_http_header*>(
160  gpr_malloc(sizeof(grpc_http_header) * request.hdr_count));
161  int i = 0;
162  for (auto const& header : headers_) {
163  headers[i].key = gpr_strdup(header.first.c_str());
164  headers[i].value = gpr_strdup(header.second.c_str());
165  ++i;
166  }
167  request.hdrs = headers;
169  ctx_->response = {};
171  GPR_ASSERT(http_request_ == nullptr);
172  RefCountedPtr<grpc_channel_credentials> http_request_creds;
173  if (url_.scheme() == "http") {
174  http_request_creds = RefCountedPtr<grpc_channel_credentials>(
176  } else {
177  http_request_creds = RefCountedPtr<grpc_channel_credentials>(
179  }
180  http_request_ =
181  HttpRequest::Get(std::move(*url_for_request), nullptr /* channel args */,
183  &ctx_->response, std::move(http_request_creds));
184  http_request_->Start();
186 }
187 
189  void* arg, grpc_error_handle error) {
191  static_cast<UrlExternalAccountCredentials*>(arg);
193 }
194 
197  http_request_.reset();
198  if (!GRPC_ERROR_IS_NONE(error)) {
200  return;
201  }
202  absl::string_view response_body(ctx_->response.body,
204  if (format_type_ == "json") {
206  Json response_json = Json::Parse(response_body, &error);
207  if (!GRPC_ERROR_IS_NONE(error) ||
208  response_json.type() != Json::Type::OBJECT) {
211  "The format of response is not a valid json object."));
212  return;
213  }
214  auto response_it =
215  response_json.object_value().find(format_subject_token_field_name_);
216  if (response_it == response_json.object_value().end()) {
218  "Subject token field not present."));
219  return;
220  }
221  if (response_it->second.type() != Json::Type::STRING) {
224  "Subject token field must be a string."));
225  return;
226  }
227  FinishRetrieveSubjectToken(response_it->second.string_value(), error);
228  return;
229  }
231 }
232 
234  std::string subject_token, grpc_error_handle error) {
235  // Reset context
236  ctx_ = nullptr;
237  // Move object state into local variables.
238  auto cb = cb_;
239  cb_ = nullptr;
240  // Invoke the callback.
241  if (!GRPC_ERROR_IS_NONE(error)) {
242  cb("", error);
243  } else {
244  cb(subject_token, GRPC_ERROR_NONE);
245  }
246 }
247 
248 } // namespace grpc_core
absl::StrSplit
strings_internal::Splitter< typename strings_internal::SelectDelimiter< Delimiter >::type, AllowEmpty, absl::string_view > StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d)
Definition: abseil-cpp/absl/strings/str_split.h:499
url_external_account_credentials.h
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
absl::MaxSplits
strings_internal::MaxSplitsImpl< typename strings_internal::SelectDelimiter< Delimiter >::type > MaxSplits(Delimiter delimiter, int limit)
Definition: abseil-cpp/absl/strings/str_split.h:294
grpc_core::UrlExternalAccountCredentials::Create
static RefCountedPtr< UrlExternalAccountCredentials > Create(Options options, std::vector< std::string > scopes, grpc_error_handle *error)
Definition: url_external_account_credentials.cc:48
regen-readme.it
it
Definition: regen-readme.py:15
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
grpc_core::UrlExternalAccountCredentials::FinishRetrieveSubjectToken
void FinishRetrieveSubjectToken(std::string subject_token, grpc_error_handle error)
Definition: url_external_account_credentials.cc:233
ctx
Definition: benchmark-async.c:30
grpc_core::Json::type
Type type() const
Definition: src/core/lib/json/json.h:174
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
memset
return memset(p, 0, total)
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
grpc_core::Json::Type::OBJECT
@ OBJECT
grpc_core
Definition: call_metric_recorder.h:31
grpc_http_response::body
char * body
Definition: src/core/lib/http/parser.h:96
grpc_core::ExternalAccountCredentials::HTTPRequestContext::pollent
grpc_polling_entity * pollent
Definition: external_account_credentials.h:81
string.h
options
double_dict options[]
Definition: capstone_test.c:55
grpc_core::UrlExternalAccountCredentials
Definition: url_external_account_credentials.h:36
benchmark.request
request
Definition: benchmark.py:77
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
grpc_core::ExternalAccountCredentials::HTTPRequestContext
Definition: external_account_credentials.h:74
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
grpc_core::ExternalAccountCredentials
Definition: external_account_credentials.h:45
grpc_core::Json::object_value
const Object & object_value() const
Definition: src/core/lib/json/json.h:177
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
closure.h
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
grpc_core::CreateHttpRequestSSLCredentials
RefCountedPtr< grpc_channel_credentials > CreateHttpRequestSSLCredentials()
Definition: httpcli_security_connector.cc:208
grpc_security.h
grpc_core::URI::Parse
static absl::StatusOr< URI > Parse(absl::string_view uri_text)
Definition: uri_parser.cc:209
credentials.h
grpc_core::UrlExternalAccountCredentials::format_subject_token_field_name_
std::string format_subject_token_field_name_
Definition: url_external_account_credentials.h:62
string_util.h
grpc_http_request_destroy
void grpc_http_request_destroy(grpc_http_request *request)
Definition: src/core/lib/http/parser.cc:422
grpc_http_header::key
char * key
Definition: src/core/lib/http/parser.h:37
grpc_core::RefCountedPtr< grpc_channel_credentials >
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc_http_header
Definition: src/core/lib/http/parser.h:36
grpc_core::URI::authority
const std::string & authority() const
Definition: uri_parser.h:69
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
grpc_core::UrlExternalAccountCredentials::http_request_
OrphanablePtr< HttpRequest > http_request_
Definition: url_external_account_credentials.h:64
httpcli_ssl_credentials.h
grpc.h
header
struct absl::base_internal::@2940::AllocList::Header header
grpc_core::UrlExternalAccountCredentials::OnRetrieveSubjectTokenInternal
void OnRetrieveSubjectTokenInternal(grpc_error_handle error)
Definition: url_external_account_credentials.cc:195
grpc_insecure_credentials_create
GRPCAPI grpc_channel_credentials * grpc_insecure_credentials_create()
Definition: core/lib/security/credentials/insecure/insecure_credentials.cc:64
arg
Definition: cmdline.cc:40
grpc_core::ExternalAccountCredentials::HTTPRequestContext::closure
grpc_closure closure
Definition: external_account_credentials.h:85
grpc_http_response_destroy
void grpc_http_response_destroy(grpc_http_response *response)
Definition: src/core/lib/http/parser.cc:434
grpc_core::UrlExternalAccountCredentials::OnRetrieveSubjectToken
static void OnRetrieveSubjectToken(void *arg, grpc_error_handle error)
Definition: url_external_account_credentials.cc:188
json.h
grpc_core::ExternalAccountCredentials::HTTPRequestContext::deadline
Timestamp deadline
Definition: external_account_credentials.h:82
grpc_core::UrlExternalAccountCredentials::format_type_
std::string format_type_
Definition: url_external_account_credentials.h:61
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
grpc_core::UrlExternalAccountCredentials::url_
URI url_
Definition: url_external_account_credentials.h:58
grpc_core::Json::Parse
static Json Parse(absl::string_view json_str, grpc_error_handle *error)
Definition: json_reader.cc:899
grpc_core::UrlExternalAccountCredentials::ctx_
HTTPRequestContext * ctx_
Definition: url_external_account_credentials.h:65
grpc_core::ExternalAccountCredentials::HTTPRequestContext::response
grpc_http_response response
Definition: external_account_credentials.h:86
grpc_core::UrlExternalAccountCredentials::UrlExternalAccountCredentials
UrlExternalAccountCredentials(Options options, std::vector< std::string > scopes, grpc_error_handle *error)
Definition: url_external_account_credentials.cc:60
grpc_core::URI::scheme
const std::string & scheme() const
Definition: uri_parser.h:68
absl::StatusOr::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: abseil-cpp/absl/status/statusor.h:491
parser.h
GRPC_ERROR_REF
#define GRPC_ERROR_REF(err)
Definition: error.h:261
absl_status_to_grpc_error
grpc_error_handle absl_status_to_grpc_error(absl::Status status)
Definition: error_utils.cc:167
grpc_core::HttpRequest::Get
static OrphanablePtr< HttpRequest > Get(URI uri, const grpc_channel_args *args, grpc_polling_entity *pollent, const grpc_http_request *request, Timestamp deadline, grpc_closure *on_done, grpc_http_response *response, RefCountedPtr< grpc_channel_credentials > channel_creds) GRPC_MUST_USE_RESULT
Definition: httpcli.cc:69
grpc_http_response::body_length
size_t body_length
Definition: src/core/lib/http/parser.h:92
grpc_core::URI::Create
static absl::StatusOr< URI > Create(std::string scheme, std::string authority, std::string path, std::vector< QueryParam > query_parameter_pairs, std::string fragment)
Definition: uri_parser.cc:289
GRPC_ERROR_CREATE_FROM_CPP_STRING
#define GRPC_ERROR_CREATE_FROM_CPP_STRING(desc)
Definition: error.h:297
grpc_core::UrlExternalAccountCredentials::headers_
std::map< std::string, std::string > headers_
Definition: url_external_account_credentials.h:60
alloc.h
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_core::UrlExternalAccountCredentials::url_full_path_
std::string url_full_path_
Definition: url_external_account_credentials.h:59
grpc_http_header::value
char * value
Definition: src/core/lib/http/parser.h:38
arg
struct arg arg
grpc_core::UrlExternalAccountCredentials::cb_
std::function< void(std::string, grpc_error_handle)> cb_
Definition: url_external_account_credentials.h:66
gpr_strdup
GPRAPI char * gpr_strdup(const char *src)
Definition: string.cc:39
absl::StatusOr
Definition: abseil-cpp/absl/status/statusor.h:187
grpc_error
Definition: error_internal.h:42
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
grpc_core::UrlExternalAccountCredentials::RetrieveSubjectToken
void RetrieveSubjectToken(HTTPRequestContext *ctx, const Options &options, std::function< void(std::string, grpc_error_handle)> cb) override
Definition: url_external_account_credentials.cc:134
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
grpc_core::Json::Type::STRING
@ STRING
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
absl::StatusOr::status
const Status & status() const &
Definition: abseil-cpp/absl/status/statusor.h:678
error_utils.h
grpc_core::ExternalAccountCredentials::Options
Definition: external_account_credentials.h:49
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
grpc_http_request
Definition: src/core/lib/http/parser.h:69
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:48