/core/externals/update-engine/externals/gdata-objectivec-client/Source/OAuth2/GTMOAuth2Authentication.h
C++ Header | 350 lines | 139 code | 75 blank | 136 comment | 1 complexity | 5fb14c40479581ab3e723bdf0b426933 MD5 | raw file
1/* Copyright (c) 2011 Google Inc. 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES 17 18// This class implements the OAuth 2 protocol for authorizing requests. 19// http://tools.ietf.org/html/draft-ietf-oauth-v2 20 21#import <Foundation/Foundation.h> 22 23// GTMHTTPFetcher.h brings in GTLDefines/GDataDefines 24#import "GTMHTTPFetcher.h" 25 26// Until all OAuth 2 providers are up to the same spec, we'll provide a crude 27// way here to override the "Bearer" string in the Authorization header 28#ifndef GTM_OAUTH2_BEARER 29#define GTM_OAUTH2_BEARER "Bearer" 30#endif 31 32#ifdef __cplusplus 33extern "C" { 34#endif 35 36// Service provider name allows stored authorization to be associated with 37// the authorizing service 38extern NSString *const kGTMOAuth2ServiceProviderGoogle; 39 40// 41// GTMOAuth2SignIn constants, included here for use by clients 42// 43extern NSString *const kGTMOAuth2ErrorDomain; 44 45// Error userInfo keys 46extern NSString *const kGTMOAuth2ErrorMessageKey; 47extern NSString *const kGTMOAuth2ErrorRequestKey; 48extern NSString *const kGTMOAuth2ErrorJSONKey; 49 50enum { 51 // Error code indicating that the window was prematurely closed 52 kGTMOAuth2ErrorWindowClosed = -1000, 53 kGTMOAuth2ErrorAuthorizationFailed = -1001, 54 kGTMOAuth2ErrorTokenExpired = -1002, 55 kGTMOAuth2ErrorTokenUnavailable = -1003, 56 kGTMOAuth2ErrorUnauthorizableRequest = -1004 57}; 58 59 60// Notifications for token fetches 61extern NSString *const kGTMOAuth2FetchStarted; 62extern NSString *const kGTMOAuth2FetchStopped; 63 64extern NSString *const kGTMOAuth2FetcherKey; 65extern NSString *const kGTMOAuth2FetchTypeKey; 66extern NSString *const kGTMOAuth2FetchTypeToken; 67extern NSString *const kGTMOAuth2FetchTypeRefresh; 68extern NSString *const kGTMOAuth2FetchTypeAssertion; 69extern NSString *const kGTMOAuth2FetchTypeUserInfo; 70 71// Token-issuance errors 72extern NSString *const kGTMOAuth2ErrorKey; 73extern NSString *const kGTMOAuth2ErrorObjectKey; 74 75extern NSString *const kGTMOAuth2ErrorInvalidRequest; 76extern NSString *const kGTMOAuth2ErrorInvalidClient; 77extern NSString *const kGTMOAuth2ErrorInvalidGrant; 78extern NSString *const kGTMOAuth2ErrorUnauthorizedClient; 79extern NSString *const kGTMOAuth2ErrorUnsupportedGrantType; 80extern NSString *const kGTMOAuth2ErrorInvalidScope; 81 82// Notification that sign-in has completed, and token fetches will begin (useful 83// for displaying interstitial messages after the window has closed) 84extern NSString *const kGTMOAuth2UserSignedIn; 85 86// Notification for token changes 87extern NSString *const kGTMOAuth2AccessTokenRefreshed; 88extern NSString *const kGTMOAuth2RefreshTokenChanged; 89extern NSString *const kGTMOAuth2AccessTokenRefreshFailed; 90 91// Notification for WebView loading 92extern NSString *const kGTMOAuth2WebViewStartedLoading; 93extern NSString *const kGTMOAuth2WebViewStoppedLoading; 94extern NSString *const kGTMOAuth2WebViewKey; 95extern NSString *const kGTMOAuth2WebViewStopKindKey; 96extern NSString *const kGTMOAuth2WebViewFinished; 97extern NSString *const kGTMOAuth2WebViewFailed; 98extern NSString *const kGTMOAuth2WebViewCancelled; 99 100// Notification for network loss during html sign-in display 101extern NSString *const kGTMOAuth2NetworkLost; 102extern NSString *const kGTMOAuth2NetworkFound; 103 104#ifdef __cplusplus 105} 106#endif 107 108@interface GTMOAuth2Authentication : NSObject <GTMFetcherAuthorizationProtocol> { 109 @private 110 NSString *clientID_; 111 NSString *clientSecret_; 112 NSString *redirectURI_; 113 NSMutableDictionary *parameters_; 114 115 // authorization parameters 116 NSURL *tokenURL_; 117 NSDate *expirationDate_; 118 119 NSString *authorizationTokenKey_; 120 121 NSDictionary *additionalTokenRequestParameters_; 122 NSDictionary *additionalGrantTypeRequestParameters_; 123 124 // queue of requests for authorization waiting for a valid access token 125 GTMHTTPFetcher *refreshFetcher_; 126 NSMutableArray *authorizationQueue_; 127 128 id <GTMHTTPFetcherServiceProtocol> fetcherService_; // WEAK 129 130 Class parserClass_; 131 132 BOOL shouldAuthorizeAllRequests_; 133 134 // arbitrary data retained for the user 135 id userData_; 136 NSMutableDictionary *properties_; 137} 138 139// OAuth2 standard protocol parameters 140// 141// These should be the plain strings; any needed escaping will be provided by 142// the library. 143 144// Request properties 145@property (copy) NSString *clientID; 146@property (copy) NSString *clientSecret; 147@property (copy) NSString *redirectURI; 148@property (retain) NSString *scope; 149@property (retain) NSString *tokenType; 150@property (retain) NSString *assertion; 151@property (retain) NSString *refreshScope; 152 153// Apps may optionally add parameters here to be provided to the token 154// endpoint on token requests and refreshes. 155@property (retain) NSDictionary *additionalTokenRequestParameters; 156 157// Apps may optionally add parameters here to be provided to the token 158// endpoint on specific token requests and refreshes, keyed by the grant_type. 159// For example, if a different "type" parameter is required for obtaining 160// the auth code and on refresh, this might be: 161// 162// viewController.authentication.additionalGrantTypeRequestParameters = @{ 163// @"authorization_code" : @{ @"type" : @"code" }, 164// @"refresh_token" : @{ @"type" : @"refresh" } 165// }; 166@property (retain) NSDictionary *additionalGrantTypeRequestParameters; 167 168// Response properties 169@property (retain) NSMutableDictionary *parameters; 170 171@property (retain) NSString *accessToken; 172@property (retain) NSString *refreshToken; 173@property (retain) NSNumber *expiresIn; 174@property (retain) NSString *code; 175@property (retain) NSString *errorString; 176 177// URL for obtaining access tokens 178@property (copy) NSURL *tokenURL; 179 180// Calculated expiration date (expiresIn seconds added to the 181// time the access token was received.) 182@property (copy) NSDate *expirationDate; 183 184// Service identifier, like "Google"; not used for authentication 185// 186// The provider name is just for allowing stored authorization to be associated 187// with the authorizing service. 188@property (copy) NSString *serviceProvider; 189 190// User ID; not used for authentication 191@property (retain) NSString *userID; 192 193// User email and verified status; not used for authentication 194// 195// The verified string can be checked with -boolValue. If the result is false, 196// then the email address is listed with the account on the server, but the 197// address has not been confirmed as belonging to the owner of the account. 198@property (retain) NSString *userEmail; 199@property (retain) NSString *userEmailIsVerified; 200 201// Property indicating if this auth has a refresh or access token so is suitable 202// for authorizing a request. This does not guarantee that the token is valid. 203@property (readonly) BOOL canAuthorize; 204 205// Property indicating if this object will authorize plain http request 206// (as well as any non-https requests.) Default is NO, only requests with the 207// scheme https are authorized, since security may be compromised if tokens 208// are sent over the wire using an unencrypted protocol like http. 209@property (assign) BOOL shouldAuthorizeAllRequests; 210 211// userData is retained for the convenience of the caller 212@property (retain) id userData; 213 214// Stored property values are retained for the convenience of the caller 215@property (retain) NSDictionary *properties; 216 217// Property for the optional fetcher service instance to be used to create 218// fetchers 219// 220// Fetcher service objects retain authorizations, so this is weak to avoid 221// circular retains. 222@property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK 223 224// Alternative JSON parsing class; this should implement the 225// GTMOAuth2ParserClass informal protocol. If this property is 226// not set, the class SBJSON must be available in the runtime. 227@property (assign) Class parserClass; 228 229// Key for the response parameter used for the authorization header; by default, 230// "access_token" is used, but some servers may expect alternatives, like 231// "id_token". 232@property (copy) NSString *authorizationTokenKey; 233 234// Convenience method for creating an authentication object 235+ (id)authenticationWithServiceProvider:(NSString *)serviceProvider 236 tokenURL:(NSURL *)tokenURL 237 redirectURI:(NSString *)redirectURI 238 clientID:(NSString *)clientID 239 clientSecret:(NSString *)clientSecret; 240 241// Clear out any authentication values, prepare for a new request fetch 242- (void)reset; 243 244// Main authorization entry points 245// 246// These will refresh the access token, if necessary, add the access token to 247// the request, then invoke the callback. 248// 249// The request argument may be nil to just force a refresh of the access token, 250// if needed. 251// 252// NOTE: To avoid accidental leaks of bearer tokens, the request must 253// be for a URL with the scheme https unless the shouldAuthorizeAllRequests 254// property is set. 255 256// The finish selector should have a signature matching 257// - (void)authentication:(GTMOAuth2Authentication *)auth 258// request:(NSMutableURLRequest *)request 259// finishedWithError:(NSError *)error; 260 261- (void)authorizeRequest:(NSMutableURLRequest *)request 262 delegate:(id)delegate 263 didFinishSelector:(SEL)sel; 264 265#if NS_BLOCKS_AVAILABLE 266- (void)authorizeRequest:(NSMutableURLRequest *)request 267 completionHandler:(void (^)(NSError *error))handler; 268#endif 269 270// Synchronous entry point; authorizing this way cannot refresh an expired 271// access token 272- (BOOL)authorizeRequest:(NSMutableURLRequest *)request; 273 274// If the authentication is waiting for a refresh to complete, spin the run 275// loop, discarding events, until the fetch has completed 276// 277// This is only for use in testing or in tools without a user interface. 278- (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds; 279 280 281////////////////////////////////////////////////////////////////////////////// 282// 283// Internal properties and methods for use by GTMOAuth2SignIn 284// 285 286// Pending fetcher to get a new access token, if any 287@property (retain) GTMHTTPFetcher *refreshFetcher; 288 289// Check if a request is queued up to be authorized 290- (BOOL)isAuthorizingRequest:(NSURLRequest *)request; 291 292// Check if a request appears to be authorized 293- (BOOL)isAuthorizedRequest:(NSURLRequest *)request; 294 295// Stop any pending refresh fetch. This will also cancel the authorization 296// for all fetch requests pending authorization. 297- (void)stopAuthorization; 298 299// Prevents authorization callback for a given request. 300- (void)stopAuthorizationForRequest:(NSURLRequest *)request; 301 302// OAuth fetch user-agent header value 303- (NSString *)userAgent; 304 305// Parse and set token and token secret from response data 306- (void)setKeysForResponseString:(NSString *)str; 307- (void)setKeysForResponseDictionary:(NSDictionary *)dict; 308 309// Persistent token string for keychain storage 310// 311// We'll use the format "refresh_token=foo&serviceProvider=bar" so we can 312// easily alter what portions of the auth data are stored 313// 314// Use these methods for serialization 315- (NSString *)persistenceResponseString; 316- (void)setKeysForPersistenceResponseString:(NSString *)str; 317 318// method to begin fetching an access token, used by the sign-in object 319- (GTMHTTPFetcher *)beginTokenFetchWithDelegate:(id)delegate 320 didFinishSelector:(SEL)finishedSel; 321 322// Entry point to post a notification about a fetcher currently used for 323// obtaining or refreshing a token; the sign-in object will also use this 324// to indicate when the user's email address is being fetched. 325// 326// Fetch type constants are above under "notifications for token fetches" 327- (void)notifyFetchIsRunning:(BOOL)isStarting 328 fetcher:(GTMHTTPFetcher *)fetcher 329 type:(NSString *)fetchType; 330 331// Arbitrary key-value properties retained for the user 332- (void)setProperty:(id)obj forKey:(NSString *)key; 333- (id)propertyForKey:(NSString *)key; 334 335// 336// Utilities 337// 338 339+ (NSString *)encodedOAuthValueForString:(NSString *)str; 340 341+ (NSString *)encodedQueryParametersForDictionary:(NSDictionary *)dict; 342 343+ (NSDictionary *)dictionaryWithResponseString:(NSString *)responseStr; 344 345+ (NSDictionary *)dictionaryWithJSONData:(NSData *)data; 346 347+ (NSString *)scopeWithStrings:(NSString *)firstStr, ... NS_REQUIRES_NIL_TERMINATION; 348@end 349 350#endif // GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES