bgneal@451: """ bgneal@451: This module handles the OAuth integration with Google. bgneal@451: bgneal@451: """ bgneal@451: from __future__ import with_statement bgneal@451: import logging bgneal@451: bgneal@451: import gdata.gauth bgneal@451: from gdata.calendar_resource.client import CalendarResourceClient bgneal@451: bgneal@451: from django.conf import settings bgneal@451: bgneal@451: bgneal@451: logger = logging.getLogger(__name__) bgneal@451: USER_AGENT = 'surfguitar101-gcalendar-v1' bgneal@451: REQ_TOKEN_SESSION_KEY = 'gcalendar oauth request token' bgneal@451: bgneal@451: bgneal@451: def fetch_auth(request, scopes, callback_url): bgneal@451: """ bgneal@451: This function fetches a request token from Google and stores it in the bgneal@451: session. It then returns the authorization URL as a string. bgneal@451: bgneal@451: request - the HttpRequest object for the user requesting the token. The bgneal@451: token is stored in the session object attached to this request. bgneal@451: bgneal@451: scopes - a list of scope strings that the request token is for. See bgneal@451: http://code.google.com/apis/gdata/faq.html#AuthScopes bgneal@451: bgneal@451: callback_url - a string that is the URL that Google should redirect the user bgneal@451: to after the user has authorized our application access to their data. bgneal@451: bgneal@451: This function only supports RSA-SHA1 authentication. Settings in the Django bgneal@451: settings module determine the consumer key and path to the RSA private key. bgneal@451: """ bgneal@453: logger.info("fetch_auth started; callback url='%s'", callback_url) bgneal@451: client = CalendarResourceClient(None, source=USER_AGENT) bgneal@451: bgneal@451: with open(settings.GOOGLE_OAUTH_PRIVATE_KEY_PATH, 'r') as f: bgneal@451: rsa_key = f.read() bgneal@451: logger.info("read RSA key; now getting request token") bgneal@451: bgneal@451: request_token = client.GetOAuthToken( bgneal@451: scopes, bgneal@451: callback_url, bgneal@451: settings.GOOGLE_OAUTH_CONSUMER_KEY, bgneal@451: rsa_private_key=rsa_key) bgneal@451: bgneal@451: logger.info("received token") bgneal@451: request.session[REQ_TOKEN_SESSION_KEY] = request_token bgneal@451: bgneal@452: auth_url = request_token.generate_authorization_url() bgneal@451: logger.info("generated auth url '%s'", str(auth_url)) bgneal@451: bgneal@451: return str(auth_url) bgneal@451: bgneal@451: bgneal@451: def get_access_token(request): bgneal@451: """ bgneal@451: This function should be called after Google has sent the user back to us bgneal@451: after the user authorized us. We retrieve the oauth token from the request bgneal@451: URL and then upgrade it to an access token. We then return the access token. bgneal@451: bgneal@451: """ bgneal@455: logger.info("get_access_token called as '%s'", request.get_full_path()) bgneal@451: bgneal@451: saved_token = request.session.get(REQ_TOKEN_SESSION_KEY) bgneal@451: if saved_token is None: bgneal@451: logger.error("saved request token not found in session!") bgneal@451: return None bgneal@451: bgneal@451: logger.info("extracting token...") bgneal@451: request_token = gdata.gauth.AuthorizeRequestToken(saved_token, bgneal@451: request.build_absolute_uri()) bgneal@451: bgneal@451: logger.info("upgrading to access token...") bgneal@451: bgneal@451: client = CalendarResourceClient(None, source=USER_AGENT) bgneal@451: access_token = client.GetAccessToken(request_token) bgneal@451: bgneal@451: logger.info("upgraded to access token...") bgneal@451: return access_token bgneal@458: bgneal@458: bgneal@458: def serialize_token(token): bgneal@458: """ bgneal@458: This function turns a token into a string and returns it. bgneal@458: bgneal@458: """ bgneal@458: return gdata.gauth.TokenToBlob(token) bgneal@458: bgneal@458: bgneal@458: def deserialize_token(s): bgneal@458: """ bgneal@458: This function turns a string into a token returns it. The string must have bgneal@458: previously been created with serialize_token(). bgneal@458: bgneal@458: """ bgneal@458: return gdata.gauth.TokenFromBlob(s)