Example #1
0
 def get_supplement_class(self):
     """Return the current registration supplement class"""
     # cache mechanisms will break the test thus disable it in test
     if not hasattr(self, '_supplement_class_cache') or 'test' in sys.argv:
         cls = get_supplement_class()
         setattr(self, '_supplement_class_cache', cls)
     return getattr(self, '_supplement_class_cache')
 def get_supplement_class(self):
     """Return the current registration supplement class"""
     # cache mechanisms will break the test thus disable it in test
     if not hasattr(self, '_supplement_class_cache') or 'test' in sys.argv:
         cls = get_supplement_class()
         setattr(self, '_supplement_class_cache', cls)
     return getattr(self, '_supplement_class_cache')
Example #3
0
 def test_get_supplement_class(self):
     from registration.supplements.default.models import DefaultRegistrationSupplement
     supplement_class = get_supplement_class(
             'registration.supplements.default.models.DefaultRegistrationSupplement')
     self.failUnless(supplement_class is DefaultRegistrationSupplement)
Example #4
0
class RegistrationProfile(models.Model):
    """Registration profile model class

    A simple profile which stores an activation key and inspection status for use
    during user account registration/inspection.

    Generally, you will not want to interact directly with instances of this model;
    the provided manager includes method for creating, accepting, rejecting and
    activating, as well as for cleaning out accounts which have never been activated
    or its registration has been rejected.

    While it is possible to use this model as the value of the ``AUTH_PROFILE_MODEL``
    setting, it's not recommended that you do so. This model's sole purpose is to
    store data temporarily during account registration, inspection and activation.

    """
    STATUS_LIST = (
        ('untreated', _('Untreated yet')),
        ('accepted', _('Registration has accepted')),
        ('rejected', _('Registration has rejected')),
    )
    user = models.OneToOneField(User,
                                verbose_name=_('user'),
                                related_name='registration_profile',
                                editable=False)
    _status = models.CharField(_('status'),
                               max_length=10,
                               db_column='status',
                               choices=STATUS_LIST,
                               default='untreated',
                               editable=False)
    activation_key = models.CharField(_('activation key'),
                                      max_length=40,
                                      null=True,
                                      default=None,
                                      editable=False)

    objects = RegistrationManager()
    supplement_class = get_supplement_class()

    class Meta:
        verbose_name = _('registration profile')
        verbose_name_plural = _('registration profiles')
        permissions = (
            ('accept_registration', 'Can accept registration'),
            ('reject_registration', 'Can reject registration'),
            ('activate_user', 'Can activate user in admin site'),
        )

    def _get_supplement(self):
        """get supplement information of this registration"""
        return getattr(self, '_supplement', None)

    supplement = property(_get_supplement)

    def _get_status(self):
        """get inspection status of this profile

        this will return 'expired' for profile which is accepted but
        activation key has expired

        """
        if self.activation_key_expired():
            return 'expired'
        return self._status

    def _set_status(self, value):
        """set inspection status of this profile

        Setting status to ``'accepted'`` will generate activation key
        and update ``date_joined`` attribute to now of associated ``User``

        Setting status not to ``'accepted'`` will remove activation key
        of this profile.

        """
        self._status = value
        # Automatically generate activation key for accepted profile
        if value == 'accepted' and not self.activation_key:
            username = self.user.username
            self.activation_key = generate_activation_key(username)
            # update user's date_joined
            self.user.date_joined = datetime_now()
            self.user.save()
        elif value != 'accepted' and self.activation_key:
            self.activation_key = None

    status = property(_get_status, _set_status)

    def get_status_display(self):
        """get human readable status"""
        sl = list(self.STATUS_LIST)
        sl.append(('expired', _('Activation key has expired')))
        sl = dict(sl)
        return sl.get(self.status)

    get_status_display.short_description = _("status")

    def __unicode__(self):
        return u"Registration information for %s" % self.user

    def __str__(self):
        return "Registration information for %s" % self.user

    def activation_key_expired(self):
        """get whether the activation key of this profile has expired

        Determine whether this ``RegistrationProfiel``'s activation key has
        expired, returning a boolean -- ``True`` if the key has expired.

        Key expiration is determined by a two-step process:

        1.  If the inspection status is not ``'accepted'``, the key is set to
            ``None``. In this case, this method returns ``False`` because these
            profiles are not treated yet or rejected by inspector.

        2.  Otherwise, the date the user signed up (which automatically updated
            in registration acceptance) is incremented by the number of days
            specified in the setting ``ACCOUNT_ACTIVATION_DAYS`` (which should
            be the number of days after acceptance during which a user is allowed
            to activate their account); if the result is less than or equal to
            the current date, the key has expired and this method return ``True``.

        """
        if self._status != 'accepted':
            return False
        expiration_date = datetime.timedelta(
            days=settings.ACCOUNT_ACTIVATION_DAYS)
        expired = self.user.date_joined + expiration_date <= datetime_now()
        return expired

    activation_key_expired.boolean = True

    def _send_email(self, site, action, extra_context=None):
        context = {
            'user': self.user,
            'site': site,
        }
        if action != 'activation':
            # the profile was deleted in 'activation' action
            context['profile'] = self

        if extra_context:
            context.update(extra_context)

        subject = render_to_string(
            'registration/%s_email_subject.txt' % action, context)
        subject = ''.join(subject.splitlines())
        message = render_to_string('registration/%s_email.txt' % action,
                                   context)

        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
                  [self.user.email])

    def send_registration_email(self, site):
        """send registration email to the user associated with this profile

        Send a registration email to the ``User`` associated with this
        ``RegistrationProfile``.

        The registration email will make use of two templates:

        ``registration/registration_email_subject.txt``
            This template will be used for the subject line of the email. Because
            it is used as the subject line of an email, this template's output
            **must** be only a single line of text; output longer than one line
            will be forcibly joined into only a single line.

        ``registration/registration_email.txt``
            This template will be used for the body of the email

        These templates will each receive the following context variables:

        ``site``
            An object representing the site on which the user registered;this is
            an instance of ``django.contrib.sites.models.Site`` or
            ``django.contrib.sites.models.RequestSite``

        ``user``
            A ``User`` instance of the registration.

        ``profile``
            A ``RegistrationProfile`` instance of the registration

        """
        self._send_email(site, 'registration')

    def send_acceptance_email(self, site, message=None):
        """send acceptance email to the user associated with this profile

        Send an acceptance email to the ``User`` associated with this
        ``RegistrationProfile``.

        The acceptance email will make use of two templates:

        ``registration/acceptance_email_subject.txt``
            This template will be used for the subject line of the email. Because
            it is used as the subject line of an email, this template's output
            **must** be only a single line of text; output longer than one line
            will be forcibly joined into only a single line.

        ``registration/acceptance_email.txt``
            This template will be used for the body of the email

        These templates will each receive the following context variables:

        ``site``
            An object representing the site on which the user registered;this is
            an instance of ``django.contrib.sites.models.Site`` or
            ``django.contrib.sites.models.RequestSite``

        ``user``
            A ``User`` instance of the registration.

        ``profile``
            A ``RegistrationProfile`` instance of the registration

        ``activation_key``
            The activation key for tne new account. Use following code to get
            activation url in the email body::

                {% load url from future %}
                http://{{ site.domain }}
                {% url 'registration_activate' activation_key=activation_key %}

        ``expiration_days``
            The number of days remaining during which the account may be activated.

        ``message``
            A message from inspector. In default template, it is not shown.

        """
        extra_context = {
            'activation_key': self.activation_key,
            'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
            'message': message,
        }
        self._send_email(site, 'acceptance', extra_context)

    def send_rejection_email(self, site, message=None):
        """send rejection email to the user associated with this profile

        Send a rejection email to the ``User`` associated with this
        ``RegistrationProfile``.

        The rejection email will make use of two templates:

        ``registration/rejection_email_subject.txt``
            This template will be used for the subject line of the email. Because
            it is used as the subject line of an email, this template's output
            **must** be only a single line of text; output longer than one line
            will be forcibly joined into only a single line.

        ``registration/rejection_email.txt``
            This template will be used for the body of the email

        These templates will each receive the following context variables:

        ``site``
            An object representing the site on which the user registered;this is
            an instance of ``django.contrib.sites.models.Site`` or
            ``django.contrib.sites.models.RequestSite``

        ``user``
            A ``User`` instance of the registration.

        ``profile``
            A ``RegistrationProfile`` instance of the registration

        ``message``
            A message from inspector. In default template, it is used for explain
            why the account registration has been rejected.

        """
        extra_context = {
            'message': message,
        }
        self._send_email(site, 'rejection', extra_context)

    def send_activation_email(self,
                              site,
                              password=None,
                              is_generated=False,
                              message=None):
        """send activation email to the user associated with this profile

        Send a activation email to the ``User`` associated with this
        ``RegistrationProfile``.

        The activation email will make use of two templates:

        ``registration/activation_email_subject.txt``
            This template will be used for the subject line of the email. Because
            it is used as the subject line of an email, this template's output
            **must** be only a single line of text; output longer than one line
            will be forcibly joined into only a single line.

        ``registration/activation_email.txt``
            This template will be used for the body of the email

        These templates will each receive the following context variables:

        ``site``
            An object representing the site on which the user registered;this is
            an instance of ``django.contrib.sites.models.Site`` or
            ``django.contrib.sites.models.RequestSite``

        ``user``
            A ``User`` instance of the registration.

        ``password``
            A raw password of ``User``. Use this to tell user to them password
            when the password is generated

        ``is_generated``
            A boolean -- ``True`` if the password is generated. Don't forget to
            tell user to them password when the password is generated

        ``message``
            A message from inspector. In default template, it is not shown.

        """
        extra_context = {
            'password': password,
            'is_generated': is_generated,
            'message': message,
        }
        self._send_email(site, 'activation', extra_context)
Example #5
0
 def _get_supplement_class(self):
     """get supplement class of this registration"""
     return get_supplement_class()
Example #6
0
 def _get_supplement_class(self):
     """get supplement class of this registration"""
     return get_supplement_class()