class fbMiddleware(object):
"""
Handle Facebook association, autologin
"""
def process_request(self, request):
request.facebookconn = False
request.facebookconn_new = False
f_name = False
l_name = False
# Check if we have the FBConnect cookie
if settings.FACEBOOK_CONNECT_KEY in request.COOKIES:
signature_hash = self.get_facebook_signature(request.COOKIES, True)
# check if cookie is valud
if signature_hash == request.COOKIES[settings.FACEBOOK_CONNECT_KEY]:
# check if it didn't expired
if datetime.fromtimestamp(float(request.COOKIES[settings.FACEBOOK_CONNECT_KEY+'_expires'])) > datetime.now():
# get the FB user ID from cookie
uid = '%s_user' % settings.FACEBOOK_CONNECT_KEY
cookie_uid = request.COOKIES[uid]
request.facebookconn = cookie_uid
# check if the FB user id is associated to a Django User account
try:
f = FBAssociation.objects.get(fb_uid=cookie_uid)
except Exception, e:
logging.debug("new Facebook association")
# no account, so we make a new one
password = ''.join([choice('1234567890qwertyuiopasdfghjklzxcvbnm') for i in range(10)])
if 'fb_name' in request.POST:
username = slughifi(request.POST['fb_name'])
else:
logging.error("NO Facebook username")
return None
if 'fb_mail' in request.POST:
email = request.POST['fb_mail']
if len(email) >= 255:
# too long
email = str(cookie_uid)
else:
logging.error("No Facebook proxy mail")
return None
username = username.replace('-', '')
# check if username taken
try:
u = User.objects.get(username=username)
except:
pass
else:
username = '%s%s' % (username, str(cookie_uid))
# this shouldn't exist
try:
u = User.objects.get(username=username)
except:
pass
else:
logging.error("Existing Facebook usernames %s" % username)
return None
# check if mail is taken
try:
u = User.objects.get(email=email)
except:
pass
else:
email = str(cookie_uid)
try:
u = User.objects.get(email=email)
except:
pass
else:
logging.error("Existing proxy email %s" % email)
return None
#make the user
user = None
try:
user = User.objects.create_user(username, email, password)
user.save()
user = authenticate(username=username, password=password)
except Exception, e:
try:
user.delete()
except:
pass
logging.error("Facebook User Creation Exception")
logging.error(e)
return None
else:
# save the Facebook association
o = FBAssociation(user=user, fb_uid=request.facebookconn, is_new=True, is_from_facebook=True)
o.save()
if user is not None:
# login user and make the association
try:
login(request, user)
except Exception, e:
logging.error("Facebook User Login Exception")
logging.error(e)
return None
if 'fb_pic' in request.POST:
try:
path = settings.MEDIA_ROOT + date.today().strftime("avatars/%Y/%b/%d")
if not os.path.isdir(path):
os.makedirs(path)
image = '%s/%s.jpg' % (path, str(user.username))
img = urllib2.urlopen(request.POST['fb_pic']).read()
tmp = open('%s/%s.jpg' % (path, str(user.username)), 'wb')
tmp.write(img)
tmp.close()
i = Image.open(image)
i.thumbnail((480, 480), Image.ANTIALIAS)
i.convert("RGB").save(image, "JPEG")
image = '%s/%s.jpg' % (date.today().strftime("avatars/%Y/%b/%d"), str(user.username))
avatar = Avatar(user=user, image=image, valid=True)
avatar.save()
except Exception, e:
logging.error("Could not save avatar from Facebook")
logging.error(e)
return None
else:
# FB ID is assigned to a Django User account. Login user
if not request.user.is_authenticated():
user = authenticate(user_id = f.user.id, fb_uid=cookie_uid)
if user is not None:
login(request, user)
else:
if request.user.is_authenticated():
# not FB cookie but user from FB logged in? logout
try:
f = FBAssociation.objects.get(user=request.user)
except:
pass
else:
if f.is_from_facebook:
logout(request)
def get_facebook_signature(self, values_dict, is_cookie_check=False):
"""
Generates signatures for FB requests/cookies
"""
signature_keys = []
for key in sorted(values_dict.keys()):
if (is_cookie_check and key.startswith(settings.FACEBOOK_CONNECT_KEY + '_')):
signature_keys.append(key)
elif (is_cookie_check is False):
signature_keys.append(key)
if (is_cookie_check):
signature_string = ''.join(['%s=%s' % (x.replace(settings.FACEBOOK_CONNECT_KEY + '_',''), values_dict[x]) for x in signature_keys])
else:
signature_string = ''.join(['%s=%s' % (x, values_dict[x]) for x in signature_keys])
signature_string = signature_string + settings.FACEBOOK_CONNECT_SECRET
return md5.new(signature_string).hexdigest()