Commit Graph

4689 Commits

Author SHA1 Message Date
Rebecca Law
d4a42471cb Merge pull request #3267 from alphagov/fix-daily-totals-query
Improve the query to get today's totals for a service.
2021-06-16 07:34:01 +01:00
Rebecca Law
8af10eb1f0 Update the job_status to in-progress sooner.
We had a situation where the delivery-worker app instance was terminated before the job was marked as `in-progress`, presumably because the query to check the daily limits was taking too long to complete.
If the job was in progress the `check_job_status` task would have restarted the job.
Updating the status to in-progress sooner will help.
2021-06-15 07:58:17 +01:00
Rebecca Law
08bb5c657f Fix the query to get todays totals for a service.
The query had a group by on notification_type and notification_status, this not only slows the query down but is wrong. The query only looked at the first result, but this query would return as many rows as different notification types and status, meaning the results do not include the correct number.

Are we concerned that all status types are included. For example letters can be cancelled or have validation-failures which shouldn't be included in the daily limit check.
2021-06-14 15:29:21 +01:00
Katie Smith
0148b3dba6 Add new total_letters field to the billing report data
This adds total_letters to the data that is returned by the
`/platform-stats/data-for-billing-report` endpoint so that we can add
total letters as a column in the CSV file that can be downloaded.
2021-06-11 11:31:22 +01:00
David McDonald
be035664c4 Add operator channel to broadcast settings route
Looks identical to the government channel in terms of the interface
2021-06-09 13:49:06 +01:00
Leo Hemsted
8e1a144f87 Merge pull request #3229 from alphagov/data-error
make sure all non-uuid service ids 403 in api keys
2021-06-07 14:09:22 +01:00
Leo Hemsted
c53ed4107b Merge pull request #3260 from alphagov/verify-to-complete
rename verify webauth endpoint to complete
2021-06-04 13:25:10 +01:00
Leo Hemsted
542b151875 rename verify webauth endpoint to complete
it doesn't really do any verification - that's the webauthn code in the
browser and the admin app that does that. Instead, this completes the
login flow, by marking the user as logged in in the database. Added a
docstring that explains this process a bit more, and also added a new
route: /<id>/complete/webauthn. We'll move the admin code over to use
this new url in time
2021-06-03 17:12:19 +01:00
Rebecca Law
684a882cf3 Revert "Do not include today's totals" 2021-06-02 16:06:33 +01:00
Rebecca Law
c668bed9d3 Merge pull request #3256 from alphagov/no-totals-for-high-volume-services
Do not include today's totals
2021-06-02 15:08:45 +01:00
Rebecca Law
a341536de0 - Add comment to test and new if statement
- Update assert in test
2021-06-02 14:13:31 +01:00
Rebecca Law
0e0c911517 Merge pull request #3252 from alphagov/upgrade-warning-to-error
Add a error log for alert tasks.
2021-06-02 13:48:01 +01:00
Rebecca Law
b170b5ed80 This change is a temporary fix to allow users for high volume services to use the admin app.
The trouble is the aggregate query to return the big blue numbers on the dashboard and /notifications/{notification_type} page is taking too long to return.
I have some ideas on how to improve the query, but should take some time to do some more research and test. In the meantime, let's just ignore "todays" total numbers for the high volume services. There are only two services that this will affect.
2021-06-02 10:31:38 +01:00
David McDonald
04e23ca6a9 Revert "Bump utils version for new invalid address character" 2021-06-01 10:53:28 +01:00
Rebecca Law
50de85988e Fix dependency issues
We haven't bumped the test version for a while.
Also bumped the version of Flask and itsdangerous.
In order to fix flask warnings I needed to changed how the blueprints were registerd.
2021-05-27 13:02:24 +01:00
Rebecca Law
ed5e3b3d9c Removed the end date in the filter.
It's always going to be in the future anyway.
After some analysis the query does perform better without it.
I'll make a note to update other queries where we get todays
notification data to remove the end date filter in a separate PR.
2021-05-26 13:47:53 +01:00
Rebecca Law
1bf5ce08b2 Add a error log for alert tasks.
Many of the team members do not look at emails from zendesk, adding a current_app.logger.error message for things we care about to give developers a better chance of seeing them.
I have purposely not added an erro log for `check_for_services_with_high_failure_rates_or_sending_to_tv_numbers` because it's not something we need to look at immediately.
2021-05-26 11:06:21 +01:00
Rebecca Law
bd1498f49f Bump utils version which contains ~ as an invalid first character for a
postal address.
2021-05-25 08:29:25 +01:00
Rebecca Law
782514a0f1 Update the dao_fetch_todays_stats_for_service query.
We have an index on Notifications(service_id, created_at), by updating the query to use between created_at rather than date(created_at) this query will use the index. Changing the query plan to use an index scan rather than a sequence scan, see query plans below.
This query is still rather slow but is improved by this update.

https://www.pivotaltracker.com/story/show/178263480

explain analyze
SELECT notification_type, notification_status, count(id)
FROM notifications
WHERE service_id = 'e791dbd4-09ea-413a-b773-ead8728ddb09'
AND date(created_at) = '2021-05-23'
AND key_type != 'test'
GROUP BY notification_type, notification_status;
                                                                                     QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Finalize GroupAggregate  (cost=6326816.31..6326926.48 rows=24 width=22) (actual time=91666.805..91712.976 rows=10 loops=1)
   Group Key: notification_type, notification_status
   ->  Gather Merge  (cost=6326816.31..6326925.88 rows=48 width=22) (actual time=91666.712..91712.962 rows=30 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Partial GroupAggregate  (cost=6325816.28..6325920.31 rows=24 width=22) (actual time=91662.907..91707.027 rows=10 loops=3)
               Group Key: notification_type, notification_status
               ->  Sort  (cost=6325816.28..6325842.23 rows=10379 width=30) (actual time=91635.890..91676.225 rows=270884 loops=3)
                     Sort Key: notification_type, notification_status
                     Sort Method: external merge  Disk: 10584kB
                     Worker 0:  Sort Method: external merge  Disk: 10648kB
                     Worker 1:  Sort Method: external merge  Disk: 10696kB
                     ->  Parallel Seq Scan on notifications  (cost=0.00..6325123.93 rows=10379 width=30) (actual time=0.036..91513.985 rows=270884 loops=3)
                           Filter: (((key_type)::text <> 'test'::text) AND (service_id = 'e791dbd4-09ea-413a-b773-ead8728ddb09'::uuid) AND (date(created_at) = '2021-05-23'::date))
                           Rows Removed by Filter: 16191366
 Planning Time: 0.760 ms
 Execution Time: 91714.500 ms
(17 rows)

explain analyze
SELECT notification_type, notification_status, count(id)
FROM notifications
WHERE service_id = 'e791dbd4-09ea-413a-b773-ead8728ddb09'
AND created_at  >= '2021-05-22 23:00'
and created_at < '2021-05-23 23:00'
AND key_type != 'test'
GROUP BY notification_type, notification_status;
                                                                                                                       QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Finalize GroupAggregate  (cost=2114273.37..2114279.57 rows=24 width=22) (actual time=21032.076..21035.725 rows=10 loops=1)
   Group Key: notification_type, notification_status
   ->  Gather Merge  (cost=2114273.37..2114278.97 rows=48 width=22) (actual time=21032.056..21035.703 rows=30 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Sort  (cost=2113273.35..2113273.41 rows=24 width=22) (actual time=21029.261..21029.265 rows=10 loops=3)
               Sort Key: notification_type, notification_status
               Sort Method: quicksort  Memory: 25kB
               Worker 0:  Sort Method: quicksort  Memory: 25kB
               Worker 1:  Sort Method: quicksort  Memory: 25kB
               ->  Partial HashAggregate  (cost=2113272.56..2113272.80 rows=24 width=22) (actual time=21029.228..21029.230 rows=10 loops=3)
                     Group Key: notification_type, notification_status
                     ->  Parallel Bitmap Heap Scan on notifications  (cost=114455.71..2111695.14 rows=210322 width=30) (actual time=4983.790..20960.581 rows=271217 loops=3)
                           Recheck Cond: ((service_id = 'e791dbd4-09ea-413a-b773-ead8728ddb09'::uuid) AND (created_at >= '2021-05-22 23:00:00'::timestamp without time zone) AND (created_at < '2021-05-23 23:00:00'::timestamp without time zone))
                           Rows Removed by Index Recheck: 1456269
                           Filter: ((key_type)::text <> 'test'::text)
                           Heap Blocks: exact=12330 lossy=123418
                           ->  Bitmap Index Scan on ix_notifications_service_created_at  (cost=0.00..114329.51 rows=543116 width=0) (actual time=4973.139..4973.140 rows=813671 loops=1)
                                 Index Cond: ((service_id = 'e791dbd4-09ea-413a-b773-ead8728ddb09'::uuid) AND (created_at >= '2021-05-22 23:00:00'::timestamp without time zone) AND (created_at < '2021-05-23 23:00:00'::timestamp without time zone))
 Planning Time: 0.191 ms
 Execution Time: 21035.770 ms
(21 rows)
2021-05-25 08:00:24 +01:00
Leo Hemsted
c1b08e4cbc make sure all non-uuid service ids 403 in api keys
previously 'invalid-strings' would be handled, but integers would just
return 500.
2021-05-19 08:57:31 +01:00
Leo Hemsted
00b0227007 add endpoint for verifying webauthn login
with sms and email auth the api handles verifying logins in the
`/<user_id>/verify/code` endpoint, when it checks the code is valid etc.
The admin app has already done this for webauthn logins, but we still
need an API endpoint so that we can set up the user's db entry to have
a new logged in timestamp, a new session id (this is important for
logging out other browser sessions), etc.

Also, we need to be able to make sure that the user's max login count
isn't exceeded. If it's exceeded, we shouldn't let them log in even with
a valid webauthn check.

This endpoint is a POST where the admin passes in a json dict with key
"succesful" being True or False. True sets up the db stuff as mentioned.
False just increments the failed login count.
2021-05-17 20:37:46 +01:00
Pea Tyczynska
251107029a Add webauthn to tests that include other auth types 2021-05-13 12:44:36 +01:00
Pea Tyczynska
098c6f031b Add webauthn as an auth type.
Both in our models and as a migration to add it to auth_types
table.

Make sure that if we downgrade, we first clean up the data.
2021-05-13 12:44:36 +01:00
Leo Hemsted
c190886bfe tweak webauthn rest errors
simplify logic by changing the dao function to require a user id and a
webauthn cred id. Note that this changes the response from a 400 to a
404 if the cred is for a different user than the supplied id.

give a minimum length to the text fields in POSTS to create/update a
credential to avoid surprising unexpected edge cases involving empty
string names etc.
2021-05-12 17:48:38 +01:00
Pea Tyczynska
d6fead7c04 On update, check that webauthn credential belongs to user 2021-05-12 17:48:38 +01:00
Pea Tyczynska
e6291187ba Remove registration_response from webauthn serialize - not needed in admin app
Also fix tests:

First add init file so the tests are found correctly, then update
the tests after we stopped serialising webauthn
registration_response.
2021-05-12 17:48:37 +01:00
Leo Hemsted
e62e050963 add webauthn crud endpoints
added some simple validation to the delete endpoint for sanity, but
generally my assumption is that more validation will happen on the admin
side.

noteably im not checking whether the credentials are duplicated, nor is
there a uniqueness constraint in the database - I'm not sure if the
credential blob will always reliably be equivalent, and I believe the
browser should hopefully take care of dupes.
2021-05-12 17:48:37 +01:00
Leo Hemsted
500feba50d add name/id and consolidate webauthn types in model/table
so we can be in line with what the admin handles, and keep it simple on
the api side and do as little manipulation of binary data as possible.

### Minor changes

* id is a UUID we can use for referencing within notify. No relation to
 the key itself.
* name is a user viewable name that can be set/edited
* fix updated_at to have onupdate, not default

### Simplify the webauthn data

credential_data is the data we store about an authenticator that we'll
use to identify the key when logging in. includes the credential_id, the
public_key, and the aaguid (which identifies the authenticator
make/model)

registration_response is the data containing audit information - in the
future we can use this to ensure that the authenticators used are of
high quality.

both of these fields are CBOR (a kind of binary json), encoded in
base64 so that they can be embedded within our regular JSON api
endpoints. we don't anticipate the api ever needing to interact with
this data directly.
2021-05-12 17:48:37 +01:00
Pea Tyczynska
3798a3bd1d Add webauthn_credential table
This is to store data for registered webauthn credentials, so
platform admins can later use them to log in.
2021-05-12 17:48:36 +01:00
Katie Smith
829b646931 Allow "government" in broadcast_channel schema
This will allow admin to pass through a value of "government" for the
broadcast_channel. We don't have any logic around the value of service.broadcast_channel,
so no updates are needed to the tasks etc.
2021-05-11 16:56:56 +01:00
Katie Smith
32fa8ee418 Merge pull request #3237 from alphagov/null-to-all
Make service_broadcast_settings.provider non-nullable
2021-05-11 13:35:26 +01:00
Katie Smith
c4d855a1a0 Remove references to broadcast provider_restriction being None
None is not a value that is allowed any more.
2021-05-10 15:59:22 +01:00
Katie Smith
4624328c36 Make service_broadcast_settings.provider non-nullable
We set all existing null values to "all", then make the column
non-nullable. Admin is already passing through the value of "all".
2021-05-10 15:59:22 +01:00
Chris Hill-Scott
0a3be6a662 Normalise content for non-templated broadcast events
We found that non-templated broadcast messages weren’t having their
content normalised before saving into an event.

This means that stuff like `\r\n` and curly quotes were being passed
through to the CBC proxy.

This commit firstly changes templated events to use
`str(BroadcastMessageTemplate)` to normalise the content, because it’s
non-obvious that calling
`BroadcastMessageTemplate.content_with_placeholders_filled_in` also
normalises content.

Then it changes the non-templated route to also call
`str(BroadcastMessageTemplate)`, where previously it was passing the
content straight through.
2021-05-10 15:55:08 +01:00
Katie Smith
1767535def Allow service.allowed_broadcast_provider to be "all"
We want to replace the value `None` for
service.allowed_broadcast_provider with the value of "all". As a first
step, we need to allow both values. Once notifications-admin has been
changed to pass through "all" and all the data in the database has been
updated, we can update the code to stop supporting both values.
2021-05-06 15:32:02 +01:00
Katie Smith
aec631f208 Add a type table for broadcast providers
This adds a type table for broadcast providers, which is the pattern we
follow with our models (e.g. we have a `broadcast_channel_types` table).

As well as the four providers, the migration populates it with `all`
which is the value that will replace `null` in a later change.

It should be safe to add the foreign key constraint to the
`service_broadcast_settings` in the same migration since the column is
still nullable and we don't have data in that column that is not in the
types table.
2021-05-06 15:30:04 +01:00
Katie Smith
46fe3fca23 Merge pull request #3230 from alphagov/zipfile-names
Change letter zip file names for Insolvency Service letters
2021-05-06 13:57:18 +01:00
Katie Smith
8a34dccda0 Remove redundant join
This was left over from when we needed to tell if a notification was
sent by a crown or non-crown service.
2021-05-06 09:34:46 +01:00
Katie Smith
8365c749e4 Change letter zip file names for Insolvency Service letters
DVLA would like to be able to identify letters sent by the Insolvency
Service, so we are changing the zipfile name. They need all zipfile
names to have the same structure, so we can't just add a marker to files
sent by that service - we have to change all filenames.

The new format is like this:
`{NOTIFY}.{DATE}.{SEQUENCE_ID}.{UNIQUE_ID}.{SERVICE_ID}.{ORG_NAME}.{EXTENSION}`
2021-05-06 09:18:44 +01:00
Ben Thorner
bd45d788c0 Increase warning threshold for SMS failures
Second attempt [1]. This increases the threshold so:

- It's a more substantial amount of money lost (£16).

- It's 10% of the minimum free allowance for a service.

- It's greater than the threshold we have for TV numbers (500).

Having a higher threshold for this alert will help prevent wasted
effort investigating more negligible failures, and reduces the
ambiguity of whether we should take action: we should.

[1]: https://github.com/alphagov/notifications-api/pull/3221
2021-05-05 17:54:43 +01:00
Rebecca Law
590f29b28a SQLAlchemy 1.4 requires SQLALCHEMY_DATABASE_URI to use postgresql rather than postgres for the connection uri to the database.
When deploying to paas the database postgres environment variables are set using VCAP_SERVICES provided by PaaS. When we start up the app and set the properties we need to replace the postgres string with postgresql for the app to start up properly.
This wasn't caught locally or with the unit tests because we were setting this property with postgresql.
2021-04-29 13:49:37 +01:00
Rebecca Law
4f196316aa Change the query to get the services to purge to use query on the db.Model rather than db.session.query.
`service_ids_to_purge` is a list of `row` object rather than a list of `UUID`.

NOTE: db.session.query(Service).filter(Service.id.notin_(services_with_data_retention)).all() would have also worked. It seems that only selecting attributes from the db.Model has caused the change.
2021-04-29 13:32:36 +01:00
Rebecca Law
68d28aa83b The update of SQLAlchemy 1.4.10 has caused some conflicts in our code. This PR fixes most of those conflicts.
- sqlalchemy.sql.expression.case must include an else statement.
- clearly define list of columns for inbound_sms_history insert, getting the list from InboundSmsHistory.__table__.c was causing data type errors.
- remove relationships when not needed, the foreign key relationship is established in the creation of the column. This will get rid of the warnings referenced here: http://sqlalche.me/e/14/qzyx.
- update queries now that he user relationship in ServiceUser db model has been removed.
- move the check that a template is archived to the view instead of the dao method. The check was clearing the session before the version history could be done.

Deleting notifications in the night tasks still needs to be
investigated. The raw sql is causing an error.
2021-04-29 13:32:36 +01:00
Ben Thorner
23f4ae32df Merge pull request #3214 from alphagov/check-broadcast-suspended
Enforce service suspension for broadcasts
2021-04-28 15:01:11 +01:00
Rebecca Law
85895a9e8b Revert "Scheduled weekly dependency update for week 16" 2021-04-28 10:17:16 +01:00
Rebecca Law
10b0554784 Merge pull request #3219 from alphagov/pyup-scheduled-update-2021-04-21
Scheduled weekly dependency update for week 16
2021-04-28 09:20:35 +01:00
David McDonald
2d345afab8 Merge pull request #3223 from alphagov/earlier-alerts
Make check-if-letters-still-in-created run at 7am
2021-04-27 17:29:12 +01:00
Rebecca Law
be797ea513 Merge pull request #3215 from alphagov/add-unique-key-annual-billing
Add unique key on annual_billing for service_id + financial_year_start.
2021-04-27 14:14:10 +01:00
David McDonald
f194231d87 Make check-if-letters-still-in-created run at 7am
If this alert goes off in the morning, it usually means we need to do
something, ideally quite quickly as it indicates a potential problem
with the sending of letters over to DVLA the night before.

Given this goes off at 9am at the moment, but actually some people start
work earlier, if we alert at 7am it means it will likely be looked at
earlier in the day and we can potentially fix any problems with letters
sooner than later.
2021-04-27 11:26:18 +01:00
Ben Thorner
99bc29418e Move request_id injection into send_task override
This applies the same change we made in other apps [1][2]. Adding
the override here is special, though, because it means the others
will now get triggered, since this app is the start of the chain
of tasks for a request. We will also retain existing request_id
tracing for tasks within this app, since "apply_async" calls the
"send_task" method internally, which is the one we're overriding.

[1]: 6f3c118a1e
[2]: 2e08b7aa95
2021-04-27 10:35:21 +01:00