Projet

Général

Profil

0001-allow-overriding-User.can_reset_password-by-hooks-fi.patch

Benjamin Dauvergne, 30 juillet 2018 16:42

Télécharger (7,58 ko)

Voir les différences:

Subject: [PATCH] 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
 ...anizationalunit_user_can_reset_password.py | 19 +++++++++++++++
 src/authentic2/a2_rbac/models.py              |  3 +++
 src/authentic2/app_settings.py                | 10 +++++++-
 src/authentic2/backends/ldap_backend.py       |  1 +
 src/authentic2/custom_user/models.py          |  3 ---
 src/authentic2/profile_views.py               |  5 +++-
 src/authentic2/utils.py                       | 23 +++++++++++++++++++
 src/authentic2/views.py                       |  2 +-
 8 files changed, 60 insertions(+), 6 deletions(-)
 create mode 100644 src/authentic2/a2_rbac/migrations/0017_organizationalunit_user_can_reset_password.py
src/authentic2/a2_rbac/migrations/0017_organizationalunit_user_can_reset_password.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import migrations, models
5

  
6

  
7
class Migration(migrations.Migration):
8

  
9
    dependencies = [
10
        ('a2_rbac', '0016_auto_20171208_1429'),
11
    ]
12

  
13
    operations = [
14
        migrations.AddField(
15
            model_name='organizationalunit',
16
            name='user_can_reset_password',
17
            field=models.NullBooleanField(verbose_name='Users can reset password'),
18
        ),
19
    ]
src/authentic2/a2_rbac/models.py
44 44
                                  content_type_field='target_ct',
45 45
                                  object_id_field='target_id')
46 46

  
47
    user_can_reset_password = models.NullBooleanField(
48
        verbose_name=_('Users can reset password'))
49

  
47 50
    objects = managers.OrganizationalUnitManager()
48 51

  
49 52
    class Meta:
src/authentic2/app_settings.py
49 49
            add_realms(self.A2_REALMS)
50 50
        return realms.items()
51 51

  
52
    @property
53
    def A2_USER_CAN_RESET_PASSWORD(self):
54
        if hasattr(self.settings, 'A2_USER_CAN_RESET_PASSWORD'):
55
            return self.settings.A2_USER_CAN_RESET_PASSWORD
56
        if hasattr(self.settings, 'A2_CAN_RESET_PASSWORD'):
57
            return self.settings.A2_CAN_RESET_PASSWORD
58
        return self.defaults['A2_USER_CAN_RESET_PASSWORD'].default
59

  
52 60
    def __getattr__(self, key):
53 61
        if key not in self.defaults:
54 62
            raise AttributeError('unknown key %s' % key)
......
107 115
                definition='Include empty fields in profile view'),
108 116
    A2_HOMEPAGE_URL = Setting(default=None, definition='IdP has no homepage, '
109 117
        'redirect to this one.'),
110
    A2_CAN_RESET_PASSWORD = Setting(default=True, definition='Allow online reset of passwords'),
118
    A2_USER_CAN_RESET_PASSWORD = Setting(default=None, definition='Allow online reset of passwords'),
111 119
    A2_EMAIL_IS_UNIQUE = Setting(default=False,
112 120
        definition='Email of users must be unique'),
113 121
    A2_REGISTRATION_EMAIL_IS_UNIQUE = Setting(default=False,
src/authentic2/backends/ldap_backend.py
216 216
        if hasattr(self, 'keep_pk'):
217 217
            self.pk = pk
218 218

  
219
    @property
219 220
    def can_reset_password(self):
220 221
        return self.block['can_reset_password']
221 222

  
src/authentic2/custom_user/models.py
250 250
                        attribute.set_value(self, getattr(self, attr_name, None))
251 251
        return rc
252 252

  
253
    def can_reset_password(self):
254
        return self.has_usable_password()
255

  
256 253
    def can_change_password(self):
257 254
        return app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD
src/authentic2/profile_views.py
81 81
                                        'or has expired'))
82 82
        if not validlink:
83 83
            return utils.redirect(request, self.get_success_url())
84
        if not self.user.can_reset_password():
84
        can_reset_password = utils.get_user_flag(user=self.user,
85
                                                 name='can_reset_password',
86
                                                 default=self.user.has_usable_password())
87
        if not can_reset_password:
85 88
            messages.warning(request, _('It\'s not possible to reset your password. Please '
86 89
                                        'contact an administrator.'))
87 90
            return utils.redirect(request, self.get_success_url())
src/authentic2/utils.py
1054 1054
def update_model(obj, d):
1055 1055
    for attr, value in d.items():
1056 1056
        setattr(obj, attr, value)
1057

  
1058

  
1059
def get_user_flag(user, name, default=None):
1060
    '''Get a boolean flag settable at user, by a hook, globally or ou wide'''
1061
    from . import hooks
1062

  
1063
    setting_value = getattr(app_settings, 'A2_USER_' + name.upper(), None)
1064
    if setting_value is not None:
1065
        return bool(setting_value)
1066

  
1067
    user_value = getattr(user, name, None)
1068
    if user_value is not None:
1069
        return user_value
1070

  
1071
    hook_value = hooks.call_hooks_first_result('user_' + name, user=user)
1072
    if hook_value is not None:
1073
        return bool(hook_value)
1074

  
1075
    if user.ou and hasattr(user.ou, 'user_' + name):
1076
        ou_value = getattr(user.ou, 'user_' + name, None)
1077
        if ou_value is not None:
1078
            return ou_value
1079
    return default
src/authentic2/views.py
292 292

  
293 293
    context_instance = RequestContext(request, {
294 294
        'cancel': nonce is not None,
295
        'can_reset_password': app_settings.A2_CAN_RESET_PASSWORD,
295
        'can_reset_password': app_settings.A2_USER_CAN_RESET_PASSWORD is not False,
296 296
        'registration_authorized': getattr(settings, 'REGISTRATION_OPEN', True),
297 297
        'registration_url': registration_url,
298 298
    })
299
-