Google Cloud Storage C++ Client  1.42.0
A C++ Client Library for Google Cloud Storage
authorized_user_credentials.h
Go to the documentation of this file.
1 // Copyright 2018 Google LLC
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 // https://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 
15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_AUTHORIZED_USER_CREDENTIALS_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_AUTHORIZED_USER_CREDENTIALS_H
17 
18 #include "google/cloud/storage/internal/curl_request_builder.h"
19 #include "google/cloud/storage/internal/http_response.h"
20 #include "google/cloud/storage/oauth2/credential_constants.h"
21 #include "google/cloud/storage/oauth2/credentials.h"
22 #include "google/cloud/storage/oauth2/refreshing_credentials_wrapper.h"
23 #include "google/cloud/storage/version.h"
24 #include "google/cloud/status.h"
25 #include <chrono>
26 #include <iostream>
27 #include <mutex>
28 #include <string>
29 
30 namespace google {
31 namespace cloud {
32 namespace storage {
34 namespace oauth2 {
35 /// Object to hold information used to instantiate an AuthorizedUserCredentials.
37  std::string client_id;
38  std::string client_secret;
39  std::string refresh_token;
40  std::string token_uri;
41 };
42 
43 /// Parses a user credentials JSON string into an AuthorizedUserCredentialsInfo.
45  std::string const& content, std::string const& source,
46  std::string const& default_token_uri = GoogleOAuthRefreshEndpoint());
47 
48 /// Parses a refresh response JSON string into an authorization header. The
49 /// header and the current time (for the expiration) form a TemporaryToken.
52  storage::internal::HttpResponse const& response,
53  std::chrono::system_clock::time_point now);
54 
55 /**
56  * Wrapper class for Google OAuth 2.0 user account credentials.
57  *
58  * Takes a AuthorizedUserCredentialsInfo and obtains access tokens from the
59  * Google Authorization Service as needed. Instances of this class should
60  * usually be created via the convenience methods declared in
61  * google_credentials.h.
62  *
63  * An HTTP Authorization header, with an access token as its value,
64  * can be obtained by calling the AuthorizationHeader() method; if the current
65  * access token is invalid or nearing expiration, this will class will first
66  * obtain a new access token before returning the Authorization header string.
67  *
68  * @see https://developers.google.com/identity/protocols/OAuth2 for an overview
69  * of using user credentials with Google's OAuth 2.0 system.
70  *
71  * @tparam HttpRequestBuilderType a dependency injection point. It makes it
72  * possible to mock internal libcurl wrappers. This should generally not be
73  * overridden except for testing.
74  * @tparam ClockType a dependency injection point to fetch the current time.
75  * This should generally not be overridden except for testing.
76  */
77 template <typename HttpRequestBuilderType =
78  storage::internal::CurlRequestBuilder,
79  typename ClockType = std::chrono::system_clock>
81  public:
83  ChannelOptions const& channel_options = {})
84  : info_(std::move(info)),
86  channel_options.ssl_root_path())),
87  clock_() {}
88 
89  StatusOr<std::string> AuthorizationHeader() override {
90  std::unique_lock<std::mutex> lock(mu_);
91  return refreshing_creds_.AuthorizationHeader(clock_.now(),
92  [this] { return Refresh(); });
93  }
94 
95  private:
96  StatusOr<RefreshingCredentialsWrapper::TemporaryToken> Refresh() {
97  HttpRequestBuilderType builder(
98  info_.token_uri,
99  storage::internal::GetDefaultCurlHandleFactory(options_));
100  std::string payload("grant_type=refresh_token");
101  payload += "&client_id=";
102  payload += builder.MakeEscapedString(info_.client_id).get();
103  payload += "&client_secret=";
104  payload += builder.MakeEscapedString(info_.client_secret).get();
105  payload += "&refresh_token=";
106  payload += builder.MakeEscapedString(info_.refresh_token).get();
107  auto response = std::move(builder).BuildRequest().MakeRequest(payload);
108  if (!response) return std::move(response).status();
109  if (response->status_code >= 300) return AsStatus(*response);
110  return ParseAuthorizedUserRefreshResponse(*response, clock_.now());
111  }
112 
114  Options options_;
115  ClockType clock_;
116  mutable std::mutex mu_;
117  RefreshingCredentialsWrapper refreshing_creds_;
118 };
119 
120 } // namespace oauth2
122 } // namespace storage
123 } // namespace cloud
124 } // namespace google
125 
126 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_AUTHORIZED_USER_CREDENTIALS_H