0001-api-prevent-password-change-on-get_or_create-34950.patch
src/authentic2/api_mixins.py | ||
---|---|---|
47 | 47 |
defaults[key] = value |
48 | 48 |
with transaction.atomic(): |
49 | 49 |
instance, created = self.Meta.model._default_manager.get_or_create(**kwargs) |
50 |
instance._a2_created = created |
|
50 | 51 |
if many_to_many and created: |
51 | 52 |
self.update(instance, many_to_many) |
52 | 53 |
return instance |
... | ... | |
78 | 79 |
defaults[key] = value |
79 | 80 |
with transaction.atomic(): |
80 | 81 |
instance, created = self.Meta.model._default_manager.get_or_create(**kwargs) |
82 |
instance._a2_created = created |
|
81 | 83 |
if many_to_many or not created: |
82 | 84 |
self.update(instance, validated_data) |
83 | 85 |
return instance |
src/authentic2/api_views.py | ||
---|---|---|
339 | 339 |
send_registration_email = serializers.BooleanField(write_only=True, required=False, |
340 | 340 |
default=False) |
341 | 341 |
send_registration_email_next_url = serializers.URLField(write_only=True, required=False) |
342 |
password = serializers.CharField(max_length=128, |
|
343 |
default=CreateOnlyDefault(utils.generate_password), |
|
344 |
required=False) |
|
342 |
password = serializers.CharField(max_length=128, required=False) |
|
345 | 343 |
force_password_reset = serializers.BooleanField(write_only=True, required=False, default=False) |
346 | 344 | |
347 | 345 |
def __init__(self, *args, **kwargs): |
... | ... | |
394 | 392 | |
395 | 393 |
attributes = validated_data.pop('attributes', {}) |
396 | 394 |
is_verified = validated_data.pop('is_verified', {}) |
395 |
password = validated_data.pop('password', None) |
|
397 | 396 |
self.check_perm('custom_user.add_user', validated_data.get('ou')) |
398 | 397 |
instance = super(BaseUserSerializer, self).create(validated_data) |
398 |
# prevent update on a get_or_create |
|
399 |
if not getattr(instance, '_a2_created', True): |
|
400 |
return instance |
|
399 | 401 |
for key, value in attributes.items(): |
400 | 402 |
if is_verified.get(key): |
401 | 403 |
setattr(instance.verified_attributes, key, value) |
... | ... | |
405 | 407 |
instance.verified_attributes.first_name = instance.first_name |
406 | 408 |
if is_verified.get('last_name'): |
407 | 409 |
instance.verified_attributes.last_name = instance.last_name |
408 |
if 'password' in validated_data: |
|
409 |
instance.set_password(validated_data['password']) |
|
410 |
instance.save() |
|
410 |
if password is not None: |
|
411 |
instance.set_password(password) |
|
412 |
else: |
|
413 |
instance.set_unusable_password() |
|
414 |
instance.save() |
|
411 | 415 |
if force_password_reset: |
412 | 416 |
PasswordReset.objects.get_or_create(user=instance) |
413 | 417 |
if send_registration_email and validated_data.get('email'): |
... | ... | |
433 | 437 |
validated_data.pop('send_registration_email_next_url', None) |
434 | 438 |
attributes = validated_data.pop('attributes', {}) |
435 | 439 |
is_verified = validated_data.pop('is_verified', {}) |
440 |
password = validated_data.pop('password', None) |
|
436 | 441 |
# Double check: to move an user from one ou into another you must be administrator of both |
437 | 442 |
self.check_perm('custom_user.change_user', instance.ou) |
438 | 443 |
if 'ou' in validated_data: |
... | ... | |
456 | 461 |
instance.verified_attributes.first_name = instance.first_name |
457 | 462 |
if is_verified.get('last_name'): |
458 | 463 |
instance.verified_attributes.last_name = instance.last_name |
459 |
if 'password' in validated_data:
|
|
460 |
instance.set_password(validated_data['password'])
|
|
464 |
if password is not None:
|
|
465 |
instance.set_password(password)
|
|
461 | 466 |
instance.save() |
462 | 467 |
if force_password_reset: |
463 | 468 |
PasswordReset.objects.get_or_create(user=instance) |
tests/test_api.py | ||
---|---|---|
1163 | 1163 |
id = resp.json['id'] |
1164 | 1164 |
assert User.objects.get(id=id).first_name == 'John' |
1165 | 1165 |
assert User.objects.get(id=id).last_name == 'Doe' |
1166 |
password = User.objects.get(id=id).password |
|
1166 | 1167 | |
1167 | 1168 |
resp = app.post_json('/api/users/?get_or_create=email', params=payload, status=201) |
1168 | 1169 |
assert id == resp.json['id'] |
1169 | 1170 |
assert User.objects.get(id=id).first_name == 'John' |
1170 | 1171 |
assert User.objects.get(id=id).last_name == 'Doe' |
1172 |
assert User.objects.get(id=id).password == password |
|
1171 | 1173 | |
1174 |
paylaod = {} |
|
1172 | 1175 |
payload['first_name'] = 'Jane' |
1173 | 1176 |
resp = app.post_json('/api/users/?update_or_create=email', params=payload, status=201) |
1174 | 1177 |
assert id == resp.json['id'] |
1175 | 1178 |
assert User.objects.get(id=id).first_name == 'Jane' |
1176 | 1179 |
assert User.objects.get(id=id).last_name == 'Doe' |
1180 |
assert User.objects.get(id=id).password == password |
|
1177 | 1181 | |
1178 | 1182 | |
1179 | 1183 |
def test_api_users_get_or_create_email_is_unique(settings, app, admin): |
... | ... | |
1214 | 1218 |
id = resp.json['id'] |
1215 | 1219 |
assert User.objects.get(id=id).first_name == 'John' |
1216 | 1220 |
assert User.objects.get(id=id).last_name == 'Doe' |
1221 |
password = User.objects.get(id=id).password |
|
1217 | 1222 | |
1218 | 1223 |
resp = app.post_json('/api/users/?get_or_create=first_name&get_or_create=last_name', params=payload, status=201) |
1219 | 1224 |
assert id == resp.json['id'] |
1220 | 1225 |
assert User.objects.get(id=id).first_name == 'John' |
1221 | 1226 |
assert User.objects.get(id=id).last_name == 'Doe' |
1227 |
assert User.objects.get(id=id).password == password |
|
1222 | 1228 | |
1223 | 1229 |
payload['email'] = 'john.doe@example2.net' |
1224 | 1230 |
resp = app.post_json('/api/users/?update_or_create=first_name&update_or_create=last_name', params=payload, status=201) |
1225 | 1231 |
assert id == resp.json['id'] |
1226 | 1232 |
assert User.objects.get(id=id).email == 'john.doe@example2.net' |
1233 |
assert User.objects.get(id=id).password == password |
|
1227 | 1234 | |
1228 | 1235 | |
1229 | 1236 |
def test_api_roles_get_or_create(settings, ou1, app, admin): |
1230 |
- |