Commit Graph

284 Commits

Author SHA1 Message Date
Chris Hill-Scott
8e8601338e Merge pull request #3136 from alphagov/validate-template-length-broadcast-api
Validate content length on broadcast API
2021-02-17 11:34:29 +00:00
Chris Hill-Scott
0bb671df45 Validate content length on broadcast API
The maximum content count of a broadcast varies depending on its
encoding, so we can’t simply validate it against a schema. This commit
moves to using the validation from `notifications-utils`, and raising a
custom error response.
2021-02-16 09:30:40 +00:00
Katie Smith
6b8ebb3421 Fix linting errors 2021-02-16 09:03:38 +00:00
Chris Hill-Scott
e8a79f5413 Don’t accept cancel or update via broadcast API
We don’t support these methods at the moment. Instead we were just
ignoring the `msgType` field, so issuing one of these commands would
cause a new alert to be broadcast 🙃

We might want to support `Cancel` in the future, but for now let’s
reject anything that isn’t `Alert` (CAP terminology for the initial
broadcast).
2021-02-15 09:32:33 +00:00
Pea Tyczynska
3037bf5fff Set broadcast message to stubbed when posting broadcast via API 2021-02-09 10:41:36 +00:00
Chris Hill-Scott
dec16a98f6 Handle XML files that have a declaration
`lxml` wants its input in bytes:

> XML is explicitly defined as a stream of bytes. It's not Unicode text.
> […] rule number one: do not decode your XML data yourself.

– https://lxml.de/FAQ.html#why-can-t-lxml-parse-my-xml-from-unicode-strings

It will accept strings unless, unless the document contains a
declaration[1] with an `encoding` attribute. Then it will refuse to
parse the document and raises a `ValueError`[2].

We can get fix this by passing `lxml` the bytes from the request, rather
than the decoded text.

1. > XML documents may begin with an XML declaration that describes some
   > information about themselves. An example is
   > `<?xml version="1.0" encoding="UTF-8"?>`.
   – https://en.wikipedia.org/wiki/XML#XML_declaration
2. See an example of this exception being raised in production here:
   https://kibana.logit.io/s/9423a789-282c-4113-908d-0be3b1bc9d1d/app/kibana#/doc/logstash-*/logstash-2021.02.05/syslog?id=AXdzfZVz5ZSa5DKpJiYd&_g=()
2021-02-08 08:51:14 +00:00
Chris Hill-Scott
ca6c46c4dd Add logging for succesful broadcast message creation 2021-01-26 16:24:45 +00:00
Chris Hill-Scott
0398ac57f1 Use correct HTTP status code for bad content type
415 is the status code for ‘Unsupported media type’

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415
2021-01-26 16:24:45 +00:00
Chris Hill-Scott
b85fcafd46 Don’t allow broadcasts to be created from JSON
Until we know we’re going to have real users for this, let’s not expose
it.
2021-01-26 16:24:45 +00:00
Chris Hill-Scott
c9d55039eb Simplify polygons before storing them
We’re going to let people pass in fairly complex polygons, but:
- we don’t want to store massive polygons
- we don’t want to pass the CBCs massive polygons

So this commit adds a step to simplify the polygons before storing them.

We think it’s best for us to do this because:
- writing code to do polygon simplification is non-trivial, and we don’t
  want to make all potential integrators do it
- the simplification we’ve developed is domain-specific to emergency
  alerting, so should throw away less information than

There’s a bit more detail about how we simplify polygons in
https://github.com/alphagov/notifications-admin/pull/3590/files
2021-01-26 16:24:45 +00:00
Chris Hill-Scott
26871eeacc Validate CAP against the spec
This gives us some extra confidence that there aren’t any problems with
the data we’re getting from the other service. It doesn’t address any
specific problems we’ve seen, rather it seems like a sensible precaution
to take.
2021-01-26 16:24:45 +00:00
Chris Hill-Scott
38f07db23e Accept CAP XML
This commit makes the existing endpoint also accept CAP XML, should the
appropriate `Content-Type` header be set.

It uses the translation code we added in a previous commit to convert
the CAP to a dict. We can then validate that dict against with the JSON
schema to ensure it’s something we can work with.
2021-01-26 16:24:44 +00:00
Chris Hill-Scott
7530408a21 Validate broadcast against schema
This commit adds a JSONSchema which can validate the fields in an API
call to create a broadcast. It takes the CAP XML schema as a starting
point.
2021-01-26 16:24:44 +00:00
Chris Hill-Scott
61c9e50ed9 Add public API endpoint to create emergency alerts
We know there is at least one system which wants to integrate with
Notify to send out emergency alerts, rather than creating them manually.

This commit adds an endpoint to the public API to let them do that.

To start with we’ll just let the system create them in a single call,
meaning they still have to be approved manually. This reduces the risk
of an attacker being able to broadcast an alert via the API, should the
other system be compromised.

We’ve worked with the owners of the other system to define which fields
we should care about initially.
2021-01-26 16:24:44 +00:00
Chris Hill-Scott
3b0b96834d Do extra code style checks with flake8-bugbear
Flake8 Bugbear checks for some extra things that aren’t code style
errors, but are likely to introduce bugs or unexpected behaviour. A
good example is having mutable default function arguments, which get
shared between every call to the function and therefore mutating a value
in one place can unexpectedly cause it to change in another.

This commit enables all the extra warnings provided by Flake8 Bugbear,
except for:
- the line length one (because we already lint for that separately)
- B903 Data class should either be immutable or use `__slots__` because
  this seems to false-positive on some of our custom exceptions
- B902 Invalid first argument 'cls' used for instance method because
  some SQLAlchemy decorators (eg `declared_attr`) make things that
  aren’t formally class methods take a class not an instance as their
  first argument

It disables:
- _B306: BaseException.message is removed in Python 3_ because I think
  our exceptions have a custom structure that means the `.message`
  attribute is still present

Matches the work done in other repos:
- https://github.com/alphagov/notifications-admin/pull/3172/files
2020-12-22 16:26:45 +00:00
Pea Tyczynska
95deb5a52f Move DATETIME_FORMAT from app to app.utils
To avoid cyclical import issues
2020-12-18 17:39:35 +00:00
Rebecca Law
171bc74c69 Rename check_character_count method to check_is_message_to_long.
Add different error message for email and text if content is too long.
Use utils version with is_message_too_long method implemented for email templates.
2020-11-09 16:06:57 +00:00
Rebecca Law
5bacfc1df9 Change how we validate the length of templates.
We want to add validation for an email that's too long, that way the user knows why the message is failing. At the moment if an email is too long it will get a technical failure, after the retries fail. This way the email post will get a validation error.

Once this: https://github.com/alphagov/notifications-utils/pull/804 is reverted, we can update the utils version.
2020-11-09 15:54:39 +00:00
Rebecca Law
29b6f84f6c Revert "Revert "Add a task to save-api-sms for high volume services."" 2020-10-29 11:12:46 +00:00
Rebecca Law
06ff1bf596 Revert "Add a task to save-api-sms for high volume services." 2020-10-27 16:18:57 +00:00
Rebecca Law
a32e418bab Make sure that letters can not use the high volume service code path.
This code is already restricted to SMS and email, so this is only to make it obvious if there is a code refactor down the line. Perhaps this is overkill and we back out this commit.
2020-10-27 12:05:59 +00:00
Rebecca Law
3dee4ad310 Add a task to save-api-sms for high volume services.
When we initially added a new task to persist the notifications for a high volume service we wanted to implement it as quickly as possible, so ignored SMS.
This will allow a high volume service to send SMS, the SMS will be sent to a queue to then persist and send the SMS, similar to emails.

At this point I haven't added a new application to consume the new save-api-sms-tasks. But we can add a separate application or be happy with how the app scales for both email and sms.
2020-10-26 13:09:37 +00:00
Rebecca Law
10fe7d9fe8 Add postage for send-one-off letters.
The postage is set to europe or rest-of-world for international letters, otherwise the template postage is used.

Also set international for letters.
2020-08-03 14:01:59 +01:00
Rebecca Law
ed5e73d548 Set postage for templated letters when the address is not from the united-kingdom.
If the address is from the united-kingdom use the postage from the template.
2020-08-03 12:03:35 +01:00
Katie Smith
c9f663fe76 Check for invalid chars in letter addresses when sending through the API
This uses the new method in notifications-utils to validate for invalid
characters in address blocks.
2020-07-31 08:58:56 +01:00
Rebecca Law
dd126df122 We have a scheduled task to check that all the jobs have completed, this will catch if an app is shut down and the job is complete yet, we only wait 10 seconds before forcing the app to shut down.
The task was raising a JobIncompleteError, yet it's not an error the task is performing it's task correctly and calling the appropriate task to restart the job.
Also used apply_sync to create the task instead of send_task.
2020-07-22 17:00:20 +01:00
Rebecca Law
40f747d8ef Merge pull request #2911 from alphagov/clean-up
Clean up
2020-07-09 07:56:22 +01:00
Leo Hemsted
0282a76bf7 rename template.serialize to serialize_for_v2
make it clear that this is for the public api, and we shouldn't add
fields to it without considering impacts

also add the broadcast_messages relationship on service and template to
the exclude from the marshmallow schemas, so it's not included elsewhere
2020-07-06 16:42:31 +01:00
Leo Hemsted
7ecd7341b0 add broadcast to template_types and add broadcast_data
had to go through the code and change a few places where we filter on
template types. i specifically didn't worry about jobs or notifications.

Also, add braodcast_data - a json column that might contain arbitrary
broadcast data that we'll figure out as we go. We don't know what it'll
look like, but it should be returned by the API
2020-07-06 15:47:13 +01:00
Rebecca Law
7fb3b3db18 Small changes to tidy up the code 2020-06-30 09:04:24 +01:00
Chris Hill-Scott
3ffdb3093b Revert "Revert "Merge pull request #2887 from alphagov/cache-the-serialised-things""
This reverts commit 7e85e37e1d.
2020-06-26 14:10:12 +01:00
Chris Hill-Scott
7e85e37e1d Revert "Merge pull request #2887 from alphagov/cache-the-serialised-things"
This reverts commit b8c2c6b291, reversing
changes made to 351aca2c5a.
2020-06-26 13:42:44 +01:00
Chris Hill-Scott
b8c2c6b291 Merge pull request #2887 from alphagov/cache-the-serialised-things
Serialise and cache services and API keys
2020-06-26 09:18:45 +01:00
Rebecca Law
be4b8f0878 Merge branch 'cache-the-serialised-things' of github.com:alphagov/notifications-api 2020-06-26 08:16:48 +01:00
Rebecca Law
ce32e577b7 Remove the use of schedule_for in post_notifications.
Years ago we started to implement a way to schedule a notification. We hit a problem but we never came up with a good solution and the feature never made it back to the top of the priority list.

This PR removes the code for scheduled_for. There will be another PR to drop the scheduled_notifications table and remove the schedule_notifications service permission

Unfortunately, I don't think we can remove the `scheduled_for` attribute from the notification.serialized method because out clients might fail if something is missing. For now I have left it in but defaulted the value to None.
2020-06-24 14:54:40 +01:00
Chris Hill-Scott
320bca70f7 Serialise service, API keys and permissions
By serialising these straight away we can:
- not go back to the database later, potentially closing the connection
  sooner
- potentially cache the serialised data, meaning we don’t touch the
  database at all
2020-06-23 16:00:41 +01:00
Chris Hill-Scott
ad2328fc05 Serialise template immediately after fetching
This commit changes the code in post notification endpoint to handle a
serialised template (ie a `dict`) rather than a database object.

This is the first step towards being able to cache the template and not
hit the database on every request.

There should be no functional changes here, it’s just refactoring.

There are some changes to the tests where the signature of functions
has changed.

Importing of the template schema has to be done at a function level,
otherwise Marshmallow gets weird.

This commit also copies the `JSONModel` class from the admin app, which
turns serialised data (a dict made from JSON) into an object on which
certain predefined properties are allowed.

This means we can still do the caching of serialised data, without
having to change too much of the code in the app, or make it ugly by
sprinkling dict lookups everywhere.

We’re not copying all of JSONModel from the admin app, just the bits we
need. We don’t need to compare or hash these objects, they’re just used
for lookups. And redefining `__getattribute__` scares Leo.
2020-06-22 10:20:51 +01:00
Katie Smith
98a69684c5 Update get_template_by_id_response & post_template_preview_response schemas
To check the format of postage. Neither of these two schemas are used
for validating - they seem to be added for reference.
2020-06-19 08:59:27 +01:00
Rebecca Law
be7afdd12b In the effort to reduce the number of database connections I introduced a small bug. This only affected the test templated letter flow, a None type error would happen when trying to creathe completed_at timestamp for a delivered message.
In the previous PR I removed the `update_notification` method to reduce the need for another update query. However, that meant the notification was marked as delivered without an updated_at timestamp.

It is weird to set the updated_at when we create the notification. So is this a better fix? Or do I put the update back now?

I recommend we push this fix now.
2020-06-18 08:30:19 +01:00
Rebecca Law
a5ed8f2079 Update the post letter flow - not able to get reduce the dB transactions used in the letter flow. Prioritising the reduction for the SMS/Email flow.
Only update the daily limit cache if the service is in trial mode.
2020-06-17 12:11:28 +01:00
Rebecca Law
21a1b8e8bd Remove the call to the db after the notification has committed.
After the commit we issue two calls to the db to get service and get notification. This is because after the commit the ORM wants to ensure that the data model objects are the latest.

So far this is just a proof of concept, but the letter flow needs to be updated and we should be able to get rid of research mode. And it needs some tidy up.
2020-06-16 14:33:53 +01:00
Leo Hemsted
58ab99d74b add more prometheus metrics
Two new metrics:

auth_db_connection_duration_seconds (histogram)
  wraps the first DB call of post notifications. This includes waiting
  to get a connection from the pool, and also making the actual request
  to the db to retrieve the service and api keys. (i'm not sure there's
  an easy way to separate these two things)

post_notification_json_parse_duration_seconds
  wraps parsing the v2 post notifications json parsing and schema
  validation. Shouldn't include any async code
2020-06-15 16:26:56 +01:00
David McDonald
dbb2dfa502 Merge pull request #2836 from alixedi/add-csv-support
Add support for CSV files
2020-05-15 12:16:16 +01:00
Pea Tyczynska
5d6f2da155 Rename task from create_letters_pdf to get_pdf_for_templated_letter
In a separate PR we will have to delete vestigial create_letters_pdf
tasks that now only redirects to get_pdf_for_templated_letter.
2020-05-11 13:33:05 +01:00
Ali Zaidi
642ab1ad1e Add support for CSV files 2020-05-06 14:11:50 +01:00
Chris Hill-Scott
ba0d330593 Allow countries in last line of addresses
For services that have permission to send international letters we
should not reject letters that are addressed to another country. We
should still reject letters that are badly-addressed.
2020-05-01 14:37:24 +01:00
Chris Hill-Scott
5ddb5a75da Use new properties of utils Templates
We’ve added some new properties to the templates in utils that we can
use instead of doing weird things like
`WithSubjectTemplate.__str__(another_instance)`
2020-04-15 16:40:42 +01:00
Chris Hill-Scott
7032bac178 Start allowing any three lines in addresses
This is part of moving away from `postcode` and towards `address line 7`

We think it will be easier for people to map their existing data to our
API if we let them fill in any 3 lines, instead of requiring at least
1, 2, and postcode specifically.
2020-04-09 18:19:53 +01:00
Chris Hill-Scott
264fbed04e Refactor postcode validation to use utils
We don’t need to reformat the postcode here once template preview takes
care of it when rendering the PDF.

It’s better (and less code) to store what people give us, so we give
them back the same thing.
2020-04-09 18:19:53 +01:00
Chris Hill-Scott
054cd16d02 Ensure correct object renders V2 template preview
The `body` field of the ‘preview a template’ endpoint should contain the
content of the template with the placeholders replaced.

It should not be rendered into a plain text email, which does stuff like
normalising newlines (so `\r\n` becomes `\n`). However the object that
the `create_post_template_preview_response` function receives is an
instance of `PlainTextEmailTemplate`. So we can’t just call `str()` on
it. Instead we need to call the `__str__` method of
`WithSubjectTemplate` which gives us the result we want.

We were already doing this the right way in the V1 endpoint[1] but
forgot to do it here too.

1. 0108749daa/app/template/rest.py (L181-L184)
2020-04-07 17:09:59 +01:00