from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from django.utils.http import urlquote_plus
+from django.utils.encoding import smart_unicode
from forum.views.decorators import login_required
from forum.modules import decorate
from django.contrib.auth import login, logout
return HttpResponseRedirect(reverse('auth_signin'))
provider_class = AUTH_PROVIDERS[auth_provider].consumer
- user_data = provider_class.get_user_data(request.session['assoc_key'])
+
+ # Pass the cookies to the Facebook authentication class get_user_data method. We need them to take the access token.
+ if provider_class.__class__.__name__ == 'FacebookAuthConsumer':
+ user_data = provider_class.get_user_data(request.COOKIES)
+ else:
+ user_data = provider_class.get_user_data(request.session['assoc_key'])
if not user_data:
user_data = request.session.get('auth_consumer_data', {})
login(request, user)
if message is None:
- message = _("Welcome back %s, you are now logged in") % user.username
+ message = _("Welcome back %s, you are now logged in") % smart_unicode(user.username)
request.user.message_set.create(message=message)
from time import time
from datetime import datetime
from urllib import urlopen, urlencode
+from urlparse import parse_qs
from forum.authentication.base import AuthenticationConsumer, ConsumerTemplateContext, InvalidAuthentication
from django.utils.translation import ugettext as _
+from django.utils.encoding import smart_unicode
import settings
decoder = JSONDecoder()
return decoder.decode(json.read())
-REST_SERVER = 'http://api.facebook.com/restserver.php'
-
class FacebookAuthConsumer(AuthenticationConsumer):
def process_authentication_request(self, request):
API_KEY = str(settings.FB_API_KEY)
- if API_KEY in request.COOKIES:
- if self.check_cookies_signature(request.COOKIES):
- if self.check_session_expiry(request.COOKIES):
- return request.COOKIES[API_KEY + '_user']
- else:
- raise InvalidAuthentication(_('Sorry, your Facebook session has expired, please try again'))
+ # Check if the Facebook cookie has been received.
+ if 'fbs_%s' % API_KEY in request.COOKIES:
+ fbs_cookie = request.COOKIES['fbs_%s' % API_KEY]
+ parsed_fbs = parse_qs(smart_unicode(fbs_cookie))
+ self.parsed_fbs = parsed_fbs
+
+ # Check if the session hasn't expired.
+ if self.check_session_expiry(request.COOKIES):
+ return parsed_fbs['uid'][0]
else:
- raise InvalidAuthentication(_('The authentication with Facebook connect failed due to an invalid signature'))
+ raise InvalidAuthentication(_('Sorry, your Facebook session has expired, please try again'))
else:
raise InvalidAuthentication(_('The authentication with Facebook connect failed, cannot find authentication tokens'))
-
- def generate_signature(self, values):
- keys = []
-
- for key in sorted(values.keys()):
- keys.append(key)
-
- signature = ''.join(['%s=%s' % (key, values[key]) for key in keys]) + str(settings.FB_APP_SECRET)
- return hashlib.md5(signature).hexdigest()
-
def check_session_expiry(self, cookies):
- return datetime.fromtimestamp(float(cookies[settings.FB_API_KEY+'_expires'])) > datetime.now()
+ return datetime.fromtimestamp(float(self.parsed_fbs['expires'][0])) > datetime.now()
- def check_cookies_signature(self, cookies):
+ def get_user_data(self, cookies):
API_KEY = str(settings.FB_API_KEY)
+ fbs_cookie = cookies['fbs_%s' % API_KEY]
+ parsed_fbs = parse_qs(smart_unicode(fbs_cookie))
- values = {}
-
- for key in cookies.keys():
- if (key.startswith(API_KEY + '_')):
- values[key.replace(API_KEY + '_', '')] = cookies[key]
-
- return self.generate_signature(values) == cookies[API_KEY]
-
- def get_user_data(self, key):
- request_data = {
- 'method': 'Users.getInfo',
- 'api_key': settings.FB_API_KEY,
- 'call_id': time(),
- 'v': '1.0',
- 'uids': key,
- 'fields': 'name,first_name,last_name,email',
- 'format': 'json',
- }
-
- request_data['sig'] = self.generate_signature(request_data)
- fb_response = load_json(urlopen(REST_SERVER, urlencode(request_data)))[0]
+ # Communicate with the access token to the Facebook oauth interface.
+ json = load_json(urlopen('https://graph.facebook.com/me?access_token=%s' % parsed_fbs['access_token'][0]))
+ # Return the user data.
return {
- 'username': fb_response['first_name'] + ' ' + fb_response['last_name'],
- 'email': fb_response['email']
+ 'username': '%s %s' % (smart_unicode(json['first_name']), smart_unicode(json['last_name'])),
+ 'email': smart_unicode(json['email']),
}
class FacebookAuthContext(ConsumerTemplateContext):
-<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US" type="text/javascript"></script>\r
-<script type="text/javascript">\r
- var FB_API_KEY = "{{ provider.API_KEY }}";\r
- var FB_CHANNEL_PATH = "{% url xd_receiver %}";\r
-\r
- FB.init(FB_API_KEY, FB_CHANNEL_PATH, {permsToRequestOnConnect : "email"});\r
+{% load extra_tags %}\r
\r
- function FB_ConnectPostAuthorization() {\r
- if ($('#validate_email').attr('checked')) {\r
- FB_RequireFeatures(["Api"], function(){\r
- var api = FB.Facebook.apiClient;\r
- var fb_uid = api.get_session().uid;\r
+<div id="fb-root"></div>\r
+<script src="http://connect.facebook.net/en_US/all.js"></script>\r
+<script>\r
+ var FB_API_KEY = "{{ provider.API_KEY }}";\r
+ FB.init({\r
+ appId:FB_API_KEY, cookie:true,\r
+ status:true, xfbml:true\r
+ });\r
\r
- $.post('{% url facebook_user_is_registered %}', {'fb_uid': fb_uid}, function(response) {\r
- if (response != "yes") {\r
- api.users_hasAppPermission("email", function(result) {\r
- if (!result) {\r
- FB.Connect.showPermissionDialog("email", redirect_to_done_page);\r
- } else {\r
- redirect_to_done_page()\r
- }\r
- })\r
+ function check_login_status() {\r
+ FB.getLoginStatus(function(response) {\r
+ if (response.session) {\r
+ redirect_to_done_page();\r
+ } else {\r
+ FB.login(function(response) {\r
+ if (response.session) {\r
+ redirect_to_done_page();\r
} else {\r
- redirect_to_done_page()\r
+ // user cancelled login\r
}\r
});\r
- });\r
- } else {\r
- redirect_to_done_page();\r
- }\r
+ }\r
+ });\r
}\r
\r
function redirect_to_done_page() {\r
window.location = "{% url auth_provider_done provider=provider.id %}";\r
}\r
-\r
</script>\r
-<fb:login-button v="2" size="medium" onlogin="FB_ConnectPostAuthorization()">Facebook</fb:login-button>
\ No newline at end of file
+<a style="position: relative; top: -8px;" href="javascript:void(0);" onclick="check_login_status()" perms="email"><img src="{% media '/media/images/openid/facebook.gif' %}" /></a>\r
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <body> <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script> </body> </html>\r
+++ /dev/null
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
-
-from views import user_is_registered
-
-urlpatterns = patterns('',
- url(r'^xd_receiver.htm$', direct_to_template, {'template': 'modules/facebookauth/xd_receiver.html'}, name='xd_receiver'),
- url(r'^facebook/user_is_registered/', user_is_registered, name="facebook_user_is_registered"),
-)
\ No newline at end of file
+++ /dev/null
-from forum.models import AuthKeyUserAssociation
-from django.http import HttpResponse
-
-def user_is_registered(request):
- try:
- fb_uid = request.POST['fb_uid']
- #print fb_uid
- AuthKeyUserAssociation.objects.get(key=fb_uid)
- return HttpResponse('yes')
- except:
- return HttpResponse('no')
\ No newline at end of file