Add support for requesting a password reset email.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2017-07-06 23:09:35 -04:00
parent ff40b1effc
commit 00d0184bad
9 changed files with 217 additions and 36 deletions

View File

@@ -49,12 +49,14 @@
<div class="group wat-cf">
{% include 'appearance/generic_form_instance.html' %}
<input type="hidden" name="next" value="{{ next|escape }}" />
<div class="form-group">
<button class="btn btn-primary" name="{% if form.prefix %}{{ form.prefix }}-submit{% else %}submit{% endif %}" type="submit"><i class="fa fa-sign-in"></i> {% trans 'Sign in' %}</button>
</div>
</form>
<hr>
<div>
<a class="pull-right" href="{% url 'authentication:password_reset_view' %}">{% trans 'Forgot your password?' %}</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,21 @@
{% extends 'appearance/base.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block base_title %}{% trans 'Password reset' %}{% endblock %}
{% block project_name %}{% endblock %}
{% block content_plain %}
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
<div class="alert alert-success" role="alert">{% trans 'Password reset complete! Click the link below to login.' %}</div>
<div class="text-center"><a class="btn btn-primary" href="{% url 'authentication:logout_view' %}">{% trans 'Login page' %}</a></div>
</div>
</div>
{% endblock content_plain %}

View File

@@ -0,0 +1,37 @@
{% extends 'appearance/base.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block base_title %}{% trans 'Password reset' %}{% endblock %}
{% block project_name %}{% endblock %}
{% block content_plain %}
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">&nbsp;</h3>
</div>
<div class="panel-body">
<h2>{% trans 'Password reset' %}</h2>
<hr>
<div class="content login">
<form action="." method="post" class="form login">{% csrf_token %}
<div class="group wat-cf">
{% include 'appearance/generic_form_instance.html' %}
<input type="hidden" name="next" value="{{ next|escape }}" />
<div class="form-group">
<button class="btn btn-primary" name="{% if form.prefix %}{{ form.prefix }}-submit{% else %}submit{% endif %}" type="submit"><i class="fa fa-check"></i> {% trans 'Submit' %}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock content_plain %}

View File

@@ -0,0 +1,18 @@
{% extends 'appearance/base.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block base_title %}{% trans 'Password reset' %}{% endblock %}
{% block project_name %}{% endblock %}
{% block content_plain %}
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
<div class="alert alert-success" role="alert">{% trans 'Password reset email sent!' %}</div>
</div>
</div>
{% endblock content_plain %}

View File

@@ -0,0 +1,6 @@
Hello {{ user.full_name|default:user }},
We received a request to reset your {{ project_title }} password.
Click the link below to choose a new one:
{{ project_website }}{% url 'authentication:password_reset_confirm_view' uid token %}

View File

@@ -0,0 +1,37 @@
{% extends 'appearance/base.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block base_title %}{% trans 'Password reset' %}{% endblock %}
{% block project_name %}{% endblock %}
{% block content_plain %}
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">&nbsp;</h3>
</div>
<div class="panel-body">
<h2>{% trans 'Password reset' %}</h2>
<hr>
<div class="content login">
<form action="." method="post" class="form login">{% csrf_token %}
<div class="group wat-cf">
{% include 'appearance/generic_form_instance.html' %}
<input type="hidden" name="next" value="{{ next|escape }}" />
<div class="form-group">
<button class="btn btn-primary" name="{% if form.prefix %}{{ form.prefix }}-submit{% else %}submit{% endif %}" type="submit"><i class="fa fa-check"></i> {% trans 'Submit' %}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock content_plain %}

View File

@@ -0,0 +1 @@
{{ project_title }} password reset link

View File

@@ -2,12 +2,13 @@ from __future__ import unicode_literals
from django.conf import settings
from django.conf.urls import url
from django.contrib.auth.views import (
logout, password_reset, password_reset_confirm, password_reset_complete,
password_reset_done
)
from django.contrib.auth.views import logout
from .views import login_view, password_change_done, password_change_view
from .views import (
login_view, password_change_done, password_change_view,
password_reset_complete_view, password_reset_confirm_view,
password_reset_done_view, password_reset_view
)
urlpatterns = [
@@ -20,35 +21,23 @@ urlpatterns = [
r'^password/change/$', password_change_view,
name='password_change_view'
),
]
urlpatterns += [
url(
r'^logout/$', logout, {'next_page': settings.LOGIN_REDIRECT_URL},
name='logout_view'
),
url(
r'^password/reset/$', password_reset, {
'email_template_name': 'appearance/password_reset_email.html',
'template_name': 'appearance/password_reset_form.html',
'post_reset_redirect': '/password/reset/done'
}, name='password_reset_view'
r'^password/reset/$', password_reset_view, name='password_reset_view'
),
url(
r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
password_reset_confirm, {
'template_name': 'appearance/password_reset_confirm.html',
'post_reset_redirect': '/password/reset/complete/'
}, name='password_reset_confirm_view'
r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
password_reset_confirm_view, name='password_reset_confirm_view'
),
url(
r'^password/reset/complete/$',
password_reset_complete, {
'template_name': 'appearance/password_reset_complete.html'
}, name='password_reset_complete_view'),
r'^password/reset/complete/$', password_reset_complete_view,
name='password_reset_complete_view'
),
url(
r'^password/reset/done/$',
password_reset_done, {
'template_name': 'appearance/password_reset_done.html'
}, name='password_reset_done_view'),
r'^password/reset/done/$', password_reset_done_view,
name='password_reset_done_view'
),
]

View File

@@ -2,12 +2,14 @@ from __future__ import absolute_import, unicode_literals
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.views import login, password_change
from django.contrib.auth.views import (
login, password_change, password_reset, password_reset_confirm,
password_reset_complete, password_reset_done
)
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from stronghold.decorators import public
from .forms import EmailAuthenticationForm, UsernameAuthenticationForm
@@ -28,9 +30,9 @@ def login_view(request):
kwargs['authentication_form'] = UsernameAuthenticationForm
if not request.user.is_authenticated():
context = {'appearance_type': 'plain'}
extra_context = {'appearance_type': 'plain'}
result = login(request, extra_context=context, **kwargs)
result = login(request, extra_context=extra_context, **kwargs)
if request.method == 'POST':
form = kwargs['authentication_form'](request, data=request.POST)
if form.is_valid():
@@ -49,11 +51,10 @@ def password_change_view(request):
"""
Password change wrapper for better control
"""
context = {'title': _('Current user password change')}
extra_context = {'title': _('Current user password change')}
return password_change(
request,
extra_context=context,
request, extra_context=extra_context,
template_name='appearance/generic_form.html',
post_change_redirect=reverse('authentication:password_change_done'),
)
@@ -63,8 +64,77 @@ def password_change_done(request):
"""
View called when the new user password has been accepted
"""
messages.success(
request, _('Your password has been successfully changed.')
)
return redirect('common:current_user_details')
@public
def password_reset_complete_view(request):
extra_context = {
'appearance_type': 'plain'
}
kwargs = {
'template_name': 'authentication/password_reset_complete.html'
}
return password_reset_complete(
request, extra_context=extra_context, **kwargs
)
@public
def password_reset_confirm_view(request, uidb64=None, token=None):
extra_context = {
'appearance_type': 'plain'
}
kwargs = {
'template_name': 'authentication/password_reset_confirm.html',
'post_reset_redirect': reverse('authentication:password_reset_complete_view'),
'uidb64': uidb64,
'token': token
}
return password_reset_confirm(
request, extra_context=extra_context, **kwargs
)
@public
def password_reset_done_view(request):
extra_context = {
'appearance_type': 'plain'
}
kwargs = {
'template_name': 'authentication/password_reset_done.html'
}
return password_reset_done(request, extra_context=extra_context, **kwargs)
@public
def password_reset_view(request):
extra_context = {
'appearance_type': 'plain'
}
kwargs = {
'email_template_name': 'authentication/password_reset_email.html',
'extra_email_context': {
'project_title': settings.PROJECT_TITLE,
'project_website': settings.PROJECT_WEBSITE,
'project_copyright': settings.PROJECT_COPYRIGHT,
'project_license': settings.PROJECT_LICENSE,
},
'subject_template_name': 'authentication/password_reset_subject.txt',
'template_name': 'authentication/password_reset_form.html',
'post_reset_redirect': reverse(
'authentication:password_reset_done_view'
)
}
return password_reset(request, extra_context=extra_context, **kwargs)