Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django Middleware for Facebook integration. Slightly modified to work with newer versions of Python Facebook SDK from https://github.com/pythonforfacebook/facebook-sdk
# 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