BBGMultiAccountManager
 All Classes Files Functions Variables Enumerator Properties Defines
GMultiAccountManager/GMultiAccountManager/GTMOAuth2Authentication.h
Go to the documentation of this file.
00001 /* Copyright (c) 2011 Google Inc.
00002  *
00003  * Licensed under the Apache License, Version 2.0 (the "License");
00004  * you may not use this file except in compliance with the License.
00005  * You may obtain a copy of the License at
00006  *
00007  *     http://www.apache.org/licenses/LICENSE-2.0
00008  *
00009  * Unless required by applicable law or agreed to in writing, software
00010  * distributed under the License is distributed on an "AS IS" BASIS,
00011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012  * See the License for the specific language governing permissions and
00013  * limitations under the License.
00014  */
00015 
00016 #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
00017 
00018 // This class implements the OAuth 2 protocol for authorizing requests.
00019 // http://tools.ietf.org/html/draft-ietf-oauth-v2
00020 
00021 #import <Foundation/Foundation.h>
00022 
00023 // GTMHTTPFetcher.h brings in GTLDefines/GDataDefines
00024 #import "GTMHTTPFetcher.h"
00025 
00026 #undef _EXTERN
00027 #undef _INITIALIZE_AS
00028 #ifdef GTMOAUTH2AUTHENTICATION_DEFINE_GLOBALS
00029   #define _EXTERN
00030   #define _INITIALIZE_AS(x) =x
00031 #else
00032   #if defined(__cplusplus)
00033     #define _EXTERN extern "C"
00034   #else
00035     #define _EXTERN extern
00036   #endif
00037   #define _INITIALIZE_AS(x)
00038 #endif
00039 
00040 // Until all OAuth 2 providers are up to the same spec, we'll provide a crude
00041 // way here to override the "Bearer" string in the Authorization header
00042 #ifndef GTM_OAUTH2_BEARER
00043 #define GTM_OAUTH2_BEARER "Bearer"
00044 #endif
00045 
00046 // Service provider name allows stored authorization to be associated with
00047 // the authorizing service
00048 _EXTERN NSString* const kGTMOAuth2ServiceProviderGoogle _INITIALIZE_AS(@"Google");
00049 
00050 //
00051 // GTMOAuth2SignIn constants, included here for use by clients
00052 //
00053 _EXTERN NSString* const kGTMOAuth2ErrorDomain  _INITIALIZE_AS(@"com.google.GTMOAuth2");
00054 
00055 // Error userInfo keys
00056 _EXTERN NSString* const kGTMOAuth2ErrorMessageKey _INITIALIZE_AS(@"error");
00057 _EXTERN NSString* const kGTMOAuth2ErrorRequestKey _INITIALIZE_AS(@"request");
00058 _EXTERN NSString* const kGTMOAuth2ErrorJSONKey    _INITIALIZE_AS(@"json");
00059 
00060 enum {
00061   // Error code indicating that the window was prematurely closed
00062   kGTMOAuth2ErrorWindowClosed          = -1000,
00063   kGTMOAuth2ErrorAuthorizationFailed   = -1001,
00064   kGTMOAuth2ErrorTokenExpired          = -1002,
00065   kGTMOAuth2ErrorTokenUnavailable      = -1003,
00066   kGTMOAuth2ErrorUnauthorizableRequest = -1004
00067 };
00068 
00069 
00070 // Notifications for token fetches
00071 _EXTERN NSString* const kGTMOAuth2FetchStarted        _INITIALIZE_AS(@"kGTMOAuth2FetchStarted");
00072 _EXTERN NSString* const kGTMOAuth2FetchStopped        _INITIALIZE_AS(@"kGTMOAuth2FetchStopped");
00073 
00074 _EXTERN NSString* const kGTMOAuth2FetcherKey          _INITIALIZE_AS(@"fetcher");
00075 _EXTERN NSString* const kGTMOAuth2FetchTypeKey        _INITIALIZE_AS(@"FetchType");
00076 _EXTERN NSString* const kGTMOAuth2FetchTypeToken      _INITIALIZE_AS(@"token");
00077 _EXTERN NSString* const kGTMOAuth2FetchTypeRefresh    _INITIALIZE_AS(@"refresh");
00078 _EXTERN NSString* const kGTMOAuth2FetchTypeAssertion  _INITIALIZE_AS(@"assertion");
00079 _EXTERN NSString* const kGTMOAuth2FetchTypeUserInfo   _INITIALIZE_AS(@"userInfo");
00080 
00081 // Token-issuance errors
00082 _EXTERN NSString* const kGTMOAuth2ErrorKey                  _INITIALIZE_AS(@"error");
00083 
00084 _EXTERN NSString* const kGTMOAuth2ErrorInvalidRequest       _INITIALIZE_AS(@"invalid_request");
00085 _EXTERN NSString* const kGTMOAuth2ErrorInvalidClient        _INITIALIZE_AS(@"invalid_client");
00086 _EXTERN NSString* const kGTMOAuth2ErrorInvalidGrant         _INITIALIZE_AS(@"invalid_grant");
00087 _EXTERN NSString* const kGTMOAuth2ErrorUnauthorizedClient   _INITIALIZE_AS(@"unauthorized_client");
00088 _EXTERN NSString* const kGTMOAuth2ErrorUnsupportedGrantType _INITIALIZE_AS(@"unsupported_grant_type");
00089 _EXTERN NSString* const kGTMOAuth2ErrorInvalidScope         _INITIALIZE_AS(@"invalid_scope");
00090 
00091 // Notification that sign-in has completed, and token fetches will begin (useful
00092 // for displaying interstitial messages after the window has closed)
00093 _EXTERN NSString* const kGTMOAuth2UserSignedIn              _INITIALIZE_AS(@"kGTMOAuth2UserSignedIn");
00094 
00095 // Notification for token changes
00096 _EXTERN NSString* const kGTMOAuth2AccessTokenRefreshed _INITIALIZE_AS(@"kGTMOAuth2AccessTokenRefreshed");
00097 _EXTERN NSString* const kGTMOAuth2RefreshTokenChanged  _INITIALIZE_AS(@"kGTMOAuth2RefreshTokenChanged");
00098 
00099 // Notification for WebView loading
00100 _EXTERN NSString* const kGTMOAuth2WebViewStartedLoading _INITIALIZE_AS(@"kGTMOAuth2WebViewStartedLoading");
00101 _EXTERN NSString* const kGTMOAuth2WebViewStoppedLoading _INITIALIZE_AS(@"kGTMOAuth2WebViewStoppedLoading");
00102 _EXTERN NSString* const kGTMOAuth2WebViewKey            _INITIALIZE_AS(@"kGTMOAuth2WebViewKey");
00103 _EXTERN NSString* const kGTMOAuth2WebViewStopKindKey    _INITIALIZE_AS(@"kGTMOAuth2WebViewStopKindKey");
00104 _EXTERN NSString* const kGTMOAuth2WebViewFinished       _INITIALIZE_AS(@"finished");
00105 _EXTERN NSString* const kGTMOAuth2WebViewFailed         _INITIALIZE_AS(@"failed");
00106 _EXTERN NSString* const kGTMOAuth2WebViewCancelled      _INITIALIZE_AS(@"cancelled");
00107 
00108 // Notification for network loss during html sign-in display
00109 _EXTERN NSString* const kGTMOAuth2NetworkLost         _INITIALIZE_AS(@"kGTMOAuthNetworkLost");
00110 _EXTERN NSString* const kGTMOAuth2NetworkFound        _INITIALIZE_AS(@"kGTMOAuthNetworkFound");
00111 
00112 @interface GTMOAuth2Authentication : NSObject <GTMFetcherAuthorizationProtocol>  {
00113  @private
00114   NSString *clientID_;
00115   NSString *clientSecret_;
00116   NSString *redirectURI_;
00117   NSMutableDictionary *parameters_;
00118 
00119   // authorization parameters
00120   NSURL *tokenURL_;
00121   NSDate *expirationDate_;
00122 
00123   NSDictionary *additionalTokenRequestParameters_;
00124 
00125   // queue of requests for authorization waiting for a valid access token
00126   GTMHTTPFetcher *refreshFetcher_;
00127   NSMutableArray *authorizationQueue_;
00128 
00129   id <GTMHTTPFetcherServiceProtocol> fetcherService_; // WEAK
00130 
00131   Class parserClass_;
00132 
00133   BOOL shouldAuthorizeAllRequests_;
00134 
00135   // arbitrary data retained for the user
00136   id userData_;
00137   NSMutableDictionary *properties_;
00138 }
00139 
00140 // OAuth2 standard protocol parameters
00141 //
00142 // These should be the plain strings; any needed escaping will be provided by
00143 // the library.
00144 
00145 // Request properties
00146 @property (copy) NSString *clientID;
00147 @property (copy) NSString *clientSecret;
00148 @property (copy) NSString *redirectURI;
00149 @property (retain) NSString *scope;
00150 @property (retain) NSString *tokenType;
00151 @property (retain) NSString *assertion;
00152 
00153 // Apps may optionally add parameters here to be provided to the token
00154 // endpoint on token requests and refreshes
00155 @property (retain) NSDictionary *additionalTokenRequestParameters;
00156 
00157 // Response properties
00158 @property (retain) NSMutableDictionary *parameters;
00159 
00160 @property (retain) NSString *accessToken;
00161 @property (retain) NSString *refreshToken;
00162 @property (retain) NSNumber *expiresIn;
00163 @property (retain) NSString *code;
00164 @property (retain) NSString *errorString;
00165 
00166 // URL for obtaining access tokens
00167 @property (copy) NSURL *tokenURL;
00168 
00169 // Calculated expiration date (expiresIn seconds added to the
00170 // time the access token was received.)
00171 @property (copy) NSDate *expirationDate;
00172 
00173 // Service identifier, like "Google"; not used for authentication
00174 //
00175 // The provider name is just for allowing stored authorization to be associated
00176 // with the authorizing service.
00177 @property (copy) NSString *serviceProvider;
00178 
00179 // User email and verified status; not used for authentication
00180 //
00181 // The verified string can be checked with -boolValue. If the result is false,
00182 // then the email address is listed with the account on the server, but the
00183 // address has not been confirmed as belonging to the owner of the account.
00184 @property (retain) NSString *userEmail;
00185 @property (retain) NSString *userEmailIsVerified;
00186 
00187 // Property indicating if this auth has a refresh token so is suitable for
00188 // authorizing a request. This does not guarantee that the token is valid.
00189 @property (readonly) BOOL canAuthorize;
00190 
00191 // Property indicating if this object will authorize plain http request
00192 // (as well as any non-https requests.) Default is NO, only requests with the
00193 // scheme https are authorized, since security may be compromised if tokens
00194 // are sent over the wire using an unencrypted protocol like http.
00195 @property (assign) BOOL shouldAuthorizeAllRequests;
00196 
00197 // userData is retained for the convenience of the caller
00198 @property (retain) id userData;
00199 
00200 // Stored property values are retained for the convenience of the caller
00201 @property (retain) NSDictionary *properties;
00202 
00203 // Property for the optional fetcher service instance to be used to create
00204 // fetchers
00205 //
00206 // Fetcher service objects retain authorizations, so this is weak to avoid
00207 // circular retains.
00208 @property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK
00209 
00210 // Alternative JSON parsing class; this should implement the
00211 // GTMOAuth2ParserClass informal protocol. If this property is
00212 // not set, the class SBJSON must be available in the runtime.
00213 @property (assign) Class parserClass;
00214 
00215 // Convenience method for creating an authentication object
00216 + (id)authenticationWithServiceProvider:(NSString *)serviceProvider
00217                                tokenURL:(NSURL *)tokenURL
00218                             redirectURI:(NSString *)redirectURI
00219                                clientID:(NSString *)clientID
00220                            clientSecret:(NSString *)clientSecret;
00221 
00222 // Clear out any authentication values, prepare for a new request fetch
00223 - (void)reset;
00224 
00225 // Main authorization entry points
00226 //
00227 // These will refresh the access token, if necessary, add the access token to
00228 // the request, then invoke the callback.
00229 //
00230 // The request argument may be nil to just force a refresh of the access token,
00231 // if needed.
00232 //
00233 // NOTE: To avoid accidental leaks of bearer tokens, the request must
00234 // be for a URL with the scheme https unless the shouldAuthorizeAllRequests
00235 // property is set.
00236 
00237 // The finish selector should have a signature matching
00238 //   - (void)authentication:(GTMOAuth2Authentication *)auth
00239 //                  request:(NSMutableURLRequest *)request
00240 //        finishedWithError:(NSError *)error;
00241 
00242 - (void)authorizeRequest:(NSMutableURLRequest *)request
00243                 delegate:(id)delegate
00244        didFinishSelector:(SEL)sel;
00245 
00246 #if NS_BLOCKS_AVAILABLE
00247 - (void)authorizeRequest:(NSMutableURLRequest *)request
00248        completionHandler:(void (^)(NSError *error))handler;
00249 #endif
00250 
00251 // Synchronous entry point; authorizing this way cannot refresh an expired
00252 // access token
00253 - (BOOL)authorizeRequest:(NSMutableURLRequest *)request;
00254 
00255 // If the authentication is waiting for a refresh to complete, spin the run
00256 // loop, discarding events, until the fetch has completed
00257 //
00258 // This is only for use in testing or in tools without a user interface.
00259 - (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds;
00260 
00261 
00263 //
00264 // Internal properties and methods for use by GTMOAuth2SignIn
00265 //
00266 
00267 // Pending fetcher to get a new access token, if any
00268 @property (retain) GTMHTTPFetcher *refreshFetcher;
00269 
00270 // Check if a request is queued up to be authorized
00271 - (BOOL)isAuthorizingRequest:(NSURLRequest *)request;
00272 
00273 // Check if a request appears to be authorized
00274 - (BOOL)isAuthorizedRequest:(NSURLRequest *)request;
00275 
00276 // Stop any pending refresh fetch
00277 - (void)stopAuthorization;
00278 
00279 // OAuth fetch user-agent header value
00280 - (NSString *)userAgent;
00281 
00282 // Parse and set token and token secret from response data
00283 - (void)setKeysForResponseString:(NSString *)str;
00284 - (void)setKeysForResponseDictionary:(NSDictionary *)dict;
00285 
00286 // Persistent token string for keychain storage
00287 //
00288 // We'll use the format "refresh_token=foo&serviceProvider=bar" so we can
00289 // easily alter what portions of the auth data are stored
00290 //
00291 // Use these methods for serialization
00292 - (NSString *)persistenceResponseString;
00293 - (void)setKeysForPersistenceResponseString:(NSString *)str;
00294 
00295 // method to begin fetching an access token, used by the sign-in object
00296 - (GTMHTTPFetcher *)beginTokenFetchWithDelegate:(id)delegate
00297                               didFinishSelector:(SEL)finishedSel;
00298 
00299 // Entry point to post a notification about a fetcher currently used for
00300 // obtaining or refreshing a token; the sign-in object will also use this
00301 // to indicate when the user's email address is being fetched.
00302 //
00303 // Fetch type constants are above under "notifications for token fetches"
00304 - (void)notifyFetchIsRunning:(BOOL)isStarting
00305                      fetcher:(GTMHTTPFetcher *)fetcher
00306                         type:(NSString *)fetchType;
00307 
00308 // Arbitrary key-value properties retained for the user
00309 - (void)setProperty:(id)obj forKey:(NSString *)key;
00310 - (id)propertyForKey:(NSString *)key;
00311 
00312 //
00313 // Utilities
00314 //
00315 
00316 + (NSString *)encodedOAuthValueForString:(NSString *)str;
00317 
00318 + (NSString *)encodedQueryParametersForDictionary:(NSDictionary *)dict;
00319 
00320 + (NSDictionary *)dictionaryWithResponseString:(NSString *)responseStr;
00321 
00322 + (NSString *)scopeWithStrings:(NSString *)firsStr, ... NS_REQUIRES_NIL_TERMINATION;
00323 @end
00324 
00325 #endif // GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES