mirror of
https://github.com/postgres/pgweb.git
synced 2025-08-13 13:12:42 +00:00
Add support for changing passwords, resetting passwords and signing
up for new accounts.
This commit is contained in:
40
pgweb/account/forms.py
Normal file
40
pgweb/account/forms.py
Normal 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")
|
@ -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'),
|
||||||
)
|
)
|
||||||
|
@ -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'))
|
||||||
|
@ -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'},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -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%}
|
||||||
|
|
||||||
|
8
templates/account/new_account_email.txt
Normal file
8
templates/account/new_account_email.txt
Normal 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}}.
|
26
templates/account/password_change.html
Normal file
26
templates/account/password_change.html
Normal 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> </label><input type="submit" value="Change password" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{%endblock%}
|
8
templates/account/password_change_done.html
Normal file
8
templates/account/password_change_done.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{%extends "base/page.html"%}
|
||||||
|
{%block contents%}
|
||||||
|
<h1>Change password</h1>
|
||||||
|
<p>
|
||||||
|
Your password has been changed.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{%endblock%}
|
17
templates/account/password_reset.html
Normal file
17
templates/account/password_reset.html
Normal 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 %}
|
6
templates/account/password_reset_complete.html
Normal file
6
templates/account/password_reset_complete.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{%extends "base/page.html"%}
|
||||||
|
{%block contents%}
|
||||||
|
<h1>Password reset complete</h1>
|
||||||
|
<p>Your password has been reset.</p>
|
||||||
|
|
||||||
|
{% endblock %}
|
32
templates/account/password_reset_confirm.html
Normal file
32
templates/account/password_reset_confirm.html
Normal 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> </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 %}
|
9
templates/account/password_reset_done.html
Normal file
9
templates/account/password_reset_done.html
Normal 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 %}
|
10
templates/account/password_reset_email.txt
Normal file
10
templates/account/password_reset_email.txt
Normal 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}}.
|
||||||
|
|
||||||
|
|
11
templates/account/signup_complete.html
Normal file
11
templates/account/signup_complete.html
Normal 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 %}
|
Reference in New Issue
Block a user