Source

django-registration-plus / registration / backends / default / __init__.py

Full commit
from django.conf import settings
from django.contrib.auth import login, authenticate
from django.contrib.sites.models import RequestSite
from django.contrib.sites.models import Site

from registration import signals
from registration.forms import RegistrationForm
from registration.models import EmailValidation
from registration.backends import EmptyBackend


class DefaultBackend(EmptyBackend):
    """
    A registration backend which follows a simple workflow:
    
    1. User signs up, inactive account is created.
    
    2. Email is sent to user with validation link.
    
    3. User clicks validation link, account is now active.
    
    Using this backend requires:
    
    * ``registration`` be listed in the ``INSTALLED_APPS`` setting
      (since this backend makes use of models defined in this
      application).
    
    * The setting ``EMAIL_VALIDATION_DAYS`` be supplied, specifying
      (as an integer) the number of days from registration during
      which a user may validate their email and activate their account (after 
      that period expires, activation will be disallowed).
    
    * The creation of the templates
      ``registration/validation_email_subject.txt``,
      ``registration/validation_email.txt`` and optionally 
      ``registration/validation_email.html``, which will be used for
      the validation email. See the notes for this backends
      ``register`` method for details regarding these templates.
    
    * The creation of the templates ``registration/registration_form.html``,
      ``registration/registration_complete.html``,
      ``registration/validation_error.html`` and
      ``registration/validation_complete.html`` for the views if you use the
      provided ``urls.py``.
    
    Optional tasks for using this backend:
    
    * Adding the ``REGISTRATION_OPEN`` setting and setting it to  ``False`` if 
      you want to close the registration. Omitting this setting, 
      or setting it to ``True``, will be interpreted as meaning that 
      registration is currently open and permitted.
    
    * Creation of the template ``registration/registration_closed.html`` for 
      when you close registration using the ``REGISTRATION_OPEN`` setting if 
      you use the provided ``urls.py``.
    
    Internally, the validation is done via storing a validation key in
    an instance of ``registration.models.EmailValidation``. See
    that model and its custom manager for full documentation of its
    fields and supported operations. 
    
    If you want to add fields to ``registration.models.EmailValidation``, you 
    can extend it and then extend this backend with a new one that only 
    specifies a different ``validation_model_class``.
    
    properties that allow simple modification of the backend:
    
    * ``required_validation`` tells the backend if the user is activated after
      email validation or immediately after registration.
    
    * ``login_after_activation`` tells the backend that it needs to log the 
      user in after registering. If ``required_validation`` is set to ``True`` 
      this setting has no effect.
    
    * ``validation_model_class`` defines the model that stores the validation 
      information. If you change it, you need to provide the same methods as 
      ``EmailValidation`` and its custom manager.
    
    """
    required_validation = True
    login_after_activation = False
    validation_model_class = EmailValidation
    
    def register(self, request, **kwargs):
        """
        Given a username, email address and password, register a new
        user account, which will initially be inactive.
        
        Along with the new ``User`` object, a new
        ``registration.models.EmailValidation`` will be created,
        tied to that ``User``, containing the validation key which
        will be used for this account.
        
        An email will be sent to the supplied email address; this
        email should contain an validation link. The email will be
        rendered using two templates. See the documentation for
        ``EmailValidation.send_validation_email()`` for
        information about these templates and the contexts provided to
        them.
        
        After the ``User`` and ``EmailValidation`` are created and
        the validation email is sent, the signal
        ``registration.signals.user_registered`` will be sent, with
        the new ``User`` as the keyword argument ``user`` and the
        class of this backend as the sender.
        
        """
        username, email, password = kwargs['username'], kwargs['email'], kwargs['password1']
        if Site._meta.installed:
            site = Site.objects.get_current()
        else:
            site = RequestSite(request)
        new_user = self.validation_model_class.objects.create_user(username, email, 
                                                       password, site, 
                                                       active=(not self.required_validation))
        for k in kwargs:
            if hasattr(new_user, k):
                setattr(new_user, k, kwargs[k])
        new_user.save()
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=request)
        if not self.required_validation:
            if self.login_after_activation:
                # authenticate() always has to be called before login(), and
                # will return the user we just created.
                new_user = authenticate(username=username, password=password)
                login(request, new_user)
            signals.user_activated.send(sender=self.__class__,
                                        user=new_user,
                                        request=request)
        return new_user
    
    def validate(self, request, validation_key):
        """
        Given an an validation key, look up and validate the user account 
        corresponding to that key (if possible).

        After successful validation, the signal 
        ``registration.signals.user_activated`` will be sent, with the newly 
        activated ``User`` as the keyword argument ``user`` and the class of 
        this backend as the sender.
        
        """
        validated = self.validation_model_class.objects.validate_email(validation_key)
        if validated:
            if self.required_validation:
                validated.is_active = True
                validated.save()
                signals.user_activated.send(sender=self.__class__,
                                            user=validated,
                                            request=request)
            signals.email_validated.send(sender=self.__class__,
                                         user=validated,
                                         request=request)
        return validated
    
    def registration_allowed(self, request):
        """
        Indicate whether account registration is currently permitted,
        based on the value of the setting ``REGISTRATION_OPEN``. This
        is determined as follows:

        * If ``REGISTRATION_OPEN`` is not specified in settings, or is
          set to ``True``, registration is permitted.

        * If ``REGISTRATION_OPEN`` is both specified and set to
          ``False``, registration is not permitted.
        
        """
        return getattr(settings, 'REGISTRATION_OPEN', True)
    
    def get_form_class(self, request):
        """
        Return the default form class used for user registration.
        
        """
        return RegistrationForm
    
    def post_registration_redirect(self, request, user):
        """
        Return the name of the URL to redirect to after successful
        user registration.
        
        """
        return ('registration_complete', (), {})
    
    def post_validation_redirect(self, request, user):
        """
        Return the name of the URL to redirect to after successful
        account validation.
        
        """
        return ('registration_validation_complete', (), {})
    

class OptionalValidationBackend(DefaultBackend):
    """
    A slight modification to the registration backend which follows a simple 
    workflow:
    
    1. User signs up, an active account is created.
    
    2. Email is sent to user with validation link.
    
    3. User clicks validation link, email is now validated.
    """
    required_validation = False
    

class OptionalValidationAutoLoginBackend(OptionalValidationBackend):
    """
    A slight modification to the registration backend which follows a simple 
    workflow:
    
    1. User signs up, an active account is created, user is logged in.
    
    2. Email is sent to user with validation link.
    
    3. User clicks validation link, email is now validated.
    """
    required_validation = False
    login_after_activation = True
    
    def post_registration_redirect(self, request, user):
        """
        After registration, redirect to the user's account page.
        
        """
        return (user.get_absolute_url(), (), {})