Projet

Général

Profil

0002-ldap-inform-user-when-password-change-has-failed-577.patch

Valentin Deniaud, 19 octobre 2021 14:23

Télécharger (5,65 ko)

Voir les différences:

Subject: [PATCH 2/2] ldap: inform user when password change has failed
 (#57733)

 src/authentic2/backends/ldap_backend.py |  4 +--
 src/authentic2/utils/misc.py            |  5 ++++
 src/authentic2/views.py                 |  6 +++-
 tests/test_ldap.py                      | 38 +++++++++++++++++++++----
 4 files changed, 45 insertions(+), 8 deletions(-)
src/authentic2/backends/ldap_backend.py
58 58
from authentic2.middleware import StoreRequestMiddleware
59 59
from authentic2.models import UserExternalId
60 60
from authentic2.user_login_failure import user_login_failure, user_login_success
61
from authentic2.utils.misc import to_list
61
from authentic2.utils.misc import PasswordChangeError, to_list
62 62
from django_rbac.utils import get_ou_model
63 63

  
64 64
# code originaly copied from by now merely inspired by
......
478 478
                self.ldap_backend.modify_password(conn, self.block, self.dn, _current_password, new_password)
479 479
            except ldap.LDAPError as e:
480 480
                log.warning('ldap: set_password failed (%s)', type(e).__name__)
481
                return
481
                raise PasswordChangeError(_('LDAP directory refused the password change.'))
482 482
            self._current_password = new_password
483 483
        self.keep_password_in_session(new_password)
484 484
        if self.block['keep_password']:
src/authentic2/utils/misc.py
1310 1310
        path=request.path,
1311 1311
        httponly=True,
1312 1312
    )
1313

  
1314

  
1315
class PasswordChangeError(Exception):
1316
    def __init__(self, message):
1317
        self.message = message
src/authentic2/views.py
1414 1414
        hooks.call_hooks('event', name='change-password', user=self.request.user, request=self.request)
1415 1415
        messages.info(self.request, _('Password changed'))
1416 1416
        models.PasswordReset.objects.filter(user=self.request.user).delete()
1417
        response = super().form_valid(form)
1417
        try:
1418
            response = super().form_valid(form)
1419
        except utils_misc.PasswordChangeError as e:
1420
            messages.error(self.request, e.message)
1421
            return utils_misc.redirect(self.request, self.post_change_redirect)
1418 1422
        self.request.journal.record('user.password.change', session=self.request.session)
1419 1423
        return response
1420 1424

  
tests/test_ldap.py
37 37
from authentic2.backends import ldap_backend
38 38
from authentic2.models import Service
39 39
from authentic2.utils import switch_user
40
from authentic2.utils.misc import authenticate
40
from authentic2.utils.misc import PasswordChangeError, authenticate
41 41
from django_rbac.utils import get_ou_model
42 42

  
43 43
from . import utils
......
1056 1056
    assert response['Location'].endswith('/accounts/')
1057 1057

  
1058 1058

  
1059
def test_user_change_password_denied(slapd, settings, app, db):
1060
    settings.LDAP_AUTH_SETTINGS = [
1061
        {
1062
            'url': [slapd.ldap_url],
1063
            'basedn': 'o=ôrga',
1064
            'use_tls': False,
1065
        }
1066
    ]
1067
    assert User.objects.count() == 0
1068
    # first login
1069
    response = app.get('/login/')
1070
    response.form['username'] = USERNAME
1071
    response.form['password'] = PASS
1072
    response = response.form.submit('login-password-submit').follow()
1073

  
1074
    response = app.get('/accounts/password/change/')
1075
    response.form['old_password'] = PASS
1076
    response.form['new_password1'] = 'hopAbcde1'
1077
    response.form['new_password2'] = 'hopAbcde1'
1078
    with mock.patch(
1079
        'authentic2.backends.ldap_backend.LDAPBackend.modify_password', side_effect=ldap.UNWILLING_TO_PERFORM
1080
    ):
1081
        response = response.form.submit().follow()
1082
        assert 'LDAP directory refused the password change' in response.text
1083

  
1084

  
1059 1085
def test_tls(db, tls_slapd, settings, client):
1060 1086
    conn = tls_slapd.get_connection_admin()
1061 1087
    conn.modify_s(
......
1266 1292
    with mock.patch(
1267 1293
        'authentic2.backends.ldap_backend.LDAPBackend.modify_password', side_effect=ldap.UNWILLING_TO_PERFORM
1268 1294
    ):
1269
        user.set_password('passé')
1270
        assert 'set_password failed (UNWILLING_TO_PERFORM)' in caplog.text
1295
        with pytest.raises(PasswordChangeError):
1296
            user.set_password('passé')
1297
            assert 'set_password failed (UNWILLING_TO_PERFORM)' in caplog.text
1271 1298

  
1272 1299

  
1273 1300
def test_login_ppolicy_pwdMaxFailure(slapd_ppolicy, settings, db, app):
......
1664 1691
    )
1665 1692

  
1666 1693
    user = authenticate(username=USERNAME, password=UPASS)
1667
    assert user.set_password('ogutOmyetew4') is None
1668
    assert 'STRONG_AUTH_REQUIRED' in caplog.text
1694
    with pytest.raises(PasswordChangeError):
1695
        user.set_password('ogutOmyetew4')
1696
        assert 'STRONG_AUTH_REQUIRED' in caplog.text
1669 1697

  
1670 1698

  
1671 1699
def test_ou_selector(slapd, settings, app, ou1):
1672
-