2 from time import time
\r
3 from datetime import datetime
\r
4 from urllib import urlopen, urlencode
\r
5 from forum.authentication.base import AuthenticationConsumer, ConsumerTemplateContext, InvalidAuthentication
\r
6 from django.utils.translation import ugettext as _
\r
11 from json import load as load_json
\r
13 from django.utils.simplejson import JSONDecoder
\r
15 def load_json(json):
\r
16 decoder = JSONDecoder()
\r
17 return decoder.decode(json.read())
\r
19 class FacebookAuthConsumer(AuthenticationConsumer):
\r
21 def process_authentication_request(self, request):
\r
22 API_KEY = settings.FB_API_KEY
\r
24 if API_KEY in request.COOKIES:
\r
25 if self.check_cookies_signature(request.COOKIES):
\r
26 if self.check_session_expiry(request.COOKIES):
\r
27 return request.COOKIES[API_KEY + '_user']
\r
29 raise InvalidAuthentication(_('Sorry, your Facebook session has expired, please try again'))
\r
31 raise InvalidAuthentication(_('The authentication with Facebook connect failed due to an invalid signature'))
\r
33 raise InvalidAuthentication(_('The authentication with Facebook connect failed, cannot find authentication tokens'))
\r
35 def generate_signature(self, values):
\r
38 for key in sorted(values.keys()):
\r
41 signature = ''.join(['%s=%s' % (key, values[key]) for key in keys]) + settings.FB_APP_SECRET
\r
42 return hashlib.md5(signature).hexdigest()
\r
44 def check_session_expiry(self, cookies):
\r
45 return datetime.fromtimestamp(float(cookies[settings.FB_API_KEY+'_expires'])) > datetime.now()
\r
47 def check_cookies_signature(self, cookies):
\r
48 API_KEY = settings.FB_API_KEY
\r
52 for key in cookies.keys():
\r
53 if (key.startswith(API_KEY + '_')):
\r
54 values[key.replace(API_KEY + '_', '')] = cookies[key]
\r
56 return self.generate_signature(values) == cookies[API_KEY]
\r
58 def get_user_data(self, key):
\r
60 'method': 'Users.getInfo',
\r
61 'api_key': settings.FB_API_KEY,
\r
65 'fields': 'name,first_name,last_name,email',
\r
69 request_data['sig'] = self.generate_signature(request_data)
\r
70 fb_response = load_json(urlopen(settings.REST_SERVER, urlencode(request_data)))[0]
\r
73 'username': fb_response['first_name'] + ' ' + fb_response['last_name'],
\r
74 'email': fb_response['email']
\r
77 class FacebookAuthContext(ConsumerTemplateContext):
\r
81 human_name = 'Facebook'
\r
82 code_template = 'modules/facebookauth/button.html'
\r
83 extra_css = ["http://www.facebook.com/css/connect/connect_button.css"]
\r
85 API_KEY = settings.FB_API_KEY