Skip to content

Instantly share code, notes, and snippets.

@c4urself
Created March 26, 2012 11:57
Show Gist options
  • Save c4urself/2204633 to your computer and use it in GitHub Desktop.
Save c4urself/2204633 to your computer and use it in GitHub Desktop.
Django email
"""
This file enables email-based authentication for Django. The only steps required are
1. Add 'EmailAuthenticationBackend' to your settings' AUTHENTICATION_BACKENDS file
2. Add the {'authentication_form': EmailAuthenticationForm} to your login view (if using 'django.contrib.auth.views.login')
3. When saving a User instance, generate the username from the email using the 'generate_hash_from_email' function
"""
import hashlib
from django import forms
from django.contrib.auth.models import User, check_password
from django.contrib.auth import authenticate
from django.core.exceptions import MultipleObjectsReturned
from django.core.validators import email_re
def generate_hash_from_email(email_string):
"""
Make a hash of the email to store as a username (no longer than 30 characters)
This ensures that the emails stay unique as only the username field in the User model is required to be unique.
"""
m = hashlib.md5()
m.update(email_string.lower())
return m.hexdigest()[:30]
class BasicBackend:
"""Basic backend: used by EmailAuthenticationBackend"""
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
class EmailAuthenticationBackend(BasicBackend):
"""Backend used by django authentication: set in base.py"""
def authenticate(self, email=None, password=None):
if email_re.search(email):
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
user = None
except MultipleObjectsReturned:
user = None
else:
if not user.check_password(password):
user = None
finally:
return user
return None
class EmailAuthenticationForm(forms.Form):
"""Email login form: passed to django.contrib.auth.login"""
email = forms.CharField(label="Email", max_length=75)
password = forms.CharField(label="Password", widget=forms.PasswordInput)
def __init__(self, request=None, *args, **kwargs):
self.request = request
self.user_cache = None
super(EmailAuthenticationForm, self).__init__(*args, **kwargs)
def clean(self):
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if email and password:
self.user_cache = authenticate(email=email, password=password)
if not email_re.search(email):
raise forms.ValidationError("Please enter a valid email")
if self.user_cache is None:
raise forms.ValidationError("Please enter a correct email and password.")
elif not self.user_cache.is_active:
raise forms.ValidationError("This account is inactive.")
if self.request:
if not self.request.session.test_cookie_worked():
raise forms.ValidationError("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in.")
return self.cleaned_data
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
def get_user(self):
return self.user_cache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment