0004-api-manage-verified-attributes-fixes-28962.patch
src/authentic2/api_views.py | ||
---|---|---|
363 | 363 |
kwargs): |
364 | 364 |
kwargs['allow_blank'] = True |
365 | 365 |
self.fields[at.name] = field_class(**kwargs) |
366 |
self.fields[at.name + '_verified'] = serializers.BooleanField( |
|
367 |
source='is_verified.%s' % at.name, required=False) |
|
366 | 368 |
for key in self.fields: |
367 | 369 |
if key in app_settings.A2_REQUIRED_FIELDS: |
368 | 370 |
self.fields[key].required = True |
... | ... | |
383 | 385 |
force_password_reset = validated_data.pop('force_password_reset', False) |
384 | 386 | |
385 | 387 |
attributes = validated_data.pop('attributes', {}) |
388 |
is_verified = validated_data.pop('is_verified', {}) |
|
386 | 389 |
self.check_perm('custom_user.add_user', validated_data.get('ou')) |
387 | 390 |
instance = super(BaseUserSerializer, self).create(validated_data) |
388 | 391 |
for key, value in attributes.iteritems(): |
389 |
setattr(instance.attributes, key, value) |
|
392 |
if is_verified.get(key): |
|
393 |
setattr(instance.verified_attributes, key, value) |
|
394 |
else: |
|
395 |
setattr(instance.attributes, key, value) |
|
396 |
if is_verified.get('first_name'): |
|
397 |
instance.verified_attributes.first_name = instance.first_name |
|
398 |
if is_verified.get('last_name'): |
|
399 |
instance.verified_attributes.last_name = instance.last_name |
|
390 | 400 |
if 'password' in validated_data: |
391 | 401 |
instance.set_password(validated_data['password']) |
392 | 402 |
instance.save() |
... | ... | |
414 | 424 |
validated_data.pop('send_registration_email', False) |
415 | 425 |
validated_data.pop('send_registration_email_next_url', None) |
416 | 426 |
attributes = validated_data.pop('attributes', {}) |
427 |
is_verified = validated_data.pop('is_verified', {}) |
|
417 | 428 |
# Double check: to move an user from one ou into another you must be administrator of both |
418 | 429 |
self.check_perm('custom_user.change_user', instance.ou) |
419 | 430 |
if 'ou' in validated_data: |
420 | 431 |
self.check_perm('custom_user.change_user', validated_data.get('ou')) |
421 | 432 |
super(BaseUserSerializer, self).update(instance, validated_data) |
422 | 433 |
for key, value in attributes.iteritems(): |
423 |
setattr(instance.attributes, key, value) |
|
434 |
if is_verified.get(key): |
|
435 |
setattr(instance.verified_attributes, key, value) |
|
436 |
else: |
|
437 |
setattr(instance.attributes, key, value) |
|
438 |
for key in is_verified: |
|
439 |
if key not in attributes: |
|
440 |
if is_verified.get(key): |
|
441 |
setattr(instance.verified_attributes, key, getattr(instance.attributes, key)) |
|
442 |
else: |
|
443 |
setattr(instance.attributes, key, getattr(instance.attributes, key)) |
|
444 |
if is_verified.get('first_name'): |
|
445 |
instance.verified_attributes.first_name = instance.first_name |
|
446 |
if is_verified.get('last_name'): |
|
447 |
instance.verified_attributes.last_name = instance.last_name |
|
424 | 448 |
if 'password' in validated_data: |
425 | 449 |
instance.set_password(validated_data['password']) |
426 | 450 |
instance.save() |
src/authentic2/custom_user/models.py | ||
---|---|---|
36 | 36 |
values = {} |
37 | 37 |
super(Attributes, self).__setattr__('values', values) |
38 | 38 |
for atv in self.owner.attribute_values.all(): |
39 |
if verified and not atv.verified: |
|
40 |
continue |
|
39 | 41 |
try: |
40 | 42 |
attribute = at_map[atv.attribute_id] |
41 | 43 |
except KeyError: |
... | ... | |
73 | 75 |
return getattr(obj, cache_name) |
74 | 76 | |
75 | 77 | |
78 |
class IsVerified(object): |
|
79 |
def __init__(self, user): |
|
80 |
self.user = user |
|
81 | ||
82 |
def __getattr__(self, name): |
|
83 |
v = getattr(self.user.attributes, name, None) |
|
84 |
return ( |
|
85 |
v is not None and |
|
86 |
v == getattr(self.user.verified_attributes, name, None) |
|
87 |
) |
|
88 | ||
89 | ||
90 |
class IsVerifiedDescriptor(object): |
|
91 |
def __get__(self, obj, objtype): |
|
92 |
return IsVerified(obj) |
|
93 | ||
94 | ||
76 | 95 |
class User(AbstractBaseUser, PermissionMixin): |
77 | 96 |
""" |
78 | 97 |
An abstract base class implementing a fully featured User model with |
... | ... | |
111 | 130 |
objects = UserManager.from_queryset(UserQuerySet)() |
112 | 131 |
attributes = AttributesDescriptor() |
113 | 132 |
verified_attributes = AttributesDescriptor(verified=True) |
133 |
is_verified = IsVerifiedDescriptor() |
|
114 | 134 | |
115 | 135 |
attribute_values = GenericRelation('authentic2.AttributeValue') |
116 | 136 |
tests/test_api.py | ||
---|---|---|
249 | 249 | |
250 | 250 |
resp = app.post_json('/api/users/', params=payload, status=status) |
251 | 251 |
if api_user.is_superuser or api_user.roles.exists(): |
252 |
assert set(['ou', 'id', 'uuid', 'is_staff', 'is_superuser', 'first_name', 'last_name', |
|
253 |
'date_joined', 'last_login', 'username', 'password', 'email', 'is_active', |
|
254 |
'title', 'modified', 'email_verified']) == set(resp.json.keys()) |
|
252 |
assert set(['ou', 'id', 'uuid', 'is_staff', 'is_superuser', |
|
253 |
'first_name', 'first_name_verified', 'last_name', |
|
254 |
'last_name_verified', 'date_joined', 'last_login', |
|
255 |
'username', 'password', 'email', 'is_active', 'title', |
|
256 |
'title_verified', 'modified', 'email_verified']) == set(resp.json.keys()) |
|
255 | 257 |
assert resp.json['first_name'] == payload['first_name'] |
256 | 258 |
assert resp.json['last_name'] == payload['last_name'] |
257 | 259 |
assert resp.json['email'] == payload['email'] |
... | ... | |
260 | 262 |
assert resp.json['uuid'] |
261 | 263 |
assert resp.json['id'] |
262 | 264 |
assert resp.json['date_joined'] |
265 |
assert not resp.json['first_name_verified'] |
|
266 |
assert not resp.json['last_name_verified'] |
|
267 |
assert not resp.json['title_verified'] |
|
263 | 268 |
if api_user.is_superuser: |
264 | 269 |
assert resp.json['ou'] == 'default' |
265 | 270 |
elif api_user.roles.exists(): |
... | ... | |
271 | 276 |
assert new_user.first_name == resp.json['first_name'] |
272 | 277 |
assert new_user.last_name == resp.json['last_name'] |
273 | 278 |
assert AttributeValue.objects.with_owner(new_user).count() == 3 |
279 |
assert AttributeValue.objects.with_owner(new_user).filter(verified=True).count() == 0 |
|
274 | 280 |
assert AttributeValue.objects.with_owner(new_user).filter(attribute=at).exists() |
275 | 281 |
assert (AttributeValue.objects.with_owner(new_user).get(attribute=at).content == |
276 | 282 |
payload['title']) |
... | ... | |
286 | 292 |
resp = app.get('/api/users/1234567890/') |
287 | 293 |
assert 'title' not in resp.json |
288 | 294 | |
295 |
at.disabled = False |
|
296 |
at.save() |
|
297 |
payload = { |
|
298 |
'username': 'john.doe2', |
|
299 |
'first_name': 'John', |
|
300 |
'first_name_verified': True, |
|
301 |
'last_name': 'Doe', |
|
302 |
'last_name_verified': True, |
|
303 |
'email': 'john.doe@example.net', |
|
304 |
'password': 'password', |
|
305 |
'title': 'Mr', |
|
306 |
'title_verified': True, |
|
307 |
} |
|
308 |
if api_user.is_superuser: |
|
309 |
status = 201 |
|
310 |
elif api_user.roles.exists(): |
|
311 |
status = 201 |
|
312 |
payload['ou'] = api_user.ou.slug |
|
313 |
else: |
|
314 |
status = 403 |
|
315 | ||
316 |
resp = app.post_json('/api/users/', params=payload, status=status) |
|
317 |
if api_user.is_superuser or api_user.roles.exists(): |
|
318 |
assert set(['ou', 'id', 'uuid', 'is_staff', 'is_superuser', |
|
319 |
'first_name', 'first_name_verified', 'last_name', |
|
320 |
'last_name_verified', 'date_joined', 'last_login', |
|
321 |
'username', 'password', 'email', 'is_active', 'title', |
|
322 |
'title_verified', 'modified', 'email_verified']) == set(resp.json.keys()) |
|
323 |
user = get_user_model().objects.get(pk=resp.json['id']) |
|
324 |
assert AttributeValue.objects.with_owner(user).filter(verified=True).count() == 3 |
|
325 |
assert AttributeValue.objects.with_owner(user).filter(verified=False).count() == 0 |
|
326 |
assert user.verified_attributes.first_name == 'John' |
|
327 |
assert user.verified_attributes.last_name == 'Doe' |
|
328 |
assert user.verified_attributes.title == 'Mr' |
|
329 |
assert resp.json['first_name_verified'] |
|
330 |
assert resp.json['last_name_verified'] |
|
331 |
assert resp.json['title_verified'] |
|
332 |
resp2 = app.patch_json('/api/users/%s/' % resp.json['uuid'], |
|
333 |
params={'title_verified': False}) |
|
334 |
assert resp.json['first_name_verified'] |
|
335 |
assert resp.json['last_name_verified'] |
|
336 |
assert not resp2.json['title_verified'] |
|
337 | ||
289 | 338 | |
290 | 339 |
def test_api_users_create_email_is_unique(settings, app, superuser): |
291 | 340 |
from django.contrib.auth import get_user_model |
292 |
- |