From 6891798c10d3c5057686412c8c34a0eb97510954 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 1 Oct 2018 16:26:33 +0200 Subject: [PATCH] enforce birthdate > 1900 through UI and API (fixes @26867) --- src/authentic2/attribute_kinds.py | 21 +++++-- tests/test_attribute_kinds.py | 92 ++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 7 deletions(-) diff --git a/src/authentic2/attribute_kinds.py b/src/authentic2/attribute_kinds.py index 27ae00b4..d142eba3 100644 --- a/src/authentic2/attribute_kinds.py +++ b/src/authentic2/attribute_kinds.py @@ -32,17 +32,26 @@ class BirthdateWidget(widgets.DateWidget): def __init__(self, *args, **kwargs): options = kwargs.setdefault('options', {}) options['endDate'] = '-1d' + options['startDate'] = '1900-01-01' super(BirthdateWidget, self).__init__(*args, **kwargs) +def validate_birthdate(value): + if value and not (datetime.date(1900, 1, 1) <= value < datetime.date.today()): + raise ValidationError(_('birthdate must be in the past and greater or equal than 1900-01-01.')) + + class BirthdateField(forms.DateField): widget = BirthdateWidget + default_validators = [ + validate_birthdate, + ] - def clean(self, value): - value = super(BirthdateField, self).clean(value) - if value and value >= datetime.date.today(): - raise ValidationError(_('birthdate must be in the past.')) - return value + +class BirthdateRestField(serializers.DateField): + default_validators = [ + validate_birthdate, + ] @to_iter @@ -137,7 +146,7 @@ DEFAULT_ATTRIBUTE_KINDS = [ 'field_class': BirthdateField, 'serialize': lambda x: x.isoformat(), 'deserialize': lambda x: x and datetime.datetime.strptime(x, '%Y-%m-%d').date(), - 'rest_framework_field_class': serializers.DateField, + 'rest_framework_field_class': BirthdateRestField, }, { 'label': _('french postcode'), diff --git a/tests/test_attribute_kinds.py b/tests/test_attribute_kinds.py index b6ecf052..b821bc6d 100644 --- a/tests/test_attribute_kinds.py +++ b/tests/test_attribute_kinds.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import datetime + from authentic2.custom_user.models import User from authentic2.models import Attribute @@ -168,8 +170,8 @@ def test_phone_number(db, app, admin, mailoutbox): response = form.submit().follow() assert 'john.doe@example.com' in response url = get_link_from_mail(mailoutbox[0]) - response = app.get(url) + response = app.get(url) form = response.form form.set('first_name', 'John') form.set('last_name', 'Doe') @@ -279,3 +281,91 @@ def test_phone_number(db, app, admin, mailoutbox): app.post_json('/api/users/', params=payload) assert qs.get().attributes.phone_number == '' qs.delete() + + +def test_birthdate(db, app, admin, mailoutbox, freezer): + freezer.move_to('2018-01-01') + Attribute.objects.create(name='birthdate', label='birthdate', kind='birthdate', + asked_on_registration=True) + qs = User.objects.filter(first_name='John') + + response = app.get('/accounts/register/') + form = response.form + form.set('email', 'john.doe@example.com') + response = form.submit().follow() + assert 'john.doe@example.com' in response + url = get_link_from_mail(mailoutbox[0]) + response = app.get(url) + + form = response.form + form.set('first_name', 'John') + form.set('last_name', 'Doe') + form.set('birthdate', '2018-01-01') + form.set('password1', '12345abcdA') + form.set('password2', '12345abcdA') + response = form.submit() + assert response.pyquery.find('.form-field-error #id_birthdate') + + form.set('birthdate', '2017-12-31') + form.set('password1', '12345abcdA') + form.set('password2', '12345abcdA') + form.submit().follow() + assert qs.get().attributes.birthdate == datetime.date(2017, 12, 31) + qs.delete() + + response = app.get(url) + form = response.form + form.set('first_name', 'John') + form.set('last_name', 'Doe') + form.set('birthdate', '1899-12-31') + form.set('password1', '12345abcdA') + form.set('password2', '12345abcdA') + response = form.submit() + assert response.pyquery.find('.form-field-error #id_birthdate') + + form.set('birthdate', '1900-01-01') + form.set('password1', '12345abcdA') + form.set('password2', '12345abcdA') + form.submit().follow() + assert qs.get().attributes.birthdate == datetime.date(1900, 1, 1) + qs.delete() + + +def test_birthdate_api(db, app, admin, mailoutbox, freezer): + freezer.move_to('2018-01-01') + Attribute.objects.create(name='birthdate', label='birthdate', kind='birthdate', + asked_on_registration=True) + qs = User.objects.filter(first_name='John') + app.authorization = ('Basic', (admin.username, admin.username)) + + payload = { + 'first_name': 'John', + 'last_name': 'Doe', + 'birthdate': '2018-01-01', + } + app.post_json('/api/users/', params=payload, status=400) + + payload = { + 'first_name': 'John', + 'last_name': 'Doe', + 'birthdate': '2017-12-31', + } + response = app.post_json('/api/users/', params=payload) + assert qs.get().attributes.birthdate == datetime.date(2017, 12, 31) + qs.delete() + + payload = { + 'first_name': 'John', + 'last_name': 'Doe', + 'birthdate': '1899-12-31', + } + app.post_json('/api/users/', params=payload, status=400) + + payload = { + 'first_name': 'John', + 'last_name': 'Doe', + 'birthdate': '1900-01-01', + } + app.post_json('/api/users/', params=payload) + assert qs.get().attributes.birthdate == datetime.date(1900, 1, 1) + qs.delete() -- 2.18.0