pythonoauthgoogle-apigoogle-email-settings-api

Move Google EmailSettings API python code from OAuth1 to OAuth2 service account


To use the new Google Directory API we created an OAuth2 "service account" (see Using OAuth 2.0 for Server to Server Applications). This is basically a PKCS #12 file. All of our Directory API scripts work fine with this service account.

We also use the EmailSettings API (Developer's Guide Email Settings API) to manage some of our Google account settings. These scripts did not move to the new API format, so we continue to use the old OAuth1 authentication method. This has, until recently, worked fine. However, it appears that Google is no longer supporting OAuth1 authentication.

So, we need to move the EmailSettings scripts from OAuth1 to our OAuth2 service account. We are using the gdata Python libraries (GitHub google/gdata-python-client) to make calls to the EmailSettings API. This is how we currently authenticate to make EmailSettings API calls:

import gdata.apps.emailsettings.service
# self is an EmailSettingsService object (gdata.apps.emailsettings.service)
self.domain = "mydomain.com"
self.source = "my application name"
token = get OAuth1 token string from a file
self.SetOAuthInputParameters(
  gdata.auth.OAuthSignatureMethod.HMAC_SHA1,
  consumer_key    = token.oauth_input_params._consumer.key,
  consumer_secret = token.oauth_input_params._consumer.secret
  )
token.oauth_input_params = self._oauth_input_params
self.SetOAuthToken(token)

Using these Python gdata libraries, how do I authenticate using our OAuth2 service account, i.e., the PKCS #12 file, to use the EmailSettings API?


Solution

  • There's another SO question which shows you how to do this but uses the slightly newer gdata.apps.emailsettings.client methods.

    If you must stay with gdata.apps.emailsettings.service then you can "hack" OAuth 2.0 onto the object with something like:

    1. Build your OAuth 2.0 credentials object as you are already doing for your Admin SDK Directory API calls.

    2. Build your GData client object as you are already doing in lines 1-3 of your code.

    3. Grab the access token from your credentials object and apply it as a header to your client object:

      client.additional_headers = { 'Authorization': u'Bearer %s' % credentials.access_token}

    If you get a 401 response (access token expired), repeat 1 and 3 to get and apply a new access token.