3 from datetime import datetime
4 from urllib import urlopen, urlencode
5 from forum.authentication.base import AuthenticationConsumer, ConsumerTemplateContext, InvalidAuthentication
6 from django.utils.translation import ugettext as _
11 from json import load as load_json
13 from django.utils.simplejson import JSONDecoder
16 decoder = JSONDecoder()
17 return decoder.decode(json.read())
19 REST_SERVER = 'http://api.facebook.com/restserver.php'
21 class FacebookAuthConsumer(AuthenticationConsumer):
23 def process_authentication_request(self, request):
24 API_KEY = str(settings.FB_API_KEY)
26 if API_KEY in request.COOKIES:
27 if self.check_cookies_signature(request.COOKIES):
28 if self.check_session_expiry(request.COOKIES):
29 return request.COOKIES[API_KEY + '_user']
31 raise InvalidAuthentication(_('Sorry, your Facebook session has expired, please try again'))
33 raise InvalidAuthentication(_('The authentication with Facebook connect failed due to an invalid signature'))
35 raise InvalidAuthentication(_('The authentication with Facebook connect failed, cannot find authentication tokens'))
37 def generate_signature(self, values):
40 for key in sorted(values.keys()):
43 signature = ''.join(['%s=%s' % (key, values[key]) for key in keys]) + str(settings.FB_APP_SECRET)
44 return hashlib.md5(signature).hexdigest()
46 def check_session_expiry(self, cookies):
47 return datetime.fromtimestamp(float(cookies[settings.FB_API_KEY+'_expires'])) > datetime.now()
49 def check_cookies_signature(self, cookies):
50 API_KEY = str(settings.FB_API_KEY)
54 for key in cookies.keys():
55 if (key.startswith(API_KEY + '_')):
56 values[key.replace(API_KEY + '_', '')] = cookies[key]
58 return self.generate_signature(values) == cookies[API_KEY]
60 def get_user_data(self, key):
62 'method': 'Users.getInfo',
63 'api_key': settings.FB_API_KEY,
67 'fields': 'name,first_name,last_name,email',
71 request_data['sig'] = self.generate_signature(request_data)
72 fb_response = load_json(urlopen(REST_SERVER, urlencode(request_data)))[0]
75 'username': fb_response['first_name'] + ' ' + fb_response['last_name'],
76 'email': fb_response['email']
79 class FacebookAuthContext(ConsumerTemplateContext):
83 human_name = 'Facebook'
84 code_template = 'modules/facebookauth/button.html'
85 extra_css = ["http://www.facebook.com/css/connect/connect_button.css"]
87 API_KEY = settings.FB_API_KEY