From 66f7d60aaa256531f8e438cbb9e020dab15e6700 Mon Sep 17 00:00:00 2001
From: Tom Teichler <tom.teichler@teckids.org>
Date: Fri, 4 Mar 2022 16:24:20 +0100
Subject: [PATCH] Add new preference to allow users change their passwords

---
 CHANGELOG.rst                                    |  1 +
 aleksis/core/preferences.py                      |  8 ++++++++
 .../core/templates/two_factor/core/login.html    |  2 +-
 aleksis/core/urls.py                             |  5 +++++
 aleksis/core/views.py                            | 16 +++++++++++++++-
 5 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 35cc51d5b..a46793f6b 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -21,6 +21,7 @@ Added
 * Allow configuring regex for allowed usernames
 * [Dev] Support scheduled notifications.
 * Implement StaticContentWidget
+* Allow to enable password change independently of password reset
 
 Changed
 ~~~~~~~
diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py
index 352d5480d..78b187435 100644
--- a/aleksis/core/preferences.py
+++ b/aleksis/core/preferences.py
@@ -271,6 +271,14 @@ class AllowPasswordChange(BooleanPreference):
     verbose_name = _("Allow users to change their passwords")
 
 
+@site_preferences_registry.register
+class AllowPasswordReset(BooleanPreference):
+    section = auth
+    name = "allow_password_reset"
+    default = True
+    verbose_name = _("Allow users to reset their passwords")
+
+
 @site_preferences_registry.register
 class SignupEnabled(BooleanPreference):
     section = auth
diff --git a/aleksis/core/templates/two_factor/core/login.html b/aleksis/core/templates/two_factor/core/login.html
index 819b20997..77b135569 100644
--- a/aleksis/core/templates/two_factor/core/login.html
+++ b/aleksis/core/templates/two_factor/core/login.html
@@ -95,7 +95,7 @@
               {% trans "Login" %}
               <i class="material-icons right">send</i>
             </button>
-            {% if request.site.preferences.auth__allow_password_change and wizard.steps.current == "auth" %}
+            {% if request.site.preferences.auth__allow_password_reset and wizard.steps.current == "auth" %}
               <a href="{% url "account_reset_password" %}" class="btn-flat right waves-effect waves-red">
                 {% trans "Reset password" %}
               </a>
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index c91bae7f2..0795dfa93 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -30,6 +30,11 @@ urlpatterns = [
         views.CustomPasswordChangeView.as_view(),
         name="account_change_password",
     ),
+    path(
+        "accounts/password/reset/",
+        views.CustomPasswordResetView.as_view(),
+        name="account_reset_password",
+    ),
     path("accounts/", include("allauth.urls")),
     path("invitations/send-invite", views.InvitePerson.as_view(), name="invite_person"),
     path(
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index 00c95c47d..789410c80 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -36,7 +36,7 @@ from django.views.generic.list import ListView
 
 import reversion
 from allauth.account.utils import _has_verified_for_login, send_email_confirmation
-from allauth.account.views import PasswordChangeView, SignupView
+from allauth.account.views import PasswordChangeView, SignupView, PasswordResetView
 from allauth.socialaccount.adapter import get_adapter
 from allauth.socialaccount.models import SocialAccount
 from celery_progress.views import get_progress
@@ -1369,6 +1369,20 @@ class CustomPasswordChangeView(PermissionRequiredMixin, PasswordChangeView):
         super().__init__(*args, **kwargs)
 
 
+class CustomPasswordResetView(PermissionRequiredMixin, PasswordResetView):
+    """Custom password reset view to allow to disable resetting of password."""
+
+    permission_required = "core.can_reset_password"
+
+    def __init__(self, *args, **kwargs):
+        if get_site_preferences()["auth__allow_password_reset"]:
+            self.template_name = "account/password_reset.html"
+        else:
+            self.template_name = "account/password_change_disabled.html"
+
+        super().__init__(*args, **kwargs)
+
+
 class SocialAccountDeleteView(DeleteView):
     """Custom view to delete django-allauth social account."""
 
-- 
GitLab