api: manage verified attributes (fixes #28962)
This commit is contained in:
parent
7d2840d4a4
commit
5cb0cb54c3
|
@ -363,6 +363,8 @@ class BaseUserSerializer(serializers.ModelSerializer):
|
|||
kwargs):
|
||||
kwargs['allow_blank'] = True
|
||||
self.fields[at.name] = field_class(**kwargs)
|
||||
self.fields[at.name + '_verified'] = serializers.BooleanField(
|
||||
source='is_verified.%s' % at.name, required=False)
|
||||
for key in self.fields:
|
||||
if key in app_settings.A2_REQUIRED_FIELDS:
|
||||
self.fields[key].required = True
|
||||
|
@ -383,10 +385,18 @@ class BaseUserSerializer(serializers.ModelSerializer):
|
|||
force_password_reset = validated_data.pop('force_password_reset', False)
|
||||
|
||||
attributes = validated_data.pop('attributes', {})
|
||||
is_verified = validated_data.pop('is_verified', {})
|
||||
self.check_perm('custom_user.add_user', validated_data.get('ou'))
|
||||
instance = super(BaseUserSerializer, self).create(validated_data)
|
||||
for key, value in attributes.iteritems():
|
||||
setattr(instance.attributes, key, value)
|
||||
if is_verified.get(key):
|
||||
setattr(instance.verified_attributes, key, value)
|
||||
else:
|
||||
setattr(instance.attributes, key, value)
|
||||
if is_verified.get('first_name'):
|
||||
instance.verified_attributes.first_name = instance.first_name
|
||||
if is_verified.get('last_name'):
|
||||
instance.verified_attributes.last_name = instance.last_name
|
||||
if 'password' in validated_data:
|
||||
instance.set_password(validated_data['password'])
|
||||
instance.save()
|
||||
|
@ -414,13 +424,27 @@ class BaseUserSerializer(serializers.ModelSerializer):
|
|||
validated_data.pop('send_registration_email', False)
|
||||
validated_data.pop('send_registration_email_next_url', None)
|
||||
attributes = validated_data.pop('attributes', {})
|
||||
is_verified = validated_data.pop('is_verified', {})
|
||||
# Double check: to move an user from one ou into another you must be administrator of both
|
||||
self.check_perm('custom_user.change_user', instance.ou)
|
||||
if 'ou' in validated_data:
|
||||
self.check_perm('custom_user.change_user', validated_data.get('ou'))
|
||||
super(BaseUserSerializer, self).update(instance, validated_data)
|
||||
for key, value in attributes.iteritems():
|
||||
setattr(instance.attributes, key, value)
|
||||
if is_verified.get(key):
|
||||
setattr(instance.verified_attributes, key, value)
|
||||
else:
|
||||
setattr(instance.attributes, key, value)
|
||||
for key in is_verified:
|
||||
if key not in attributes:
|
||||
if is_verified.get(key):
|
||||
setattr(instance.verified_attributes, key, getattr(instance.attributes, key))
|
||||
else:
|
||||
setattr(instance.attributes, key, getattr(instance.attributes, key))
|
||||
if is_verified.get('first_name'):
|
||||
instance.verified_attributes.first_name = instance.first_name
|
||||
if is_verified.get('last_name'):
|
||||
instance.verified_attributes.last_name = instance.last_name
|
||||
if 'password' in validated_data:
|
||||
instance.set_password(validated_data['password'])
|
||||
instance.save()
|
||||
|
|
|
@ -36,6 +36,8 @@ class Attributes(object):
|
|||
values = {}
|
||||
super(Attributes, self).__setattr__('values', values)
|
||||
for atv in self.owner.attribute_values.all():
|
||||
if verified and not atv.verified:
|
||||
continue
|
||||
try:
|
||||
attribute = at_map[atv.attribute_id]
|
||||
except KeyError:
|
||||
|
@ -73,6 +75,23 @@ class AttributesDescriptor(object):
|
|||
return getattr(obj, cache_name)
|
||||
|
||||
|
||||
class IsVerified(object):
|
||||
def __init__(self, user):
|
||||
self.user = user
|
||||
|
||||
def __getattr__(self, name):
|
||||
v = getattr(self.user.attributes, name, None)
|
||||
return (
|
||||
v is not None and
|
||||
v == getattr(self.user.verified_attributes, name, None)
|
||||
)
|
||||
|
||||
|
||||
class IsVerifiedDescriptor(object):
|
||||
def __get__(self, obj, objtype):
|
||||
return IsVerified(obj)
|
||||
|
||||
|
||||
class User(AbstractBaseUser, PermissionMixin):
|
||||
"""
|
||||
An abstract base class implementing a fully featured User model with
|
||||
|
@ -111,6 +130,7 @@ class User(AbstractBaseUser, PermissionMixin):
|
|||
objects = UserManager.from_queryset(UserQuerySet)()
|
||||
attributes = AttributesDescriptor()
|
||||
verified_attributes = AttributesDescriptor(verified=True)
|
||||
is_verified = IsVerifiedDescriptor()
|
||||
|
||||
attribute_values = GenericRelation('authentic2.AttributeValue')
|
||||
|
||||
|
|
|
@ -249,9 +249,11 @@ def test_api_users_create(settings, app, api_user):
|
|||
|
||||
resp = app.post_json('/api/users/', params=payload, status=status)
|
||||
if api_user.is_superuser or api_user.roles.exists():
|
||||
assert set(['ou', 'id', 'uuid', 'is_staff', 'is_superuser', 'first_name', 'last_name',
|
||||
'date_joined', 'last_login', 'username', 'password', 'email', 'is_active',
|
||||
'title', 'modified', 'email_verified']) == set(resp.json.keys())
|
||||
assert set(['ou', 'id', 'uuid', 'is_staff', 'is_superuser',
|
||||
'first_name', 'first_name_verified', 'last_name',
|
||||
'last_name_verified', 'date_joined', 'last_login',
|
||||
'username', 'password', 'email', 'is_active', 'title',
|
||||
'title_verified', 'modified', 'email_verified']) == set(resp.json.keys())
|
||||
assert resp.json['first_name'] == payload['first_name']
|
||||
assert resp.json['last_name'] == payload['last_name']
|
||||
assert resp.json['email'] == payload['email']
|
||||
|
@ -260,6 +262,9 @@ def test_api_users_create(settings, app, api_user):
|
|||
assert resp.json['uuid']
|
||||
assert resp.json['id']
|
||||
assert resp.json['date_joined']
|
||||
assert not resp.json['first_name_verified']
|
||||
assert not resp.json['last_name_verified']
|
||||
assert not resp.json['title_verified']
|
||||
if api_user.is_superuser:
|
||||
assert resp.json['ou'] == 'default'
|
||||
elif api_user.roles.exists():
|
||||
|
@ -271,6 +276,7 @@ def test_api_users_create(settings, app, api_user):
|
|||
assert new_user.first_name == resp.json['first_name']
|
||||
assert new_user.last_name == resp.json['last_name']
|
||||
assert AttributeValue.objects.with_owner(new_user).count() == 3
|
||||
assert AttributeValue.objects.with_owner(new_user).filter(verified=True).count() == 0
|
||||
assert AttributeValue.objects.with_owner(new_user).filter(attribute=at).exists()
|
||||
assert (AttributeValue.objects.with_owner(new_user).get(attribute=at).content ==
|
||||
payload['title'])
|
||||
|
@ -286,6 +292,49 @@ def test_api_users_create(settings, app, api_user):
|
|||
resp = app.get('/api/users/1234567890/')
|
||||
assert 'title' not in resp.json
|
||||
|
||||
at.disabled = False
|
||||
at.save()
|
||||
payload = {
|
||||
'username': 'john.doe2',
|
||||
'first_name': 'John',
|
||||
'first_name_verified': True,
|
||||
'last_name': 'Doe',
|
||||
'last_name_verified': True,
|
||||
'email': 'john.doe@example.net',
|
||||
'password': 'password',
|
||||
'title': 'Mr',
|
||||
'title_verified': True,
|
||||
}
|
||||
if api_user.is_superuser:
|
||||
status = 201
|
||||
elif api_user.roles.exists():
|
||||
status = 201
|
||||
payload['ou'] = api_user.ou.slug
|
||||
else:
|
||||
status = 403
|
||||
|
||||
resp = app.post_json('/api/users/', params=payload, status=status)
|
||||
if api_user.is_superuser or api_user.roles.exists():
|
||||
assert set(['ou', 'id', 'uuid', 'is_staff', 'is_superuser',
|
||||
'first_name', 'first_name_verified', 'last_name',
|
||||
'last_name_verified', 'date_joined', 'last_login',
|
||||
'username', 'password', 'email', 'is_active', 'title',
|
||||
'title_verified', 'modified', 'email_verified']) == set(resp.json.keys())
|
||||
user = get_user_model().objects.get(pk=resp.json['id'])
|
||||
assert AttributeValue.objects.with_owner(user).filter(verified=True).count() == 3
|
||||
assert AttributeValue.objects.with_owner(user).filter(verified=False).count() == 0
|
||||
assert user.verified_attributes.first_name == 'John'
|
||||
assert user.verified_attributes.last_name == 'Doe'
|
||||
assert user.verified_attributes.title == 'Mr'
|
||||
assert resp.json['first_name_verified']
|
||||
assert resp.json['last_name_verified']
|
||||
assert resp.json['title_verified']
|
||||
resp2 = app.patch_json('/api/users/%s/' % resp.json['uuid'],
|
||||
params={'title_verified': False})
|
||||
assert resp.json['first_name_verified']
|
||||
assert resp.json['last_name_verified']
|
||||
assert not resp2.json['title_verified']
|
||||
|
||||
|
||||
def test_api_users_create_email_is_unique(settings, app, superuser):
|
||||
from django.contrib.auth import get_user_model
|
||||
|
|
Loading…
Reference in New Issue