Mercurial > public > sg101
view gcalendar/oauth.py @ 943:cf9918328c64
Haystack tweaks for Django 1.7.7.
I had to upgrade to Haystack 2.3.1 to get it to work with Django
1.7.7. I also had to update the Xapian backend. But I ran into
problems.
On my laptop anyway (Ubuntu 14.0.4), xapian gets mad when search terms
are greater than 245 chars (or something) when indexing. So I created
a custom field that would simply omit terms greater than 64 chars and
used this field everywhere I previously used a CharField.
Secondly, the custom search form was broken now. Something changed in
the Xapian backend and exact searches stopped working. Fortunately the
auto_query (which I was using originally and broke during an upgrade)
started working again. So I cut the search form back over to doing an
auto_query. I kept the form the same (3 fields) because I didn't want
to change the form and I think it's better that way.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 13 May 2015 20:25:07 -0500 |
parents | 9165edfb1709 |
children |
line wrap: on
line source
""" This module handles the OAuth integration with Google. """ import datetime import logging import os from oauth2client.client import OAuth2WebServerFlow, FlowExchangeError from oauth2client.file import Storage from django.conf import settings from django.core.cache import cache logger = logging.getLogger(__name__) FLOW_CACHE_KEY = 'gcalendar-oauth-flow' FLOW_CACHE_TIMEOUT = 60 SCOPE = 'https://www.googleapis.com/auth/calendar' class OAuthError(Exception): """Base exception for errors raised by the oauth module""" def check_credentials_status(): """Performs a stat() on the credentials file and returns the last modified time as a datetime object. If an error occurs, None is returned. """ try: status = os.stat(settings.GCAL_CREDENTIALS_PATH) except OSError: return None return datetime.datetime.fromtimestamp(status.st_mtime) def get_auth_url(callback_url): """ This function creates an OAuth flow object and uses it to generate an authorization URL which is returned to the caller. callback_url - a string that is the URL that Google should redirect the user to after the user has authorized our application access to their data. """ logger.info("get_auth_url started; callback url='%s'", callback_url) flow = OAuth2WebServerFlow(client_id=settings.GCAL_CLIENT_ID, client_secret=settings.GCAL_CLIENT_SECRET, scope=SCOPE, redirect_uri=callback_url) auth_url = flow.step1_get_authorize_url() logger.info("auth url: '%s'", auth_url) # Save the flow in the cache so we can use it when Google calls the # callback. The expiration time also lets us check to make sure someone # isn't spoofing google if we are called at some random time. # Note: using the session might seem like a more obvious choice, but flow # objects are not JSON-serializable, and we don't want to use pickelable # sessions for security reasons. cache.set(FLOW_CACHE_KEY, flow, FLOW_CACHE_TIMEOUT) return auth_url def auth_return(request): """ This function should be called after Google has redirected the user after the user authorized us. We retrieve the authorization code from the request query parameters and then exchange it for access tokens. These tokens are stored in our credentials file. If an error is encountered, an OAuthError is raised. """ logger.info("auth_return called as '%s'", request.get_full_path()) # Try to retrieve the flow object from the cache flow = cache.get(FLOW_CACHE_KEY) if not flow: logger.warning("auth_return no flow in cache, bailing out") raise OAuthError("No flow found. Perhaps we timed out?") # Delete flow out of cache to close our operational window cache.delete(FLOW_CACHE_KEY) # Process the request error = request.GET.get('error') if error: logging.error("auth_return received error: %s", error) raise OAuthError("Error authorizing request: %s" % error) code = request.GET.get('code') if not code: logging.error("auth_return missing code") raise OAuthError("No authorization code received") logging.info("auth_return exchanging code for credentials") try: credentials = flow.step2_exchange(code) except FlowExchangeError as ex: logging.error("auth_return exchange failed: %s", ex) raise OAuthError(str(ex)) logging.info("auth_return storing credentials") storage = Storage(settings.GCAL_CREDENTIALS_PATH) storage.put(credentials) logging.info("auth_return completed successfully") def get_credentials(): """Obtain the stored credentials if available, or None if they are not.""" storage = Storage(settings.GCAL_CREDENTIALS_PATH) return storage.get()