From 2e7730ebf0e843d375b5e0b3ba4d41226fa568ed Mon Sep 17 00:00:00 2001 From: Ricky Rosario Date: Tue, 5 Jun 2012 17:41:28 -0400 Subject: [PATCH] [bug 613084] Use session to store twitter oauth token. --- apps/twitter/__init__.py | 48 ++++++++++++++------------------------ apps/twitter/middleware.py | 20 +++++++++------- settings.py | 1 + 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/apps/twitter/__init__.py b/apps/twitter/__init__.py index ff8dcfc66df..dcd6eada01a 100644 --- a/apps/twitter/__init__.py +++ b/apps/twitter/__init__.py @@ -1,15 +1,12 @@ import logging -from uuid import uuid4 from django import http from django.conf import settings -from django.core.cache import cache log = logging.getLogger('k') PREFIX = 'custcare_' -ACCESS_NAME = PREFIX + 'access' REDIRECT_NAME = PREFIX + 'redirect' REQUEST_KEY_NAME = PREFIX + 'request_key' REQUEST_SECRET_NAME = PREFIX + 'request_secret' @@ -30,7 +27,10 @@ def url(request, override=None): def auth_wanted(view_func): - """Twitter sessions are SSL only, so redirect to SSL if needed.""" + """Twitter sessions are SSL only, so redirect to SSL if needed. + + Don't redirect if TWITTER_COOKIE_SECURE is False. + """ def wrapper(request, *args, **kwargs): is_secure = settings.TWITTER_COOKIE_SECURE if (request.COOKIES.get(REDIRECT_NAME) and @@ -56,48 +56,34 @@ def wrapper(request, *args, **kwargs): class Session(object): - id = None - key = None - secret = None - - @property - def cachekey_key(self): - return '{0}_key_{1}'.format(ACCESS_NAME, self.id) - - @property - def cachekey_secret(self): - return '{0}_secret_{1}'.format(ACCESS_NAME, self.id) + key_key = 'twitter_oauth_key' + key_secret = 'twitter_oauth_secret' @property def authed(self): - return bool(self.id and self.key and self.secret) + return bool(self.key and self.secret) def __init__(self, key=None, secret=None): - self.id = uuid4().hex self.key = key self.secret = secret @classmethod def from_request(cls, request): s = cls() - s.id = request.COOKIES.get(ACCESS_NAME) - s.key = cache.get(s.cachekey_key) - s.secret = cache.get(s.cachekey_secret) + s.key = request.session.get(s.key_key) + s.secret = request.session.get(s.key_secret) return s - def delete(self, response): + def delete(self, request, response): response.delete_cookie(REDIRECT_NAME) - response.delete_cookie(ACCESS_NAME) - cache.delete(self.cachekey_key) - cache.delete(self.cachekey_secret) - self.id = None + if self.key_key in request.session: + del request.session[self.key_key] + if self.key_secret in request.session: + del request.session[self.key_secret] self.key = None self.secret = None - def save(self, response): - cache.set(self.cachekey_key, self.key, MAX_AGE) - cache.set(self.cachekey_secret, self.secret, MAX_AGE) + def save(self, request, response): + request.session[self.key_key] = self.key + request.session[self.key_secret] = self.secret response.set_cookie(REDIRECT_NAME, '1', max_age=MAX_AGE) - is_secure = settings.TWITTER_COOKIE_SECURE - response.set_cookie( - ACCESS_NAME, self.id, max_age=MAX_AGE, secure=is_secure) diff --git a/apps/twitter/middleware.py b/apps/twitter/middleware.py index bbf96ae93ee..6ffd1e838cd 100644 --- a/apps/twitter/middleware.py +++ b/apps/twitter/middleware.py @@ -4,8 +4,8 @@ from django import http from django.conf import settings -from twitter import * import tweepy +from twitter import url, Session, REQUEST_KEY_NAME, REQUEST_SECRET_NAME log = logging.getLogger('k') @@ -21,13 +21,16 @@ def process_request(self, request): request.twitter = Session.from_request(request) + # If is_secure is True (should always be true except for local dev), + # we will be redirected back to https and all cookies set will be + # secure only. is_secure = settings.TWITTER_COOKIE_SECURE + ssl_url = url(request, {'scheme': 'https' if is_secure else 'http'}) auth = tweepy.OAuthHandler(settings.TWITTER_CONSUMER_KEY, settings.TWITTER_CONSUMER_SECRET, ssl_url, - secure=is_secure) - #import pdb; pdb.set_trace() + secure=True) if request.REQUEST.get('twitter_delete_auth'): request.twitter = Session() @@ -62,8 +65,9 @@ def process_request(self, request): 'path': request.path}) response = http.HttpResponseRedirect(ssl_url) - Session(auth.access_token.key, - auth.access_token.secret).save(response) + Session( + auth.access_token.key, + auth.access_token.secret).save(request, response) return response else: # request tokens didn't validate @@ -91,11 +95,11 @@ def process_request(self, request): def process_response(self, request, response): if getattr(request, 'twitter', False): if request.REQUEST.get('twitter_delete_auth'): - request.twitter.delete(response) + request.twitter.delete(request, response) - if request.twitter.authed: + if request.twitter.authed and REQUEST_KEY_NAME in request.COOKIES: response.delete_cookie(REQUEST_KEY_NAME) response.delete_cookie(REQUEST_SECRET_NAME) - request.twitter.save(response) + request.twitter.save(request, response) return response diff --git a/settings.py b/settings.py index 800e128548f..801206d11d1 100644 --- a/settings.py +++ b/settings.py @@ -838,6 +838,7 @@ def read_only_mode(env): CC_STATS_WARNING = 30 * 60 * 60 # Warn if JSON data is older than 30 hours CC_IGNORE_USERS = ['fx4status'] # User names whose tweets to ignore. +TWITTER_COOKIE_SECURE = True TWITTER_CONSUMER_KEY = '' TWITTER_CONSUMER_SECRET = ''