Git Product home page Git Product logo

gtm-oauth2's Introduction

⚠️ Deprecation Notice

Google has deprecated the use of embedded web-views for OAuth, which this library relies on. When making OAuth requests to Google, use the replacement GTMAppAuth library.

GTM OAuth 2: Google Toolbox for Mac - OAuth 2 Controllers

Project site https://github.com/google/gtm-oauth2
Discussion group http://groups.google.com/group/gtm-oauth2

The Google Toolbox for Mac OAuth 2 Controllers make it easy for Cocoa applications to sign in to services using OAuth 2 for authentication and authorization.

Features include:

  • Complete embedded user interface using WebKit
  • Works with Google APIs and with any standard OAuth 2 provider
  • Handles sign-in, keychain storage of authorization token, and authorizing of requests
  • Independent of other projects

To get started with GTM OAuth 2, read the wiki.

If you have a problem or want a new feature to be included in the library, please join the GTM-OAuth 2 discussion group or submit an issue.

The library incorporates the GTM Session Fetcher project.

There is a separate project for OAuth 1 controllers.

Other useful classes for Mac and iOS developers are available in the Google Toolbox for Mac.

gtm-oauth2's People

Contributors

gmrobbins avatar perotinus avatar thomasvl avatar williamdenniss avatar zkrige avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gtm-oauth2's Issues

auth.userEmail getting wrong email address

What steps will reproduce the problem?
1. After succesful autentication using self.auth = 
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:GOOGLE_KEYCHAIN
                                                          clientID:GOOGLE_CLIENT_ID
                                                      clientSecret:GOOGLE_CLIENT_SECRET];
2.
3.

What is the expected output? What do you see instead?
I need the gmail email string '[email protected]' but I get 
[email protected]


What version of the product are you using? On what operating system?
Last version


Please provide any additional information below.


Original issue reported on code.google.com by [email protected] on 19 Jul 2014 at 12:02

Patch for /trunk/Source/GTMOAuth2Authentication.h

/* Copyright (c) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if GTM_INCLUDE_OAUTH2 || !GDATA_REQUIRE_SERVICE_INCLUDES

// This class implements the OAuth 2 protocol for authorizing requests.
// http://tools.ietf.org/html/draft-ietf-oauth-v2

#import <Foundation/Foundation.h>

#if GTM_USE_SESSION_FETCHER
  #import "GTMSessionFetcher.h"
#else
  #import "GTMHTTPFetcher.h"
#endif  // GTM_USE_SESSION_FETCHER

#define GTMOAuth2Fetcher GTMBridgeFetcher
#define GTMOAuth2FetcherService GTMBridgeFetcherService
#define GTMOAuth2FetcherServiceProtocol GTMBridgeFetcherServiceProtocol
#define GTMOAuth2AssertValidSelector GTMBridgeAssertValidSelector
#define GTMOAuth2CookieStorage GTMBridgeCookieStorage
#define kGTMOAuth2FetcherStatusDomain kGTMBridgeFetcherStatusDomain
#define kGTMOAuth2StatusBadRequest kGTMBridgeFetcherStatusBadRequest


// Until all OAuth 2 providers are up to the same spec, we'll provide a crude
// way here to override the "Bearer" string in the Authorization header
#ifndef GTM_OAUTH2_BEARER
#define GTM_OAUTH2_BEARER "Bearer"
#endif

#ifdef __cplusplus
extern "C" {
#endif

// Service provider name allows stored authorization to be associated with
// the authorizing service
extern NSString *const kGTMOAuth2ServiceProviderGoogle;

//
// GTMOAuth2SignIn constants, included here for use by clients
//
extern NSString *const kGTMOAuth2ErrorDomain;

// Error userInfo keys
extern NSString *const kGTMOAuth2ErrorMessageKey;
extern NSString *const kGTMOAuth2ErrorRequestKey;
extern NSString *

Original issue reported on code.google.com by dulowiskotic1234 on 3 May 2015 at 3:54

Attachments:

JSON format issue for POJO objects as @ApiMethod parameters

What steps will reproduce the problem?
1. Create a Google Endpoint that takes a POJO parameter
2. Generate the client proxies for Objective-C using the provided tool
3. Call the service method by creating the Api parameter object generated and 
calling the service method
4. The object properties will be NULL at the server for the incoming POJO

What is the expected output? What do you see instead?

Expect the values put into the Obj-C client proxy version of the POJO.

The Google Endpoint project has 3 clients: Android, Javascript (Web) and iOS.  
By comparing the body POST data of the working client calls with those of the 
iOS/gtm client, I was able to find the issue.

The JSON being sent to the API for the POJO parameter differs in that it is 
nested below a top level object "resource:"... aka. kBodyObjectParamKey

So what works for the param:
{
    someProp:"some value";
}
is sent as
{
    resource: {
          someProp:"some value";
    }
}
and the server side POJO has null values.

What version of the product are you using? On what operating system?
2.x on Mac.  Should not be a factor.

Please provide any additional information below.
I was able to isolate the issue and modify the code in GTLService so that it 
would place the JSON body under the "params" directly, without the nesting 
below "resource:", and no surprise, it started working just like the other 
clients.  There may be something going on deeper that I am missing, or an 
option I missed, but I don't see it in the code so far.  Going to do more 
testing, but any insight would be helpful.


Original issue reported on code.google.com by [email protected] on 28 Jan 2014 at 4:17

Extension Grants

Resource Owner Password Credentials Grant is not supported yet.
and in order to comply with the document "rfc6749", especially "4.5.  Extension 
Grants", provider-extended grant should be supported.

Original issue reported on code.google.com by [email protected] on 13 Feb 2014 at 11:47

Authentication does not work with some SAML based SSO IdPs

What steps will reproduce the problem?
1. Login to an account with a sheffield.ac.uk (we use SAML SSO with Google). 
2. Get redirected to our internal CAS service (correct)
3. Get logged into our portal (incorrect... this generally happens because the 
URL query string is missing that tells CAS to redirect you back to our SAML IdP 
before getting passed to Google)

What is the expected output? What do you see instead?

OAuth Token never gets generated as Google never receives a valid SAML response 
from our IdP. 


What version of the product are you using? On what operating system?

Example application compiled from latest SVN.

Please provide any additional information below.

I've been discussing this problem with the developers of BusyCal. It seems that 
gtm-oauth2 is not playing nicely with our IdP. We get to the google sign in 
page, which on receipt of a sheffield.ac.uk domain redirects you to our SAML 
IdP, which in turn redirects you to our internal CAS servers (our internal 
authentication). By this point, the query string seems to have been removed, 
which causes our CAS server to log you into the default service (our internal 
portal) and the request never gets back to the Google SP. 

Original issue reported on code.google.com by [email protected] on 17 May 2013 at 10:45

error=access_denied after submitting user name and password in OAuth2 Process

I am doing OAuth2 for sharepoint and onedrive using GTM but after I submitting the credentials i am getting this error frequently .
Authentication error: Error Domain=com.google.GTMOAuth2 Code=-1000 "The operation couldn’t be completed. (com.google.GTMOAuth2 error -1000.)"

And for some users I am not getting this error. I am surprised why it not working for some users. And I observed one thing for any user OAuth Process is not asking accept perrmision screen. Can any one help me to find out the problem
I used the same sample signInToDailyMotion code by replacing my Client ID and Secret

This is my code:

/* Copyright (c) 2011 Google Inc.
*

  • Licensed under the Apache License, Version 2.0 (the "License");
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at
    *
  • http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an "AS IS" BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */

// OAuth2SampleRootViewControllerTouch.m

import "OAuth2SampleRootViewControllerTouch.h"

import "GTMOAuth2ViewControllerTouch.h"

import "GTMOAuth2SignIn.h"

static NSString *const kKeychainItemName = @"OAuth Sample: Google Contacts";
static NSString *const kShouldSaveInKeychainKey = @"shouldSaveInKeychain";

static NSString *const kDailyMotionAppServiceName = @"OAuth Sample: DailyMotion";
static NSString *const kDailyMotionServiceName = @"DailyMotion";

@implementation OAuth2SampleRootViewControllerTouch

@synthesize clientIDField = mClientIDField,
clientSecretField = mClientSecretField,
serviceNameField = mServiceNameField,
emailField = mEmailField,
expirationField = mExpirationField,
accessTokenField = mAccessTokenField,
refreshTokenField = mRefreshTokenField,
fetchButton = mFetchButton,
expireNowButton = mExpireNowButton,
serviceSegments = mServiceSegments,
shouldSaveInKeychainSwitch = mShouldSaveInKeychainSwitch,
signInOutButton = mSignInOutButton;

@synthesize auth = mAuth;

// NSUserDefaults keys
static NSString *const kGoogleClientIDKey = @"GoogleClientID";
static NSString *const kGoogleClientSecretKey = @"GoogleClientSecret";
static NSString *const kDailyMotionClientIDKey = @"DailyMotionClientID";
static NSString *const kDailyMotionClientSecretKey = @"DailyMotionClientSecret";

  • (void)awakeFromNib {
    // Listen for network change notifications
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(incrementNetworkActivity:) name:kGTMOAuth2WebViewStartedLoading object:nil];
    [nc addObserver:self selector:@selector(decrementNetworkActivity:) name:kGTMOAuth2WebViewStoppedLoading object:nil];
    [nc addObserver:self selector:@selector(incrementNetworkActivity:) name:kGTMOAuth2FetchStarted object:nil];
    [nc addObserver:self selector:@selector(decrementNetworkActivity:) name:kGTMOAuth2FetchStopped object:nil];
    [nc addObserver:self selector:@selector(signInNetworkLostOrFound:) name:kGTMOAuth2NetworkLost object:nil];
    [nc addObserver:self selector:@selector(signInNetworkLostOrFound:) name:kGTMOAuth2NetworkFound object:nil];

    // Fill in the Client ID and Client Secret text fields
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    // First, we'll try to get the saved Google authentication, if any, from
    // the keychain

    // Normal applications will hardcode in their client ID and client secret,
    // but the sample app allows the user to enter them in a text field, and
    // saves them in the preferences
    NSString *clientID = [defaults stringForKey:kGoogleClientIDKey];
    NSString *clientSecret = [defaults stringForKey:kGoogleClientSecretKey];

    GTMOAuth2Authentication *auth = nil;

    if (clientID && clientSecret) {
    auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
    clientID:clientID
    clientSecret:clientSecret];
    }

    if (auth.canAuthorize) {
    // Select the Google service segment
    self.serviceSegments.selectedSegmentIndex = 0;
    } else {
    // There is no saved Google authentication
    //
    // Perhaps we have a saved authorization for DailyMotion instead; try getting
    // that from the keychain

    clientID = [defaults stringForKey:kDailyMotionClientIDKey];
    clientSecret = [defaults stringForKey:kDailyMotionClientSecretKey];

    if (clientID && clientSecret) {
    auth = [self authForDailyMotion];
    if (auth) {
    auth.clientID = clientID;
    auth.clientSecret = clientSecret;

      BOOL didAuth = [GTMOAuth2ViewControllerTouch authorizeFromKeychainForName:kDailyMotionAppServiceName
                                                                 authentication:auth
                                                                          error:NULL];
      if (didAuth) {
        // select the DailyMotion radio button
        self.serviceSegments.selectedSegmentIndex = 1;
      }
    }
    

    }
    }

    // Save the authentication object, which holds the auth tokens and
    // the scope string used to obtain the token. For Google services,
    // the auth object also holds the user's email address.
    self.auth = auth;

    // Update the client ID value text fields to match the radio button selection
    [self loadClientIDValues];

    BOOL isRemembering = [self shouldSaveInKeychain];
    self.shouldSaveInKeychainSwitch.on = isRemembering;
    [self updateUI];
    }

  • (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [mServiceSegments release];
    [mClientIDField release];
    [mClientSecretField release];
    [mServiceNameField release];
    [mEmailField release];
    [mAccessTokenField release];
    [mExpirationField release];
    [mRefreshTokenField release];
    [mFetchButton release];
    [mExpireNowButton release];
    [mShouldSaveInKeychainSwitch release];
    [mSignInOutButton release];
    [mAuth release];

    [super dealloc];
    }

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
    // Returns non-zero on iPad, but backward compatible to SDKs earlier than 3.2.
    if (UI_USER_INTERFACE_IDIOM()) {
    return YES;
    }
    return [super shouldAutorotateToInterfaceOrientation:orientation];
    }

  • (BOOL)isSignedIn {
    BOOL isSignedIn = self.auth.canAuthorize;
    return isSignedIn;
    }

  • (BOOL)isGoogleSegmentSelected {
    NSInteger segmentIndex = self.serviceSegments.selectedSegmentIndex;
    return (segmentIndex == 0);
    }

  • (IBAction)serviceSegmentClicked:(id)sender {
    [self loadClientIDValues];
    }

  • (IBAction)signInOutClicked:(id)sender {
    [self saveClientIDValues];

    if (![self isSignedIn]) {
    // Sign in
    if ([self isGoogleSegmentSelected]) {
    [self signInToGoogle];
    } else {
    [self signInToDailyMotion];
    }
    } else {
    // Sign out
    [self signOut];
    }
    [self updateUI];
    }

  • (IBAction)fetchClicked:(id)sender {
    // Just to prove we're signed in, we'll attempt an authenticated fetch for the
    // signed-in user
    [self doAnAuthenticatedAPIFetch];
    }

  • (IBAction)expireNowClicked:(id)sender {
    NSDate *date = self.auth.expirationDate;
    if (date) {
    self.auth.expirationDate = [NSDate dateWithTimeIntervalSince1970:0];
    [self updateUI];
    }
    }

// UISwitch does the toggling for us. We just need to read the state.

  • (IBAction)toggleShouldSaveInKeychain:(UISwitch *)sender {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:sender.isOn forKey:kShouldSaveInKeychainKey];
    }

  • (void)signOut {
    if ([self.auth.serviceProvider isEqual:kGTMOAuth2ServiceProviderGoogle]) {
    // remove the token from Google's servers
    [GTMOAuth2ViewControllerTouch revokeTokenForGoogleAuthentication:self.auth];
    }

    // remove the stored Google authentication from the keychain, if any
    [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];

    // remove the stored DailyMotion authentication from the keychain, if any
    [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kDailyMotionAppServiceName];

    // Discard our retained authentication object.
    self.auth = nil;

    [self updateUI];
    }

  • (void)signInToGoogle {
    [self signOut];

    NSString *keychainItemName = nil;
    if ([self shouldSaveInKeychain]) {
    keychainItemName = kKeychainItemName;
    }

    // For Google APIs, the scope strings are available
    // in the service constant header files.
    NSString *scope = @"https://www.googleapis.com/auth/plus.me";

    // Typically, applications will hardcode the client ID and client secret
    // strings into the source code; they should not be user-editable or visible.
    //
    // But for this sample code, they are editable.
    NSString *clientID = self.clientIDField.text;
    NSString *clientSecret = self.clientSecretField.text;

    if ([clientID length] == 0 || [clientSecret length] == 0) {
    NSString *msg = @"The sample code requires a valid client ID and client secret to sign in.";
    [self displayAlertWithMessage:msg];
    return;
    }

    // Note:
    // GTMOAuth2ViewControllerTouch is not designed to be reused. Make a new
    // one each time you are going to show it.

    // Display the autentication view.
    SEL finishedSel = @selector(viewController:finishedWithAuth:error:);

    GTMOAuth2ViewControllerTouch *viewController;
    viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:scope
    clientID:clientID
    clientSecret:clientSecret
    keychainItemName:keychainItemName
    delegate:self
    finishedSelector:finishedSel];

    // You can set the title of the navigationItem of the controller here, if you
    // want.

    // If the keychainItemName is not nil, the user's authorization information
    // will be saved to the keychain. By default, it saves with accessibility
    // kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, but that may be
    // customized here. For example,
    //
    // viewController.keychainItemAccessibility = kSecAttrAccessibleAlways;

    // During display of the sign-in window, loss and regain of network
    // connectivity will be reported with the notifications
    // kGTMOAuth2NetworkLost/kGTMOAuth2NetworkFound
    //
    // See the method signInNetworkLostOrFound: for an example of handling
    // the notification.

    // Optional: Google servers allow specification of the sign-in display
    // language as an additional "hl" parameter to the authorization URL,
    // using BCP 47 language codes.
    //
    // For this sample, we'll force English as the display language.
    NSDictionary *params = [NSDictionary dictionaryWithObject:@"en"
    forKey:@"hl"];
    viewController.signIn.additionalAuthorizationParameters = params;

    // By default, the controller will fetch the user's email, but not the rest of
    // the user's profile. The full profile can be requested from Google's server
    // by setting this property before sign-in:
    //
    // viewController.signIn.shouldFetchGoogleUserProfile = YES;
    //
    // The profile will be available after sign-in as
    //
    // NSDictionary *profile = viewController.signIn.userProfile;

    // Optional: display some html briefly before the sign-in page loads
    NSString *html = @"

    Loading sign-in page...
    ";
    viewController.initialHTMLString = html;

    [[self navigationController] pushViewController:viewController animated:YES];

    // The view controller will be popped before signing in has completed, as
    // there are some additional fetches done by the sign-in controller.
    // The kGTMOAuth2UserSignedIn notification will be posted to indicate
    // that the view has been popped and those additional fetches have begun.
    // It may be useful to display a temporary UI when kGTMOAuth2UserSignedIn is
    // posted, just until the finished selector is invoked.
    }

  • (GTMOAuth2Authentication *)authForDailyMotion {
    // http://www.dailymotion.com/doc/api/authentication.html
    // NSURL *tokenURL = [NSURL URLWithString:@"https://api.dailymotion.com/oauth/token"];
    NSURL *tokenURL = [NSURL URLWithString:@"https://login.windows.net/common/oauth2/token"];
    NSString *redirectURI = @"http://localhost/OAuthCallback";
    NSString *clientID = @"###########";
    NSString *clientSecret = @"#############";
    // NSDictionary *additionalParams = @{@"resource" : @"https://api.office.com/discovery/",@"prompt":@"consent"};

    // We'll make up an arbitrary redirectURI. The controller will watch for
    // the server to redirect the web view to this URI, but this URI will not be
    // loaded, so it need not be for any actual web page.
    // NSString *redirectURI = @"http://www.google.com/OAuthCallback";

// NSString *clientID = self.clientIDField.text;
// NSString *clientSecret = self.clientSecretField.text;

GTMOAuth2Authentication *auth;
auth = [GTMOAuth2Authentication authenticationWithServiceProvider:kDailyMotionServiceName
tokenURL:tokenURL
redirectURI:redirectURI
clientID:clientID
clientSecret:clientSecret
];
return auth;
}

  • (void)signInToDailyMotion {
    [self signOut];

    GTMOAuth2Authentication *auth = [self authForDailyMotion];
    auth.scope = @"read";

    if ([auth.clientID length] == 0 || [auth.clientSecret length] == 0) {
    NSString *msg = @"The sample code requires a valid client ID and client secret to sign in.";
    [self displayAlertWithMessage:msg];
    return;
    }

    NSString *keychainItemName = nil;
    if ([self shouldSaveInKeychain]) {
    keychainItemName = kKeychainItemName;
    }

    NSURL *authURL = [NSURL URLWithString:@"https://login.windows.net/common/oauth2/authorize"];

    // Display the authentication view
    SEL sel = @selector(viewController:finishedWithAuth:error:);

    GTMOAuth2ViewControllerTouch *viewController;
    viewController = [GTMOAuth2ViewControllerTouch controllerWithAuthentication:auth
    authorizationURL:authURL
    keychainItemName:keychainItemName
    delegate:self
    finishedSelector:sel];

    // We can set a URL for deleting the cookies after sign-in so the next time
    // the user signs in, the browser does not assume the user is already signed
    // in
    viewController.browserCookiesURL = [NSURL URLWithString:@"http://api.dailymotion.com/"];

    // You can set the title of the navigationItem of the controller here, if you want

    // Now push our sign-in view
    [[self navigationController] pushViewController:viewController animated:YES];
    }

  • (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
    finishedWithAuth:(GTMOAuth2Authentication *)auth
    error:(NSError *)error {
    if (error != nil) {
    // Authentication failed (perhaps the user denied access, or closed the
    // window before granting access)
    NSLog(@"Authentication error: %@", error);
    NSData *responseData = [[error userInfo] objectForKey:@"data"]; // kGTMHTTPFetcherStatusDataKey
    if ([responseData length] > 0) {
    // show the body of the server's authentication failure response
    NSString *str = [[[NSString alloc] initWithData:responseData
    encoding:NSUTF8StringEncoding] autorelease];
    NSLog(@"%@", str);
    }

    self.auth = nil;
    } else {
    // Authentication succeeded
    //
    // At this point, we either use the authentication object to explicitly
    // authorize requests, like
    //
    // [auth authorizeRequest:myNSURLMutableRequest
    // completionHandler:^(NSError *error) {
    // if (error == nil) {
    // // request here has been authorized
    // }
    // }];
    //
    // or store the authentication object into a fetcher or a Google API service
    // object like
    //
    // [fetcher setAuthorizer:auth];

    // save the authentication object
    self.auth = auth;
    }

    [self updateUI];
    }

  • (void)doAnAuthenticatedAPIFetch {
    NSString *urlStr;
    if ([self isGoogleSegmentSelected]) {
    // Google Plus feed
    urlStr = @"https://www.googleapis.com/plus/v1/people/me/activities/public";
    } else {
    // DailyMotion status feed
    urlStr = @"https://api.dailymotion.com/videos/favorites";
    }

    NSURL *url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [self.auth authorizeRequest:request
    completionHandler:^(NSError *authError) {
    if (authError) {
    [self displayAlertWithMessage:[authError description]];
    } else {
    NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:cfg
    delegate:nil
    delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
    completionHandler:^(NSData *data,
    NSURLResponse *response,
    NSError *taskError) {
    NSString *output = nil;

       if (!taskError) {
         // API fetch succeeded
         output = [[[NSString alloc] initWithData:data
                                         encoding:NSUTF8StringEncoding] autorelease];
       } else {
         // fetch failed
         output = [taskError description];
       }
       [self displayAlertWithMessage:output];
       [self updateUI];
     }];
    [task resume];
    

    }
    }];
    }

pragma mark -

  • (void)incrementNetworkActivity:(NSNotification *)notify {
    ++mNetworkActivityCounter;
    if (mNetworkActivityCounter == 1) {
    UIApplication *app = [UIApplication sharedApplication];
    [app setNetworkActivityIndicatorVisible:YES];
    }
    }
  • (void)decrementNetworkActivity:(NSNotification *)notify {
    --mNetworkActivityCounter;
    if (mNetworkActivityCounter == 0) {
    UIApplication *app = [UIApplication sharedApplication];
    [app setNetworkActivityIndicatorVisible:NO];
    }
    }
  • (void)signInNetworkLostOrFound:(NSNotification *)notify {
    if ([[notify name] isEqual:kGTMOAuth2NetworkLost]) {
    // network connection was lost; alert the user, or dismiss
    // the sign-in view with
    // [[[notify object] delegate] cancelSigningIn];
    } else {
    // network connection was found again
    }
    }

pragma mark -

  • (void)updateUI {
    // update the text showing the signed-in state and the button title
    // A real program would use NSLocalizedString() for strings shown to the user.
    if ([self isSignedIn]) {
    // signed in
    self.serviceNameField.text = self.auth.serviceProvider;
    self.emailField.text = self.auth.userEmail;
    self.accessTokenField.text = self.auth.accessToken;
    self.expirationField.text = [self.auth.expirationDate description];
    self.refreshTokenField.text = self.auth.refreshToken;

    self.signInOutButton.title = @"Sign Out";
    self.fetchButton.enabled = YES;
    self.expireNowButton.enabled = YES;
    } else {
    // signed out
    self.serviceNameField.text = @"-Not signed in-";
    self.emailField.text = @"";
    self.accessTokenField.text = @"-No access token-";
    self.expirationField.text = @"";
    self.refreshTokenField.text = @"-No refresh token-";

    self.signInOutButton.title = @"Sign In";
    self.fetchButton.enabled = NO;
    self.expireNowButton.enabled = NO;
    }

    BOOL isRemembering = [self shouldSaveInKeychain];
    self.shouldSaveInKeychainSwitch.on = isRemembering;
    }

  • (void)displayAlertWithMessage:(NSString *)message {
    UIAlertController *alert =
    [UIAlertController alertControllerWithTitle:@"OAuth2Sample"
    message:message
    preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK"
    style:UIAlertActionStyleDefault
    handler:nil];
    [alert addAction:action];
    [self presentViewController:alert animated:YES completion:nil];
    }

  • (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
    }

  • (void)textFieldDidEndEditing:(UITextField *)textField {
    [self saveClientIDValues];
    }

  • (BOOL)shouldSaveInKeychain {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    BOOL flag = [defaults boolForKey:kShouldSaveInKeychainKey];
    return flag;
    }

pragma mark Client ID and Secret

//
// Normally an application will hardwire the client ID and client secret
// strings in the source code. This sample app has to allow them to be
// entered by the developer, so we'll save them across runs into preferences.
//

  • (void)saveClientIDValues {
    // Save the client ID and secret from the text fields into the prefs
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *clientID = self.clientIDField.text;
    NSString *clientSecret = self.clientSecretField.text;

    if ([self isGoogleSegmentSelected]) {
    [defaults setObject:clientID forKey:kGoogleClientIDKey];
    [defaults setObject:clientSecret forKey:kGoogleClientSecretKey];
    } else {
    [defaults setObject:clientID forKey:kDailyMotionClientIDKey];
    [defaults setObject:clientSecret forKey:kDailyMotionClientSecretKey];
    }
    }

  • (void)loadClientIDValues {
    // Load the client ID and secret from the prefs into the text fields
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    if ([self isGoogleSegmentSelected]) {
    self.clientIDField.text = [defaults stringForKey:kGoogleClientIDKey];
    self.clientSecretField.text = [defaults stringForKey:kGoogleClientSecretKey];
    } else {
    self.clientIDField.text = [defaults stringForKey:kDailyMotionClientIDKey];
    self.clientSecretField.text = [defaults stringForKey:kDailyMotionClientSecretKey];
    }
    }

@EnD

Support text/javascript as valid content-type for JSON responses

What steps will reproduce the problem?

Do OAuth2 with Dropbox Core API using gtm-oauth2

What is the expected output? What do you see instead?

Expect: get access token back
Actual: get nil for the access token

What version of the product are you using? On what operating system?

latest

Please provide any additional information below.

GTMOAuth2Authentication.m in 

- (void)tokenFetcher:(GTMOAuth2Fetcher *)fetcher
    finishedWithData:(NSData *)data
               error:(NSError *)error {

determines if the response is JSON when a response's Content-Type is 
"application/json"

some services, like dropbox, are returning JSON and setting Content-Type to 
"text/javascript".  When that happens gtm-oauth doesn't parse the response 
properly, succeeding but not passing the access token along.

The dart team ran into the same snag and fixed their stuff: 
https://code.google.com/p/dart/issues/detail?id=17067

Original issue reported on code.google.com by [email protected] on 21 Feb 2015 at 7:48

Hi, i got an error while using vpn

DiskCookieStorage changing policy from 0 to 2, cookie file: 
file:///Users/James/Library/Developer/CoreSimulator/Devices/81664719-D3D3-4FAC-9
D68-4BA845AFB0F5/data/Containers/Data/Application/87A986CD-F7E2-4ED2-BC81-3EE208
9097C4/Library/Cookies/Cookies.binarycookies

Original issue reported on code.google.com by [email protected] on 30 Oct 2014 at 1:37

additionalAuthorizationParameters not exposed from Touch View Controller

What steps will reproduce the problem?
1. Need to add additional query string parameter to the authentication HTML URL 
request. The ability to add parameters exists in the GTMOAuth2SignIn class, 
however the view controller instantiates the signIn instance and therefore 
requires you to subclass the view controller in order to set 
additionalAuthorizationParameters on the sign in object.

This is for signing into LinkedIn; they require an additional 'state' query 
string parameter. https://developer.linkedin.com/documents/authentication


What is the expected output? What do you see instead?
Ability to affect the auth URL without having to subclass the OAuth2 web view 
controller.


What version of the product are you using? On what operating system?
iOS 6.1, bringing in the source via CocoaPods.

Please provide any additional information below.

Thanks,
Rene

Original issue reported on code.google.com by [email protected] on 25 Mar 2013 at 11:57

GTMOAuth2Authentication expiresIn can return wrong type

What steps will reproduce the problem?
1. Using Paypal endpoint (sandbox was tested)
2. Login with sandbox credentials
3. method updateExpirationDate throws exception on 
   unsigned long deltaSeconds = [expiresIn unsignedLongValue]; 
-[__NSCFString unsignedLongValue]: unrecognized selector sent to instance 
0x76db300

expiresIn is a NSString because it was sent as quoted string in the JSON 
response from server

What is the expected output? What do you see instead?
exception thrown on completion

What version of the product are you using? On what operating system?
iOS 6 - new application

Please provide any additional information below.

Properties are assigned to GTMOAuth2Authentication properties blindly from  
JSON parsed data, so some implementations may return NSString in token response.

In my case here is the Paypal (truncated) response to 
https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice

{
    "token_type": "Bearer",
    "expires_in": "28800",
    "refresh_token": "XXXXX",
    "id_token": "YYYYYY",
    "access_token": "ZZZZZZ"
}

Would suggest changing implementation of expiresIn to:

- (NSNumber *)expiresIn {
    id value = [self.parameters objectForKey:kOAuth2ExpiresInKey];

    if ([value isKindOfClass:[NSString class]]) {
        value = [NSNumber numberWithInteger:[value integerValue]];
    }
    return value;
}


Original issue reported on code.google.com by [email protected] on 11 Sep 2013 at 10:20

Sign-up/sign-in ios UiWebView is not zoomable

What steps will reproduce the problem?
0. Start with an iOS application where you are not yet signed in to Google
1. Go through an application flow for iOS that requires sign-in
2. Touch the "sign up" button to create a new account
3. Watch the behavior of the UIWebView as it redirects you to an account 
sign-up page

What is the expected output? What do you see instead?

The sign-in page is presentationally optimized for mobile: 
https://accounts.google.com/ServiceLogin?[queryparameters]. The sign-up page 
that the UIWebView directs to from there when the user clicks -- 
https://accounts.google.com/SignUpGadget?[queryparameters] is not mobile 
optimized.

Moreover, the UIWebView is not set to allow the content to be zoomable! Even if 
SignUpGadget is not presenting mobile-optimized HTML -- this is likely beyond 
the scope of this codebase -- the UIWebView should assume it may have to zoom 
or unzoom its content. The server can override this on pages where it knows 
better by including <meta name="viewport" content="user-scalable=no"> in the 
content -- as indeed is done for ServiceLogin -- but the client's baseline 
assumption should be different.


What version of the product are you using? On what operating system?

7-Oct-2011 release of gtm-oauth2. Running on the XCode 4.2 iOS 5.0 simulator 
(bug originally reported on real hardware, though.)


Please provide any additional information below.


Original issue reported on code.google.com by [email protected] on 15 Feb 2012 at 5:42

GTMOAuth2ViewControllerTouch needs refactoring

This class is way too complicated/overloaded.  As a result, it is hard to 
customize.  

1.  Needs better MVC separation.
2.  There are two classes defined in the same class file 
GTMOAuth2ViewControllerTouch and GTMOAuth2Keychain.
3.  Needs ARC compliance.
4.  The finishedSelector can be removed entirely as developers should use 
blocks instead.  This makes the code simpler and cleaner to work with.
5.  Needs support for Storyboard UIs with segue to this authentication 
controller.

Original issue reported on code.google.com by [email protected] on 14 Mar 2014 at 6:22

Hiding view before the pop animation completes is ugly

The code of GTMOAuth2ViewControllerTouch's -popView make the pop animation ugly:
    if (!self.view.isHidden) {
      // Set the flag to our viewWillDisappear method so it knows
      // this is a disappearance initiated by the sign-in object,
      // not the user cancelling via the navigation controller
      didDismissSelf_ = YES;

      if (popViewBlock) {
#if NS_BLOCKS_AVAILABLE
        popViewBlock();
        self.popViewBlock = nil;
#endif
      } else {
        [self.navigationController popViewControllerAnimated:YES];
      }
      self.view.hidden = YES;
    }

I think didViewAppear_ or didDismissSelf_ can by used instead of 
self.view.isHidden as the flag to determine the run path of code so that 
self.view.hidden need not be set to YES here.

Original issue reported on code.google.com by [email protected] on 3 Aug 2012 at 2:02

Invalid convertion from BOOL to (NSMutableDictionary*)

In GTMOAuth2SignIn.m, the -[GTMOAuth2SignIn parametersForWebRequest] method may 
return "NO" if both hasClientID and hasRedirect are both "NO".

> - (NSMutableDictionary *)parametersForWebRequest {
>   GTMOAuth2Authentication *auth = self.authentication;
>   NSString *clientID = auth.clientID;
>   NSString *redirectURI = auth.redirectURI;
> 
>   BOOL hasClientID = ([clientID length] > 0);
>   BOOL hasRedirect = ([redirectURI length] > 0
>                       || redirectURI == [[self class] 
nativeClientRedirectURI]);
>   if (!hasClientID || !hasRedirect) {
> #if DEBUG
>     NSAssert(hasClientID, @"GTMOAuth2SignIn: clientID needed");
>     NSAssert(hasRedirect, @"GTMOAuth2SignIn: redirectURI needed");
> #endif
>     return NO;
>   }

Here, the "return NO;" should either be "return nil;" or "return 
[NSMutableDictionary dictionaryWithObjectsAndKeys:nil];".

Original issue reported on code.google.com by [email protected] on 16 Jan 2014 at 2:27

Unable to customize navigationBar/navigationItem properties if GTMOAuth2ViewController is the rootViewController

As the title I'm unable to customize these properties.

I'm looking to edit the navigationBar color, navigationBar 
button/attributedString attributes, navigationBar title/attributedString 
attributes.

I've already tried overriding setUpNavigation and subclassing, but the result 
is shitty; with shitty I means:

1. If I set the attributedString attributes the text will disappear
2. Can't even set the tintColor

This is happening only with this class.

Original issue reported on code.google.com by [email protected] on 13 Dec 2013 at 6:24

GTMOAuth2ViewControllerTouch does not support endpoints using HTTP basic authentication

What steps will reproduce the problem?
1. Initialize GTMOAuth2ViewControllerTouch with an instance of 
GTMOAuth2Authentication configured with a custom provider
2. Push the view controller instance on the navigation stack and wait for the 
login page to load 
3.

What is the expected output? What do you see instead?

An empty page is loaded if the login page is relying on basic HTTP 
authentication (example is an ADFS server). This is due to the fact that the 
UIWebView does not handle authentication and GTMOAuth2ViewControllerTouch does 
not mitigate this. Hence the support is not there. If the authentication 
endpoint URL is opened in Safari, a popup asking for credentials is shown.

What version of the product are you using? On what operating system?
Revision 117, iOS 5.1, iOS 6.1 OS X 10.8.5. Xcode 4.X.

Please provide any additional information below.

Original issue reported on code.google.com by [email protected] on 21 Sep 2013 at 9:32

retrieving access token from keychain

What steps will reproduce the problem?
1.trying to access the token from keychain


What is the expected output? What do you see instead?
i want to set the token directly and perform the upload. Instead a pop up comes 
asking the permission to access the keychain.

What version of the product are you using? On what operating system?
GTM-OAUTH2 in  Mac OS X 10.6


Please provide any additional information below.
i neednot require any pop ups that asks permission which allows or denies it. i 
want the upload to be done directly

Original issue reported on code.google.com by [email protected] on 5 Oct 2011 at 5:33

Authentication breaks when redirectURI is of the form scheme:/path

I ran into an issue when using gtm-oauth2 to authenticate against an OAuth2 
provider that requires a redirectURI in the form of scheme:/path.

Web authentication is successful but the WebView delegate fails to match the 
redirected request to the redirectURI.

This patch updates the requestRedirectedToRequest method of the GTMOAuth2SignIn 
object to compare scheme and path of the redirectURI when the host is missing. 
This fixes the issue I encountered.

Original issue reported on code.google.com by [email protected] on 31 Dec 2013 at 7:12

Attachments:

Missing GTMOAuth2ViewTouch.nib when built at framework

When building the project as a framework, for instance by include use_frameworks! in the Podfile, using the library will result in a black screen and an error like:

MyApp[123:456]: missing GTMOAuth2ViewTouch.nib

The root of the problem seems to be that the code is looking for the nib/xib in the main bundle, which isn't correctly when the library is included as a framework. As per the Cocoapods documentation on frameworks, the library should use NSBundle bundleForClass instead of NSBundle mainBundle when looking for the resources, to ensure it works correctly whether built as a static library or a framework.

assertion failure at GTMHTTPUploadFetcher.m:402 when using account with no YouTube channel

What steps will reproduce the problem?
1. attempt to upload a video to YouTube on iOS
2.
3.

What is the expected output? What do you see instead?
assertion failure at GTMHTTPUploadFetcher.m:402
Apparently as a result of using a google account with no YouTube account 
channel.

What version of the product are you using? On what operating system?
latest as of dec 3 2013

Please provide any additional information below.


Original issue reported on code.google.com by [email protected] on 4 Dec 2013 at 9:46

GTMOAuth2ViewControllerTouch doesn't correctly handle dismissal with a pop gesture

What steps will reproduce the problem?
1. [in code] Create a new GTMOAuth2ViewControllerTouch instance and push it 
onto the navigation stack.
2. Build and run the app and cause the GTMOAuth2ViewControllerTouch controller 
to be presented.
3. Use the iOS 7 navigation stack pop gesture, but tap and drag from the left 
edge of the screen instead of doing a quick tap and swipe. Don't allow the pop 
to complete by dragging part-way across the screen then back so that the pop 
operation is effectively started and canceled.

What is the expected output? What do you see instead?

The problem is that -viewWillDisappear: is implemented instead of 
-viewDidDisappear:, so as the pop gesture is started, -viewWillDisappear: is 
called and does a state cleanup. When you cancel the pop by dragging back then 
the controller is still active but it's in an inconsistent state. By just 
renaming -viewWillDisappear: to -viewDidDisappear: (both the controller's 
method and its call to super), then the cleanup only happens when the pop has 
actually completed.

This is not something that you would notice if you tapped on the Back button 
since the pop operation always runs to completion.

What version of the product are you using? On what operating system?

This is being built against the iOS 7 SDK and is in the current source as of 
today.

Please provide any additional information below.


Original issue reported on code.google.com by [email protected] on 7 Mar 2014 at 8:24

iOS setCookie

What steps will reproduce the problem?

1. Open the Touch Example App
2. Validate for App Store submission
3. Validator responds with - iTunes Store operation failed. The app references 
non-public selectors ... setCookies. See attached image.



What version of the product are you using? On what operating system?

The latest (r124)



Please provide any additional information below.

The following fixes the validation, but evidently will limit functionality if 
it breaks any sort of NSHTTPCookieStorage logic. 

Changing GTMHTTPFetcher.h:396

from:

- (void)setCookies:(NSArray *)newCookies;

to:

- (void)setCookiesNow:(NSArray *)newCookies;

& changing GTMHTTPFetcher.m:983

from:

[cookieStorage_ setCookies:cookies];

to;

[cookieStorage_ setCookiesNow:cookies];

Original issue reported on code.google.com by [email protected] on 29 Sep 2014 at 12:16

Attachments:

Gmail API GTMOAuth2Authentication.h

Project failing to bridge header because GTMOAuth2Authentication.h is not found (in the GTMOAuth2ViewControllerTouch.h)

(this was after the slight changes Gmail had a few days ago; the source code was fine up until the update)

Sometime do not authenticate with GDATA API in IOS 5.0

Hi all google developer,

I am using OAUTH 2.0 which you provide in your page here 
:"http://code.google.com/p/gtm-oauth2/wiki/Introduction".

I successfully integrate in my IOS 5.0 application and authenticate the user 
and also allow the user to upload the video on their YouTube account but after 
three or four day, GDATA API was not work properly as they have not 
authenticate the user most of the time and after entering 5 to 6 time email and 
password in GTMOAuth2ViewControllerTouch controller worked some of time.

Here i am attaching the error report which i produced every time when login to 
YouTube.

Please provide the solution as i launch my application in next 2 or 3 days.

Original issue reported on code.google.com by [email protected] on 13 Feb 2012 at 10:22

Attachments:

Printers not selecting and settings not displaying

What steps will reproduce the problem?
1. Opening the app the printers are all listed on the left side.  But I'm 
unable to choose which printer to use.
2. Signing in and out of the app doesn't make a difference.  Even trying a 
different user doesn't fix or solve the issue either.
3. Deleting the app and reinstalling it, sometimes I'm able to select the 
printer I want to use again.  But upon selecting "Printer Setting", printers go 
un-clickable again and stay's that way.


What is the expected output? What do you see instead?  As long as the printer I 
want is selected at first open it prints fine.  I cannot select a different 
printer or see the settings of any printer.


What version of the product are you using? On what operating system?  App V. 
1.8.2  -  OSX 10.8.3


Please provide any additional information below.  I've tried everything I can 
think of.  It seems intermittent on when the printers are selectable or not.  
It's very inconsistent.

Original issue reported on code.google.com by [email protected] on 12 May 2013 at 8:31

Attachments:

Cannot do cross-client identity requests

As it stands, there's no way to make a well-formed request to get a token response with the server_code field per this documentation. Even when I alter the code to allow for an audience request parameter, the returned token is missing server_code. I'd use the Google Sign-In library except my app needs to support a single user authorizing multiple Google accounts.

Classes not recognized by the XCode

Hi,

I included the library using pod 'GTMOAuth2' but unable to use it because XCode does not recognize the classes in it. I also tried to include the library manually, and i got the same result, got not found error when i tried to use one of classes of the library.

I have XCode7.3, and cocoapods 1.0.0.beta.4.

Pods
screen shot 2016-03-30 at 12 56 01

Import
screen shot 2016-03-30 at 12 56 47

When i want to use library
screen shot 2016-03-30 at 12 59 04

connection library should be switched from gtm-http-fetcher to gtm-session-fetcher

From the gtm-http-fetcher README:
https://github.com/google/gtm-http-fetcher/

NOTE: Because NSURLConnection is deprecated as of iOS 9 and OS X 10.11, this class has been superseded by GTMSessionFetcher.

It also looks like NSURLSession explicitly supports background operation, which may fix issues around background authentication on iOS.
https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/index.html

GTMOAuth2Authentication.refreshScope is either useless or broken

GTMOAuth2Authentication has properties called scope and refreshScope.  Inside 
makeTokenFetchRequest on line 778 (of 
http://gtm-oauth2.googlecode.com/svn/trunk r121), the refreshScope property is 
used to set the "scope" URL parameter.  It is then potentially overwritten by 
the value of the scope property on line 794, which sets exactly the same URL 
parameter.

As far as I can see, either refreshScope was intended to set a URL parameter 
called refreshScope instead of scope (in which case it is broken right now) or 
it's a bit of old code that has been superseded and is no longer useful (since 
callers can always use scope instead).

The refreshScope property is declared in a section commented "OAuth2 standard 
protocol parameters" but I can't find a refreshScope or refresh_scope parameter 
in RFC 6749 or https://developers.google.com/accounts/docs/OAuth2WebServer, so 
I don't know what standard this is referring to, if any.

Original issue reported on code.google.com by [email protected] on 13 Mar 2014 at 11:16

A bug may cause NetworkActivityIndicator always visible

What steps will reproduce the problem?
1. push GTMOAuth2ViewControllerTouch
2. pop GTMOAuth2ViewControllerTouch while web view is still loading

Quick fix:
Add this in -dealloc

    if (webView_.loading) {
        [self notifyWithName:kGTMOAuth2WebViewStoppedLoading
                     webView:webView_
                        kind:nil];
    }


Original issue reported on code.google.com by [email protected] on 29 Oct 2011 at 4:34

Application problem (Question by non-programmer, sorry)

Hi there! I have a problem with my cobook application for Mac Os X. I am not 
sure if this is the right place to ask a question like this, because I am not a 
programmer. I did not find any other source for addressing this problem though. 
Maybe someone can help?


What steps will reproduce the problem?
>> Syncing contacts with Cobook Application and Google Account

What is the expected output? What do you see instead?
>> Isee an exclamation mark and the message: "Google: The operation couldn't be 
completed. (com.google.GTMOAuth2 error -1001.)"

What version of the product are you using? On what operating system?
Mac Os X 10.9.2
Cobook 3.0.4 (3113)

What is that error? What does it mean?


Thanks for your help!


aeiou

Original issue reported on code.google.com by [email protected] on 24 Mar 2014 at 11:33

version 1.0.126 not working properly

I was using 1.0.125 and it was showing correctly the uiwebview. When I updated 
my pods specs, that version updated to 1.0.126 and suddenly the webview stopped 
to show anything. I believe (because I didn't test it properly) isn't retaining 
the webview and closes before loading anything, so you can never login, etc...





Original issue reported on code.google.com by [email protected] on 29 Apr 2015 at 7:03

could not build objective-c module gtm_oauth2

iOS: 9.1

It says the error: "GTMHTTPFetcher.h" file not found.

However, since it is not supported, it should use GTMSessionFetcher.h instead. But when I use cocoapods, it does not work.

Authentication suddenly failing with no error - did Google change the API?

I've been using these classes for weeks now with no problems but a few days ago 
it suddenly stopped working without me touching anything. I suspect Google 
changed something with their API but I can't work out what.

My Google Reader client appears to successfully authenticate and no errors are 
returned, yet when I ask it for the number of subscriptions with the URL 
https://www.google.com/reader/api/0/subscription/list?output=json it returns:

{"subscriptions":[]}

If I paste the same URL into my web browser when I am logged into Google, it 
returns the subscriptions successfully. If I then log out and try it, it 
returns the same data my app returns, so it would seem to be an authentication 
issue.

It seems like I'm not the only one to have experienced it suddenly fail to work 
in the past few days, although what caused it remains unknown:
http://stackoverflow.com/questions/8684769/problems-with-googles-oauth

Can anyone else shed some light on this?

I'm running it on OS X 10.6.8 using Xcode 4.2.

Original issue reported on code.google.com by [email protected] on 31 Dec 2011 at 10:41

Client Secret question of this library

Hi all,

I am trying to use this library for youtube oauth. I encounter a question, right now, there is no client secret anymore, but this library is still using client secret in the example. How can I avoid to use the client secret?

Thanks a lot.

Duplicated podspec on cocoapods.

Looks like the project appears twice on cocoapods, it failed when i tried to install using:

pod 'gtm-oauth2'

Proper one was

pod 'GTMOAuth2'

Both pods point to same github project.

redirectURI is loaded but the control is not returned to app

What steps will reproduce the problem?
1. Update example app to use another service provider
2. Provide client ID/secret key
3. Press Sign-In

What is the expected output? What do you see instead?
I expected my app to regain the control after web page authorization finishes. 
If I separately check my service provider then it says my app has been granted 
access. In my if I manually pop the web view, 
viewController:finishedWithAuth:error reports authentication failure.

What version of the product are you using? On what operating system?
trunk. iOS 5.

Please provide any additional information below.


Original issue reported on code.google.com by [email protected] on 24 Aug 2012 at 6:04

When hitting "Allow access" too fast, iOS gives "Javascript is disabled" error messsage

What steps will reproduce the problem?
--
After entering your username & password, Google gives you the standard "Blah 
blah app is requesting permission to..." screen. If you hit the "Allow access" 
button before that page has enough time to load all of its JS assets, you will 
invariably get the following error:

"You've reached this page because we have detected that Javascript is disabled 
in your browser. The page you attempted to load cannot display properly if 
scripts are disabled."
(This screen is black & white and has no Google branding on it.)

You can time this event by hitting "Allow access" before the application's icon 
(just above the button) loads. If you wait until the icon loads (that is, 
presumably, when the JS files loads), you won't get this error message and 
everything will work just fine.


What is the expected output? What do you see instead?
--
User should not have to wait for JS files to load before completing auth. 


What version of the product are you using? On what operating system?
--
svn commit #96 via gdata-objective-client on both iOS 5.1 and IOS 6. I've seen 
it with apps currently available in the App Store (Asana, for example) as well 
as on the simulator (Xcode 4.5.1 on Mountain Lion).

Please provide any additional information below.
-- 
It's probably not something in the gtm-oauth2 library so much as it is the web 
backend where gtm-oauth points to, but I wasn't sure where else to report it. 
If someone points me in the right direction I can re-post this issue.

Original issue reported on code.google.com by [email protected] on 25 Oct 2012 at 11:52

Support for OAUth2 providers that have HTTP instead of JSON authentication responses

According to the OAUth2 speciification, the result of an authentication token 
should be a JSON body. There are however OAUth2 providers that provide an HTTP 
form response (access_token=token&token_type=). GitHub's API is one where I 
encountered this. I've heard that Facebook has the same problem.

The attached patch adds support for form field responses; It looks at the 
response headers to determine whether JSON or form fields should be used.

Original issue reported on code.google.com by [email protected] on 3 Sep 2011 at 9:30

Attachments:

iOS 7 user interface

What steps will reproduce the problem?
1. Open the iOS GTMOAuth2ViewControllerTouch

What is the expected output? What do you see instead?
You'll  see "ugly" buttons that belong in iOS6 and before.
Instead I would like to see simplified buttons that fit the iOS 7 (and 8) UX.

What version of the product are you using? On what operating system?
iOS 7.1

Original issue reported on code.google.com by itavero on 16 Jul 2014 at 5:39

Attachments:

Please add semantic version tags

I’ve recently updated gtm-oauth2 to the CocoaPods package manager repo.

CocoaPods is a tool for managing dependencies for OS X and iOS Xcode projects 
and provides a central repository for iOS/OS X libraries. This makes adding 
libraries to a project and updating them extremely easy and it will help users 
to resolve dependencies of the libraries they use.

However, gtm-oauth2 doesn't have any version tags. I’ve added the current 
HEAD as version 0.0.1, but a version tag will make dependency resolution much 
easier.

Semantic version tags (instead of plain commit hashes/revisions) allow for 
resolution of cross-dependencies.

In case you didn’t know this yet; you can tag the current HEAD as, for 
instance, version 1.0.0, like so:

$ git tag -a 1.0.0 -m "Tag release 1.0.0"
$ git push --tags

Original issue reported on code.google.com by [email protected] on 22 Mar 2013 at 12:38

Sample app crashes in webcore after grant access action

I've been trying to use the library for an OS X Application and for non google OAuth services, the sample app included with the bundle and the one I made with the usage instructions crash before the control reaching the callback - (void)viewController:(GTMOAuthViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuthAuthentication *)auth

I've attached the crash logs for your reference.
Archive.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.