Projet

Général

Profil

0002-a2_rbac-fix-inconsistencies-in-OUs-user-password-res.patch

Paul Marillonnet, 22 juin 2021 16:49

Télécharger (5,33 ko)

Voir les différences:

Subject: [PATCH 2/2] a2_rbac: fix inconsistencies in OUs' user password reset
 option (#46650)

 .../migrations/0025_auto_20210622_1132.py     | 21 ++++++++++
 src/authentic2/a2_rbac/models.py              | 10 ++++-
 src/authentic2/views.py                       |  6 ++-
 tests/test_password_reset.py                  | 38 +++++++++++++++++++
 4 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 src/authentic2/a2_rbac/migrations/0025_auto_20210622_1132.py
src/authentic2/a2_rbac/migrations/0025_auto_20210622_1132.py
1
# Generated by Django 2.2.19 on 2021-06-22 09:32
2

  
3
from django.db import migrations, models
4

  
5

  
6
class Migration(migrations.Migration):
7

  
8
    dependencies = [
9
        ('a2_rbac', '0024_fix_self_admin_perm'),
10
    ]
11

  
12
    operations = [
13
        migrations.AlterField(
14
            model_name='organizationalunit',
15
            name='user_can_reset_password',
16
            field=models.NullBooleanField(
17
                choices=[(None, 'System default'), (True, 'Yes'), (False, 'No')],
18
                verbose_name='Users can reset password',
19
            ),
20
        ),
21
    ]
src/authentic2/a2_rbac/models.py
56 56
        (MANUAL_PASSWORD_POLICY, _('Manual password definition')),
57 57
    )
58 58

  
59
    USER_CAN_RESET_PASSWD_CHOICES = (
60
        (None, _("System default")),
61
        (True, _("Yes")),
62
        (False, _("No")),
63
    )
64

  
59 65
    PolicyValue = namedtuple(
60 66
        'PolicyValue',
61 67
        ['generate_password', 'reset_password_at_next_login', 'send_mail', 'send_password_reset'],
......
78 84
        rbac_utils.get_permission_model_name(), content_type_field='target_ct', object_id_field='target_id'
79 85
    )
80 86

  
81
    user_can_reset_password = models.NullBooleanField(verbose_name=_('Users can reset password'))
87
    user_can_reset_password = models.NullBooleanField(
88
        verbose_name=_('Users can reset password'), choices=USER_CAN_RESET_PASSWD_CHOICES
89
    )
82 90

  
83 91
    user_add_password_policy = models.IntegerField(
84 92
        verbose_name=_('User creation password policy'), choices=USER_ADD_PASSWD_POLICY_CHOICES, default=0
src/authentic2/views.py
794 794
        can_reset_password = utils.get_user_flag(
795 795
            user=self.user, name='can_reset_password', default=self.user.has_usable_password()
796 796
        )
797
        if not can_reset_password:
797
        if (
798
            can_reset_password is False
799
            or can_reset_password is None
800
            and not app_settings.A2_USER_CAN_RESET_PASSWORD
801
        ):
798 802
            messages.warning(
799 803
                request, _('It\'s not possible to reset your password. Please contact an administrator.')
800 804
            )
tests/test_password_reset.py
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
import re
17

  
16 18
import pytest
17 19
from django.test.utils import override_settings
18 20
from django.urls import reverse
......
207 209
    response = response.follow()
208 210
    assert len(mailoutbox) == 0
209 211
    assert 'Your password reset request has been refused' in response
212

  
213

  
214
def test_ou_policies(app, db, settings, user_ou1, ou1, user_ou2, ou2, mailoutbox):
215

  
216
    settings.A2_USER_CAN_RESET_PASSWORD = True
217

  
218
    user_ou1.email = 'john.doe.ou1@example.net'
219
    user_ou1.save()
220
    ou1.user_can_reset_password = False  # impossible
221
    ou1.save()
222

  
223
    url = reverse('password_reset')
224
    resp = app.get(url, status=200)
225
    resp.form.set('email', user_ou1.email)
226
    resp = resp.form.submit()
227
    url = utils.get_link_from_mail(mailoutbox[0])
228
    relative_url = url.split('testserver')[1]
229
    resp = app.get(relative_url, status=302)  # impossible, redirected to /
230
    assert resp['Location'] == '/'
231

  
232
    ou2.user_can_reset_password = None  # system default
233
    ou2.save()
234

  
235
    url = reverse('password_reset')
236
    resp = app.get(url, status=200)
237
    resp.form.set('email', user_ou2.email)
238
    resp = resp.form.submit()
239
    url = utils.get_link_from_mail(mailoutbox[1])
240
    relative_url = url.split('testserver')[1]
241
    resp = app.get(relative_url, status=200)
242
    assert 'In order to create a secure password' in resp.text
243

  
244
    settings.A2_USER_CAN_RESET_PASSWORD = False
245

  
246
    url = reverse('password_reset')
247
    resp = app.get(url, status=404)  # globally deactivated, page not found
210
-