hakanw avatar hakanw committed 50531de

First commit of all the stuff I've got.

Comments (0)

Files changed (8)

+django-email-usernames was developed by Håkan Waara <hwaara@gmail.com>
+Copyright (c) 2008, Håkan Waara
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of the author nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Add a comment to this file

email_usernames/__init__.py

Empty file added.

email_usernames/backends.py

+# encoding: utf-8
+from django.conf import settings
+from django.contrib.auth.models import User
+from django import forms
+
+dummy_field = forms.EmailField()
+def is_email(username):
+    try:
+        dummy_field.clean(username)
+        return True
+    except forms.ValidationError:
+        return False
+ 
+# This is an authentication backend, that allows email addresses to be used as usernames,
+# which the default auth backend doesn't.
+class EmailOrUsernameModelBackend(object):
+    def authenticate(self, username=None, password=None):
+        # If username is an email, then try to pull it up
+        if is_email(username):
+            try:
+                user = User.objects.get(email=username)
+            except User.DoesNotExist:
+                return None
+        else:
+            # We have a non email-address we should try for username
+            # This is good, because it means superusers can access the admin, without
+            # using email addresses, which the admin login can't handle yet.
+            try:
+                user = User.objects.get(username=username)
+            except User.DoesNotExist:
+                return None
+            
+        if user.check_password(password):
+            return user
+
+    def get_user(self, user_id):
+        try:
+            return User.objects.get(pk=user_id)
+        except User.DoesNotExist:
+            return None

email_usernames/forms.py

+# encoding: utf-8
+from django import forms
+from django.utils.translation import ugettext_lazy as _
+from django.contrib.auth import authenticate
+
+try:
+    # If you have django-registration installed, this is a form you can
+    # use for users that signup.
+    from registration.forms import RegistrationFormUniqueEmail
+    class EmailRegistrationForm(RegistrationFormUniqueEmail):
+        def __init__(self, *args, **kwargs):
+            super(EmailRegistrationForm, self).__init__(*args, **kwargs)
+            del self.fields['username']
+
+        def save(self, *args, **kwargs):
+            # Note: if the username column has not been altered to allow 75 chars, this will not
+            #       work for some long email addresses.
+            self.cleaned_data['username'] = self.cleaned_data['email']
+            return super(EmailRegistrationForm, self).save(*args, **kwargs)
+except ImportError:
+    pass
+
+class EmailLoginForm(forms.Form):
+    email = forms.CharField(label=_("Email"), max_length=75, widget=forms.TextInput(attrs=dict(maxlength=75)))
+    password = forms.CharField(label=_(u"Password"), widget=forms.PasswordInput)
+
+    def clean(self):
+        # Try to authenticate the user
+        if self.cleaned_data.get('email') and self.cleaned_data.get('password'):
+            user = authenticate(username=self.cleaned_data['email'], password=self.cleaned_data['password'])
+            if user is not None:
+                if user.is_active:
+                    self.user = user # So the login view can access it
+                else:
+                    raise forms.ValidationError(_("This account is inactive."))
+            else:
+                raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive."))
+
+        return self.cleaned_data

email_usernames/management.py

+from django.db.models.signals import post_syncdb
+
+message = """
+    'django-email-accounts' has detected that you just installed Django's authentication system (django.auth). 
+         
+    For your convenience, django-email-accounts can alter the user table's username field to allow 75 characters instead
+    of the default 35 chars. Unless you do this, emails that are longer than 30 characters will be cut off, and this 
+    app will probably not work!
+    
+    NOTE: this will only work if the SQL user account you have created for django has the privileges
+    to run ALTER statements.
+    
+    Do you want django-email-accounts to try to alter the auth_user.username column to allow 75 characters? 
+    (y/N): """
+
+def query_fix_usertable(sender, app, created_models, verbosity, interactive, **kwargs):
+    model_names = [m.__name__ for m in created_models]
+    if not interactive or app.__name__ != 'django.contrib.auth.models' or "User" not in model_names:
+        return
+    
+    answer = raw_input(message)
+    while not answer.lower() in ('y', 'n', 'yes', 'no'):
+        raw_input("You need to either decide yes ('y') or no ('n'). Default is no. (y/N): ")
+        
+    from django.db import connection
+    cursor = connection.cursor()
+    cursor.execute("ALTER TABLE auth_user MODIFY COLUMN username varchar(75) NOT NULL")
+    
+post_syncdb.connect(query_fix_usertable)

email_usernames/urls.py

+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('email_usernames.views',
+    url(r'^login/$', 'email_login', name="email-login"), 
+)
+
+try:
+    import registration
+    from email_usernames.forms import EmailRegistrationForm
+    urlpatterns += patterns('registration.views', 
+        url(r'^register/$', 'register', { 'form_class':EmailRegistrationForm }, name="email-register"),
+    )
+except ImportError:
+    pass

email_usernames/views.py

+from django.conf import settings
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.contrib.auth import login
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+
+from forms import EmailLoginForm
+
+def email_login(request, template="registration/login.html", extra_context=None):
+    """A generic view that you can use instead of the default auth.login view, for email logins.
+       On GET:
+            will render the specified template with and pass the an empty EmailLoginForm as login_form
+            with its context, that you can use for the login.
+       On POST:
+            will try to validate and authenticate the user, using the EmailLoginForm. Upon successful
+            login, will redirect to whatever the standard LOGIN_REDIRECT_URL is set to, or the 'next'
+            parameter, if specified."""
+
+    if request.method == 'POST':
+        login_form = EmailLoginForm(data=request.POST)
+        if login_form.is_valid():
+            # The user has been authenticated, so log in and redirect
+            user = login(request, login_form.user)
+            # Redirect to page pointed to by the 'next' param, or else just the first page
+            next_page = request.REQUEST.get('next', settings.LOGIN_REDIRECT_URL)
+            return HttpResponseRedirect(next_page)
+    else:
+        login_form = EmailLoginForm()
+
+    context = { 'login_form':login_form, 'next':request.GET.get('next') }
+    if extra_context is None: extra_context = {}
+    for key, value in extra_context.items():
+        if callable(value):
+            context[key] = value()
+        else:
+            context[key] = value
+
+    return render_to_response(template, context, context_instance=RequestContext(request))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.