misc: do not send password reset link to ldap users (#50348)

This commit is contained in:
Valentin Deniaud 2021-09-15 17:41:15 +02:00 committed by Paul Marillonnet
parent c6fa98b05a
commit 4b215cc74c
5 changed files with 59 additions and 5 deletions

View File

@ -77,6 +77,19 @@ class PasswordResetForm(HoneypotForm):
active_users = self.users.filter(is_active=True)
for user in active_users:
if user.userexternalid_set.exists():
user = utils_misc.authenticate(user=user) # get LDAPUser
can_reset_password = utils_misc.get_user_flag(
user=user, name='can_reset_password', default=user.has_usable_password()
)
if not can_reset_password:
login_url = utils_misc.get_token_login_url(user)
utils_misc.send_templated_mail(
user, ['authentic2/password_reset_ldap'], {'login_url': login_url}
)
logger.info('password reset failed for user "%r": account is from ldap', user)
continue
# we don't set the password to a random string, as some users should not have
# a password
set_random_password = user.has_usable_password() and app_settings.A2_SET_RANDOM_PASSWORD_ON_RESET

View File

@ -0,0 +1,16 @@
{% extends "emails/body_base.html" %}
{% load i18n %}
{% block content %}
<p>{% trans "Hi," %}</p>
<p>{% blocktrans trimmed with hostname=request.get_host %}
You requested reset of your password on {{ hostname }}. Unfortunately, it cannot be done from this website, because your account is synchronised from a LDAP server. Hence password reset should be handled in the directory.
{% endblocktrans %}</p>
<p>{% trans "In the meantine, you can access your account using the button below." %}</p>
{% with _("Access account") as button_label %}
{% include "emails/button-link.html" with url=login_url label=button_label %}
{% endwith %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "emails/body_base.txt" %}
{% load i18n %}
{% block content %}{% trans "Hi," %}
{% blocktrans trimmed with hostname=request.get_host %}
You requested reset of your password on {{ hostname }}. Unfortunately, it cannot be done from this website, because your account is synchronised from a LDAP server. Hence password reset should be handled from the directory.
{% endblocktrans %}
{% trans "In the meantine, you can access your account using this link:" %} {{ login_url }}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends "emails/subject.txt" %}
{% load i18n %}
{% block email-subject %}{% blocktrans with hostname=request.get_host %}Password reset cannot be performed on {{ hostname }}{% endblocktrans %}{% endblock %}

View File

@ -981,16 +981,28 @@ def test_reset_password_ldap_user(slapd, settings, app, db):
assert user.email == EMAIL
# logout
response = response.click('Logout').maybe_follow()
# password reset not allowed
response = response.click('Reset it!')
response.form['email'] = EMAIL
assert len(mail.outbox) == 0
response = response.form.submit().maybe_follow()
response.form.submit().maybe_follow()
assert len(mail.outbox) == 1
reset_email_url = utils.get_link_from_mail(mail.outbox[0])
response = app.get(reset_email_url, status=302)
response = response.maybe_follow()
assert 'login-password-submit' in response.text
assert mail.outbox[0].subject == 'Password reset cannot be performed on testserver'
assert 'your account is synchronised from a LDAP server' in mail.outbox[0].body
# access to account is possible anyway
token_login_url = utils.get_link_from_mail(mail.outbox[0])
response = app.get(token_login_url).follow()
assert '_auth_user_id' in app.session
response = response.click('Logout').maybe_follow()
settings.LDAP_AUTH_SETTINGS[0]['can_reset_password'] = True
response = response.click('Reset it!')
response.form['email'] = EMAIL
response.form.submit().maybe_follow()
assert len(mail.outbox) == 2
reset_email_url = utils.get_link_from_mail(mail.outbox[1])
response = app.get(reset_email_url, status=200)
new_password = 'Aa1xxxxx'
response.form['new_password1'] = new_password