BBGMultiAccountManager
|
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 // 00017 // GTMOAuth2ViewControllerTouch.h 00018 // 00019 // This view controller for iPhone handles sign-in via OAuth to Google or 00020 // other services. 00021 // 00022 // This controller is not reusable; create a new instance of this controller 00023 // every time the user will sign in. 00024 // 00025 00026 #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES 00027 00028 #import <Foundation/Foundation.h> 00029 00030 #if TARGET_OS_IPHONE 00031 00032 #import <UIKit/UIKit.h> 00033 00034 #import "GTMOAuth2Authentication.h" 00035 00036 #undef _EXTERN 00037 #undef _INITIALIZE_AS 00038 #ifdef GTMOAUTH2VIEWCONTROLLERTOUCH_DEFINE_GLOBALS 00039 #define _EXTERN 00040 #define _INITIALIZE_AS(x) =x 00041 #else 00042 #define _EXTERN extern 00043 #define _INITIALIZE_AS(x) 00044 #endif 00045 00046 _EXTERN NSString* const kGTMOAuth2KeychainErrorDomain _INITIALIZE_AS(@"com.google.GTMOAuthKeychain"); 00047 00048 00049 @class GTMOAuth2SignIn; 00050 @class GTMOAuth2ViewControllerTouch; 00051 00052 @interface GTMOAuth2ViewControllerTouch : UIViewController<UINavigationControllerDelegate, UIWebViewDelegate> { 00053 @private 00054 UIButton *backButton_; 00055 UIButton *forwardButton_; 00056 UIView *navButtonsView_; 00057 UIBarButtonItem *rightBarButtonItem_; 00058 UIWebView *webView_; 00059 00060 // The object responsible for the sign-in networking sequence; it holds 00061 // onto the authentication object as well. 00062 GTMOAuth2SignIn *signIn_; 00063 00064 // the page request to load when awakeFromNib occurs 00065 NSURLRequest *request_; 00066 00067 // The user we're calling back 00068 // 00069 // The delegate is retained only until the callback is invoked 00070 // or the sign-in is canceled 00071 id delegate_; 00072 SEL finishedSelector_; 00073 00074 #if NS_BLOCKS_AVAILABLE 00075 void (^completionBlock_)(GTMOAuth2ViewControllerTouch *, GTMOAuth2Authentication *, NSError *); 00076 #endif 00077 00078 NSString *keychainItemName_; 00079 CFTypeRef keychainItemAccessibility_; 00080 00081 // if non-nil, the html string to be displayed immediately upon opening 00082 // of the web view 00083 NSString *initialHTMLString_; 00084 00085 // if non-nil, the URL for which cookies will be deleted when the 00086 // browser view is dismissed 00087 NSURL *browserCookiesURL_; 00088 00089 id userData_; 00090 NSMutableDictionary *properties_; 00091 00092 // We delegate the decision to our owning NavigationController (if any). 00093 // But, the NavigationController will call us back, and ask us. 00094 // BOOL keeps us from infinite looping. 00095 BOOL isInsideShouldAutorotateToInterfaceOrientation_; 00096 00097 // YES, when view first shown in this signIn session. 00098 BOOL isViewShown_; 00099 00100 // YES, after the view has fully transitioned in. 00101 BOOL didViewAppear_; 00102 00103 // YES between sends of start and stop notifications 00104 BOOL hasNotifiedWebViewStartedLoading_; 00105 00106 // To prevent us from calling our delegate's selector more than once. 00107 BOOL hasCalledFinished_; 00108 00109 // Set in a webView callback. 00110 BOOL hasDoneFinalRedirect_; 00111 00112 // Set during the pop initiated by the sign-in object; otherwise, 00113 // viewWillDisappear indicates that some external change of the view 00114 // has stopped the sign-in. 00115 BOOL didDismissSelf_; 00116 } 00117 00118 // the application and service name to use for saving the auth tokens 00119 // to the keychain 00120 @property (nonatomic, copy) NSString *keychainItemName; 00121 00122 // the keychain item accessibility is a system constant for use 00123 // with kSecAttrAccessible. 00124 // 00125 // Since it's a system constant, we do not need to retain it. 00126 @property (nonatomic, assign) CFTypeRef keychainItemAccessibility; 00127 00128 // optional html string displayed immediately upon opening the web view 00129 // 00130 // This string is visible just until the sign-in web page loads, and 00131 // may be used for a "Loading..." type of message or to set the 00132 // initial view color 00133 @property (nonatomic, copy) NSString *initialHTMLString; 00134 00135 // the underlying object to hold authentication tokens and authorize http 00136 // requests 00137 @property (nonatomic, retain, readonly) GTMOAuth2Authentication *authentication; 00138 00139 // the underlying object which performs the sign-in networking sequence 00140 @property (nonatomic, retain, readonly) GTMOAuth2SignIn *signIn; 00141 00142 // user interface elements 00143 @property (nonatomic, retain) IBOutlet UIButton *backButton; 00144 @property (nonatomic, retain) IBOutlet UIButton *forwardButton; 00145 @property (nonatomic, retain) IBOutlet UIView *navButtonsView; 00146 @property (nonatomic, retain) IBOutlet UIBarButtonItem *rightBarButtonItem; 00147 @property (nonatomic, retain) IBOutlet UIWebView *webView; 00148 00149 // the default timeout for an unreachable network during display of the 00150 // sign-in page is 10 seconds; set this to 0 to have no timeout 00151 @property (nonatomic, assign) NSTimeInterval networkLossTimeoutInterval; 00152 00153 // if set, cookies are deleted for this URL when the view is hidden 00154 // 00155 // For Google sign-ins, this is set by default to https://google.com/accounts 00156 // but it may be explicitly set to nil to disable clearing of browser cookies 00157 @property (nonatomic, retain) NSURL *browserCookiesURL; 00158 00159 // userData is retained for the convenience of the caller 00160 @property (nonatomic, retain) id userData; 00161 00162 // Stored property values are retained for the convenience of the caller 00163 - (void)setProperty:(id)obj forKey:(NSString *)key; 00164 - (id)propertyForKey:(NSString *)key; 00165 00166 @property (nonatomic, retain) NSDictionary *properties; 00167 00168 // Method for creating a controller to authenticate to Google services 00169 // 00170 // scope is the requested scope of authorization 00171 // (like "http://www.google.com/m8/feeds") 00172 // 00173 // keychain item name is used for storing the token on the keychain, 00174 // keychainItemName should be like "My Application: Google Latitude" 00175 // (or set to nil if no persistent keychain storage is desired) 00176 // 00177 // the delegate is retained only until the finished selector is invoked 00178 // or the sign-in is canceled 00179 // 00180 // If you don't like the default nibName and bundle, you can change them 00181 // using the UIViewController properties once you've made one of these. 00182 // 00183 // finishedSelector is called after authentication completes. It should follow 00184 // this signature. 00185 // 00186 // - (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController 00187 // finishedWithAuth:(GTMOAuth2Authentication *)auth 00188 // error:(NSError *)error; 00189 // 00190 #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT 00191 + (id)controllerWithScope:(NSString *)scope 00192 clientID:(NSString *)clientID 00193 clientSecret:(NSString *)clientSecret 00194 keychainItemName:(NSString *)keychainItemName 00195 delegate:(id)delegate 00196 finishedSelector:(SEL)finishedSelector; 00197 00198 - (id)initWithScope:(NSString *)scope 00199 clientID:(NSString *)clientID 00200 clientSecret:(NSString *)clientSecret 00201 keychainItemName:(NSString *)keychainItemName 00202 delegate:(id)delegate 00203 finishedSelector:(SEL)finishedSelector; 00204 00205 #if NS_BLOCKS_AVAILABLE 00206 + (id)controllerWithScope:(NSString *)scope 00207 clientID:(NSString *)clientID 00208 clientSecret:(NSString *)clientSecret 00209 keychainItemName:(NSString *)keychainItemName 00210 completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler; 00211 00212 - (id)initWithScope:(NSString *)scope 00213 clientID:(NSString *)clientID 00214 clientSecret:(NSString *)clientSecret 00215 keychainItemName:(NSString *)keychainItemName 00216 completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler; 00217 #endif 00218 #endif 00219 00220 // Create a controller for authenticating to non-Google services, taking 00221 // explicit endpoint URLs and an authentication object 00222 + (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth 00223 authorizationURL:(NSURL *)authorizationURL 00224 keychainItemName:(NSString *)keychainItemName // may be nil 00225 delegate:(id)delegate 00226 finishedSelector:(SEL)finishedSelector; 00227 00228 // This is the designated initializer 00229 - (id)initWithAuthentication:(GTMOAuth2Authentication *)auth 00230 authorizationURL:(NSURL *)authorizationURL 00231 keychainItemName:(NSString *)keychainItemName 00232 delegate:(id)delegate 00233 finishedSelector:(SEL)finishedSelector; 00234 00235 #if NS_BLOCKS_AVAILABLE 00236 + (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth 00237 authorizationURL:(NSURL *)authorizationURL 00238 keychainItemName:(NSString *)keychainItemName // may be nil 00239 completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler; 00240 00241 - (id)initWithAuthentication:(GTMOAuth2Authentication *)auth 00242 authorizationURL:(NSURL *)authorizationURL 00243 keychainItemName:(NSString *)keychainItemName 00244 completionHandler:(void (^)(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error))handler; 00245 #endif 00246 00247 // Override default in UIViewController. If we have a navigationController, ask 00248 // it. else default result (i.e., Portrait mode only). 00249 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; 00250 00251 // subclasses may override authNibName to specify a custom name 00252 + (NSString *)authNibName; 00253 00254 // subclasses may override authNibBundle to specify a custom bundle 00255 + (NSBundle *)authNibBundle; 00256 00257 // apps may replace the sign-in class with their own subclass of it 00258 + (Class)signInClass; 00259 + (void)setSignInClass:(Class)theClass; 00260 00261 - (void)cancelSigningIn; 00262 00263 // revocation of an authorized token from Google 00264 #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT 00265 + (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth; 00266 #endif 00267 00268 // 00269 // Keychain 00270 // 00271 00272 // create an authentication object for Google services from the access 00273 // token and secret stored in the keychain; if no token is available, return 00274 // an unauthorized auth object 00275 #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT 00276 + (GTMOAuth2Authentication *)authForGoogleFromKeychainForName:(NSString *)keychainItemName 00277 clientID:(NSString *)clientID 00278 clientSecret:(NSString *)clientSecret; 00279 #endif 00280 00281 // add tokens from the keychain, if available, to the authentication object 00282 // 00283 // returns YES if the authentication object was authorized from the keychain 00284 + (BOOL)authorizeFromKeychainForName:(NSString *)keychainItemName 00285 authentication:(GTMOAuth2Authentication *)auth; 00286 00287 // method for deleting the stored access token and secret, useful for "signing 00288 // out" 00289 + (BOOL)removeAuthFromKeychainForName:(NSString *)keychainItemName; 00290 00291 // method for saving the stored access token and secret 00292 + (BOOL)saveParamsToKeychainForName:(NSString *)keychainItemName 00293 accessibility:(CFTypeRef)accessibility 00294 authentication:(GTMOAuth2Authentication *)auth; 00295 00296 // older version, defaults to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 00297 + (BOOL)saveParamsToKeychainForName:(NSString *)keychainItemName 00298 authentication:(GTMOAuth2Authentication *)auth; 00299 00300 @end 00301 00302 // To function, GTMOAuth2ViewControllerTouch needs a certain amount of access 00303 // to the iPhone's keychain. To keep things simple, its keychain access is 00304 // broken out into a helper class. We declare it here in case you'd like to use 00305 // it too, to store passwords. 00306 00307 enum { 00308 kGTMOAuth2KeychainErrorBadArguments = -1301, 00309 kGTMOAuth2KeychainErrorNoPassword = -1302 00310 }; 00311 00312 00313 @interface GTMOAuth2Keychain : NSObject 00314 00315 + (GTMOAuth2Keychain *)defaultKeychain; 00316 00317 // OK to pass nil for the error parameter. 00318 - (NSString *)passwordForService:(NSString *)service 00319 account:(NSString *)account 00320 error:(NSError **)error; 00321 00322 // OK to pass nil for the error parameter. 00323 - (BOOL)removePasswordForService:(NSString *)service 00324 account:(NSString *)account 00325 error:(NSError **)error; 00326 00327 // OK to pass nil for the error parameter. 00328 // 00329 // accessibility should be one of the constants for kSecAttrAccessible 00330 // such as kSecAttrAccessibleWhenUnlocked 00331 - (BOOL)setPassword:(NSString *)password 00332 forService:(NSString *)service 00333 accessibility:(CFTypeRef)accessibility 00334 account:(NSString *)account 00335 error:(NSError **)error; 00336 00337 // For unit tests: allow setting a mock object 00338 + (void)setDefaultKeychain:(GTMOAuth2Keychain *)keychain; 00339 00340 @end 00341 00342 #endif // TARGET_OS_IPHONE 00343 00344 #endif // #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES