allow overriding User.can_reset_password by hooks (fixes #25534)
This commit introduce the concept of an user flag, this flag can be defined in many places: * globally trough a setting named A2_USER_<FLAG> * on the user object itself if there is a property user.<flag> which is not None * by any hook returning a not None result and named a2_hook_user_<flag> * for all users of an OU if the ou.<flag> is not None
This commit is contained in:
parent
eeb93e79d3
commit
d7a2af17c3
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('a2_rbac', '0016_auto_20171208_1429'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='organizationalunit',
|
||||
name='user_can_reset_password',
|
||||
field=models.NullBooleanField(verbose_name='Users can reset password'),
|
||||
),
|
||||
]
|
|
@ -44,6 +44,9 @@ class OrganizationalUnit(OrganizationalUnitAbstractBase):
|
|||
content_type_field='target_ct',
|
||||
object_id_field='target_id')
|
||||
|
||||
user_can_reset_password = models.NullBooleanField(
|
||||
verbose_name=_('Users can reset password'))
|
||||
|
||||
objects = managers.OrganizationalUnitManager()
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -49,6 +49,14 @@ class AppSettings(object):
|
|||
add_realms(self.A2_REALMS)
|
||||
return realms.items()
|
||||
|
||||
@property
|
||||
def A2_USER_CAN_RESET_PASSWORD(self):
|
||||
if hasattr(self.settings, 'A2_USER_CAN_RESET_PASSWORD'):
|
||||
return self.settings.A2_USER_CAN_RESET_PASSWORD
|
||||
if hasattr(self.settings, 'A2_CAN_RESET_PASSWORD'):
|
||||
return self.settings.A2_CAN_RESET_PASSWORD
|
||||
return self.defaults['A2_USER_CAN_RESET_PASSWORD'].default
|
||||
|
||||
def __getattr__(self, key):
|
||||
if key not in self.defaults:
|
||||
raise AttributeError('unknown key %s' % key)
|
||||
|
@ -107,7 +115,7 @@ default_settings = dict(
|
|||
definition='Include empty fields in profile view'),
|
||||
A2_HOMEPAGE_URL = Setting(default=None, definition='IdP has no homepage, '
|
||||
'redirect to this one.'),
|
||||
A2_CAN_RESET_PASSWORD = Setting(default=True, definition='Allow online reset of passwords'),
|
||||
A2_USER_CAN_RESET_PASSWORD = Setting(default=None, definition='Allow online reset of passwords'),
|
||||
A2_EMAIL_IS_UNIQUE = Setting(default=False,
|
||||
definition='Email of users must be unique'),
|
||||
A2_REGISTRATION_EMAIL_IS_UNIQUE = Setting(default=False,
|
||||
|
|
|
@ -216,6 +216,7 @@ class LDAPUser(get_user_model()):
|
|||
if hasattr(self, 'keep_pk'):
|
||||
self.pk = pk
|
||||
|
||||
@property
|
||||
def can_reset_password(self):
|
||||
return self.block['can_reset_password']
|
||||
|
||||
|
|
|
@ -250,8 +250,5 @@ class User(AbstractBaseUser, PermissionMixin):
|
|||
attribute.set_value(self, getattr(self, attr_name, None))
|
||||
return rc
|
||||
|
||||
def can_reset_password(self):
|
||||
return self.has_usable_password()
|
||||
|
||||
def can_change_password(self):
|
||||
return app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD
|
||||
|
|
|
@ -81,7 +81,10 @@ class PasswordResetConfirmView(cbv.RedirectToNextURLViewMixin, FormView):
|
|||
'or has expired'))
|
||||
if not validlink:
|
||||
return utils.redirect(request, self.get_success_url())
|
||||
if not self.user.can_reset_password():
|
||||
can_reset_password = utils.get_user_flag(user=self.user,
|
||||
name='can_reset_password',
|
||||
default=self.user.has_usable_password())
|
||||
if not can_reset_password:
|
||||
messages.warning(request, _('It\'s not possible to reset your password. Please '
|
||||
'contact an administrator.'))
|
||||
return utils.redirect(request, self.get_success_url())
|
||||
|
|
|
@ -1054,3 +1054,26 @@ def send_email_change_email(user, email, request=None, context=None, template_na
|
|||
def update_model(obj, d):
|
||||
for attr, value in d.items():
|
||||
setattr(obj, attr, value)
|
||||
|
||||
|
||||
def get_user_flag(user, name, default=None):
|
||||
'''Get a boolean flag settable at user, by a hook, globally or ou wide'''
|
||||
from . import hooks
|
||||
|
||||
setting_value = getattr(app_settings, 'A2_USER_' + name.upper(), None)
|
||||
if setting_value is not None:
|
||||
return bool(setting_value)
|
||||
|
||||
user_value = getattr(user, name, None)
|
||||
if user_value is not None:
|
||||
return user_value
|
||||
|
||||
hook_value = hooks.call_hooks_first_result('user_' + name, user=user)
|
||||
if hook_value is not None:
|
||||
return bool(hook_value)
|
||||
|
||||
if user.ou and hasattr(user.ou, 'user_' + name):
|
||||
ou_value = getattr(user.ou, 'user_' + name, None)
|
||||
if ou_value is not None:
|
||||
return ou_value
|
||||
return default
|
||||
|
|
|
@ -292,7 +292,7 @@ def login(request, template_name='authentic2/login.html',
|
|||
|
||||
context_instance = RequestContext(request, {
|
||||
'cancel': nonce is not None,
|
||||
'can_reset_password': app_settings.A2_CAN_RESET_PASSWORD,
|
||||
'can_reset_password': app_settings.A2_USER_CAN_RESET_PASSWORD is not False,
|
||||
'registration_authorized': getattr(settings, 'REGISTRATION_OPEN', True),
|
||||
'registration_url': registration_url,
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue