Projet

Général

Profil

0001-api-add-a-hashed_password-attribute-for-user-api-354.patch

Nicolas Roche, 04 septembre 2019 18:33

Télécharger (5,9 ko)

Voir les différences:

Subject: [PATCH] api: add a hashed_password attribute for user api (#35482)

 src/authentic2/api_views.py | 18 +++++++++++++++---
 tests/test_api.py           | 30 ++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)
src/authentic2/api_views.py
340 340
    send_registration_email_next_url = serializers.URLField(write_only=True, required=False)
341 341
    password = serializers.CharField(max_length=128, required=False)
342 342
    force_password_reset = serializers.BooleanField(write_only=True, required=False, default=False)
343
    hashed_password = serializers.CharField(max_length=128, required=False)
343 344

  
344 345
    def __init__(self, *args, **kwargs):
345 346
        super(BaseUserSerializer, self).__init__(*args, **kwargs)
......
392 393
        attributes = validated_data.pop('attributes', {})
393 394
        is_verified = validated_data.pop('is_verified', {})
394 395
        password = validated_data.pop('password', None)
396
        hashed_password = validated_data.pop('hashed_password', None)
395 397
        self.check_perm('custom_user.add_user', validated_data.get('ou'))
396 398
        instance = super(BaseUserSerializer, self).create(validated_data)
397 399
        # prevent update on a get_or_create
......
413 415
        instance.save()
414 416
        if force_password_reset:
415 417
            PasswordReset.objects.get_or_create(user=instance)
418
        if hashed_password is not None:
419
            instance.password = hashed_password
420
            instance.save()
416 421
        if send_registration_email and validated_data.get('email'):
417 422
            try:
418 423
                utils.send_password_reset_mail(
......
437 442
        attributes = validated_data.pop('attributes', {})
438 443
        is_verified = validated_data.pop('is_verified', {})
439 444
        password = validated_data.pop('password', None)
445
        hashed_password = validated_data.pop('hashed_password', None)
440 446
        # Double check: to move an user from one ou into another you must be administrator of both
441 447
        self.check_perm('custom_user.change_user', instance.ou)
442 448
        if 'ou' in validated_data:
......
465 471
            instance.save()
466 472
        if force_password_reset:
467 473
            PasswordReset.objects.get_or_create(user=instance)
474
        if hashed_password is not None:
475
            instance.password = hashed_password
476
            instance.save()
468 477
        return instance
469 478

  
470 479
    def validate(self, data):
......
491 500
            if ou and ou.email_is_unique and qs.filter(ou=ou, email=data['email']).exists():
492 501
                already_used = True
493 502

  
503
        errors = {}
494 504
        if already_used:
495
            raise serializers.ValidationError({
496
                'email': 'email already used',
497
            })
505
            errors['email'] = 'email already used'
506
        if data.get('password') and data.get('hashed_password'):
507
            errors['hashed_password'] = 'conflict with provided password'
508
        if errors:
509
            raise serializers.ValidationError(errors)
498 510
        return data
499 511

  
500 512
    class Meta:
tests/test_api.py
1187 1187
    assert User.objects.get(id=id).last_name == 'Doe'
1188 1188
    assert User.objects.get(id=id).password != password
1189 1189
    assert User.objects.get(id=id).check_password('secret')
1190
    password = User.objects.get(id=id).password
1191

  
1192
    payload['hashed_password'] = 'pbkdf2_sha256$36000$re9zaUj1ize0$bX1cqB91ni4aMOtRh8//TLaJkX+xnD2w84MCQx9AJcE='
1193
    resp = app.post_json('/api/users/?update_or_create=email', params=payload, status=400)
1194
    assert resp.json['result'] == 0
1195
    assert resp.json['errors']['hashed_password'] == ['conflict with provided password']
1196

  
1197
    del payload['password']
1198
    resp = app.post_json('/api/users/?update_or_create=email', params=payload, status=200)
1199
    assert User.objects.get(id=id).first_name == 'Jane'
1200
    assert User.objects.get(id=id).last_name == 'Doe'
1201
    assert User.objects.get(id=id).password != password
1202
    assert User.objects.get(id=id).check_password('admin')
1190 1203

  
1191 1204

  
1192 1205
def test_api_users_get_or_create_email_is_unique(settings, app, admin):
......
1244 1257
    assert User.objects.get(id=id).email == 'john.doe@example2.net'
1245 1258
    assert User.objects.get(id=id).password != password
1246 1259
    assert User.objects.get(id=id).check_password('secret')
1260
    password = User.objects.get(id=id).password
1261

  
1262
    payload['hashed_password'] = 'pbkdf2_sha256$36000$re9zaUj1ize0$bX1cqB91ni4aMOtRh8//TLaJkX+xnD2w84MCQx9AJcE='
1263
    resp = app.post_json(
1264
        '/api/users/?update_or_create=first_name&update_or_create=last_name',
1265
        params=payload, status=400)
1266
    assert resp.json['result'] == 0
1267
    assert resp.json['errors']['hashed_password'] == ['conflict with provided password']
1268

  
1269
    del payload['password']
1270
    resp = app.post_json(
1271
        '/api/users/?update_or_create=first_name&update_or_create=last_name',
1272
        params=payload, status=200)
1273
    assert User.objects.get(id=id).first_name == 'John'
1274
    assert User.objects.get(id=id).last_name == 'Doe'
1275
    assert User.objects.get(id=id).password != password
1276
    assert User.objects.get(id=id).check_password('admin')
1247 1277

  
1248 1278

  
1249 1279
def test_api_roles_get_or_create(settings, ou1, app, admin):
1250
-