improved translation a little bit. some update in ikog and task lists.
[worddb.git] / libs / registration / models.py
blob1e4d55030f95e8bbe7e5ecf59af89c209418a03c
1 import datetime
2 import random
3 import re
4 import sha
6 from django.conf import settings
7 from django.db import models
8 from django.template.loader import render_to_string
9 from django.utils.translation import ugettext_lazy as _
10 from django.contrib.auth.models import User
11 from django.contrib.sites.models import Site
14 SHA1_RE = re.compile('^[a-f0-9]{40}$')
17 class RegistrationManager(models.Manager):
18 """
19 Custom manager for the ``RegistrationProfile`` model.
21 The methods defined here provide shortcuts for account creation
22 and activation (including generation and emailing of activation
23 keys), and for cleaning out expired inactive accounts.
25 """
26 def activate_user(self, activation_key):
27 """
28 Validate an activation key and activate the corresponding
29 ``User`` if valid.
31 If the key is valid and has not expired, return the ``User``
32 after activating.
34 If the key is not valid or has expired, return ``False``.
36 If the key is valid but the ``User`` is already active,
37 return ``False``.
39 To prevent reactivation of an account which has been
40 deactivated by site administrators, the activation key is
41 reset to the string ``ALREADY_ACTIVATED`` after successful
42 activation.
44 """
45 # Make sure the key we're trying conforms to the pattern of a
46 # SHA1 hash; if it doesn't, no point trying to look it up in
47 # the database.
48 if SHA1_RE.search(activation_key):
49 try:
50 profile = self.get(activation_key=activation_key)
51 except self.model.DoesNotExist:
52 return False
53 if not profile.activation_key_expired():
54 user = profile.user
55 user.is_active = True
56 user.save()
57 profile.activation_key = "ALREADY_ACTIVATED"
58 profile.save()
59 return user
60 return False
62 def create_inactive_user(self, username, password, email,
63 send_email=True, profile_callback=None):
64 """
65 Create a new, inactive ``User``, generates a
66 ``RegistrationProfile`` and email its activation key to the
67 ``User``, returning the new ``User``.
69 To disable the email, call with ``send_email=False``.
71 To enable creation of a custom user profile along with the
72 ``User`` (e.g., the model specified in the
73 ``AUTH_PROFILE_MODULE`` setting), define a function which
74 knows how to create and save an instance of that model with
75 appropriate default values, and pass it as the keyword
76 argument ``profile_callback``. This function should accept one
77 keyword argument:
79 ``user``
80 The ``User`` to relate the profile to.
82 """
83 new_user = User.objects.create_user(username, email, password)
84 new_user.is_active = False
85 new_user.save()
87 registration_profile = self.create_profile(new_user)
89 if profile_callback is not None:
90 profile_callback(user=new_user)
92 if send_email:
93 from django.core.mail import send_mail
94 current_site = Site.objects.get_current()
96 subject = render_to_string('registration/activation_email_subject.txt',
97 { 'site': current_site })
98 # Email subject *must not* contain newlines
99 subject = ''.join(subject.splitlines())
101 message = render_to_string('registration/activation_email.txt',
102 { 'activation_key': registration_profile.activation_key,
103 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
104 'site': current_site })
106 send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [new_user.email])
107 return new_user
109 def create_profile(self, user):
111 Create a ``RegistrationProfile`` for a given
112 ``User``, and return the ``RegistrationProfile``.
114 The activation key for the ``RegistrationProfile`` will be a
115 SHA1 hash, generated from a combination of the ``User``'s
116 username and a random salt.
119 salt = sha.new(str(random.random())).hexdigest()[:5]
120 activation_key = sha.new(salt+user.username).hexdigest()
121 return self.create(user=user,
122 activation_key=activation_key)
124 def delete_expired_users(self):
126 Remove expired instances of ``RegistrationProfile`` and their
127 associated ``User``s.
129 Accounts to be deleted are identified by searching for
130 instances of ``RegistrationProfile`` with expired activation
131 keys, and then checking to see if their associated ``User``
132 instances have the field ``is_active`` set to ``False``; any
133 ``User`` who is both inactive and has an expired activation
134 key will be deleted.
136 It is recommended that this method be executed regularly as
137 part of your routine site maintenance; this application
138 provides a custom management command which will call this
139 method, accessible as ``manage.py cleanupregistration``.
141 Regularly clearing out accounts which have never been
142 activated serves two useful purposes:
144 1. It alleviates the ocasional need to reset a
145 ``RegistrationProfile`` and/or re-send an activation email
146 when a user does not receive or does not act upon the
147 initial activation email; since the account will be
148 deleted, the user will be able to simply re-register and
149 receive a new activation key.
151 2. It prevents the possibility of a malicious user registering
152 one or more accounts and never activating them (thus
153 denying the use of those usernames to anyone else); since
154 those accounts will be deleted, the usernames will become
155 available for use again.
157 If you have a troublesome ``User`` and wish to disable their
158 account while keeping it in the database, simply delete the
159 associated ``RegistrationProfile``; an inactive ``User`` which
160 does not have an associated ``RegistrationProfile`` will not
161 be deleted.
164 for profile in self.all():
165 if profile.activation_key_expired():
166 user = profile.user
167 if not user.is_active:
168 user.delete()
171 class RegistrationProfile(models.Model):
173 A simple profile which stores an activation key for use during
174 user account registration.
176 Generally, you will not want to interact directly with instances
177 of this model; the provided manager includes methods
178 for creating and activating new accounts, as well as for cleaning
179 out accounts which have never been activated.
181 While it is possible to use this model as the value of the
182 ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do
183 so. This model's sole purpose is to store data temporarily during
184 account registration and activation, and a mechanism for
185 automatically creating an instance of a site-specific profile
186 model is provided via the ``create_inactive_user`` on
187 ``RegistrationManager``.
190 user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
191 activation_key = models.CharField(_('activation key'), max_length=40)
193 objects = RegistrationManager()
195 class Meta:
196 verbose_name = _('registration profile')
197 verbose_name_plural = _('registration profiles')
199 def __unicode__(self):
200 return u"Registration information for %s" % self.user
202 def activation_key_expired(self):
204 Determine whether this ``RegistrationProfile``'s activation
205 key has expired, returning a boolean -- ``True`` if the key
206 has expired.
208 Key expiration is determined by a two-step process:
210 1. If the user has already activated, the key will have been
211 reset to the string ``ALREADY_ACTIVATED``. Re-activating is
212 not permitted, and so this method returns ``True`` in this
213 case.
215 2. Otherwise, the date the user signed up is incremented by
216 the number of days specified in the setting
217 ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of
218 days after signup during which a user is allowed to
219 activate their account); if the result is less than or
220 equal to the current date, the key has expired and this
221 method returns ``True``.
224 expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
225 return self.activation_key == "ALREADY_ACTIVATED" or \
226 (self.user.date_joined + expiration_date <= datetime.datetime.now())
227 activation_key_expired.boolean = True