views:

545

answers:

3

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, Token invalid - Invalid AuthSub token.

Token invalid - Invalid AuthSub token.

Error 401

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)))

Thanks everyone in advance for your help. I've been looking high and low on the web for an answer & I have not been able to find one.

A: 

I have personally not worked with OAuth, but a few things I noticed that may (or may not) help:

  1. The 401 error is likely an HTTP 401 error, which means that the url was valid but required authentication. This obviously is explained by the failed OAuth attempt, but it also might be important to redirect users who are not logged in to another page.

  2. The error is occurring when you assign your feed variable. Is the auth_token parameter simply supposed to be a username?

3.You are using the line.

gdata.gauth.AeLoad(users.get_current_user().user_id())

frequently. Even though it might not be related to your auth problems, you would probably be better off making this query once and storing it in a variable. Then when you need it again, access it that way. It will improve the speed of your application.

Again, I apologize that I have had no specific OAuth experience. I just tried to scan and find some things that may spark you onto the right path.

jcady
+1  A: 

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.

sje397
Aeoid ( or other openid lib ) might be needed for OAuth + OpenID combo.
iamgopal
@iamgopal - did you read my answer?
sje397
A: 

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

Marco Bonechi