diff options
-rw-r--r-- | askbot/__init__.py | 2 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/util.py | 64 | ||||
-rw-r--r-- | askbot/doc/source/changelog.rst | 4 |
3 files changed, 49 insertions, 21 deletions
diff --git a/askbot/__init__.py b/askbot/__init__.py index eba7d205..2989d660 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -9,7 +9,7 @@ import smtplib import sys import logging -VERSION = (0, 7, 38) +VERSION = (0, 7, 39) #keys are module names used by python imports, #values - the package qualifier to use for pip diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py index 4468a6d2..28f6b2dd 100644 --- a/askbot/deps/django_authopenid/util.py +++ b/askbot/deps/django_authopenid/util.py @@ -29,7 +29,7 @@ try: except: from yadis import xri -import time, base64, hashlib, operator, logging +import time, base64, hmac, hashlib, operator, logging from models import Association, Nonce __all__ = ['OpenID', 'DjangoOpenIDStore', 'from_openid_response', 'clean_next'] @@ -787,30 +787,54 @@ class FacebookError(Exception): """ pass -def get_facebook_user_id(request): - try: - key = askbot_settings.FACEBOOK_KEY - secret = askbot_settings.FACEBOOK_SECRET +def urlsafe_b64decode(input): + length = len(input) + return base64.urlsafe_b64decode( + input.ljust(length + length % 4, '=') + ) - fb_cookie = request.COOKIES['fbs_%s' % key] - fb_response = dict(cgi.parse_qsl(fb_cookie)) +def parse_signed_facebook_request(signed_request, secret): + """ + Parse signed_request given by Facebook (usually via POST), + decrypt with app secret. - signature = None - payload = '' - for key in sorted(fb_response.keys()): - if key != 'sig': - payload += '%s=%s' % (key, fb_response[key]) + Arguments: + signed_request -- Facebook's signed request given through POST + secret -- Application's app_secret required to decrpyt signed_request - if 'sig' in fb_response: - if md5(payload + secret).hexdigest() != fb_response['sig']: - raise ValueError('signature does not match') - else: - raise ValueError('no signature in facebook response') + slightly edited copy from https://gist.github.com/1190267 + """ + + if "." in signed_request: + esig, payload = signed_request.split(".") + else: + return {} - if 'uid' not in fb_response: - raise ValueError('no user id in facebook response') + sig = urlsafe_b64decode(str(esig)) + data = simplejson.loads(urlsafe_b64decode(str(payload))) - return fb_response['uid'] + if not isinstance(data, dict): + raise ValueError("Pyload is not a json string!") + return {} + + if data["algorithm"].upper() == "HMAC-SHA256": + if hmac.new(str(secret), str(payload), hashlib.sha256).digest() == sig: + return data + else: + raise ValueError("Not HMAC-SHA256 encrypted!") + + return {} + +def get_facebook_user_id(request): + try: + key = askbot_settings.FACEBOOK_KEY + fb_cookie = request.COOKIES['fbsr_%s' % key] + if not fb_cookie: + raise ValueError('cannot access facebook cookie') + + secret = askbot_settings.FACEBOOK_SECRET + response = parse_signed_facebook_request(fb_cookie, secret) + return response['user_id'] except Exception, e: raise FacebookError(e) diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index bd67fd48..7751cba6 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -1,6 +1,10 @@ Changes in Askbot ================= +0.7.39 (Jan 11, 2012) +--------------------- +* restored facebook login after FB changed the procedure (Evgeny) + 0.7.38 (Jan 11, 2012) --------------------- * xss vulnerability fix, issue found by Radim Řehůřek (Evgeny) |