Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oauth + Aeoid +Python + Google App Engine + Google documents

I am trying to complete a story assignment system for my school newspaper in Google App Engine. It'll track deadlines for writers, allow writers to pick up stories, and give an "at a glance" view of the weeks stories. My partner and I are trying to fully integrate it with our newspapers Google Apps installation. Oh, and we have to use 3 legged Oauth because we don't have Google Apps Premier.

In that endeavor, I stumbled upon Aeoid and was able to follow the instructions to make federated login work. It's very cool!

Where I'm running into trouble is using Oauth to get a list of the users google documents. I have a test page set up here: mustrun.cornellsun.com/test. It is giving me errors - I've copied them at the bottom of this mail. I don't know if this has to do with my consumer secret (should I be using the key I get from google marketplace? or should I be using the key I get from the manage domains page?). Right now I'm using the key I got from the manage domains page

Also complicating this is that the actual appspot domain is mustrun2sun [].appspot[too new can't post more than one link].com, but I set it up in google apps so that only users from my domain can log in and also so that the app is deployed on my domain. (app is deployed as must[]run[].corn[]ellsun[].[]com & everything refers to it as such, even in the manage domains thing.)

I'm using GDClient 2.0 classes so I'm fairly sure that everything should work as planned... i.e. I'm not using the old service stuff or anything. I've used htt[]p:/[]/k[]ing[]yo-bachi.blog[]spot.c[]om/2010/05/gaego[]ogleoauth.ht[]ml as a bit of a template for my Oauth "dance" because the Google examples are out of date & use the old Google data 1.0 library - I think.

The error that I'm getting when I go to my test page is

Traceback (most recent call last):
  File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 511, in __call__
    handler.get(*groups)
  File "/base/data/home/apps/mustrun2sun/1.341947133742569880/main.py", line 170, in get
    feed = client.GetDocList(auth_token=gdata.gauth.AeLoad(users.get_current_user().user_id())) #auth_token=TOKEN
  File "/base/data/home/apps/mustrun2sun/1.341947133742569880/gdata/docs/client.py", line 141, in get_doclist
    auth_token=auth_token, **kwargs)
  File "/base/data/home/apps/mustrun2sun/1.341947133742569880/gdata/client.py", line 635, in get_feed
    **kwargs)
  File "/base/data/home/apps/mustrun2sun/1.341947133742569880/gdata/client.py", line 308, in request
    response, Unauthorized)
Unauthorized: Unauthorized - Server responded with: 401, <HTML>
<HEAD>
<TITLE>Token invalid - Invalid AuthSub token.</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid - Invalid AuthSub token.</H1>
<H2>Error 401</H2>
</BODY>
</HTML>

Also, since this is hard w/o any source code, below is the relevant code:

import gdata.auth
import gdata.gauth
import gdata.docs.client
import gdata.docs.data
import gdata.docs.service
import gdata.alt.appengine

from aeoid import middleware, users

class GetOauthToken(webapp.RequestHandler):
    def get(self):
        user_id = users.get_current_user().user_id()
        saved_request_token = gdata.gauth.AeLoad("tmp_"+user_id)
        gdata.gauth.AeDelete ("tmp_" + user_id)
        request_token = gdata.gauth.AuthorizeRequestToken(saved_request_token, self.request.uri)
        #upgrade the token
        access_token = client.GetAccessToken(request_token)
        #save the upgraded token
        gdata.gauth.AeSave(access_token, user_id)
        self.redirect('/test')     

class Test(webapp.RequestHandler):
    def get(self):
        TOKEN = gdata.gauth.AeLoad(users.get_current_user().user_id())
        if TOKEN:
            client = gdata.docs.client.DocsClient(source=SETTINGS['APP_NAME'])
            client.auth_token = gdata.gauth.AeLoad(users.get_current_user().user_id()) #could try to put back as TOKEN?

            self.response.out.write('moo baby')
            client.ssl = True
            feed = client.GetDocList(auth_token=gdata.gauth.AeLoad(users.get_current_user().user_id())) #auth_token=TOKEN
            self.response.out.write(feed)
            self.response.out.write('moo boobob')
            self.response.headers['Content-Type'] = 'text/plain'
            for entry in feed.entry:
                self.response.out.writeln(entry.title.text)
        else:
            # Get unauthorized request token
            gdata.gauth.AeDelete(users.get_current_user().user_id())
            client = gdata.docs.client.DocsClient(source=SETTINGS['APP_NAME'])
            client.ssl = True # Force communication through HTTPS

            oauth_callback_url = ('http://%s/get_oauth_token' %
                                  self.request.host)

            request_token = client.GetOAuthToken(
                SETTINGS['SCOPES'], oauth_callback_url, SETTINGS['CONSUMER_KEY'],
                consumer_secret=SETTINGS['CONSUMER_SECRET'])
            gdata.gauth.AeSave(request_token, "tmp_"+users.get_current_user().user_id())
            # Authorize request token
            domain = None#'cornellsun.com'
            self.redirect(str(request_token.generate_authorization_url(google_apps_domain=domain)))

I've been looking high and low on the web for an answer & I have not been able to find one.

like image 682
James Elkins Avatar asked Oct 15 '22 05:10

James Elkins


2 Answers

I have a working python App Engine app that uses OpenID, and OAuth to get your google contacts:

http://github.com/sje397/Chess

It is running at:

http://your-move.appspot.com

Note that Aeoid is not needed anymore, since App Engine has built-in OpenID support.

like image 200
sje397 Avatar answered Oct 25 '22 06:10

sje397


I just found out wasting a couple of hours, that you get a 401 also if the URL is not correct.

In my example, I was doing

.../buzz/v1/activities/@me/@self**?&**alt=json

Instead of

.../buzz/v1/activities/@me/@self**?**alt=json
like image 29
Marco Bonechi Avatar answered Oct 25 '22 06:10

Marco Bonechi