Added new setting, widget, form and auth backend to allow login via user email address
To enable:
AUTHENTICATION_BACKENDS = ('common.auth.email_auth_backend.EmailAuthBackend',)
COMMON_LOGIN_METHOD = 'email'
This commit is contained in:
0
apps/common/auth/__init__.py
Normal file
0
apps/common/auth/__init__.py
Normal file
23
apps/common/auth/email_auth_backend.py
Normal file
23
apps/common/auth/email_auth_backend.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# From: http://www.micahcarrick.com/django-email-authentication.html
|
||||
from django.contrib.auth.models import User, check_password
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
|
||||
|
||||
class EmailAuthBackend(ModelBackend):
|
||||
"""
|
||||
Email Authentication Backend
|
||||
|
||||
Allows a user to sign in using an email/password pair rather than
|
||||
a username/password pair.
|
||||
"""
|
||||
|
||||
def authenticate(self, email=None, password=None):
|
||||
"""
|
||||
Authenticate a user based on email address as the user name.
|
||||
"""
|
||||
try:
|
||||
user = User.objects.get(email=email)
|
||||
if user.check_password(password):
|
||||
return user
|
||||
except User.DoesNotExist:
|
||||
return None
|
||||
@@ -55,3 +55,12 @@ register_setting(
|
||||
global_name=u'COMMON_AUTO_ADMIN_PASSWORD',
|
||||
default=u'admin',
|
||||
)
|
||||
|
||||
register_setting(
|
||||
namespace=u'common',
|
||||
module=u'common.conf.settings',
|
||||
name=u'LOGIN_METHOD',
|
||||
global_name=u'COMMON_LOGIN_METHOD',
|
||||
default=u'username',
|
||||
description=_(u'Controls the mechanism used to authenticated user. Options are: username, email'),
|
||||
)
|
||||
|
||||
@@ -2,9 +2,12 @@ from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth import authenticate
|
||||
|
||||
from common.utils import return_attrib
|
||||
from common.widgets import DetailSelectMultiple, PlainWidget, TextAreaDiv
|
||||
from common.widgets import DetailSelectMultiple, PlainWidget, \
|
||||
TextAreaDiv, EmailInput
|
||||
|
||||
|
||||
class DetailForm(forms.ModelForm):
|
||||
@@ -115,3 +118,29 @@ class UserForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'last_name')
|
||||
|
||||
|
||||
class EmailAuthenticationForm(AuthenticationForm):
|
||||
"""
|
||||
Override the default authentication form to use email address
|
||||
authentication
|
||||
"""
|
||||
email = forms.CharField(label=_(u'Email'), max_length=75,
|
||||
widget=EmailInput()
|
||||
)
|
||||
|
||||
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 self.user_cache is None:
|
||||
raise forms.ValidationError(_('Please enter a correct email and password. Note that the password fields is case-sensitive.'))
|
||||
elif not self.user_cache.is_active:
|
||||
raise forms.ValidationError(_('This account is inactive.'))
|
||||
self.check_for_test_cookie()
|
||||
return self.cleaned_data
|
||||
|
||||
# Remove the inherited username field
|
||||
EmailAuthenticationForm.base_fields.keyOrder = ['email', 'password']
|
||||
|
||||
@@ -2,23 +2,22 @@ from django.conf.urls.defaults import patterns, url
|
||||
from django.views.generic.simple import direct_to_template
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
urlpatterns = patterns('common.views',
|
||||
url(r'^about/$', direct_to_template, {'template': 'about.html'}, 'about'),
|
||||
#url(r'^password/change/done/$', 'django.contrib.auth.views.password_change_done', {'template_name': 'password_change_done.html'}),
|
||||
url(r'^password/change/done/$', 'password_change_done', (), name='password_change_done'),
|
||||
url(r'^object/multiple/action/$', 'multi_object_action_view', (), name='multi_object_action_view'),
|
||||
|
||||
url(r'^user/$', 'current_user_details', (), 'current_user_details'),
|
||||
url(r'^user/edit/$', 'current_user_edit', (), 'current_user_edit'),
|
||||
|
||||
url(r'^login/$', 'login_view', (), name='login_view'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('',
|
||||
url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name='login_view'),
|
||||
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}, name='logout_view'),
|
||||
|
||||
url(r'^password/change/$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change_form.html', 'post_change_redirect': '/password/change/done/'}, name='password_change_view'),
|
||||
#url(r'^password/change/done/$', 'django.contrib.auth.views.password_change_done', {'template_name': 'password_change_done.html'}),
|
||||
|
||||
url(r'^password/reset/$', 'django.contrib.auth.views.password_reset', {'email_template_name': 'password_reset_email.html', 'template_name': 'password_reset_form.html', 'post_reset_redirect': '/password/reset/done'}, name='password_reset_view'),
|
||||
url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {'template_name': 'password_reset_confirm.html', 'post_reset_redirect': '/password/reset/complete/'}, name='password_reset_confirm_view'),
|
||||
url(r'^password/reset/complete/$', 'django.contrib.auth.views.password_reset_complete', {'template_name': 'password_reset_complete.html'}, name='password_reset_complete_view'),
|
||||
|
||||
@@ -7,8 +7,11 @@ from django.contrib import messages
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.http import urlencode
|
||||
from django.contrib.auth.views import login
|
||||
|
||||
from common.forms import ChoiceForm, UserForm, UserForm_view
|
||||
from common.forms import EmailAuthenticationForm
|
||||
from common.conf.settings import LOGIN_METHOD
|
||||
|
||||
|
||||
def password_change_done(request):
|
||||
@@ -167,3 +170,14 @@ def current_user_edit(request):
|
||||
'title': _(u'edit current user details'),
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def login_view(request):
|
||||
#url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name='login_view'),
|
||||
#url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html', 'authentication_form': EmailAuthenticationForm}, name='login_view'),
|
||||
kwargs = {'template_name': 'login.html'}
|
||||
|
||||
if LOGIN_METHOD == 'email':
|
||||
kwargs['authentication_form'] = EmailAuthenticationForm
|
||||
|
||||
return login(request, **kwargs)
|
||||
|
||||
@@ -83,3 +83,16 @@ class TextAreaDiv(forms.widgets.Widget):
|
||||
conditional_escape(force_unicode(value))))
|
||||
|
||||
return mark_safe(result.replace('\n', '<br>'))
|
||||
|
||||
|
||||
# From: http://www.peterbe.com/plog/emailinput-html5-django
|
||||
class EmailInput(forms.widgets.Input):
|
||||
input_type = 'email'
|
||||
|
||||
def render(self, name, value, attrs=None):
|
||||
if attrs is None:
|
||||
attrs = {}
|
||||
attrs.update(dict(autocorrect='off',
|
||||
autocapitalize='off',
|
||||
spellcheck='false'))
|
||||
return super(EmailInput, self).render(name, value, attrs=attrs)
|
||||
|
||||
Reference in New Issue
Block a user