Mercurial > hg > bts-webui
changeset 169:992a9db773e9 draft
Removed embedded copy of python-django-registration
author | eriol-guest |
---|---|
date | Thu, 07 Jul 2011 03:44:27 +0000 |
parents | e0f4dccd70f6 |
children | e7a9a76fcc46 |
files | bts_webui/registration/LICENSE.txt bts_webui/registration/README.txt bts_webui/registration/__init__.py bts_webui/registration/models.py bts_webui/registration/myforms.py bts_webui/registration/urls.py bts_webui/registration/views.py |
diffstat | 7 files changed, 0 insertions(+), 511 deletions(-) [+] |
line wrap: on
line diff
deleted file mode 100644 --- a/bts_webui/registration/LICENSE.txt +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2007, James Bennett -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.
deleted file mode 100644 --- a/bts_webui/registration/README.txt +++ /dev/null @@ -1,179 +0,0 @@ -=================== -Django Registration -=================== - -This is a fairly simple user-registration application for Django_, -designed to make allowing user signups as painless as possible. It -requires a recent Subversion checkout of Django, since it uses -newforms and a couple other post-0.95 additions. Aside from that, it -has no external dependencies. - - -Installation notes -================== - -Google Code recommends doing the Subversion checkout like so:: - - svn checkout http://django-registration.googlecode.com/svn/trunk/ django-registration - -But the hyphen in the application name can cause issues installing -into a DB, so it's really better to do this:: - - svn checkout http://django-registration.googlecode.com/svn/trunk/ registration - -If you've already downloaded, rename the directory before installing. - -Then just add ``registration`` to the ``INSTALLED_APPS`` setting of -your project, and you should be good to go. - -Note that one of the templates included with this app uses the -``humanize`` library, so you'll want to have -``django.contrib.humanize`` installed if you don't already. - - -The short and sweet instructions -================================ - -Here's the workflow for user signup: - -1. User signs up for account. -2. User gets emailed an activation link. -3. User clicks the activation link before it expires. -4. User becomes a happy and productive contributor to your site. - -To make this work, start by putting this app into your -``INSTALLED_APPS`` setting and running ``syncdb``. Then, add a new -setting in your settings file: ``ACCOUNT_ACTIVATION_DAYS``. This -should be a number, and will be used as the number of days before an -activation key expires. - -Next, either edit the included templates (see below) to suit your -site, or create your own templates which integrate with your site's -look and feel. - -Finally, drop this line into your root URLConf:: - - (r'^accounts/', include('registration.urls')), - -And point people at the URL ``/accounts/register/``. Things should -just work. - - -If emails never get sent -======================== - -Welcome to the world of spam filtering! Assuming your server settings -are correct and Django is otherwise able to send email, the most -likely problem is overzealous filtering on the receiving end. Many -spam filtering solutions are depressingly overactive and love to eat -account-registration emails. - -If you know how to solve this, you will make millions of dollars. - - -How it works under the hood -=========================== - -This app defines one model -- ``RegistrationProfile`` -- which is tied -to the ``User`` model via a unique foreign key (so there can only ever -be one ``RegistrationProfile`` per ``User``), and which stores an -activation key and the date/time the key was generated. - -There's a custom manager on ``RegistrationProfile`` which has two -important methods: - -1. ``create_inactive_user`` takes a username, email address and - password, and first creates a new ``User``, setting the - ``is_active`` field to ``False``. Then it generates an activation - key and creates a ``RegistrationProfile`` for that - ``User``. Finally, it sends an email to the new user with an - activation link to click on. -2. ``activate_user`` takes an activation key, looks up the - ``RegistrationProfile`` it goes with, and sets ``is_active`` to - ``True`` on the corresponding ``User``. - -The views and form defined in this app basically exist solely to -expose this functionality over the Web. The registration form, used in -the initial sign-up view, does a little checking to make sure that the -username isn't taken and that the user types a password twice without -typos, but once that validation is taken care of everything gets -handed off to ``RegistrationProfile.objects.create_inactive_user``. - -Similarly, the activation view doesn't do a whole lot other than call -``RegistrationProfile.objects.activate_user``. - - -Clearing out inactive accounts -============================== - -Since activation keys do eventually expire (after however many days -you've specified in the ``ACCOUNT_ACTIVATION_DAYS`` setting), there's -a possibility that you'll end up with people who signed up but never -activated their accounts. And that's bad, because it clutters up your -database and it keeps the username they signed up with from ever -actually being used. - -So there's also a third method defined on ``RegistrationProfile``'s -custom manager: ``delete_expired_users``. All it does is loop through -the DB, looking for inactive accounts with expired activation keys, -and deletes them. It's recommended that you run it every once in a -while (ideally, just set up a cron job to do it periodically) so you -can clear out any inactive accounts and free up those usernames. - -The only time this isn't desirable is when you use the ``is_active`` -field as a way to keep troublesome users under control -- when you set -``is_active`` to ``False``, they can't log in, which is pretty -handy. But that means you _want_ to have an inactive account in your -DB and you *don't* want ``delete_expired_users`` to delete it -- if -that happened, the troublemaker could just re-create the account and -start all over again. - -For this reason, ``delete_expired_users`` looks first at the -``RegistrationProfile`` table, and only goes into the ``User`` table -when it finds expired profiles. So to keep a ``User`` around and -permanently inactive, just manually delete their -``RegistrationProfile`` instance and ``delete_inactive_users`` will -never touch their account. - - -A note on templates -=================== - -The download includes a set of example templates to give you an idea -of how to use the app, but please note that they are **examples** and -almost certainly will not work "out of the box" with your site; the -example templates are copied directly from a site which uses this -application, which means that they include assumptions about the -existence of that site's base templates and page structure. If you try -to use them as-is, you will most likely receive errors about -"base.html" not existing, or run into a mismatch between the blocks -defined in your site's base template and the blocks used in the -example templates. - -**As a result, it is assumed that you will look at, and edit, the -included templates before trying to use them on your own site**. If -you like, you can copy them into your site's template directory and -edit them there, or edit them in-place; Django's "app directories" -template loader, which is active by default, will be able to find them -if you do so. - -If you're unsure of how to work with Django templates, consult `the -Django template documentation`_. - -The included template for activation emails requires the ``humanize`` -library, so if you use it as-is, be sure to add -``django.contrib.humanize`` to your ``INSTALLED_APPS`` setting. - -Questions? Problems? -==================== - -If you've got a question that isn't covered here or in the comments -and docstrings in the code, or if you run into a bug, swing on over to -`this app's Google Code project page`_ and file a new "issue". I'll do -my best to respond promptly. - - -.. _Django: http://www.djangoproject.com/ -.. _the Django template documentation: http://www.djangoproject.com/documentation/templates/ -.. _this app's Google Code project page: http://code.google.com/p/django-registration/ - \ No newline at end of file
deleted file mode 100644 --- a/bts_webui/registration/models.py +++ /dev/null @@ -1,153 +0,0 @@ -""" -A registration profile model and associated manager. - -The RegistrationProfile model and especially its custom manager -implement nearly all the logic needed to handle user registration and -account activation, so before implementing something in a view or -form, check here to see if they can take care of it for you. - -Also, be sure to see the note on RegistrationProfile about use of the -``AUTH_PROFILE_MODULE`` setting. - -""" - -import datetime, random, re, sha -from django.db import models -from django.template import Context, loader -from django.contrib.auth.models import User -from django.contrib.sites.models import Site -from django.conf import settings - - -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. - - -class RegistrationProfile(models.Model): - """ - Simple profile model for a User, storing a registration date and - an activation key for the account. - - While it is possible to use this model as the value of the - ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do - so. This model is intended solely to store some data needed for - user registration, and can do that regardless of what you set in - ``AUTH_PROFILE_MODULE``, so if you want to use user profiles in a - project, it's far better to develop a customized model for that - purpose and just let this one handle registration. - - """ - user = models.ForeignKey(User, unique=True) - activation_key = models.CharField(max_length=40) - key_generated = models.DateTimeField() - - objects = RegistrationManager() - - class Admin: - pass - - def save(self, *args, **kwargs): - if not self.id: - self.key_generated = datetime.datetime.now() - super(RegistrationProfile, self).save() - - def __str__(self): - return "User profile for %s" % self.user.username - - def activation_key_expired(self): - """ - Determines whether this Profile's activation key has expired, - based on the value of the setting ``ACCOUNT_ACTIVATION_DAYS``. - - """ - expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS) - return self.key_generated + expiration_date <= datetime.datetime.now()
deleted file mode 100644 --- a/bts_webui/registration/myforms.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -Form and validation code for user registration. - -""" -from django.contrib.auth.models import User - -import sys -from django import forms - -# I put this on all required fields, because it's easier to pick up -# on them with CSS or JavaScript if they have a class of "required" -# in the HTML. Your mileage may vary. -attrs_dict = { 'class': 'required' } - -class RegistrationForm(forms.Form): - """ - Form for registering a new user account. - - Validates that the password is entered twice and matches, - and that the username is not already taken. - - """ - username = forms.CharField(max_length=30, - widget=forms.TextInput(attrs=attrs_dict), - label=u'Username') - email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict, - maxlength=200)), - label=u'Email address') - password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict), - label=u'Password') - password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict), - label=u'Password (again, to catch typos)') - - def clean_username(self): - """ - Validates that the username is not already in use. - - """ - if self.cleaned_data.get('username', None): - try: - user = User.objects.get(username__exact=self.cleaned_data['username']) - except User.DoesNotExist: - return self.cleaned_data['username'] - raise forms.ValidationError(u'The username "%s" is already taken. Please choose another.' % self.cleaned_data['username']) - - def clean_password2(self): - """ - Validates that the two password inputs match. - - """ - if self.cleaned_data.get('password1', None) and self.cleaned_data.get('password2', None) and \ - self.cleaned_data['password1'] == self.cleaned_data['password2']: - return self.cleaned_data['password2'] - raise forms.ValidationError(u'You must type the same password each time') -
deleted file mode 100644 --- a/bts_webui/registration/urls.py +++ /dev/null @@ -1,26 +0,0 @@ -# vim: set sw=4 ts=4 sts=4 noet: -""" -URLConf for Django user registration. - -Recommended usage is to use a call to ``include()`` in your project's -root URLConf to include this URLConf for any URL begninning with -'/accounts/'. - -""" - -from django.conf.urls.defaults import * -#from django.views.generic.simple import direct_to_template -#from django.contrib.auth.views import login, logout -#from views import activate, register - -urlpatterns = patterns('', - # Activation keys get matched by \w+ instead of the more specific - # [a-fA-F0-9]+ because a bad activation key should still get to the view; - # that way it can return a sensible "invalid key" message instead of a - # confusing 404. - (r'^activate/(?P<activation_key>\w+)/$', 'registration.views.activate'), - (r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'registration/login.html'}), - (r'^logout/$', 'django.contrib.auth.views.logout', {'template_name': 'registration/logout.html'}), - (r'^register/$', 'registration.views.register'), - (r'^register/complete/$', 'django.views.generic.simple.direct_to_template', {'template': 'registration/registration_complete.html'}), - )
deleted file mode 100644 --- a/bts_webui/registration/views.py +++ /dev/null @@ -1,70 +0,0 @@ -# vim: set sw=4 ts=4 sts=4 noet: -""" -Views which allow users to create and activate accounts. - -""" - -from django.conf import settings -from django.http import HttpResponseRedirect -from django.shortcuts import render_to_response -from django.template import RequestContext -from models import RegistrationProfile -from myforms import RegistrationForm - -def activate(request, activation_key): - """ - Activates a user's account, if their key is valid and hasn't - expired. - - Context:: - account - The ``User`` object corresponding to the account, - if the activation was successful. - - expiration_days - The number of days for which activation keys stay valid. - - Template:: - registration/activate.html - - """ - activation_key = activation_key.lower() # Normalize before trying anything with it. - account = RegistrationProfile.objects.activate_user(activation_key) - return render_to_response('registration/activate.html', - {'account': account, - 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS }, - context_instance=RequestContext(request)) - -def register(request, success_url='/accounts/register/complete/'): - """ - Allows a new user to register an account. - - On successful registration, an email will be sent to the new user - with an activation link to click to make the account active. This - view will then redirect to ``success_url``, which defaults to - '/accounts/register/complete/'. This application has a URL pattern - for that URL and routes it to the ``direct_to_template`` generic - view to display a short message telling the user to check their - email for the account activation link. - - Context:: - form - The registration form - - Template:: - registration/registration_form.html - - """ - - if request.method == 'POST': - form = RegistrationForm(request.POST) - if form.is_valid(): - new_user = RegistrationProfile.objects.create_inactive_user(username=form.cleaned_data['username'], - password=form.cleaned_data['password1'], - email=form.cleaned_data['email']) - return HttpResponseRedirect(success_url) - else: - form = RegistrationForm() - return render_to_response('registration/registration_form.html', - { 'form': form }, - context_instance=RequestContext(request))