Google APIs Client Library for C++
oauth2_authorization.h
Go to the documentation of this file.
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 &lt;deleted&gt; 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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines