Projet

Général

Profil

0001-ldap-move-messages-from-hard-coded-to-templates-5129.patch

Loïc Dachary, 04 mars 2021 12:31

Télécharger (7 ko)

Voir les différences:

Subject: [PATCH] ldap: move messages from hard coded to templates (#51294)

Fixes: #51294

Licenses: MIT
 src/authentic2/backends/ldap_backend.py | 63 ++++++++++++++-----------
 1 file changed, 35 insertions(+), 28 deletions(-)
src/authentic2/backends/ldap_backend.py
47 47
from django.contrib import messages
48 48
from django.contrib.auth import get_user_model
49 49
from django.contrib.auth.models import Group
50
from django.template import loader
50 51
from django.utils.encoding import force_bytes, force_text
51 52
from django.utils import six
52 53
from django.utils.six.moves.urllib import parse as urlparse
......
226 227

  
227 228

  
228 229
def map_text(d):
229
    if d is None:
230
    if d is None or callable(d):
230 231
        return d
231 232
    elif isinstance(d, six.string_types):
232 233
        return force_text(d)
......
237 238
    raise NotImplementedError
238 239

  
239 240

  
240
def password_policy_control_messages(ctrl):
241
    messages = []
241
def password_policy_control_messages(ctrl, control_messages):
242
    results = []
242 243

  
243 244
    if ctrl.error:
244 245
        error = ppolicy.PasswordPolicyError.namedValues[ctrl.error]
245
        error2message = {
246
            'passwordExpired': _('The password expired'),
247
            'accountLocked': _('The account is locked.'),
248
            'changeAfterReset': _('The password was reset and must be changed.'),
249
            'passwordModNotAllowed': _('It is not possible to modify the password.'),
250
            'mustSupplyOldPassword': _('The old password must be supplied.'),
251
            'insufficientPasswordQuality': _('The password does not meet the quality requirements.'),
252
            'passwordTooShort': _('The password is too short.'),
253
            'passwordTooYoung': _('It is too soon to change the password.'),
254
            'passwordInHistory': _('This password was recently used and cannot be used again.'),
255
        }
256
        messages.append(error2message.get(error, _('Unexpected error {error}').format(error=error)))
257
        return messages
246
        if error not in control_messages:
247
            results.append(_('Unexpected error {error}').format(error=error))
248
        else:
249
            results.append(control_messages[error]())
250
        return results
258 251

  
259 252
    if ctrl.timeBeforeExpiration:
260
        timeBeforeExpiration = time.asctime(time.localtime(time.time() + ctrl.timeBeforeExpiration))
261
        messages.append(_('The password will expire at {timeBeforeExpiration}.').format(
262
            timeBeforeExpiration=timeBeforeExpiration))
253
        expiration_date = time.asctime(time.localtime(time.time() + ctrl.timeBeforeExpiration))
254
        results.append(control_messages['expiration_date']().format(expiration_date=expiration_date))
263 255
    if ctrl.graceAuthNsRemaining:
264
        messages.append(ngettext(
265
            'This password expired: this is the last time it can be used.',
266
            'This password expired and can only be used {graceAuthNsRemaining} times, including this one.',
267
            ctrl.graceAuthNsRemaining).format(graceAuthNsRemaining=ctrl.graceAuthNsRemaining))
268
    return messages
256
        results.append(control_messages['graceAuthNsRemaining'](ctrl.graceAuthNsRemaining).format(
257
            graceAuthNsRemaining=ctrl.graceAuthNsRemaining))
258
    return results
269 259

  
270 260
class LDAPUser(User):
271 261
    SESSION_LDAP_DATA_KEY = 'ldap-data'
......
548 538
        'user_attributes': [],
549 539
        # https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#ldap-controls
550 540
        'use_controls': True,
541
        'ppolicy_messages': {
542
            'passwordExpired': lambda *args: _('The password expired'),
543
            'accountLocked': lambda *args: _('The account is locked.'),
544
            'changeAfterReset': lambda *args: _('The password was reset and must be changed.'),
545
            'passwordModNotAllowed': lambda *args: _('It is not possible to modify the password.'),
546
            'mustSupplyOldPassword': lambda *args: _('The old password must be supplied.'),
547
            'insufficientPasswordQuality': lambda *args: _('The password does not meet the quality requirements.'),
548
            'passwordTooShort': lambda *args: _('The password is too short.'),
549
            'passwordTooYoung': lambda *args: _('It is too soon to change the password.'),
550
            'passwordInHistory': lambda *args: _('This password was recently used and cannot be used again.'),
551
            'expiration_date': lambda *args: _('The password will expire at {expiration_date}.'),
552
            'graceAuthNsRemaining': lambda *args: ngettext(
553
                'This password expired: this is the last time it can be used.',
554
                'This password expired and can only be used {graceAuthNsRemaining} times, including this one.',
555
                *args),
556
        },
551 557
    }
552 558
    _REQUIRED = ('url', 'basedn')
553 559
    _TO_ITERABLE = ('url', 'groupsu', 'groupstaff', 'groupactive')
......
579 585
        return blocks
580 586

  
581 587
    @staticmethod
582
    def process_controls(request, authz_id, ctrls):
588
    def process_controls(request, authz_id, ctrls, block):
583 589
        for c in ctrls:
584 590
            if c.controlType == ppolicy.PasswordPolicyControl.controlType:
585
                message = ' '.join(password_policy_control_messages(c))
591
                message = ' '.join(password_policy_control_messages(c, block['ppolicy_messages']))
586 592
                if request is not None:
587 593
                    messages.add_message(request, messages.WARNING, message)
588 594
            else:
......
706 712
                            else:
707 713
                                serverctrls = []
708 714
                            results = conn.simple_bind_s(authz_id, password, serverctrls=serverctrls)
709
                            self.process_controls(request, authz_id, results[3])
715
                            self.process_controls(request, authz_id, results[3], block)
710 716
                            user_login_success(authz_id)
711 717
                            if not block['connect_with_user_credentials']:
712 718
                                try:
......
717 723
                            break
718 724
                        except ldap.INVALID_CREDENTIALS as e:
719 725
                            if block.get('use_controls') and len(e.args) > 0 and 'ctrls' in e.args[0]:
720
                                self.process_controls(request, authz_id, DecodeControlTuples(e.args[0]['ctrls']))
726
                                self.process_controls(request, authz_id,
727
                                                      DecodeControlTuples(e.args[0]['ctrls']), block)
721 728
                            user_login_failure(authz_id)
722 729
                            pass
723 730
                    else:
724
-