0001-api-add-a-hashed_password-attribute-for-user-api-354.patch
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 |
- |