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/internal/oauth2_cached_credentials.h"
27#include "google/cloud/internal/oauth2_compute_engine_credentials.h"
28#include "google/cloud/status.h"
38GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
42
43
44
45
47 std::set<std::string>
scopes;
52
53
54
55
57 storage::internal::HttpResponse
const& response);
60
61
62
63
64
65
68 storage::internal::HttpResponse
const& response,
69 std::chrono::system_clock::time_point now);
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96template <
typename HttpRequestBuilderType =
97 storage::internal::CurlRequestBuilder,
98 typename ClockType = std::chrono::system_clock>
99class ComputeEngineCredentials;
103class ComputeEngineCredentials<
storage::internal::CurlRequestBuilder,
106 explicit ComputeEngineCredentials() : ComputeEngineCredentials(
"default") {}
107 explicit ComputeEngineCredentials(std::string service_account_email);
109 StatusOr<std::string> AuthorizationHeader()
override {
110 return oauth2_internal::AuthorizationHeaderJoined(*cached_);
113 std::string AccountEmail()
const override {
return impl_->AccountEmail(); }
116
117
118
119
120
121
122
123
124 std::string service_account_email() {
return impl_->service_account_email(); }
127
128
129
130
131
132
133 std::set<std::string> scopes()
const {
return impl_->scopes(); }
136 friend struct ComputeEngineCredentialsTester;
137 ComputeEngineCredentials(std::string service_account_email,
138 oauth2_internal::HttpClientFactory client_factory);
140 StatusOr<std::string> AuthorizationHeaderForTesting(
141 std::chrono::system_clock::time_point tp) {
142 return oauth2_internal::AuthorizationHeaderJoined(*cached_, tp);
145 std::shared_ptr<oauth2_internal::ComputeEngineCredentials> impl_;
146 std::shared_ptr<oauth2_internal::CachedCredentials> cached_;
150template <
typename HttpRequestBuilderType,
typename ClockType>
151class ComputeEngineCredentials :
public Credentials {
156 : clock_(), service_account_email_(std::move(service_account_email)) {}
159 std::unique_lock<std::mutex> lock(mu_);
160 return refreshing_creds_.AuthorizationHeader(clock_.now(),
161 [
this] {
return Refresh(); });
165 std::unique_lock<std::mutex> lock(mu_);
167 RetrieveServiceAccountInfo();
168 return service_account_email_;
172
173
174
175
176
177
178
179
181 std::unique_lock<std::mutex> lock(mu_);
182 return service_account_email_;
186
187
188
189
190
191
192 std::set<std::string>
scopes()
const {
193 std::unique_lock<std::mutex> lock(mu_);
199
200
201
202
203
204 StatusOr<
storage::internal::HttpResponse> DoMetadataServerGetRequest(
205 std::string
const& path,
bool recursive)
const {
207 std::string metadata_server_hostname =
210 HttpRequestBuilderType builder(
211 std::move(
"http://" + metadata_server_hostname + path),
212 storage::internal::GetDefaultCurlHandleFactory());
213 builder.AddHeader(
"metadata-flavor: Google");
214 if (recursive) builder.AddQueryParameter(
"recursive",
"true");
215 return std::move(builder).BuildRequest().MakeRequest(std::string{});
219
220
221
222
223
224
225 Status RetrieveServiceAccountInfo()
const {
226 auto response = DoMetadataServerGetRequest(
227 "/computeMetadata/v1/instance/service-accounts/" +
228 service_account_email_ +
"/",
231 return std::move(response).status();
233 if (response->status_code >= 300) {
234 return AsStatus(*response);
237 auto metadata = ParseMetadataServerResponse(*response);
239 return metadata.status();
241 service_account_email_ = std::move(metadata->email);
242 scopes_ = std::move(metadata->scopes);
247 auto status = RetrieveServiceAccountInfo();
252 auto response = DoMetadataServerGetRequest(
253 "/computeMetadata/v1/instance/service-accounts/" +
254 service_account_email_ +
"/token",
257 return std::move(response).status();
259 if (response->status_code >= 300) {
260 return AsStatus(*response);
263 return ParseComputeEngineRefreshResponse(*response, clock_.now());
267 mutable std::mutex mu_;
269 mutable std::set<std::string> scopes_;
270 mutable std::string service_account_email_;
274GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
std::string service_account_email() const
Returns the email or alias of this credential's service account.
Definition: compute_engine_credentials.h:180
ComputeEngineCredentials(std::string service_account_email)
Definition: compute_engine_credentials.h:155
StatusOr< std::string > AuthorizationHeader() override
Attempts to obtain a value for the Authorization HTTP header.
Definition: compute_engine_credentials.h:158
ComputeEngineCredentials()
Definition: compute_engine_credentials.h:153
std::set< std::string > scopes() const
Returns the set of scopes granted to this credential's service account.
Definition: compute_engine_credentials.h:192
std::string AccountEmail() const override
Return the account's email associated with these credentials, if any.
Definition: compute_engine_credentials.h:164
Interface for OAuth 2.0 credentials used to access Google Cloud services.
Definition: credentials.h:47
Wrapper for refreshable parts of a Credentials object.
Definition: refreshing_credentials_wrapper.h:37
Authentication components for Google Cloud Storage.
Definition: anonymous_credentials.h:26
StatusOr< ServiceAccountMetadata > ParseMetadataServerResponse(storage::internal::HttpResponse const &response)
Parses a metadata server response JSON string into a ServiceAccountMetadata.
StatusOr< RefreshingCredentialsWrapper::TemporaryToken > ParseComputeEngineRefreshResponse(storage::internal::HttpResponse const &response, std::chrono::system_clock::time_point now)
Parses a refresh response JSON string into an authorization header.
Contains all the Google Cloud Storage C++ client APIs.
Definition: auto_finalize.h:24
Definition: refreshing_credentials_wrapper.h:41