feat: Add reset password #5
|
@ -3,3 +3,4 @@
|
|||
/django_gas.egg-info
|
||||
/.coverage
|
||||
/htmlcov
|
||||
*.pyc
|
||||
|
|
|
@ -8,5 +8,9 @@ urlpatterns = [
|
|||
path('login/', views.GASLoginView.as_view(), name='login'),
|
||||
path('logout/', logout_then_login, {'login_url': 'gas:login'}, name='logout'),
|
||||
path('change-password/', views.GASPasswordChangeView.as_view(), name='change_password'),
|
||||
path('reset-password-confirm/<uidb64>/<token>/', views.GASPasswordResetConfirmView.as_view(), name='password_reset_confirm'),
|
||||
path('reset-password-confirm/done/', views.GASPasswordResetCompleteView.as_view(), name='password_reset_complete'),
|
||||
path('reset-password/done/', views.GASPasswordResetDoneView.as_view(), name='password_reset_done'),
|
||||
path('reset-password/', views.GASPasswordResetView.as_view(), name='reset_password'),
|
||||
path('', views.Index.as_view(), name='index'),
|
||||
]
|
||||
|
|
|
@ -1,45 +1,72 @@
|
|||
from django.contrib.auth.views import LoginView, PasswordChangeView
|
||||
from django.contrib.auth.views import (
|
||||
LoginView,
|
||||
PasswordChangeView,
|
||||
PasswordResetConfirmView,
|
||||
PasswordResetDoneView,
|
||||
PasswordResetView,
|
||||
)
|
||||
from django.shortcuts import resolve_url
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from gas import gas_settings
|
||||
from gas.views import GASMixin
|
||||
|
||||
from gas import gas_settings
|
||||
|
||||
class GASPasswordChangeView(GASMixin, PasswordChangeView):
|
||||
template_name = "gas/base_form.html"
|
||||
success_url = reverse_lazy("gas:index")
|
||||
continue_url = reverse_lazy("gas:change_password")
|
||||
title = _("Change your password")
|
||||
success_message = _("Password changed.")
|
||||
|
||||
|
||||
class GASLoginView(LoginView):
|
||||
class Index(GASMixin, TemplateView):
|
||||
main_menu = "index"
|
||||
template_name = "gas/index.html"
|
||||
roles = ("staff",)
|
||||
|
||||
|
||||
class GASContextMixin:
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
css = gas_settings.MEDIA["css"]
|
||||
javascript = gas_settings.MEDIA["js"]
|
||||
if gas_settings.EXTRA_MEDIA:
|
||||
css = css + gas_settings.EXTRA_MEDIA.get("css", [])
|
||||
javascript = javascript + gas_settings.EXTRA_MEDIA.get("js", [])
|
||||
ctx.update(
|
||||
{
|
||||
"logo_static_url": gas_settings.LOGO,
|
||||
"css": css,
|
||||
"js": javascript,
|
||||
}
|
||||
)
|
||||
return ctx
|
||||
|
||||
|
||||
class GASLoginView(GASContextMixin, LoginView):
|
||||
template_name = "gas/login.html"
|
||||
|
||||
def get_success_url(self):
|
||||
url = self.get_redirect_url()
|
||||
return url or resolve_url('gas:index')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
css = gas_settings.MEDIA['css']
|
||||
javascript = gas_settings.MEDIA['js']
|
||||
if gas_settings.EXTRA_MEDIA:
|
||||
css = css + gas_settings.EXTRA_MEDIA.get('css', [])
|
||||
javascript = javascript + gas_settings.EXTRA_MEDIA.get('js', [])
|
||||
ctx.update({
|
||||
'logo_static_url': gas_settings.LOGO,
|
||||
'css': css,
|
||||
'js': javascript,
|
||||
})
|
||||
return ctx
|
||||
return url or resolve_url("gas:index")
|
||||
|
||||
|
||||
class GASPasswordChangeView(GASMixin, PasswordChangeView):
|
||||
template_name = 'gas/base_form.html'
|
||||
success_url = reverse_lazy('gas:index')
|
||||
continue_url = reverse_lazy('gas:change_password')
|
||||
title = _('Change your password')
|
||||
success_message = _('Password changed.')
|
||||
class GASPasswordResetView(GASContextMixin, PasswordResetView):
|
||||
template_name = "gas/reset.html"
|
||||
email_template_name = "email/password_reset_email.html"
|
||||
success_url = reverse_lazy("gas:password_reset_done")
|
||||
|
||||
|
||||
class Index(GASMixin, TemplateView):
|
||||
main_menu = 'index'
|
||||
template_name = "gas/index.html"
|
||||
roles = ('staff',)
|
||||
class GASPasswordResetDoneView(GASContextMixin, PasswordResetDoneView):
|
||||
template_name = "gas/reset_done.html"
|
||||
|
||||
|
||||
class GASPasswordResetConfirmView(GASContextMixin, PasswordResetConfirmView):
|
||||
template_name = "gas/reset_confirm.html"
|
||||
success_url = reverse_lazy("gas:password_reset_complete")
|
||||
|
||||
|
||||
class GASPasswordResetCompleteView(GASContextMixin, TemplateView):
|
||||
template_name = "gas/reset_complete.html"
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{% load i18n %}{% autoescape off %}
|
||||
{% blocktranslate %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktranslate %}
|
||||
|
||||
{% translate "Please go to the following page and choose a new password:" %}
|
||||
{% block reset_link %}
|
||||
{{ protocol }}://{{ domain }}{% url 'gas:password_reset_confirm' uidb64=uid token=token %}
|
||||
{% endblock %}
|
||||
{% translate 'Your username, in case you’ve forgotten:' %} {{ user.get_username }}
|
||||
|
||||
{% translate "Thanks for using our site!" %}
|
||||
|
||||
{% blocktranslate %}The {{ site_name }} team{% endblocktranslate %}
|
||||
|
||||
{% endautoescape %}
|
|
@ -0,0 +1,20 @@
|
|||
{% load i18n static form_tags %}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>{{ gas_title }} {% trans "Login" %}</title>
|
||||
{% for cssfile in css %}
|
||||
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
|
||||
{% endfor %}
|
||||
</head>
|
||||
<body id="login">
|
||||
<p>{% translate 'Forgotten your password? Enter your email address below, and we’ll email instructions for setting a new one.' %}</p>
|
||||
<form action="." method="POST">{% csrf_token %}
|
||||
{% form_errors form %}
|
||||
{% form_field form.email %}
|
||||
<input type="hidden" name="next" value="{{ next }}">
|
||||
<button type="submit">{% trans "Reset my password" %}</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
{% load i18n static form_tags %}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>{{ gas_title }} {% trans "Login" %}</title>
|
||||
{% for cssfile in css %}
|
||||
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
|
||||
{% endfor %}
|
||||
</head>
|
||||
<body id="login">
|
||||
<p>{% translate 'Your password was changed.' %}</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
{% load i18n static form_tags %}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>{{ gas_title }} {% trans "Login" %}</title>
|
||||
{% for cssfile in css %}
|
||||
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
|
||||
{% endfor %}
|
||||
</head>
|
||||
<body id="login">
|
||||
{% if validlink %}
|
||||
<p>{% translate "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||
<form action="." method="POST">{% csrf_token %}
|
||||
<input class="hidden" autocomplete="username" value="{{ form.user.get_username }}">
|
||||
{% form_errors form %}
|
||||
{% form_field form.new_password1 %}
|
||||
{% form_field form.new_password2 %}
|
||||
<input type="hidden" name="next" value="{{ next }}">
|
||||
<button type="submit">{% trans "Change my password" %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>{% translate "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
{% load i18n static form_tags %}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>{{ gas_title }} {% trans "Login" %}</title>
|
||||
{% for cssfile in css %}
|
||||
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
|
||||
{% endfor %}
|
||||
</head>
|
||||
<body id="login">
|
||||
<p>{% translate 'We’ve emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.' %}</p>
|
||||
<p>{% translate 'If you don’t receive an email, please make sure you’ve entered the address you registered with, and check your spam folder.' %}</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -3,28 +3,58 @@ from django.urls import reverse
|
|||
|
||||
from model_bakery import baker
|
||||
|
||||
from gas.gas.core.views import GASLoginView
|
||||
|
||||
|
||||
class GASLoginTestCase(TestCase):
|
||||
def test_load(self):
|
||||
client = Client()
|
||||
response = client.get(reverse('gas:login'))
|
||||
response = client.get(reverse("gas:login"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class IndexTestCase(TestCase):
|
||||
def test_load(self):
|
||||
admin_user = baker.make(
|
||||
'auth.User',
|
||||
username='admin',
|
||||
"auth.User",
|
||||
username="admin",
|
||||
is_superuser=True,
|
||||
)
|
||||
|
||||
client = Client()
|
||||
response = client.get(reverse('gas:index'))
|
||||
response = client.get(reverse("gas:index"))
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
client.force_login(admin_user)
|
||||
response = client.get(reverse('gas:index'))
|
||||
response = client.get(reverse("gas:index"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class GASPasswordResetViewTestCase(TestCase):
|
||||
def test_load(self):
|
||||
client = Client()
|
||||
response = client.get(reverse("gas:reset_password"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "gas/reset.html")
|
||||
|
||||
|
||||
class GASPasswordResetDoneViewTestCase(TestCase):
|
||||
def test_load(self):
|
||||
client = Client()
|
||||
response = client.get(reverse("gas:password_reset_done"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "gas/reset_done.html")
|
||||
|
||||
|
||||
class GASPasswordResetConfirmViewTestCase(TestCase):
|
||||
def test_load(self):
|
||||
client = Client()
|
||||
response = client.get(reverse("gas:password_reset_confirm", kwargs={"uidb64": "uidb64", "token": "token"}))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "gas/reset_confirm.html")
|
||||
|
||||
|
||||
class GASPasswordResetCompleteViewTestCase(TestCase):
|
||||
def test_load(self):
|
||||
client = Client()
|
||||
response = client.get(reverse("gas:password_reset_complete"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "gas/reset_complete.html")
|
||||
|
|
Loading…
Reference in New Issue