From 6a8eed17d235a9613fd2ce0031ac3835cff17615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Thu, 17 Jan 2019 08:25:02 +0100 Subject: [PATCH] utils: add hook to decide if user can change/set password (fixes #28848) --- src/authentic2/backends/ldap_backend.py | 2 +- src/authentic2/custom_user/models.py | 2 +- src/authentic2/utils.py | 10 ++++++++++ src/authentic2/views.py | 4 ++-- tests/test_utils.py | 8 +++++++- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/authentic2/backends/ldap_backend.py b/src/authentic2/backends/ldap_backend.py index b86ff7e11..a64a7416a 100644 --- a/src/authentic2/backends/ldap_backend.py +++ b/src/authentic2/backends/ldap_backend.py @@ -221,7 +221,7 @@ class LDAPUser(get_user_model()): return self.block['can_reset_password'] def can_change_password(self): - return app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD and self.block['user_can_change_password'] + return self.block['user_can_change_password'] class LDAPBackend(object): diff --git a/src/authentic2/custom_user/models.py b/src/authentic2/custom_user/models.py index 5c006c3a2..fe92fabd0 100644 --- a/src/authentic2/custom_user/models.py +++ b/src/authentic2/custom_user/models.py @@ -274,4 +274,4 @@ class User(AbstractBaseUser, PermissionMixin): return rc def can_change_password(self): - return app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD + return True diff --git a/src/authentic2/utils.py b/src/authentic2/utils.py index 3ac4b023d..e4bdd7070 100644 --- a/src/authentic2/utils.py +++ b/src/authentic2/utils.py @@ -1075,3 +1075,13 @@ def get_user_flag(user, name, default=None): if ou_value is not None: return ou_value return default + + +def user_can_change_password(user, request=None): + from . import hooks + if not app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD: + return False + for can in hooks.call_hooks('user_can_change_password', user=user, request=request): + if can is False: + return can + return True diff --git a/src/authentic2/views.py b/src/authentic2/views.py index 478bdb023..0f8b4045a 100644 --- a/src/authentic2/views.py +++ b/src/authentic2/views.py @@ -503,7 +503,7 @@ class ProfileView(cbv.TemplateNamesMixin, TemplateView): 'allow_profile_edit': EditProfile.can_edit_profile(), 'allow_email_change': app_settings.A2_PROFILE_CAN_CHANGE_EMAIL, # TODO: deprecated should be removed when publik-base-theme is updated - 'allow_password_change': request.user.can_change_password(), + 'allow_password_change': utils.user_can_change_password(user=request.user, request=request), 'federation_management': federation_management, }) hooks.call_hooks('modify_context_data', self, context) @@ -582,7 +582,7 @@ def logout(request, next_url=None, default_next_url='auth_homepage', def login_password_profile(request, *args, **kwargs): context = kwargs.pop('context', {}) - can_change_password = app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD + can_change_password = utils.user_can_change_password(user=request.user, request=request) has_usable_password = request.user.has_usable_password() context.update( {'can_change_password': can_change_password, diff --git a/tests/test_utils.py b/tests/test_utils.py index 7f1618157..8146c8502 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,4 +1,4 @@ -from authentic2.utils import good_next_url, same_origin, select_next_url +from authentic2.utils import good_next_url, same_origin, select_next_url, user_can_change_password def test_good_next_url(rf, settings): @@ -46,3 +46,9 @@ def test_select_next_url(rf, settings): assert select_next_url(request, '/') == '/' settings.A2_REDIRECT_WHITELIST = ['//example.com/'] assert select_next_url(request, '/') == 'http://example.com/' + + +def test_user_can_change_password(simple_user, settings): + assert user_can_change_password(user=simple_user) is True + settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD = False + assert user_can_change_password(user=simple_user) is False