Created
May 10, 2010 21:15
-
-
Save geschke/396557 to your computer and use it in GitHub Desktop.
Django Middleware for Facebook integration. Slightly modified to work with newer versions of Python Facebook SDK from https://github.com/pythonforfacebook/facebook-sdk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Facebook Connect Middleware with new Facebook Python SDK from https://github.com/pythonforfacebook/facebook-sdk and Graph API | |
# | |
# based on http://www.djangosnippets.org/snippets/1252/ | |
# | |
from django.contrib.auth import authenticate, login, logout, get_user | |
from django.contrib.auth.models import User | |
from django.conf import settings | |
from kuerbisorg.comcore.models import ComUser, COUNTRY_CHOICES, ACTIVE_CHOICES | |
import hashlib | |
import facebook | |
PROBLEM_ERROR = 'There was a problem. Try again later.' | |
ACCOUNT_DISABLED_ERROR = 'Your account is not active.' | |
ACCOUNT_PROBLEM_ERROR = 'There is a problem with your account.' | |
class FacebookConnectMiddleware(object): | |
delete_fb_cookies = False | |
facebook_user_is_authenticated = False | |
def process_request(self,request): | |
try: | |
# Set the facebook message to empty. This message can be used to display info from the middleware on a Web page. | |
request.facebook_message = None | |
# Don't bother trying FB Connect login if the user is already logged in | |
if not request.user.is_authenticated(): | |
# FB Connect will set a cookie with a key == 'fbm_' + Application ID if the user has been authenticated | |
if "fbm_" + settings.FB_APP_ID in request.COOKIES: | |
current_user = facebook.get_user_from_cookie(request.COOKIES, settings.FB_APP_ID, settings.FB_API_SECRET) | |
if current_user: | |
graph = facebook.GraphAPI(current_user["access_token"]) | |
profile = graph.get_object("me") | |
try: | |
# Try to get Django account corresponding to friend | |
# Authenticate then login (or display disabled error message) | |
django_user = User.objects.get(username="fb_" + profile['id']) | |
user = authenticate(username="fb_" + profile['id'], | |
password=hashlib.md5("fb_" + profile['id'] + settings.SECRET_KEY).hexdigest()) | |
if user is not None: | |
if user.is_active: | |
login(request, user) | |
self.facebook_user_is_authenticated = True | |
else: | |
request.facebook_message = ACCOUNT_DISABLED_ERROR | |
self.delete_fb_cookies = True | |
else: | |
request.facebook_message = ACCOUNT_PROBLEM_ERROR | |
self.delete_fb_cookies = True | |
except User.DoesNotExist: | |
# There is no Django account for this Facebook user. | |
# Create one, then log the user in. | |
# Create user | |
user = User.objects.create_user("fb_" + profile['id'], '', | |
hashlib.md5("fb_" + profile['id'] + | |
settings.SECRET_KEY).hexdigest()) | |
user.first_name = profile['first_name'] | |
user.last_name = profile['last_name'] | |
user.save() | |
comUser = ComUser(user=user, | |
active='a', | |
source='FB', | |
country='__' # todo: get from locale | |
) | |
regToken = comUser.createToken() | |
comUser.save() | |
# Authenticate and log in (or display disabled error message) | |
user = authenticate(username="fb_" + profile['id'], | |
password=hashlib.md5("fb_" + profile['id'] + settings.SECRET_KEY).hexdigest()) | |
if user is not None: | |
if user.is_active: | |
login(request, user) | |
self.facebook_user_is_authenticated = True | |
else: | |
request.facebook_message = ACCOUNT_DISABLED_ERROR | |
self.delete_fb_cookies = True | |
else: | |
request.facebook_message = ACCOUNT_PROBLEM_ERROR | |
self.delete_fb_cookies = True | |
else: | |
logout(request) | |
self.delete_fb_cookies = True | |
else: | |
get_user(request) | |
self.delete_fb_cookies = True | |
# Logged in | |
else: | |
comUser = ComUser.objects.get(user=request.user) | |
if comUser.source == 'FB': # check successful facebook login. If user is logged per site authentication only, just pass. | |
# FB Connect user? | |
if "fbsr_" + settings.FB_APP_ID in request.COOKIES: | |
# IP hash cookie set | |
if 'fb_ip' in request.COOKIES: | |
real_ip = self.get_real_ip(request) | |
# If IP hash cookie is NOT correct... otherwise: pass | |
if request.COOKIES['fb_ip'] != hashlib.md5(real_ip + settings.FB_API_SECRET + settings.SECRET_KEY).hexdigest(): | |
logout(request) | |
self.delete_fb_cookies = True | |
# FB Connect user without hash cookie set | |
else: | |
logout(request) | |
self.delete_fb_cookies = True | |
else: | |
logout(request) | |
self.delete_fb_cookies = True | |
# Something else happened. Make sure user doesn't have site access until problem is fixed. | |
except: | |
request.facebook_message = PROBLEM_ERROR | |
logout(request) | |
self.delete_fb_cookies = True | |
def process_response(self, request, response): | |
# Delete FB Connect cookies | |
# FB Connect JavaScript may add them back, but this will ensure they're deleted if they should be | |
if self.delete_fb_cookies is True: | |
response.delete_cookie("fbm_" + settings.FB_APP_ID) | |
self.delete_fb_cookies = False | |
if self.facebook_user_is_authenticated is True: | |
real_ip = self.get_real_ip(request) | |
response.set_cookie('fb_ip', hashlib.md5(real_ip + settings.FB_API_SECRET + settings.SECRET_KEY).hexdigest()) | |
# process_response() must always return a HttpResponse | |
return response | |
def get_real_ip(self, request): | |
try: | |
real_ip = request.META['HTTP_X_FORWARDED_FOR'] | |
except KeyError: | |
real_ip = request.META['REMOTE_ADDR'] | |
return real_ip | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment