From 61a5730596ca2990851bd4e3b69c9e0c578264c9 Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Thu, 9 Jul 2020 12:59:09 +0100 Subject: [PATCH] add more friendly datetime validator to jsonschema add `datetime` format (note, not the built-in `date-time`) to our json schemas. this uses the iso8601 library to try and parse the string. also, move `strict-rfc3339` and `rfc3987` (used by jsonschema to validate `date-time` and `uri` formats respectively from test requirements to regular requirements. if they're not installed, validation silently succeeds, so validation wouldnt reject anything bad on prod, only in unit tests. --- app/broadcast_message/broadcast_message_schema.py | 8 ++++---- app/schema_validation/__init__.py | 11 +++++++++++ requirements-app.txt | 2 ++ requirements.txt | 6 ++++-- requirements_for_test.txt | 3 --- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/broadcast_message/broadcast_message_schema.py b/app/broadcast_message/broadcast_message_schema.py index f8a668127..743ca54d7 100644 --- a/app/broadcast_message/broadcast_message_schema.py +++ b/app/broadcast_message/broadcast_message_schema.py @@ -11,8 +11,8 @@ create_broadcast_message_schema = { 'service_id': uuid, 'created_by': uuid, 'personalisation': {'type': 'object'}, - 'starts_at': {'type': 'string', 'format': 'date-time'}, - 'finishes_at': {'type': 'string', 'format': 'date-time'}, + 'starts_at': {'type': 'string', 'format': 'datetime'}, + 'finishes_at': {'type': 'string', 'format': 'datetime'}, 'areas': {"type": "array", "items": {"type": "string"}}, }, 'required': ['template_id', 'service_id', 'created_by'], @@ -26,8 +26,8 @@ update_broadcast_message_schema = { 'title': 'Update broadcast_message', 'properties': { 'personalisation': {'type': 'object'}, - 'starts_at': {'type': 'string', 'format': 'date-time'}, - 'finishes_at': {'type': 'string', 'format': 'date-time'}, + 'starts_at': {'type': 'string', 'format': 'datetime'}, + 'finishes_at': {'type': 'string', 'format': 'datetime'}, 'areas': {"type": "array", "items": {"type": "string"}}, }, 'required': [], diff --git a/app/schema_validation/__init__.py b/app/schema_validation/__init__.py index 0ddd51f16..f5f2dc9ef 100644 --- a/app/schema_validation/__init__.py +++ b/app/schema_validation/__init__.py @@ -54,6 +54,17 @@ def validate_schema_date_with_hour(instance): return True +@format_checker.checks('datetime', raises=ValidationError) +def validate_schema_datetime(instance): + if isinstance(instance, str): + try: + iso8601.parse_date(instance) + except ParseError: + raise ValidationError("datetime format is invalid. It must be a valid ISO8601 date time format, " + "https://en.wikipedia.org/wiki/ISO_8601") + return True + + def validate(json_to_validate, schema): validator = Draft7Validator(schema, format_checker=format_checker) errors = list(validator.iter_errors(json_to_validate)) diff --git a/requirements-app.txt b/requirements-app.txt index 50f3b6f28..ed4803a3a 100644 --- a/requirements-app.txt +++ b/requirements-app.txt @@ -20,6 +20,8 @@ marshmallow==2.21.0 # pyup: <3 # v3 throws errors psycopg2-binary==2.8.5 PyJWT==1.7.1 SQLAlchemy==1.3.17 +strict-rfc3339==0.7 +rfc3987==1.3.8 cachetools==4.1.0 notifications-python-client==5.5.1 diff --git a/requirements.txt b/requirements.txt index e42c6931c..c96dd1dfe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,6 +22,8 @@ marshmallow==2.21.0 # pyup: <3 # v3 throws errors psycopg2-binary==2.8.5 PyJWT==1.7.1 SQLAlchemy==1.3.17 +strict-rfc3339==0.7 +rfc3987==1.3.8 cachetools==4.1.0 notifications-python-client==5.5.1 @@ -40,14 +42,14 @@ alembic==1.4.2 amqp==1.4.9 anyjson==0.3.3 attrs==19.3.0 -awscli==1.18.93 +awscli==1.18.96 bcrypt==3.1.7 billiard==3.3.0.23 bleach==3.1.4 blinker==1.4 boto==2.49.0 boto3==1.10.38 -botocore==1.17.16 +botocore==1.17.19 certifi==2020.6.20 chardet==3.0.4 click==7.1.2 diff --git a/requirements_for_test.txt b/requirements_for_test.txt index f8edc4dc1..9db32b421 100644 --- a/requirements_for_test.txt +++ b/requirements_for_test.txt @@ -8,8 +8,5 @@ pytest-cov==2.8.1 pytest-xdist==1.31.0 freezegun==0.3.12 requests-mock==1.7.0 -# optional requirements for jsonschema -strict-rfc3339==0.7 -rfc3987==1.3.8 # used for creating manifest file locally jinja2-cli[yaml]==0.7.0