Projet

Général

Profil

0001-ldap-redirect-password-change-if-it-is-about-to-expi.patch

Loïc Dachary, 19 février 2021 17:51

Télécharger (5,64 ko)

Voir les différences:

Subject: [PATCH] ldap: redirect /password/change if it is about to expire
 (#51268)

Fixes: #51268

License: MIT
 src/authentic2/authenticators.py        |  4 ++
 src/authentic2/backends/ldap_backend.py |  2 +
 tests/test_ldap.py                      | 75 ++++++++++++++++++++-----
 3 files changed, 68 insertions(+), 13 deletions(-)
src/authentic2/authenticators.py
132 132
                if 'ou' in form.fields:
133 133
                    utils.prepend_remember_cookie(request, response, 'preferred-ous', form.cleaned_data['ou'].pk)
134 134

  
135
                if hasattr(request, 'needs_password_change'):
136
                    del request.needs_password_change
137
                    return utils.redirect(request, 'password_change', params={'next': response.url}, resolve=True)
138

  
135 139
                return response
136 140
            else:
137 141
                username = form.cleaned_data.get('username', '').strip()
src/authentic2/backends/ldap_backend.py
585 585
                message = ' '.join(password_policy_control_messages(c))
586 586
                if request is not None:
587 587
                    messages.add_message(request, messages.WARNING, message)
588
                    if c.graceAuthNsRemaining or c.timeBeforeExpiration:
589
                        request.needs_password_change = True
588 590
            else:
589 591
                message = str(vars(c))
590 592
            log.info('ldap: bind error with authz_id "%s" -> "%s"', authz_id, message)
tests/test_ldap.py
742 742
    assert force_bytes('Étienne Michu') in response.body
743 743

  
744 744

  
745
def test_reset_password_ldap_user(slapd, settings, app, db):
746
    settings.LDAP_AUTH_SETTINGS = [{
747
        'url': [slapd.ldap_url],
748
        'binddn': force_text(slapd.root_bind_dn),
749
        'bindpw': force_text(slapd.root_bind_password),
750
        'basedn': u'o=ôrga',
751
        'use_tls': False,
752
    }]
745
def reset_password_ldap_user(settings, app):
753 746
    assert User.objects.count() == 0
754 747
    # first login
755 748
    response = app.get('/login/')
......
761 754
    user = User.objects.get()
762 755
    assert user.email == EMAIL
763 756
    # logout
764
    response = response.click('Logout')
765
    if response.status_code == 200:  # Django 1.7, same_origin is bugged; testserver != localhost:80
766
        response = response.form.submit().maybe_follow()
767
    else:
768
        response = response.maybe_follow()
757
    response = response.click('Logout').maybe_follow()
769 758
    response = response.click('Reset it!')
770 759
    response.form['email'] = EMAIL
771 760
    assert len(mail.outbox) == 0
......
781 770
    response.form['new_password1'] = new_password
782 771
    response.form['new_password2'] = new_password
783 772
    response = response.form.submit(status=302).maybe_follow()
773
    # logout
774
    response = response.click('Logout').maybe_follow()
775
    return new_password
776

  
777

  
778
def test_reset_password_ldap_user(slapd, settings, app, db):
779
    settings.LDAP_AUTH_SETTINGS = [{
780
        'url': [slapd.ldap_url],
781
        'binddn': force_text(slapd.root_bind_dn),
782
        'bindpw': force_text(slapd.root_bind_password),
783
        'basedn': u'o=ôrga',
784
        'use_tls': False,
785
    }]
786
    new_password = reset_password_ldap_user(settings, app)
784 787
    # verify password has changed
785 788
    slapd.get_connection().bind_s(DN, new_password)
786 789
    with pytest.raises(ldap.INVALID_CREDENTIALS):
......
1130 1133
    assert 'password will expire' in caplog.text
1131 1134

  
1132 1135

  
1136
def test_login_ppolicy_pwdExpireWarning(slapd_ppolicy, settings, app, db, caplog):
1137
    settings.LDAP_AUTH_SETTINGS = [{
1138
        'url': [slapd_ppolicy.ldap_url],
1139
        'binddn': force_text(slapd_ppolicy.root_bind_dn),
1140
        'bindpw': force_text(slapd_ppolicy.root_bind_password),
1141
        'basedn': u'o=ôrga',
1142
        'use_tls': False,
1143
    }]
1144

  
1145
    pwdMaxAge = 3600
1146
    slapd_ppolicy.add_ldif('''
1147
dn: cn=default,ou=ppolicies,o=ôrga
1148
cn: default
1149
objectclass: top
1150
objectclass: device
1151
objectclass: pwdPolicy
1152
objectclass: pwdPolicyChecker
1153
pwdAttribute: userPassword
1154
pwdMinAge: 0
1155
pwdMaxAge: {pwdMaxAge}
1156
pwdInHistory: 1
1157
pwdCheckQuality: 0
1158
pwdMinLength: 0
1159
pwdExpireWarning: {pwdMaxAge}
1160
pwdGraceAuthnLimit: 0
1161
pwdLockout: TRUE
1162
pwdLockoutDuration: 0
1163
pwdMaxFailure: 0
1164
pwdMaxRecordedFailure: 0
1165
pwdFailureCountInterval: 0
1166
pwdMustChange: FALSE
1167
pwdAllowUserChange: TRUE
1168
pwdSafeModify: FALSE
1169
'''.format(pwdMaxAge=pwdMaxAge))
1170

  
1171
    password = reset_password_ldap_user(settings, app)
1172

  
1173
    time.sleep(2)
1174

  
1175
    response = app.get('/login/')
1176
    response.form['username'] = USERNAME
1177
    response.form['password'] = password
1178
    response = response.form.submit('login-password-submit')
1179
    assert '/password/change/' in response['Location']
1180

  
1181

  
1133 1182
def test_authenticate_ppolicy_pwdAllowUserChange(slapd_ppolicy, settings, db, caplog):
1134 1183
    settings.LDAP_AUTH_SETTINGS = [{
1135 1184
        'url': [slapd_ppolicy.ldap_url],
1136
-