15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_COMPUTE_ENGINE_CREDENTIALS_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_COMPUTE_ENGINE_CREDENTIALS_H
18 #include "google/cloud/storage/internal/compute_engine_util.h"
19 #include "google/cloud/storage/internal/curl_request_builder.h"
20 #include "google/cloud/storage/internal/openssl_util.h"
21 #include "google/cloud/storage/oauth2/credential_constants.h"
22 #include "google/cloud/storage/oauth2/credentials.h"
23 #include "google/cloud/storage/oauth2/refreshing_credentials_wrapper.h"
24 #include "google/cloud/storage/version.h"
25 #include "google/cloud/internal/getenv.h"
26 #include "google/cloud/status.h"
46 storage::internal::HttpResponse
const& response);
52 storage::internal::HttpResponse
const& response,
53 std::chrono::system_clock::time_point now);
78 template <
typename HttpRequestBuilderType =
79 storage::internal::CurlRequestBuilder,
80 typename ClockType = std::chrono::system_clock>
86 : clock_(), service_account_email_(std::move(service_account_email)) {}
89 std::unique_lock<std::mutex> lock(mu_);
90 return refreshing_creds_.AuthorizationHeader(clock_.now(),
91 [
this] {
return Refresh(); });
95 std::unique_lock<std::mutex> lock(mu_);
97 RetrieveServiceAccountInfo();
98 return service_account_email_;
111 std::unique_lock<std::mutex> lock(mu_);
112 return service_account_email_;
123 std::unique_lock<std::mutex> lock(mu_);
134 StatusOr<
storage::internal::HttpResponse> DoMetadataServerGetRequest(
135 std::string
const& path,
bool recursive)
const {
137 std::string metadata_server_hostname =
140 HttpRequestBuilderType builder(
141 std::move(
"http://" + metadata_server_hostname + path),
142 storage::internal::GetDefaultCurlHandleFactory());
143 builder.AddHeader(
"metadata-flavor: Google");
144 if (recursive) builder.AddQueryParameter(
"recursive",
"true");
145 return std::move(builder).BuildRequest().MakeRequest(std::string{});
155 Status RetrieveServiceAccountInfo()
const {
156 auto response = DoMetadataServerGetRequest(
157 "/computeMetadata/v1/instance/service-accounts/" +
158 service_account_email_ +
"/",
161 return std::move(response).status();
163 if (response->status_code >= 300) {
164 return AsStatus(*response);
167 auto metadata = ParseMetadataServerResponse(*response);
169 return metadata.status();
171 service_account_email_ = std::move(metadata->email);
172 scopes_ = std::move(metadata->scopes);
177 auto status = RetrieveServiceAccountInfo();
182 auto response = DoMetadataServerGetRequest(
183 "/computeMetadata/v1/instance/service-accounts/" +
184 service_account_email_ +
"/token",
187 return std::move(response).status();
189 if (response->status_code >= 300) {
190 return AsStatus(*response);
193 return ParseComputeEngineRefreshResponse(*response, clock_.now());
197 mutable std::mutex mu_;
199 mutable std::set<std::string> scopes_;
200 mutable std::string service_account_email_;