stages/password: show password forgotten prompt when recovery flow configured
This commit is contained in:
parent
a5319fc2fe
commit
023423c6e7
|
@ -19,11 +19,7 @@ error_reporting: false
|
||||||
domain: localhost
|
domain: localhost
|
||||||
|
|
||||||
passbook:
|
passbook:
|
||||||
password_reset:
|
footer_links:
|
||||||
# Enable password reset, passwords are reset in internal Database and in LDAP if ldap.reset_password is true
|
|
||||||
enabled: true
|
|
||||||
footer:
|
|
||||||
links:
|
|
||||||
# Optionally add links to the footer on the login page
|
# Optionally add links to the footer on the login page
|
||||||
# - name: test
|
# - name: test
|
||||||
# href: https://test
|
# href: https://test
|
||||||
|
|
|
@ -59,7 +59,12 @@
|
||||||
<li>
|
<li>
|
||||||
<a href="https://beryju.github.io/passbook/">{% trans 'Documentation' %}</a>
|
<a href="https://beryju.github.io/passbook/">{% trans 'Documentation' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<!-- TODO: load config.passbook.footer.links -->
|
{% config 'passbook.footer_links' as footer_links %}
|
||||||
|
{% for link in footer_links %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ link.href }}">{{ link.name }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,6 +12,7 @@ from django.views.generic import FormView
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.core.models import User
|
from passbook.core.models import User
|
||||||
|
from passbook.flows.models import Flow, FlowDesignation
|
||||||
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER
|
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||||
from passbook.flows.stage import AuthenticationStage
|
from passbook.flows.stage import AuthenticationStage
|
||||||
from passbook.lib.utils.reflection import path_to_class
|
from passbook.lib.utils.reflection import path_to_class
|
||||||
|
@ -51,6 +52,13 @@ class PasswordStage(FormView, AuthenticationStage):
|
||||||
form_class = PasswordForm
|
form_class = PasswordForm
|
||||||
template_name = "stages/password/backend.html"
|
template_name = "stages/password/backend.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
kwargs = super().get_context_data(**kwargs)
|
||||||
|
recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY)
|
||||||
|
if recovery_flow.exists():
|
||||||
|
kwargs["recovery_flow"] = recovery_flow.first()
|
||||||
|
return kwargs
|
||||||
|
|
||||||
def form_valid(self, form: PasswordForm) -> HttpResponse:
|
def form_valid(self, form: PasswordForm) -> HttpResponse:
|
||||||
"""Authenticate against django's authentication backend"""
|
"""Authenticate against django's authentication backend"""
|
||||||
if PLAN_CONTEXT_PENDING_USER not in self.executor.plan.context:
|
if PLAN_CONTEXT_PENDING_USER not in self.executor.plan.context:
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block beneath_form %}
|
{% block beneath_form %}
|
||||||
{% if show_password_forget_notice %}
|
{% if recovery_flow %}
|
||||||
{# TODO: Link to dedicated recovery flow #}
|
<a href="{% url 'passbook_flows:flow-executor' flow_slug=recovery_flow.slug %}">{% trans 'Forgot password?' %}</a>
|
||||||
<a href="{% url 'passbook_flows:auth-process' %}?password-forgotten">{% trans 'Forgot password?' %}</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -57,6 +57,25 @@ class TestPasswordStage(TestCase):
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertEqual(response.url, reverse("passbook_flows:denied"))
|
self.assertEqual(response.url, reverse("passbook_flows:denied"))
|
||||||
|
|
||||||
|
def test_recovery_flow_link(self):
|
||||||
|
"""Test link to the default recovery flow"""
|
||||||
|
flow = Flow.objects.create(
|
||||||
|
designation=FlowDesignation.RECOVERY, slug="qewrqerqr"
|
||||||
|
)
|
||||||
|
|
||||||
|
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
|
||||||
|
session = self.client.session
|
||||||
|
session[SESSION_KEY_PLAN] = plan
|
||||||
|
session.save()
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
reverse(
|
||||||
|
"passbook_flows:flow-executor", kwargs={"flow_slug": self.flow.slug}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertIn(flow.slug, response.rendered_content)
|
||||||
|
|
||||||
def test_valid_password(self):
|
def test_valid_password(self):
|
||||||
"""Test with a valid pending user and valid password"""
|
"""Test with a valid pending user and valid password"""
|
||||||
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
|
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])
|
||||||
|
|
Reference in New Issue