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])