Use iso8601 to validate scheduled_for datetime.

Added a validation method that always fails for scheduled notifications.
Comment out config for scheduled task.
The schedule notifications will be turned on once we can invite services to use it.
Waiting for the service permission story, must commit this in order to keep things from going stale.
This commit is contained in:
Rebecca Law
2017-05-24 16:27:15 +01:00
parent 383dee3bb2
commit 9f6c037530
8 changed files with 53 additions and 18 deletions

View File

@@ -109,11 +109,11 @@ class Config(object):
'schedule': crontab(minute=1),
'options': {'queue': 'periodic'}
},
'send-scheduled-notifications': {
'task': 'send-scheduled-notifications',
'schedule': crontab(minute='*/15'),
'options': {'queue': 'periodic'}
},
# 'send-scheduled-notifications': {
# 'task': 'send-scheduled-notifications',
# 'schedule': crontab(minute='*/15'),
# 'options': {'queue': 'periodic'}
# },
'delete-verify-codes': {
'task': 'delete-verify-codes',
'schedule': timedelta(minutes=63),

View File

@@ -891,8 +891,7 @@ class Notification(db.Model):
"sent_at": self.sent_at.strftime(DATETIME_FORMAT) if self.sent_at else None,
"completed_at": self.completed_at(),
"scheduled_for": convert_bst_to_utc(self.scheduled_notification.scheduled_for
).strftime(
"%Y-%m-%d %H:%M") if self.scheduled_notification else None
).strftime(DATETIME_FORMAT) if self.scheduled_notification else None
}
return serialized

View File

@@ -90,3 +90,8 @@ def check_sms_content_char_count(content_count):
if content_count > char_count_limit:
message = 'Content for template has a character count greater than the limit of {}'.format(char_count_limit)
raise BadRequestError(message=message)
def service_can_schedule_notification(service):
# TODO: implement once the service permission works.
raise BadRequestError(message="Your service must be invited to schedule notifications via the API.")

View File

@@ -1,6 +1,7 @@
import json
from datetime import datetime, timedelta
from iso8601 import iso8601, ParseError
from jsonschema import (Draft4Validator, ValidationError, FormatChecker)
from notifications_utils.recipients import (validate_phone_number, validate_email_address, InvalidPhoneError,
InvalidEmailError)
@@ -25,14 +26,14 @@ def validate(json_to_validate, schema):
def validate_schema_date_with_hour(instance):
if isinstance(instance, str):
try:
dt = datetime.strptime(instance, "%Y-%m-%d %H:%M")
dt = iso8601.parse_date(instance).replace(tzinfo=None)
if dt < datetime.utcnow():
raise ValidationError("datetime can not be in the past")
if dt > datetime.utcnow() + timedelta(hours=24):
raise ValidationError("datetime can only be 24 hours in the future")
except ValueError as e:
raise ValidationError("datetime format is invalid. Use the format: "
"YYYY-MM-DD HH:MI, for example 2017-05-30 13:15")
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
validator = Draft4Validator(schema, format_checker=format_checker)

View File

@@ -15,7 +15,7 @@ from app.notifications.validators import (
check_template_is_active,
check_sms_content_char_count,
validate_and_format_recipient,
check_rate_limiting)
check_rate_limiting, service_can_schedule_notification)
from app.schema_validation import validate
from app.v2.errors import BadRequestError
from app.v2.notifications import v2_notification_blueprint
@@ -33,6 +33,10 @@ def post_notification(notification_type):
else:
form = validate(request.get_json(), post_sms_request)
scheduled_for = form.get("scheduled_for", None)
if scheduled_for:
if not service_can_schedule_notification(authenticated_service):
return
check_rate_limiting(authenticated_service, api_user)
form_send_to = form['phone_number'] if notification_type == SMS_TYPE else form['email_address']
@@ -57,7 +61,6 @@ def post_notification(notification_type):
client_reference=form.get('reference', None),
simulated=simulated)
scheduled_for = form.get("scheduled_for", None)
if scheduled_for:
persist_scheduled_notification(notification.id, form["scheduled_for"])
else: