OAuth2 authentication in GAE accessing Calendar API V3 (domain hosted)

295 views
Skip to first unread message

Jorge Arévalo

unread,
Dec 10, 2012, 9:46:07 PM12/10/12
to oauth...@googlegroups.com

I'm developing a Google App Engine app with Python. And I'm using:

  • Google Calendar API v3 (to access a calendar in my own domain. So, this is Google Apps installed in my domain)
  • Google APIs client library for Python.
  • OAuth2 to authenticate users of my domain (na...@mydomain.com)

I thought I had to use Service Accounts, because of this:

"If your App Engine application needs to call an API to access data owned by the application's project, you can simplify OAuth 2.0 by using Service Accounts"

Taken from https://developers.google.com/api-client-library/python/platforms/google_app_engine#ServiceAccounts

But I'm not sure if I misunderstood something. Is my scenario (GAE app trying to access Google Apps in my own domain) a candidate for Service Accounts?

I've tried several ways to handle OAuth2:

  • With Service Accounts, as said
  • With Python decorators provided by Google APIs client library for Python (OAuth2Decorator and OAuth2DecoratorFromClientSecrets)

In both cases, I get the same errors:

I'm totally lost. Any clues?

Many thanks in advance

Adam Eijdenberg

unread,
Dec 11, 2012, 12:14:17 AM12/11/12
to oauth...@googlegroups.com
Hi Jorge,

Is your app trying to get permission from the user to access their own calendars? If that is what you are trying to do then you should instead use the "Web application" flow when you create your client ID. Make sure you include "http://localhost:8080/oauth2callback" as a redirect URI if you want to test locally before you deploy.

Once you do that, the following code snippet should work:

import webapp2
from oauth2client.appengine import OAuth2Decorator
from apiclient.discovery import build

service = build('calendar', 'v3')
decorator = OAuth2Decorator(
    client_secret='xxxxxxxxxxxxxxxxx',

class MainHandler(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    http = decorator.http()
    result = service.calendarList().list().execute(http=http)
    ...


app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ...
    (decorator.callback_path, decorator.callback_handler()),
], debug=True)


Let me know if that helps. A service account is usually used to access data on behalf of an application (such as accessing other services such as Google Compute Engine, Prediction API etc) and doesn't require a user consent screen (since it isn't access data on behalf of the logged in user).

Cheers, Adam



--
 
 



--

Adam Eijdenberg |
 Product Manager | eijde...@google.com | +1 617-784-2600


This e-mail is confidential. If you are not the right addressee please do not forward it, please inform the sender, and please erase this e-mail including any attachments.Thanks.

 

 

The above terms reflect a potential business arrangement, are provided solely as a basis for further discussion, and are not intended to be and do not constitute a legally binding obligation. No legally binding obligations will be created, implied, or inferred until an agreement in final form is executed in writing by all parties involved.


Jorge Arévalo

unread,
Dec 11, 2012, 10:05:58 AM12/11/12
to oauth...@googlegroups.com
Hi Adam,

Many thanks. It totally worked. I reduced my code to the basis, and it worked with OAuth2Decorator and with oauth2decorator_from_clientsecrets. Both of them.

Now I have a different problem. I specify start and end date for my event in a html form (two input texts, no big deal). When I take the data from the form, I get a HTTP 400 Error. But if I hardcode the dates, it works:

So, this works (event added to calendar)

some_event = {
        "end": {
          "date": "2012-12-14"
        },
        "start": {
          "date": "2012-12-11"
        },
        "summary": "Test event",
        "status" : "tentative",
        "description": "This is a test event"
      }

But this raises a HTTP 400 Error

some_event = {
        "end": {
          "date": start_date
        },
        "start": {
          "date": end_date
        },
        "summary": "Leave request",
        "status" : "tentative",
        "description": "Esto es una prueba de mierda"
      }

The error text is: The specified time range is empty

Both start_date and end_date has the %Y-%m-%d format, as required. And some_event can be serialized without problems with json.dumps(some_event). 

I've tried with several other methods, like datetime.isoformat(), but same error.


What can be happening? Is there any way I can see the content sent to Google? The error is raised in http.py, once the response from google is received. I've tried with Firebug and Chrome console, but I can see the data sent to Google that causes the 400 response.

Jorge Arévalo

unread,
Dec 11, 2012, 10:24:27 AM12/11/12
to oauth...@googlegroups.com
Forget it. I was just swapping start and end dates. It's working now :-)
Reply all
Reply to author
Forward
0 new messages