diff --git a/passbook/lib/default.yml b/passbook/lib/default.yml
index 867b3798d..df570ea9e 100644
--- a/passbook/lib/default.yml
+++ b/passbook/lib/default.yml
@@ -19,11 +19,7 @@ error_reporting: false
domain: localhost
passbook:
- password_reset:
- # 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
- # - name: test
- # href: https://test
+ footer_links:
+ # Optionally add links to the footer on the login page
+ # - name: test
+ # href: https://test
diff --git a/passbook/stages/identification/templates/stages/identification/recovery.html b/passbook/stages/identification/templates/stages/identification/recovery.html
index 4a425ff9c..1dab0ae77 100644
--- a/passbook/stages/identification/templates/stages/identification/recovery.html
+++ b/passbook/stages/identification/templates/stages/identification/recovery.html
@@ -59,7 +59,12 @@
{% trans 'Documentation' %}
-
+ {% config 'passbook.footer_links' as footer_links %}
+ {% for link in footer_links %}
+
+ {{ link.name }}
+
+ {% endfor %}
diff --git a/passbook/stages/password/stage.py b/passbook/stages/password/stage.py
index 67c30990b..80b2114ba 100644
--- a/passbook/stages/password/stage.py
+++ b/passbook/stages/password/stage.py
@@ -12,6 +12,7 @@ from django.views.generic import FormView
from structlog import get_logger
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.stage import AuthenticationStage
from passbook.lib.utils.reflection import path_to_class
@@ -51,6 +52,13 @@ class PasswordStage(FormView, AuthenticationStage):
form_class = PasswordForm
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:
"""Authenticate against django's authentication backend"""
if PLAN_CONTEXT_PENDING_USER not in self.executor.plan.context:
diff --git a/passbook/stages/password/templates/stages/password/backend.html b/passbook/stages/password/templates/stages/password/backend.html
index e270a5bbc..9bec92301 100644
--- a/passbook/stages/password/templates/stages/password/backend.html
+++ b/passbook/stages/password/templates/stages/password/backend.html
@@ -3,8 +3,7 @@
{% load i18n %}
{% block beneath_form %}
-{% if show_password_forget_notice %}
-{# TODO: Link to dedicated recovery flow #}
-{% trans 'Forgot password?' %}
+{% if recovery_flow %}
+{% trans 'Forgot password?' %}
{% endif %}
{% endblock %}
diff --git a/passbook/stages/password/tests.py b/passbook/stages/password/tests.py
index 82cb4d947..d0cec72b8 100644
--- a/passbook/stages/password/tests.py
+++ b/passbook/stages/password/tests.py
@@ -57,6 +57,25 @@ class TestPasswordStage(TestCase):
self.assertEqual(response.status_code, 302)
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):
"""Test with a valid pending user and valid password"""
plan = FlowPlan(flow_pk=self.flow.pk.hex, stages=[self.stage])