class RegistrationManager(models.Manager): """ Custom manager for the RegistrationProfile model. The methods defined here provide shortcuts for account creation and activation (including generation and emailing of activation keys), and for cleaning out expired inactive accounts. """ def activate_user(self, activation_key): """ Given the activation key, makes a User's account active if the activation key is valid and has not expired. Returns the User if successful, or False if the account was not found or the key had expired. """ # Make sure the key we're trying conforms to the pattern of a # SHA1 hash; if it doesn't, no point even trying to look it up # in the DB. if re.match('[a-f0-9]{40}', activation_key): try: user_profile = self.get(activation_key=activation_key) except self.model.DoesNotExist: return False if not user_profile.activation_key_expired(): # Account exists and has a non-expired key. Activate it. user = user_profile.user user.is_active = True user.save() return user return False def create_inactive_user(self, username, password, email, send_email=True): """ Creates a new User and a new RegistrationProfile for that User, generates an activation key, and mails it. Pass ``send_email=False`` to disable sending the email. """ # Create the user. new_user = User.objects.create_user(username, email, password) new_user.is_active = False new_user.save() # Generate a salted SHA1 hash to use as a key. salt = sha.new(str(random.random())).hexdigest()[:5] activation_key = sha.new(salt+new_user.username).hexdigest() # And finally create the profile. new_profile = self.create(user=new_user, activation_key=activation_key) if send_email: from django.core.mail import send_mail current_domain = Site.objects.get_current().domain subject = "Activate your new account at %s" % current_domain message_template = loader.get_template('registration/activation_email.txt') message_context = Context({ 'site_url': 'http://%s/' % current_domain, 'activation_key': activation_key, 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS }) message = message_template.render(message_context) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [new_user.email]) return new_user def delete_expired_users(self): """ Removes unused profiles and their associated accounts. This is provided largely as a convenience for maintenance purposes; if a RegistrationProfile's key expires without the account being activated, then both the RegistrationProfile and the associated User become clutter in the database, and (more importantly) it won't be possible for anyone to ever come back and claim the username. For best results, set this up to run regularly as a cron job. If you have a User whose account you want to keep in the database even though it's inactive (say, to prevent a troublemaker from accessing or re-creating his account), just delete that User's RegistrationProfile and this method will leave it alone. """ for profile in self.all(): if profile.activation_key_expired(): user = profile.user if not user.is_active: user.delete() # Removing the User will remove the RegistrationProfile, too.