Google APIs Client Library for C++
|
00001 /* 00002 * \copyright Copyright 2013 Google Inc. All Rights Reserved. 00003 * \license @{ 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 * @} 00018 */ 00019 00020 /* 00021 * @defgroup AuthSupportOAuth2 Auth Support - OAuth 2.0 Module 00022 * 00023 * The OAuth 2.0 module provides support for 00024 * <a href='http://tools.ietf.org/html/rfc6749#section-1.3.1'> 00025 * RFC 6749 OAuth 2.0</a>. The Google Cloud Platform uses OAuth 2.0 to 00026 * authorize access to services and endpoints when refering user data and 00027 * other protected resources. 00028 * 00029 * The OAuth 2.0 module provides the authorization for the HTTP transport layer 00030 * by using building on the AuthorizationCredential abstraction defined by the 00031 * transport layer. It adds a specialized mediator, OAuth2AuthorizationFlow, to 00032 * simplify the complex interactions making up the OAuth 2.0 protocol. 00033 * 00034 * The other abstractions using AuthorizationCredential can be used with 00035 * the OAuth2Credential defined by this module. This includes CredentialStore 00036 * for persisting credentials. The high level OAuth2AuthorizationFlow mediator 00037 * provides support for using a CredentialStore. 00038 */ 00039 00040 #ifndef APISERVING_CLIENTS_CPP_AUTH_OAUTH2_AUTHORIZATION_H_ 00041 #define APISERVING_CLIENTS_CPP_AUTH_OAUTH2_AUTHORIZATION_H_ 00042 00043 #include <string> 00044 using std::string; 00045 #include <vector> 00046 using std::vector; 00047 #include "googleapis/base/callback.h" 00048 #include "googleapis/base/macros.h" 00049 #include "googleapis/base/mutex.h" 00050 #include "googleapis/base/scoped_ptr.h" 00051 #include "googleapis/client/transport/http_authorization.h" 00052 #include "googleapis/client/transport/http_request.h" 00053 #include "googleapis/strings/stringpiece.h" 00054 namespace googleapis { 00055 00056 namespace client { 00057 class CredentialStore; 00058 class HttpTransport; 00059 class HttpRequest; 00060 class HttpResponse; 00061 00062 class OAuth2AuthorizationFlow; 00063 class OAuth2ClientSpec; 00064 class OAuth2Credential; 00065 00066 /* 00067 * A data object containing specifying the client information to present to 00068 * the OAuth 2.0 server. 00069 * @ingroup AuthSupportOAuth2 00070 * 00071 * Normally this class is created by 00072 * OAuth2AuthorizationFlow::InitFromJsonData() and not created directly. 00073 * The various attribute values come from the 00074 * <a href='https://code.google.com/apis/console/'> Google APIs console</a> 00075 * when registering the application. 00076 * 00077 * @see OAuth2AuthorizationFlow::InitFromJsonData() 00078 */ 00079 class OAuth2ClientSpec { 00080 public: 00081 /* 00082 * Standard constructor. 00083 */ 00084 OAuth2ClientSpec(); 00085 00086 /* 00087 * Standard destructor. 00088 */ 00089 ~OAuth2ClientSpec(); 00090 00091 /* 00092 * Returns the client ID. 00093 */ 00094 const string& client_id() const { return client_id_; } 00095 00096 /* 00097 * Sets the client ID. 00098 */ 00099 void set_client_id(const StringPiece& id) { client_id_ = id.as_string(); } 00100 00101 /* 00102 * Returns the client secret. 00103 */ 00104 const string& client_secret() const { return client_secret_; } 00105 00106 /* 00107 * Sets the client secret. 00108 */ 00109 void set_client_secret(const StringPiece& secret) { 00110 client_secret_ = secret.as_string(); 00111 } 00112 00113 /* 00114 * Returns the redirect url. 00115 */ 00116 const string& redirect_uri() const { return redirect_uri_; } 00117 00118 /* 00119 * Sets the redirect url. 00120 * 00121 * @see OAuth2AuthorizationFlow::kOutOfBandUrl 00122 */ 00123 void set_redirect_uri(const StringPiece& uri) { 00124 redirect_uri_ = uri.as_string(); 00125 } 00126 00127 00128 /* 00129 * Returns the url for requesting an OAuth2 Authorization Code for 00130 * this service. 00131 */ 00132 const string& auth_uri() const { return auth_uri_; } 00133 00134 /* 00135 * Sets the url for requesting an OAuth2 Authorization Code for this service. 00136 */ 00137 void set_auth_uri(const StringPiece& uri) { auth_uri_ = uri.as_string(); } 00138 00139 00140 /* 00141 * Returns the url for requesting an OAuth2 Access Token for this service. 00142 */ 00143 const string& token_uri() const { return token_uri_; } 00144 00145 /* 00146 * Sets the url for requesting an OAuth2 Access Token for this service. 00147 */ 00148 void set_token_uri(const StringPiece& uri) { token_uri_ = uri.as_string(); } 00149 00150 00151 /* 00152 * Returns url for revoking an OAuth2 Access Token for this service. 00153 */ 00154 const string& revoke_uri() const { return revoke_uri_; } 00155 00156 /* 00157 * Sets the url for revoking an OAuth2 Access Token for this service. 00158 */ 00159 void set_revoke_uri(const StringPiece& uri) { revoke_uri_ = uri.as_string(); } 00160 00161 private: 00162 string client_id_; 00163 string client_secret_; 00164 string redirect_uri_; 00165 string auth_uri_; 00166 string token_uri_; 00167 string revoke_uri_; 00168 00169 DISALLOW_COPY_AND_ASSIGN(OAuth2ClientSpec); 00170 }; 00171 00172 // Implements a threadsafe string. This is intended for access/refresh tokens 00173 // which are primarily read only to copy them into headers and such but will 00174 // need to be updated at some point, perhaps in another thread. If the mutex 00175 // is in the object managing the string (e.g. credential managing the access 00176 // token) then the update and access operations would need to be in that class 00177 // as well (or the mutex exposed externally). However pushing the mutex down 00178 // to the attribute (e.g. access token) decouples the management from uses, 00179 // plus allows the different attributes to be managed independent of one 00180 // another. 00181 /* 00182 * For internal use only 00183 */ 00184 class ThreadsafeString { 00185 public: 00186 ThreadsafeString() {} 00187 00188 bool empty() const { 00189 MutexLock l(&mutex_); 00190 return value_.empty(); 00191 } 00192 00193 void clear() { 00194 MutexLock l(&mutex_); 00195 value_.clear(); 00196 } 00197 00198 void set(const StringPiece& value) { 00199 MutexLock l(&mutex_); 00200 value_ = value.as_string(); 00201 } 00202 00203 string as_string() const { 00204 MutexLock l(&mutex_); 00205 return value_; 00206 } 00207 00208 void AppendTo(string *target) const { 00209 MutexLock l(&mutex_); 00210 target->append(value_); 00211 } 00212 00213 private: 00214 mutable Mutex mutex_; 00215 string value_; 00216 DISALLOW_COPY_AND_ASSIGN(ThreadsafeString); 00217 }; 00218 00219 /* 00220 * For internal use only 00221 */ 00222 template <typename T> 00223 class ThreadsafePrimitive { 00224 public: 00225 ThreadsafePrimitive() : value_(0) {} 00226 T get() const { 00227 MutexLock l(&mutex_); 00228 return value_; 00229 } 00230 00231 void set(T value) { 00232 MutexLock l(&mutex_); 00233 value_ = value; 00234 } 00235 00236 private: 00237 mutable Mutex mutex_; 00238 T value_; 00239 DISALLOW_COPY_AND_ASSIGN(ThreadsafePrimitive); 00240 }; 00241 00242 /* 00243 * Specifies an OAuth 2.0 Credential. 00244 * @ingroup AuthSupportOAuth2 00245 * 00246 * The purpose of a credential is to carry the available access and 00247 * refresh tokens used to authorize HTTP requests. 00248 * 00249 * The easiest way to manage credentials is using 00250 * OAuth2AuthorizationFlow::RefreshCredentialWithOptions(), which lets you 00251 * treat the credential as an opaque type and not worry about any of its 00252 * attributes or other methods to manage them. 00253 * 00254 * However sometimes you may need to manipulate the credentials directly 00255 * if you are using non-standard storage techniques. 00256 * 00257 * @see OAuth2AuthorizationFlow::RefreshCredentialWithOptions() 00258 * @see CredentialStore 00259 */ 00260 class OAuth2Credential : public AuthorizationCredential { 00261 public: 00262 /* 00263 * Constructs an empty credential. 00264 * 00265 * @see Load() 00266 */ 00267 OAuth2Credential(); 00268 00269 /* 00270 * Standard destructor. 00271 */ 00272 ~OAuth2Credential(); 00273 00274 /* 00275 * Clears all the values in the credential but does not revoke any tokens. 00276 */ 00277 void Clear(); 00278 00279 /* 00280 * Binds a flow to this instance so that it can support Refresh(). 00281 * 00282 * @param[in] flow NULL unbinds the flow. Otherwise, the caller retains 00283 * ownership of the flow so must keep it active. 00284 */ 00285 void set_flow(OAuth2AuthorizationFlow* flow) { flow_ = flow; } 00286 00287 /* 00288 * Returns the flow currently bound. 00289 */ 00290 OAuth2AuthorizationFlow* flow() const { return flow_; } 00291 00292 /* 00293 * Sets the access token. 00294 * 00295 * @param[in] access_token The access token provided by the OAuth 2.0 server. 00296 * 00297 * @see OAuth2ExchangeAuthorizationCodeRequest 00298 * @see OAuth2RefreshTokenRequest 00299 */ 00300 void set_access_token(const StringPiece& access_token) { 00301 access_token_.set(access_token); 00302 } 00303 00304 /* 00305 * Sets the refresh token. 00306 * 00307 * @param[in] refresh_token The refresh token provided by the 00308 * OAuth 2.0 server. 00309 * 00310 * @see OAuth2ExchangeAuthorizationCodeRequest 00311 */ 00312 void set_refresh_token(const StringPiece& refresh_token) { 00313 refresh_token_.set(refresh_token); 00314 } 00315 00316 /* 00317 * Returns the access token. 00318 * 00319 * The access token might no longer be valid. 00320 * 00321 * @return to get the value, take .as_string() from the result. 00322 * 00323 */ 00324 const ThreadsafeString& access_token() const { return access_token_; } 00325 00326 /* 00327 * Returns a modifiable access token. 00328 */ 00329 ThreadsafeString* mutable_access_token() { return &access_token_; } 00330 00331 00332 /* 00333 * Returns the refresh token. 00334 * 00335 * @return to get the value, take .as_string() from the result. 00336 */ 00337 const ThreadsafeString& refresh_token() const { return refresh_token_; } 00338 00339 /* 00340 * Returns a modifiable access token. 00341 */ 00342 ThreadsafeString* mutable_refresh_token() { return &refresh_token_; } 00343 00344 00345 /* 00346 * Returns the timestamp (in epoch seconds) when the access token will 00347 * expire. 00348 * 00349 * @return Absolute value of epoch seconds might have already passed. 00350 */ 00351 int64 expiration_timestamp_secs() const { 00352 return expiration_timestamp_secs_.get(); 00353 } 00354 00355 /* 00356 * Sets the timestamp (in epoch seconds) when the access token will 00357 * expire. 00358 * 00359 * @param[in] secs Absolute value of epoch seconds. 00360 */ 00361 void set_expiration_timestamp_secs(int64 secs) { 00362 expiration_timestamp_secs_.set(secs); 00363 } 00364 00365 /* 00366 * Resets the credential from the JSON data in the reader. 00367 * 00368 * @param[in] reader The JSON stream containing the credential attributes. 00369 * @return status indicating whether the credential values could be reset. 00370 * 00371 * @see Update() 00372 */ 00373 virtual util::Status Load(DataReader* reader); 00374 00375 /* 00376 * Updates the credential attributes from the JSON data in the reader. 00377 * 00378 * Unlike Load(), any attributes not explicitly specified in the reader 00379 * data will be left as is. 00380 * 00381 * @param[in] reader The JSON stream containing the credential attributes 00382 * to update. 00383 * @return status indicating whether the credential values could be updated. 00384 */ 00385 virtual util::Status Update(DataReader* reader); 00386 00387 /* 00388 * Serializes the credential as a JSON stream. 00389 * 00390 * @return an in-memory data reader specifying the credential. 00391 */ 00392 virtual DataReader* MakeDataReader() const; 00393 00394 /* 00395 * Identifies this as an kOAuth2Type credential. 00396 */ 00397 virtual const StringPiece type() const; 00398 00399 /* 00400 * Adds the OAuth 2.9 Authorization Bearer header to the request. 00401 * 00402 * The value of the header will be the current access token. 00403 */ 00404 virtual util::Status AuthorizeRequest(HttpRequest* request); 00405 00406 /* 00407 * Updates the credential from a JSON string. 00408 * 00409 * Existing properties not present in the json are left as is. 00410 * 00411 * @param[in] json The JSON string containing the attributes to update. 00412 * @return fail if the JSON argument was not valid. 00413 * 00414 * @see Update() 00415 */ 00416 util::Status UpdateFromString(const StringPiece& json); 00417 00418 /* 00419 * Returns the user ID associated with this credential, if known. 00420 * 00421 * The user_id is not used for runtime authentication. 00422 * It is normally used for managing persistence but certain flows such as 00423 * web flow may use it as a login_hint. 00424 * 00425 * @warning The client application may have set the user id different from 00426 * the source which actually authorized the user, making these out 00427 * of sync. 00428 * 00429 * @see user_id_verified 00430 */ 00431 const string& user_id() const { return user_id_; } 00432 00433 /* 00434 * Returns true if the user_id has been verified to be the actual user id 00435 * that authorized access. 00436 * 00437 * @warning even if this is true, this data structure might not have come 00438 * from a secure source so this attribute might be compramised. 00439 */ 00440 bool user_id_verified() const { return user_id_verified_; } 00441 00442 /* 00443 * Set the user_id for the credential. 00444 * 00445 * @param[in] user_id The user_id will be copied into the credental. 00446 * @param[in] verified Whether or not the user_id has been verified as true. 00447 */ 00448 void set_user_id(const StringPiece& user_id, bool verified) { 00449 user_id_ = user_id.as_string(); 00450 user_id_verified_ = verified; 00451 } 00452 00453 /* 00454 * The AuthorizationCredential type identfying OAuth 2.0 credentials. 00455 */ 00456 static const StringPiece kOAuth2CredentialType; 00457 00458 /* 00459 * Attempts to refresh the credential. 00460 * 00461 * This will certainly fail if there is no flow bound. 00462 * 00463 * @return ok on success or reason for failure. 00464 */ 00465 virtual util::Status Refresh(); 00466 00467 private: 00468 OAuth2AuthorizationFlow* flow_; 00469 ThreadsafeString access_token_; 00470 ThreadsafeString refresh_token_; 00471 ThreadsafePrimitive<int64> expiration_timestamp_secs_; 00472 string user_id_; 00473 bool user_id_verified_; 00474 00475 DISALLOW_COPY_AND_ASSIGN(OAuth2Credential); 00476 }; 00477 00478 /* 00479 * Options for overriding the default attributes in an OAuth2AuthorizationFlow 00480 * when making OAuth2TokenRequests. 00481 * @ingroup AuthSupportOAuth2 00482 * 00483 * These overrides are used in APIs to change the default values configured 00484 * in the flow. Empty values will defer to the default value (if any). 00485 */ 00486 struct OAuth2RequestOptions { 00487 string redirect_uri; 00488 string scopes; 00489 string user_id; 00490 }; 00491 00492 /* 00493 * The base class for token-related requests made to an OAuth 2.0 server. 00494 * 00495 * @deprecated Use OAuth2AuthorizatioFlow methods 00496 */ 00497 class OAuth2TokenRequest { 00498 public: 00499 /* 00500 * Constructor 00501 * @param[in] request Takes ownership 00502 */ 00503 explicit OAuth2TokenRequest(HttpRequest* request); 00504 00505 /* 00506 * Standard destructor. 00507 */ 00508 virtual ~OAuth2TokenRequest(); 00509 00510 /* 00511 * Sends the request to the OAuth 2.0 server and waits until the 00512 * response comes back and has been processed. 00513 * 00514 * @return ok if the request was successful, otherwise the cause of failure. 00515 */ 00516 virtual util::Status Execute() = 0; 00517 00518 /* 00519 * Returns the response from the HTTP request to the OAuth 2.0 server. 00520 */ 00521 HttpResponse* http_response() const { return http_request_->response(); } 00522 00523 protected: 00524 /* 00525 * Returns the HttpRequest used for the message to the OAuth 2.0 server. 00526 */ 00527 HttpRequest* http_request() { return http_request_.get(); } 00528 00529 private: 00530 scoped_ptr<HttpRequest> http_request_; 00531 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenRequest); 00532 }; 00533 00534 /* 00535 * A concrete OAuth2TokenRequest for revoking access and refresh tokens. 00536 * 00537 * @deprecated Use OAuth2AuthorizatioFlow methods 00538 */ 00539 class OAuth2RevokeTokenRequest : public OAuth2TokenRequest { 00540 public: 00541 /* 00542 * Constructs the request. 00543 * 00544 * The caller retains ownership to all parameters. The instance will 00545 * be using these pointers so the caller must keep them valid over the 00546 * lifetime of the request. 00547 * 00548 * @param[in] transport Transport instance to use. 00549 * @param[in] client Client specification. 00550 * @param[in] token The token to revoke. 00551 */ 00552 OAuth2RevokeTokenRequest( 00553 HttpTransport* transport, 00554 const OAuth2ClientSpec* client, 00555 ThreadsafeString* token); 00556 00557 /* 00558 * Asks the OAuth 2.0 server to revoke the token. 00559 * 00560 * This will clear the token given the the constructor on success. 00561 */ 00562 virtual util::Status Execute(); 00563 00564 private: 00565 const OAuth2ClientSpec* client_; 00566 ThreadsafeString* token_; 00567 DISALLOW_COPY_AND_ASSIGN(OAuth2RevokeTokenRequest); 00568 }; 00569 00570 /* 00571 * A concrete OAuth2TokenRequest for turning an authorization code 00572 * into access and refresh tokens. 00573 * 00574 * @deprecated Use OAuth2AuthorizatioFlow methods 00575 */ 00576 class OAuth2ExchangeAuthorizationCodeRequest : public OAuth2TokenRequest { 00577 public: 00578 /* 00579 * Constructs the request. 00580 * 00581 * The caller retains ownership to all parameters. The instance will 00582 * be using these pointers so the caller must keep them valid over the 00583 * lifetime of the request. 00584 * 00585 * @param[in] transport Transport instance to use. 00586 * @param[in] authorization_code The authorization code from the user action 00587 * that authorized access. 00588 * @param[in] client Client specification. 00589 * @param[in] options Can override the redirect_uri from the one in 00590 * the client parameter. 00591 * @param[in] credential The credential to update with the response tokens. 00592 */ 00593 OAuth2ExchangeAuthorizationCodeRequest( 00594 HttpTransport* transport, 00595 const StringPiece& authorization_code, 00596 const OAuth2ClientSpec& client, 00597 const OAuth2RequestOptions& options, 00598 OAuth2Credential* credential); 00599 00600 /* 00601 * Asks the OAuth 2.0 server for an initial Access Token and Refresh Token. 00602 * 00603 * This will update the credential given the constructor on success. 00604 */ 00605 virtual util::Status Execute(); 00606 00607 private: 00608 OAuth2Credential* credential_; 00609 string content_; 00610 string token_uri_; 00611 DISALLOW_COPY_AND_ASSIGN(OAuth2ExchangeAuthorizationCodeRequest); 00612 }; 00613 00614 /* 00615 * A concrete OAuth2TokenRequest for obtaining a new access token 00616 * from a refresh token. 00617 * 00618 * @deprecated Use OAuth2AuthorizatioFlow methods 00619 */ 00620 class OAuth2RefreshTokenRequest : public OAuth2TokenRequest { 00621 public: 00622 /* 00623 * Constructs the request. 00624 * 00625 * The caller retains ownership to all parameters. The instance will 00626 * be using these pointers so the caller must keep them valid over the 00627 * lifetime of the request. 00628 * 00629 * @param[in] transport Transport instance to use. 00630 * @param[in] client Client specification. 00631 * @param[in] credential The credential to update with the response tokens. 00632 */ 00633 OAuth2RefreshTokenRequest( 00634 HttpTransport* transport, 00635 const OAuth2ClientSpec* client, 00636 OAuth2Credential* credential); 00637 00638 /* 00639 * Asks the OAuth 2.0 server for a new Access Token from the 00640 * existing Refresh Token 00641 * 00642 * This will update the credential given the constructor on success. 00643 */ 00644 virtual util::Status Execute(); 00645 00646 private: 00647 const OAuth2ClientSpec* client_; 00648 OAuth2Credential* credential_; 00649 00650 DISALLOW_COPY_AND_ASSIGN(OAuth2RefreshTokenRequest); 00651 }; 00652 00653 /* 00654 * Mediates interaction with the user, client and an OAuth 2.0 server to 00655 * obtain credentials for accessing protected resources. 00656 * @ingroup AuthSupportOAuth2 00657 * 00658 * This classs is based on a Mediator Pattern with the goal of 00659 * obtaining credentials to access resources protected by OAuth 2.0. 00660 * 00661 * This class is concrete, however is often subclassed for different 00662 * OAuth 2.0 flow patterns that may add additional specialized parameters 00663 * to their token requests. These are determined by the Client Type selection 00664 * in the <a href='https://code.google.com/apis/console/'> 00665 * Google APIs console</a> when the client was registered. 00666 * 00667 * To use this class you must first configure the client secrets needed 00668 * to issue requests to the OAuth 2.0 server on behalf of the client. 00669 * The easiest way to do this is to use the MakeFlowFromClientSecretsPath() 00670 * factory method to construct the flow or the InitFromJson() method if you 00671 * want to instantiate the flow yourself. Otherwise get the client spec using 00672 * mutable_client_spec(). 00673 * 00674 * If a CredentialStore is bound to the flow then it will be used as a cache. 00675 * This is particularly useful for persisting refresh tokens across multiple 00676 * program executions. Without an existing refresh token the user will have 00677 * to re-authorize access all over again. With the store, the user will only 00678 * have to authorize access the first time the program is run. 00679 * 00680 * @see OAuth2Credential 00681 * @see OAuth2ClientSpec 00682 * @see MakeFlowFromClientSecretsPath 00683 * @see ResetCredentialStore 00684 */ 00685 class OAuth2AuthorizationFlow { 00686 public: 00687 /* 00688 * Responsible for getting an Authorization Code for the specified options. 00689 * 00690 * Note the Authorization Code is not an access token. 00691 * 00692 * @return util::Status is a failure if the authorization code could not 00693 * be obtained, including if the user denies access. 00694 * 00695 * @param[in] OAuth2RequestOptions Specifies the scope and redirect_uri. 00696 * @param[out] string The authorization code if the call is successful. 00697 */ 00698 typedef ResultCallback2< util::Status, 00699 const OAuth2RequestOptions&, string*> 00700 AuthorizationCodeCallback; 00701 00702 /* 00703 * Constructs the flow. 00704 * 00705 * @param[in] transport Transport to use when talking to the OAuth 2.0 00706 * server. Ownership is passed to the flow. 00707 */ 00708 explicit OAuth2AuthorizationFlow(HttpTransport* transport); 00709 00710 /* 00711 * Standard destructor. 00712 */ 00713 virtual ~OAuth2AuthorizationFlow(); 00714 00715 /* 00716 * Initializes the flow attributes from the JSON string. 00717 * 00718 * This includes the standard attributes for the client spec, 00719 * and any additional attributes for the specialization within the 00720 * flow. This method calls the protected InitFromJsonData() method 00721 * so that derived classes can initialize their specialized attributes 00722 * as well. 00723 * 00724 * @param[in] json JSON-encoded object with the configuraton attributes. 00725 */ 00726 util::Status InitFromJson(const StringPiece& json); 00727 00728 /* 00729 * Sets the callback used to obtain an Authorization Code. 00730 * 00731 * @param[in] callback Must be repeatable if not NULL. Ownership is 00732 * passed to the flow. 00733 * 00734 * @see NewPermanentCallback() 00735 */ 00736 void set_authorization_code_callback(AuthorizationCodeCallback* callback); 00737 00738 /* 00739 * Returns the callback for obtaining Authorization Codes, or NULL 00740 * if it was not set. 00741 */ 00742 AuthorizationCodeCallback* authorization_code_callback() const { 00743 return authorization_code_callback_.get(); 00744 } 00745 00746 /* 00747 * Sets the CredentialStore used by this flow. 00748 * 00749 * @param[in] store Ownership of the credential store is passed to the flow. 00750 * A NULL valid indicates that credentials should neither be 00751 * stored nor restored. 00752 */ 00753 void ResetCredentialStore(CredentialStore* store); 00754 00755 /* 00756 * Returne the bound credential store, if any. 00757 */ 00758 CredentialStore* credential_store() const { return credential_store_.get(); } 00759 00760 /* 00761 * Returns the client specification with the details needed for it to 00762 * use the OAuth 2.0 server. 00763 */ 00764 const OAuth2ClientSpec& client_spec() const { return client_spec_; } 00765 00766 /* 00767 * Returns a modificable client specification. 00768 */ 00769 OAuth2ClientSpec* mutable_client_spec() { return &client_spec_; } 00770 00771 /* 00772 * Returns the default scopes to request when asking for Access Tokens. 00773 */ 00774 const string& default_scopes() const { return default_scopes_; } 00775 00776 /* 00777 * Sets the default scopes to request when asking for Access Tokens. 00778 * 00779 * The OAuth2RequestOptions passed to various methods can be used to 00780 * override these on a per-request basis if needed. It is not required 00781 * to set this, but it is simpler if requests tend to use the same scopes. 00782 * 00783 * @param[in] scopes The specific values are specified by the individual 00784 * services that you wish to talk to. 00785 */ 00786 void set_default_scopes(const StringPiece& scopes) { 00787 default_scopes_ = scopes.as_string(); 00788 } 00789 00790 /* 00791 * Refreshes the credential with a current access token. 00792 * 00793 * @param options Clarifies details about the desired credentials. 00794 * <table><tr><th>Option<th>Purpose 00795 * <tr><td>user_id 00796 * <td>Only used as a key for the CredentialStore. If there is 00797 * no store for the flow or this is empty then the call will 00798 * proceed without using a CredentialStore. Some flows, such 00799 * as the web flow, may also use this as a login_hint. 00800 * <tr><td>scopes 00801 * <td>Used to override the flow's default scope. This option 00802 * is only required if the flow was not given a default. 00803 * <tr><td>redirect_uri 00804 * <td>Used to override the flow's default redirect_uri. This 00805 * option is only required if the flow was not given a 00806 * default. 00807 * </table> 00808 * 00809 * @param[in] credential The credential to refresh can be empty. If it 00810 * has already been initialized then the user_id, if any, must 00811 * match that in the options. 00812 * 00813 * The a CredentialStore is to be used, then the flow will attempt to 00814 * read an existing credential from the store. Also, the flow will store 00815 * newly obtained or updated credentials into the store. 00816 * 00817 * When existing credentials are found in the store, it may already have a 00818 * valid access token. Otherwise it should have a refresh token from which 00819 * a new access token can be obtained. The flow will attempt to obtain 00820 * a valid access token and update the credential as needed. 00821 * 00822 * If there is no credential in the store, or the credential failed to update 00823 * then the flow will attempt to obtain a new Authorization Code, which will 00824 * require user interaction to approve. To obtain the Authorization Code, 00825 * the flow will call the AuthorizationCodeCallback, if one was bound. 00826 * If this code is obtained, the flow will use it to update the credential 00827 * with a valid Access Token and store the updated credential if 00828 * a store was configured. 00829 */ 00830 // TODO(ewiseblatt): This currently only considers the scopes when the 00831 // credential has no refresh_token. If there is a refresh token, then the 00832 // updated credentials will still only be for the old scopes. To get around 00833 // this bug, you need to clear the credential and start all over. 00834 // 00835 virtual util::Status RefreshCredentialWithOptions( 00836 const OAuth2RequestOptions& options, OAuth2Credential* credential); 00837 00838 /* 00839 * Returns a URL to the OAuth 2.0 server requesting a new Authorization Code. 00840 * 00841 * This method is only intended when manually implementing flows. 00842 * 00843 * @param[in] scopes The desired scopes. If more than one scope is desired 00844 * then this should be a ' '-delimited string. 00845 * The scope values are specified by the specific service you 00846 * wish to get authorization to access. 00847 * @return The appropriate URL to HTTP GET. 00848 * 00849 * @see RefreshCredentialWithOptions. 00850 * @see GeenrateAuthorizationCodeRequestUrlWithOptions 00851 */ 00852 string GenerateAuthorizationCodeRequestUrl(const StringPiece& scopes) const { 00853 OAuth2RequestOptions options; 00854 options.scopes = scopes.as_string(); 00855 return GenerateAuthorizationCodeRequestUrlWithOptions(options); 00856 } 00857 00858 /* 00859 * Variation of GenerateAuthorizationCodeRequestUrl that takes a vector of 00860 * scopes rather than a ' '-delmited string. 00861 * 00862 * @param[in] scopes The individual scope strings. 00863 * 00864 * @see GenerateAuthorizationCodeRequestUrl 00865 */ 00866 string GenerateAuthorizationCodeRequestUrl( 00867 const vector<StringPiece>& scopes) const; 00868 00869 /* 00870 * Returns a URL to the OAuth 2.0 server requesting a new Authorization Code. 00871 * 00872 * This method is only intended when manually implementing flows. 00873 * 00874 * @param[in] options Used to refine what is being requested. 00875 * @return The appropriate URL to HTTP GET. 00876 * 00877 * @see RefreshCredentialWithOptions. 00878 */ 00879 virtual string GenerateAuthorizationCodeRequestUrlWithOptions( 00880 const OAuth2RequestOptions& options) const; 00881 00882 /* 00883 * Talk to the OAuth 2.0 server to refresh the access token. 00884 * 00885 * @param[in] options Overriden options, like the redirect_uri. 00886 * @param[in, out] credential Uses the refresh_token to update access_token. 00887 * 00888 * @return ok on success or reason for failure. 00889 */ 00890 virtual util::Status PerformRefreshToken( 00891 const OAuth2RequestOptions& options, OAuth2Credential* credential); 00892 00893 /* 00894 * Sends request to OAuth 2.0 server to obtain Access and Refresh tokens from 00895 * an Authorization Code. 00896 * 00897 * @param[in] authorization_code The Authorization Code. 00898 * @param[in] options Used to refine what is being requested. 00899 * @param[out] credential The credential to update with the tokens. 00900 * @return ok or reason for error. 00901 * 00902 * @see RefreshCredentialWithOptions. 00903 */ 00904 virtual util::Status PerformExchangeAuthorizationCode( 00905 const string& authorization_code, 00906 const OAuth2RequestOptions& options, 00907 OAuth2Credential* credential); 00908 00909 /* 00910 * Sends a request to the OAuth 2.0 server to revoke the credentials. 00911 * 00912 * @param[in] access_token_only If true then only revoke the access token 00913 * leaving the refresh token intact. 00914 * @param[in] credential The credential to update should contain the 00915 * refresh and/or access tokens. The tokens will be cleared after 00916 * the revoke request executes successfully. 00917 */ 00918 virtual util::Status PerformRevokeToken( 00919 bool access_token_only, OAuth2Credential* credential); 00920 00921 /* 00922 * Creates a new request for obtaining Access and Refresh tokens from 00923 * an Authorization Code. 00924 * 00925 * This method is only intended when manually implementing flows. 00926 * 00927 * @param[in] authorization_code The Authorization Code. 00928 * @param[out] credential The credential to update with the tokens. 00929 * 00930 * @see RefreshCredentialWithOptions. 00931 * @see PerformExchangeAuthorizationCode 00932 * 00933 * @deprecated 00934 */ 00935 OAuth2TokenRequest* NewExchangeAuthorizationCodeRequest( 00936 const StringPiece& authorization_code, 00937 OAuth2Credential* credential) { 00938 return NewExchangeAuthorizationCodeRequestWithOptions( 00939 authorization_code, OAuth2RequestOptions(), credential); 00940 } 00941 00942 /* 00943 * Creates a new request for obtaining Access and Refresh tokens from 00944 * an Authorization Code. 00945 * 00946 * This method is only intended when manually implementing flows. 00947 * 00948 * @param[in] authorization_code The Authorization Code. 00949 * @param[in] options Used to refine what is being requested. 00950 * @param[out] credential The credential to update with the tokens. 00951 * 00952 * @see RefreshCredentialWithOptions. 00953 * @see PerformExchangeAuthorizationCode 00954 * 00955 * @deprecated 00956 */ 00957 OAuth2TokenRequest* NewExchangeAuthorizationCodeRequestWithOptions( 00958 const StringPiece& authorization_code, 00959 const OAuth2RequestOptions& options, 00960 OAuth2Credential* credential); 00961 00962 /* 00963 * Creates a new request for obtaining an Access Token from an 00964 * existing Refresh Token. 00965 * 00966 * @param[in] credential The credential to update should already contain 00967 * an existing refresh token. The credential will be updated 00968 * with a new Access Token if the request is executed 00969 * successfully. 00970 * @see RefreshCredentialWithOptions 00971 * @see PerformRefreshToken 00972 * 00973 * @deprecated 00974 */ 00975 OAuth2TokenRequest* NewRefreshTokenRequest(OAuth2Credential* credential); 00976 00977 /* 00978 * Creates a new request for revoking a Refresh Token so that it is no 00979 * longer valid. 00980 * 00981 * The user will have to go through the entire flow to obtain a new 00982 * Authorization Code if they want to use the credential again. 00983 * 00984 * @param[in] credential The credential to update should already contain 00985 * an existing refresh token. The token will be cleared after 00986 * the revoke request executes successfully. 00987 * 00988 * @see PerformRevokeToken 00989 * 00990 * @deprecated 00991 */ 00992 OAuth2TokenRequest* NewRevokeRefreshTokenRequest( 00993 OAuth2Credential* credential); 00994 00995 /* 00996 * Creates a new request for revoking an Access Token so that it is no 00997 * longer valid. 00998 * 00999 * @param[in] credential The credential to update should already contain 01000 * an existing access token. The token will be cleared after 01001 * the revoke request executes successfully. 01002 * @see PerformRevokeToken 01003 * 01004 * @deprecated 01005 */ 01006 OAuth2TokenRequest* NewRevokeAccessTokenRequest( 01007 OAuth2Credential* credential); 01008 01009 /* 01010 * The standard URL used for clients that do not have an HTTP server. 01011 // TODO(ewiseblatt): Better description. 01012 */ 01013 static const char kOutOfBandUrl[]; 01014 01015 /* 01016 * The root URL for the standard OAuth 2.0 server used by the 01017 * Google Cloud Platform. 01018 */ 01019 static const char kGoogleAccountsOauth2Url[]; 01020 01021 /* 01022 * Creates a new flow from a client secrets file. 01023 * 01024 * This method is a wrapper around MakeFlowFromClientSecretsJson 01025 * that reads the contents of a file and uess that as the JSON 01026 * paraemter to MakeFlowFromClientSecretsJson. 01027 * 01028 * As a security safeguard, the file must be read-only and not a symbolic 01029 * link. 01030 * 01031 * @param[in] path The path to a file containing the JSON-encoded secrets. 01032 * @param[in] transport The transport to use with the flow will be owned 01033 * by the flow. If the flow could not be created then this 01034 * transport will be destroyed. 01035 * @param[out] status Will explain the cause for failure. 01036 * 01037 * @return Ownership of a new authorization flow or NULL on failure. 01038 * 01039 * @see MakeFlowFromClientSecretsJson 01040 */ 01041 static OAuth2AuthorizationFlow* MakeFlowFromClientSecretsPath( 01042 const StringPiece& path, HttpTransport* transport, 01043 util::Status* status); 01044 01045 /* 01046 * Creates a new flow from a client secrets JSON document. 01047 * 01048 * The JSON document is a composite object whose name specifies the type 01049 * of flow to be created. For example 01050 * <pre>{ 01051 * "installed": { 01052 * "client_id": "<deleted>.apps.googleusercontent.com", 01053 * "client_secret": "<deleted>" 01054 * } 01055 * }</pre> 01056 * where <deleted> were values created when the program was registered. 01057 * 01058 * @param[in] json The JSON encoded client secrets to configure the flow 01059 * from. This can come from the Google APIs Console. 01060 * @param[in] transport The transport to use with the flow will be owned 01061 * by the flow. If the flow could not be created then this 01062 * transport will be destroyed. 01063 * @param[out] status Will explain the cause for failure. 01064 * 01065 * @return Ownership of a new authorization flow or NULL on failure. 01066 */ 01067 static OAuth2AuthorizationFlow* MakeFlowFromClientSecretsJson( 01068 const StringPiece& json, HttpTransport* transport, 01069 util::Status* status); 01070 01071 /* 01072 * Helper function to produce a ' '-delimited scopes string 01073 * from a vector of individual scopes. 01074 * 01075 * @param[in] scopes 01076 * @return scopes string for OAuth2RequestOptions 01077 */ 01078 static string JoinScopes(const vector<StringPiece>& scopes); 01079 01080 /* 01081 * Returns a new credential instance that will use this flow to refresh. 01082 * 01083 * @return Ownership of the credential is passed to the caller. 01084 * The instance will be constructed with this flow bound to it 01085 * to implement its refresh method. Therefore this flow must remain 01086 * valid over the lifetime of the result or until you unbind the flow 01087 * using OAuth2Credential::set_flow(NULL). 01088 */ 01089 OAuth2Credential* NewCredential(); 01090 01091 protected: 01092 /* 01093 * The parser is currently private to the implementation because I do not 01094 * want to couple JsonCpp in the public API at this time. 01095 */ 01096 friend class OAuth2Credential; 01097 class SimpleJsonData; 01098 01099 protected: 01100 /* 01101 * Called by InitFromJson 01102 * @param[out] data The data to initialized. 01103 */ 01104 virtual util::Status InitFromJsonData(const SimpleJsonData* data); 01105 01106 private: 01107 OAuth2ClientSpec client_spec_; 01108 string default_scopes_; 01109 scoped_ptr<HttpTransport> transport_; 01110 scoped_ptr<CredentialStore> credential_store_; 01111 scoped_ptr<AuthorizationCodeCallback> authorization_code_callback_; 01112 01113 DISALLOW_COPY_AND_ASSIGN(OAuth2AuthorizationFlow); 01114 }; 01115 01116 /* 01117 * Manages credentials using OAuth 2.0 installed application flow. 01118 * @ingroup AuthSupportOAuth2 01119 * 01120 * This is a specialization of OAuth2Authorization flow. 01121 * 01122 * It does not add anything beyond that which is already in the base class, 01123 * however this will be the class created for "installed" application flows 01124 * for future maintainability. 01125 */ 01126 class OAuth2InstalledApplicationFlow : public OAuth2AuthorizationFlow { 01127 public: 01128 explicit OAuth2InstalledApplicationFlow( 01129 HttpTransport* transport); 01130 virtual ~OAuth2InstalledApplicationFlow(); 01131 virtual string GenerateAuthorizationCodeRequestUrl( 01132 const StringPiece& scope) const; 01133 01134 protected: 01135 // Called by initFromJson. 01136 virtual util::Status InitFromJsonData(const SimpleJsonData* data); 01137 01138 private: 01139 DISALLOW_COPY_AND_ASSIGN(OAuth2InstalledApplicationFlow); 01140 }; 01141 01142 01143 /* 01144 * Manages credentials using OAuth 2.0 web application flow. 01145 * @ingroup AuthSupportOAuth2 01146 * 01147 * This is a specialization of OAuth2Authorization flow. 01148 * 01149 * The web application flow adds the "approval_prompt" and "access_type" 01150 * attributes. 01151 */ 01152 class OAuth2WebApplicationFlow : public OAuth2AuthorizationFlow { 01153 public: 01154 explicit OAuth2WebApplicationFlow(HttpTransport* transport); 01155 virtual ~OAuth2WebApplicationFlow(); 01156 virtual string GenerateAuthorizationCodeRequestUrl( 01157 const StringPiece& scope) const; 01158 01159 /* 01160 * Returns whether or not the "approval_prompt" should be 'force'. 01161 */ 01162 bool force_approval_prompt() const { return force_approval_prompt_; } 01163 01164 /* 01165 * Used to set the approval_prompt attribute. 01166 * 01167 * @param[in] force If true then approval_prompt will be "force". 01168 * Otherwise it will be the default ("auto"). 01169 */ 01170 void set_force_approval_prompt(bool force) { 01171 force_approval_prompt_ = force; 01172 } 01173 01174 /* 01175 * Returns whether the "access_type" attribute should be 'offline'. 01176 */ 01177 bool offline_access_type() const { return offline_access_type_; } 01178 01179 /* 01180 * Used to set the access_type attribute. 01181 * 01182 * @param[in] offline If true then access_type will be "offline". 01183 * Otherwise it will be the default ("online"). 01184 */ 01185 void set_offline_access_type(bool offline) { 01186 offline_access_type_ = offline; 01187 } 01188 01189 protected: 01190 /* 01191 * Intitializes from the JSON data, including web-flow specific attributes. 01192 * 01193 * @param[in] data The json data specifying the flow. 01194 */ 01195 virtual util::Status InitFromJsonData(const SimpleJsonData* data); 01196 01197 private: 01198 bool offline_access_type_; 01199 bool force_approval_prompt_; 01200 01201 DISALLOW_COPY_AND_ASSIGN(OAuth2WebApplicationFlow); 01202 }; 01203 01204 } // namespace client 01205 01206 } // namespace googleapis 01207 #endif // APISERVING_CLIENTS_CPP_AUTH_OAUTH2_AUTHORIZATION_H_