a2_rbac: fix inconsistencies in OUs' user password reset option (#46650)

This commit is contained in:
Paul Marillonnet 2020-10-27 12:18:37 +01:00
parent dc26670153
commit 2928bbf704
4 changed files with 71 additions and 2 deletions

View File

@ -0,0 +1,21 @@
# Generated by Django 2.2.19 on 2021-06-22 09:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('a2_rbac', '0024_fix_self_admin_perm'),
]
operations = [
migrations.AlterField(
model_name='organizationalunit',
name='user_can_reset_password',
field=models.NullBooleanField(
choices=[(None, 'System default'), (True, 'Yes'), (False, 'No')],
verbose_name='Users can reset password',
),
),
]

View File

@ -56,6 +56,12 @@ class OrganizationalUnit(OrganizationalUnitAbstractBase):
(MANUAL_PASSWORD_POLICY, _('Manual password definition')),
)
USER_CAN_RESET_PASSWD_CHOICES = (
(None, _("System default")),
(True, _("Yes")),
(False, _("No")),
)
PolicyValue = namedtuple(
'PolicyValue',
['generate_password', 'reset_password_at_next_login', 'send_mail', 'send_password_reset'],
@ -78,7 +84,9 @@ class OrganizationalUnit(OrganizationalUnitAbstractBase):
rbac_utils.get_permission_model_name(), content_type_field='target_ct', object_id_field='target_id'
)
user_can_reset_password = models.NullBooleanField(verbose_name=_('Users can reset password'))
user_can_reset_password = models.NullBooleanField(
verbose_name=_('Users can reset password'), choices=USER_CAN_RESET_PASSWD_CHOICES
)
user_add_password_policy = models.IntegerField(
verbose_name=_('User creation password policy'), choices=USER_ADD_PASSWD_POLICY_CHOICES, default=0

View File

@ -794,7 +794,11 @@ class PasswordResetConfirmView(cbv.RedirectToNextURLViewMixin, FormView):
can_reset_password = utils.get_user_flag(
user=self.user, name='can_reset_password', default=self.user.has_usable_password()
)
if not can_reset_password:
if (
can_reset_password is False
or can_reset_password is None
and not app_settings.A2_USER_CAN_RESET_PASSWORD
):
messages.warning(
request, _('It\'s not possible to reset your password. Please contact an administrator.')
)

View File

@ -207,3 +207,39 @@ def test_honeypot(app, db, settings, mailoutbox):
response = response.follow()
assert len(mailoutbox) == 0
assert 'Your password reset request has been refused' in response
def test_ou_policies(app, db, settings, user_ou1, ou1, user_ou2, ou2, mailoutbox):
settings.A2_USER_CAN_RESET_PASSWORD = True
user_ou1.email = 'john.doe.ou1@example.net'
user_ou1.save()
ou1.user_can_reset_password = False # impossible
ou1.save()
url = reverse('password_reset')
resp = app.get(url, status=200)
resp.form.set('email', user_ou1.email)
resp = resp.form.submit()
url = utils.get_link_from_mail(mailoutbox[0])
relative_url = url.split('testserver')[1]
resp = app.get(relative_url, status=302) # impossible, redirected to /
assert resp['Location'] == '/'
ou2.user_can_reset_password = None # system default
ou2.save()
url = reverse('password_reset')
resp = app.get(url, status=200)
resp.form.set('email', user_ou2.email)
resp = resp.form.submit()
url = utils.get_link_from_mail(mailoutbox[1])
relative_url = url.split('testserver')[1]
resp = app.get(relative_url, status=200)
assert 'In order to create a secure password' in resp.text
settings.A2_USER_CAN_RESET_PASSWORD = False
url = reverse('password_reset')
resp = app.get(url, status=404) # globally deactivated, page not found