BBGMultiAccountManager
 All Classes Files Functions Variables Enumerator Properties Defines
GMultiAccountManager/GMultiAccountManager/GTMOAuth2WindowController.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 // GTMOAuth2WindowController
00017 //
00018 // This window controller for Mac handles sign-in via OAuth2 to Google or
00019 // other services.
00020 //
00021 // This controller is not reusable; create a new instance of this controller
00022 // every time the user will sign in.
00023 //
00024 // Sample usage for signing in to a Google service:
00025 //
00026 //  static NSString *const kKeychainItemName = @”My App: Google Plus”;
00027 //  NSString *scope = @"https://www.googleapis.com/auth/plus.me";
00028 //
00029 //
00030 //  GTMOAuth2WindowController *windowController;
00031 //  windowController = [[[GTMOAuth2WindowController alloc] initWithScope:scope
00032 //                                                              clientID:clientID
00033 //                                                          clientSecret:clientSecret
00034 //                                                      keychainItemName:kKeychainItemName
00035 //                                                        resourceBundle:nil] autorelease];
00036 //
00037 //  [windowController signInSheetModalForWindow:mMainWindow
00038 //                                     delegate:self
00039 //                             finishedSelector:@selector(windowController:finishedWithAuth:error:)];
00040 //
00041 // The finished selector should have a signature matching this:
00042 //
00043 //  - (void)windowController:(GTMOAuth2WindowController *)windowController
00044 //          finishedWithAuth:(GTMOAuth2Authentication *)auth
00045 //                     error:(NSError *)error {
00046 //    if (error != nil) {
00047 //     // sign in failed
00048 //    } else {
00049 //     // sign in succeeded
00050 //     //
00051 //     // with the GTL library, pass the authentication to the service object,
00052 //     // like
00053 //     //   [[self contactService] setAuthorizer:auth];
00054 //     //
00055 //     // or use it to sign a request directly, like
00056 //     //  BOOL isAuthorizing = [self authorizeRequest:request
00057 //     //                                     delegate:self
00058 //     //                            didFinishSelector:@selector(auth:finishedWithError:)];
00059 //    }
00060 //  }
00061 //
00062 // To sign in to services other than Google, use the longer init method,
00063 // as shown in the sample application
00064 //
00065 // If the network connection is lost for more than 30 seconds while the sign-in
00066 // html is displayed, the notification kGTLOAuthNetworkLost will be sent.
00067 
00068 #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES
00069 
00070 #include <Foundation/Foundation.h>
00071 
00072 #if !TARGET_OS_IPHONE
00073 
00074 #import <Cocoa/Cocoa.h>
00075 #import <WebKit/WebKit.h>
00076 
00077 // GTMHTTPFetcher.h brings in GTLDefines/GDataDefines
00078 #import "GTMHTTPFetcher.h"
00079 
00080 #import "GTMOAuth2SignIn.h"
00081 #import "GTMOAuth2Authentication.h"
00082 #import "GTMHTTPFetchHistory.h" // for GTMCookieStorage
00083 
00084 @class GTMOAuth2SignIn;
00085 
00086 @interface GTMOAuth2WindowController : NSWindowController {
00087  @private
00088   // IBOutlets
00089   NSButton *keychainCheckbox_;
00090   WebView *webView_;
00091   NSButton *webCloseButton_;
00092   NSButton *webBackButton_;
00093 
00094   // the object responsible for the sign-in networking sequence; it holds
00095   // onto the authentication object as well
00096   GTMOAuth2SignIn *signIn_;
00097 
00098   // the page request to load when awakeFromNib occurs
00099   NSURLRequest *initialRequest_;
00100 
00101   // local storage for WebKit cookies so they're not shared with Safari
00102   GTMCookieStorage *cookieStorage_;
00103 
00104   // the user we're calling back
00105   //
00106   // the delegate is retained only until the callback is invoked
00107   // or the sign-in is canceled
00108   id delegate_;
00109   SEL finishedSelector_;
00110 
00111 #if NS_BLOCKS_AVAILABLE
00112   void (^completionBlock_)(GTMOAuth2Authentication *, NSError *);
00113 #elif !__LP64__
00114   // placeholders: for 32-bit builds, keep the size of the object's ivar section
00115   // the same with and without blocks
00116 #ifndef __clang_analyzer__
00117   id completionPlaceholder_;
00118 #endif
00119 #endif
00120 
00121   // flag allowing application to quit during display of sign-in sheet on 10.6
00122   // and later
00123   BOOL shouldAllowApplicationTermination_;
00124 
00125   // delegate method for handling URLs to be opened in external windows
00126   SEL externalRequestSelector_;
00127 
00128   BOOL isWindowShown_;
00129 
00130   // paranoid flag to ensure we only close once during the sign-in sequence
00131   BOOL hasDoneFinalRedirect_;
00132 
00133   // paranoid flag to ensure we only call the user back once
00134   BOOL hasCalledFinished_;
00135 
00136   // if non-nil, we display as a sheet on the specified window
00137   NSWindow *sheetModalForWindow_;
00138 
00139   // if non-empty, the name of the application and service used for the
00140   // keychain item
00141   NSString *keychainItemName_;
00142 
00143   // if non-nil, the html string to be displayed immediately upon opening
00144   // of the web view
00145   NSString *initialHTMLString_;
00146 
00147   // if true, we allow default WebView handling of cookies, so the
00148   // same user remains signed in each time the dialog is displayed
00149   BOOL shouldPersistUser_;
00150 
00151   // user-defined data
00152   id userData_;
00153   NSMutableDictionary *properties_;
00154 }
00155 
00156 // User interface elements
00157 @property (nonatomic, assign) IBOutlet NSButton *keychainCheckbox;
00158 @property (nonatomic, assign) IBOutlet WebView *webView;
00159 @property (nonatomic, assign) IBOutlet NSButton *webCloseButton;
00160 @property (nonatomic, assign) IBOutlet NSButton *webBackButton;
00161 
00162 // The application and service name to use for saving the auth tokens
00163 // to the keychain
00164 @property (nonatomic, copy)   NSString *keychainItemName;
00165 
00166 // If true, the sign-in will remember which user was last signed in
00167 //
00168 // Defaults to false, so showing the sign-in window will always ask for
00169 // the username and password, rather than skip to the grant authorization
00170 // page.  During development, it may be convenient to set this to true
00171 // to speed up signing in.
00172 @property (nonatomic, assign) BOOL shouldPersistUser;
00173 
00174 // Optional html string displayed immediately upon opening the web view
00175 //
00176 // This string is visible just until the sign-in web page loads, and
00177 // may be used for a "Loading..." type of message
00178 @property (nonatomic, copy)   NSString *initialHTMLString;
00179 
00180 // The default timeout for an unreachable network during display of the
00181 // sign-in page is 30 seconds, after which the notification
00182 // kGTLOAuthNetworkLost is sent; set this to 0 to have no timeout
00183 @property (nonatomic, assign) NSTimeInterval networkLossTimeoutInterval;
00184 
00185 // On 10.6 and later, the sheet can allow application termination by calling
00186 // NSWindow's setPreventsApplicationTerminationWhenModal:
00187 @property (nonatomic, assign) BOOL shouldAllowApplicationTermination;
00188 
00189 // Selector for a delegate method to handle requests sent to an external
00190 // browser.
00191 //
00192 // Selector should have a signature matching
00193 // - (void)windowController:(GTMOAuth2WindowController *)controller
00194 //             opensRequest:(NSURLRequest *)request;
00195 //
00196 // The controller's default behavior is to use NSWorkspace's openURL:
00197 @property (nonatomic, assign) SEL externalRequestSelector;
00198 
00199 // The underlying object to hold authentication tokens and authorize http
00200 // requests
00201 @property (nonatomic, retain, readonly) GTMOAuth2Authentication *authentication;
00202 
00203 // The underlying object which performs the sign-in networking sequence
00204 @property (nonatomic, retain, readonly) GTMOAuth2SignIn *signIn;
00205 
00206 // Any arbitrary data object the user would like the controller to retain
00207 @property (nonatomic, retain) id userData;
00208 
00209 // Stored property values are retained for the convenience of the caller
00210 - (void)setProperty:(id)obj forKey:(NSString *)key;
00211 - (id)propertyForKey:(NSString *)key;
00212 
00213 @property (nonatomic, retain) NSDictionary *properties;
00214 
00215 - (IBAction)closeWindow:(id)sender;
00216 
00217 // Create a controller for authenticating to Google services
00218 //
00219 // scope is the requested scope of authorization
00220 //   (like "http://www.google.com/m8/feeds")
00221 //
00222 // keychainItemName is used for storing the token on the keychain,
00223 //   and is required for the "remember for later" checkbox to be shown;
00224 //   keychainItemName should be like "My Application: Google Contacts"
00225 //   (or set to nil if no persistent keychain storage is desired)
00226 //
00227 // resourceBundle may be nil if the window is in the main bundle's nib
00228 #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
00229 + (id)controllerWithScope:(NSString *)scope
00230                  clientID:(NSString *)clientID
00231              clientSecret:(NSString *)clientSecret
00232          keychainItemName:(NSString *)keychainItemName  // may be nil
00233            resourceBundle:(NSBundle *)bundle;           // may be nil
00234 
00235 - (id)initWithScope:(NSString *)scope
00236            clientID:(NSString *)clientID
00237        clientSecret:(NSString *)clientSecret
00238    keychainItemName:(NSString *)keychainItemName
00239      resourceBundle:(NSBundle *)bundle;
00240 #endif
00241 
00242 // Create a controller for authenticating to non-Google services, taking
00243 //   explicit endpoint URLs and an authentication object
00244 + (id)controllerWithAuthentication:(GTMOAuth2Authentication *)auth
00245                   authorizationURL:(NSURL *)authorizationURL
00246                   keychainItemName:(NSString *)keychainItemName  // may be nil
00247                     resourceBundle:(NSBundle *)bundle;           // may be nil
00248 
00249 // This is the designated initializer
00250 - (id)initWithAuthentication:(GTMOAuth2Authentication *)auth
00251             authorizationURL:(NSURL *)authorizationURL
00252             keychainItemName:(NSString *)keychainItemName
00253               resourceBundle:(NSBundle *)bundle;
00254 
00255 // Entry point to begin displaying the sign-in window
00256 //
00257 // the finished selector should have a signature matching
00258 //  - (void)windowController:(GTMOAuth2WindowController *)windowController
00259 //          finishedWithAuth:(GTMOAuth2Authentication *)auth
00260 //                     error:(NSError *)error {
00261 //
00262 // Once the finished method has been invoked with no error, the auth object
00263 // may be used to authorize requests (refreshing the access token, if necessary,
00264 // and adding the auth header) like:
00265 //
00266 //     [authorizer authorizeRequest:myNSMutableURLRequest]
00267 //                        delegate:self
00268 //               didFinishSelector:@selector(auth:finishedWithError:)];
00269 //
00270 // or can be stored in a GTL service object like
00271 //   GTLServiceGoogleContact *service = [self contactService];
00272 //   [service setAuthorizer:auth];
00273 //
00274 // The delegate is retained only until the finished selector is invoked or
00275 //   the sign-in is canceled
00276 - (void)signInSheetModalForWindow:(NSWindow *)parentWindowOrNil
00277                          delegate:(id)delegate
00278                  finishedSelector:(SEL)finishedSelector;
00279 
00280 #if NS_BLOCKS_AVAILABLE
00281 - (void)signInSheetModalForWindow:(NSWindow *)parentWindowOrNil
00282                 completionHandler:(void (^)(GTMOAuth2Authentication *auth, NSError *error))handler;
00283 #endif
00284 
00285 - (void)cancelSigningIn;
00286 
00287 // Subclasses may override authNibName to specify a custom name
00288 + (NSString *)authNibName;
00289 
00290 // apps may replace the sign-in class with their own subclass of it
00291 + (Class)signInClass;
00292 + (void)setSignInClass:(Class)theClass;
00293 
00294 // Revocation of an authorized token from Google
00295 #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
00296 + (void)revokeTokenForGoogleAuthentication:(GTMOAuth2Authentication *)auth;
00297 #endif
00298 
00299 // Keychain
00300 //
00301 // The keychain checkbox is shown if the keychain application service
00302 // name (typically set in the initWithScope: method) is non-empty
00303 //
00304 
00305 // Create an authentication object for Google services from the access
00306 // token and secret stored in the keychain; if no token is available, return
00307 // an unauthorized auth object
00308 #if !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
00309 + (GTMOAuth2Authentication *)authForGoogleFromKeychainForName:(NSString *)keychainItemName
00310                                                      clientID:(NSString *)clientID
00311                                                  clientSecret:(NSString *)clientSecret;
00312 #endif
00313 
00314 // Add tokens from the keychain, if available, to the authentication object
00315 //
00316 // returns YES if the authentication object was authorized from the keychain
00317 + (BOOL)authorizeFromKeychainForName:(NSString *)keychainItemName
00318                       authentication:(GTMOAuth2Authentication *)auth;
00319 
00320 // Method for deleting the stored access token and secret, useful for "signing
00321 // out"
00322 + (BOOL)removeAuthFromKeychainForName:(NSString *)keychainItemName;
00323 
00324 // Method for saving the stored access token and secret; typically, this method
00325 // is used only by the window controller
00326 + (BOOL)saveAuthToKeychainForName:(NSString *)keychainItemName
00327                    authentication:(GTMOAuth2Authentication *)auth;
00328 @end
00329 
00330 #endif // #if !TARGET_OS_IPHONE
00331 
00332 #endif // #if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES