Add support for changing passwords, resetting passwords and signing

up for new accounts.
This commit is contained in:
Magnus Hagander
2010-02-26 15:57:33 +01:00
parent c3be6c213f
commit 7b54520396
14 changed files with 244 additions and 6 deletions

40
pgweb/account/forms.py Normal file
View File

@ -0,0 +1,40 @@
from django import forms
from django.contrib.auth.models import User
class SignupForm(forms.Form):
username = forms.CharField(max_length=30)
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.EmailField()
email2 = forms.EmailField()
def clean_email2(self):
# If the primary email checker had an exception, the data will be gone
# from the cleaned_data structure
if not self.cleaned_data.has_key('email'):
return self.cleaned_data['email2']
email1 = self.cleaned_data['email']
email2 = self.cleaned_data['email2']
if email1 != email2:
raise forms.ValidationError("Email addresses don't match")
return email2
def clean_username(self):
username = self.cleaned_data['username']
try:
u = User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError("This username is already in use")
def clean_email(self):
email = self.cleaned_data['email']
try:
u = User.objects.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError("A user with this email address is already registered")

View File

@ -18,9 +18,19 @@ urlpatterns = patterns('',
# Docs comments # Docs comments
(r'^comments/(new)/(.*)/(.*)/$', 'docs.views.commentform'), (r'^comments/(new)/(.*)/(.*)/$', 'docs.views.commentform'),
# Log in # Log in, logout, change password etc
(r'^login/$', 'account.views.login'), (r'^login/$', 'account.views.login'),
# Log out
(r'^logout/$', 'account.views.logout'), (r'^logout/$', 'account.views.logout'),
(r'^changepwd/$', 'account.views.changepwd'),
(r'^changepwd/done/$', 'django.contrib.auth.views.password_change_done', {
'template_name': 'account/password_change_done.html', }),
(r'^reset/$', 'account.views.resetpwd'),
(r'^reset/done/$', 'django.contrib.auth.views.password_reset_done', {
'template_name': 'account/password_reset_done.html', }),
(r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {
'template_name': 'account/password_reset_confirm.html', }),
(r'^reset/complete/$', 'django.contrib.auth.views.password_reset_complete', {
'template_name': 'account/password_reset_complete.html', }),
(r'^signup/$', 'account.views.signup'),
(r'^signup/complete/$', 'account.views.signup_complete'),
) )

View File

@ -1,17 +1,23 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
import django.contrib.auth.views as authviews import django.contrib.auth.views as authviews
from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseServerError
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.utils.http import int_to_base36
from django.contrib.auth.tokens import default_token_generator
from django.conf import settings
from pgweb.util.decorators import ssl_required from pgweb.util.decorators import ssl_required
from pgweb.util.contexts import NavContext from pgweb.util.contexts import NavContext
from pgweb.util.misc import send_template_mail
from pgweb.news.models import NewsArticle from pgweb.news.models import NewsArticle
from pgweb.events.models import Event from pgweb.events.models import Event
from pgweb.core.models import Organisation from pgweb.core.models import Organisation
from pgweb.downloads.models import Product from pgweb.downloads.models import Product
from forms import SignupForm
@ssl_required @ssl_required
@login_required @login_required
def home(request): def home(request):
@ -65,3 +71,56 @@ def login(request):
@ssl_required @ssl_required
def logout(request): def logout(request):
return authviews.logout_then_login(request, login_url='/') return authviews.logout_then_login(request, login_url='/')
@ssl_required
def changepwd(request):
return authviews.password_change(request, template_name='account/password_change.html')
@ssl_required
def resetpwd(request):
return authviews.password_reset(request, template_name='account/password_reset.html',
email_template_name='account/password_reset_email.txt')
@ssl_required
def signup(request):
if request.user.is_authenticated():
return HttpResponseServerError("You must log out before you can sign up for a new account")
if request.method == 'POST':
# Attempt to create user then, eh?
form = SignupForm(data=request.POST)
if form.is_valid():
# Attempt to create the user here
# XXX: Do we need to validate something else?
user = User.objects.create_user(form.cleaned_data['username'], form.cleaned_data['email'])
user.first_name = form.cleaned_data['first_name']
user.last_name = form.cleaned_data['last_name']
user.save()
# Now generate a token
token = default_token_generator.make_token(user)
# Generate an outgoing email
send_template_mail(settings.NOTIFICATION_FROM,
form.cleaned_data['email'],
'Your new postgresql.org community account',
'account/new_account_email.txt',
{ 'uid': int_to_base36(user.id), 'token': token, 'user': user}
)
return HttpResponseRedirect('/account/signup/complete/')
else:
form = SignupForm()
return render_to_response('base/form.html', {
'form': form,
'formitemtype': 'Account',
'form_intro': 'This is the intro text',
}, NavContext(request, 'account'))
@ssl_required
def signup_complete(request):
return render_to_response('account/signup_complete.html', {
}, NavContext(request, 'account'))

View File

@ -81,6 +81,7 @@ sitenav = {
{'title': 'Products', 'link':'/account/edit/products/'}, {'title': 'Products', 'link':'/account/edit/products/'},
{'title': 'Organisations', 'link':'/account/edit/organisations/'}, {'title': 'Organisations', 'link':'/account/edit/organisations/'},
]}, ]},
{'title': 'Change password', 'link':'/account/changepwd/'},
{'title': 'Logout', 'link':'/account/logout'}, {'title': 'Logout', 'link':'/account/logout'},
], ],
} }

View File

@ -2,7 +2,9 @@
{%block contents%} {%block contents%}
<h1>Log in</h1> <h1>Log in</h1>
<p> <p>
Please log in to your community account. Please log in to your community account to reach this area. If you do not already have an account,
you may <a href="/account/signup/">sign up</a> for one now. If you have one but have lost your
password, you can use the <a href="/account/reset/">password reset</a> form.
</p> </p>
<form action="." method="post" id="login-form"> <form action="." method="post" id="login-form">
@ -21,7 +23,6 @@ Please log in to your community account.
<script type="text/javascript"> <script type="text/javascript">
document.getElementById('id_username').focus() document.getElementById('id_username').focus()
</script> </script>
</div>
{%endblock%} {%endblock%}

View File

@ -0,0 +1,8 @@
You are receiving this e-mail because you requested a new
PostgreSQL community account.
Please go to the following page and choose a new password:
https://wwwmaster.postgresql.org/account/reset/{{uid}}-{{token}}/
Your username, in case you've forgotten, is {{user.username}}.

View File

@ -0,0 +1,26 @@
{%extends "base/page.html"%}
{%block contents%}
<h1>Change password</h1>
<p>
From this form you can change the password of your community account.
</p>
<form action="." method="post" id="login-form">
<div class="form-row">
{{ form.old_password.errors }}
<label for="id_old_password">Old password:</label>{{ form.old_password }}
</div>
<div class="form-row">
{{ form.new_password1.errors }}
<label for="id_new_password1">New password</label>{{ form.new_password1 }}
</div>
<div class="form-row">
{{ form.new_password2.errors }}
<label for="id_new_password2">Confirm password:</label>{{ form.new_password2 }}
</div>
<div class="submit-row">
<label>&nbsp;</label><input type="submit" value="Change password" />
</div>
</form>
{%endblock%}

View File

@ -0,0 +1,8 @@
{%extends "base/page.html"%}
{%block contents%}
<h1>Change password</h1>
<p>
Your password has been changed.
</p>
{%endblock%}

View File

@ -0,0 +1,17 @@
{%extends "base/page.html"%}
{%block contents%}
<h1>Password reset</h1>
<p>
If you've forgotten your password, you can enter your email address in the field below
and we'll email you instructions for setting a new one.
</p>
<form action="" method="post">
<div class="form-row">
{{ form.email.errors }}
<label for="id_email">E-mail address</label> {{ form.email }} <input type="submit" value="Reset my password" />
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,6 @@
{%extends "base/page.html"%}
{%block contents%}
<h1>Password reset complete</h1>
<p>Your password has been reset.</p>
{% endblock %}

View File

@ -0,0 +1,32 @@
{%extends "base/page.html"%}
{%block contents%}
{% if validlink %}
<h1>Enter new password</h1>
<p>Please enter your new password twice so we can verify you typed it in correctly.</p>
<form action="" method="post">
<div class="form-row">
{{ form.new_password1.errors }}
<label for="id_new_password1">New password:</label>{{ form.new_password1 }}
</div>
<div class="form-row">
{{ form.new_password2.errors }}
<label for="id_new_password2">Confirm password:</label>{{ form.new_password2 }}
</div>
<div class="submit-row">
<label>&nbsp;</label><input type="submit" value="Change password" />
</div>
</form>
{% else %}
<h1>Password reset unsuccessful</h1>
<p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{%extends "base/page.html"%}
{%block contents%}
<h1>Password reset</h1>
<p>
We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly.
</p>
{% endblock %}

View File

@ -0,0 +1,10 @@
You are receiving this e-mail because you requested a password reset for your
PostgreSQL community account.
Please go to the following page and choose a new password:
https://wwwmaster.postgresql.org/account/reset/{{uid}}-{{token}}/
Your username, in case you've forgotten, is {{user.username}}.

View File

@ -0,0 +1,11 @@
{%extends "base/page.html"%}
{%block contents%}
<h1>Account created</h1>
<p>
Your new account has been created, and we have emailed you instructions
for how to set a password to enable it. It should arrive in your mailbox
shortly.
</p>
{% endblock %}