Commit Graph

190 Commits

Author SHA1 Message Date
Katie Smith
5b52b6f9bf Clear user cache when broadcast service settings form is submitted
When the broadcast service settings form is submitted it now removes all
permissions for users in notifications-api. This means it should be
clearing the user cache.
2021-07-13 17:06:35 +01:00
Rebecca Law
77c2aa9fd6 Stop passing in today_only for the get_service_statistics method.
We now only ever call it with False.
To remove it from the api call will require a change in the API so will do that at another time.
2021-06-29 07:33:40 +01:00
Rebecca Law
44f02f2e30 To check the daily limit get the daily notification_count from redis.
The daily limit cache is set by the api when a notification is created. There is one cache key per service per day and it expires after 24 hours.
2021-06-23 15:56:05 +01:00
Leo Hemsted
0993792137 rename verify to complete in api endpoint
it was changed in this PR: https://github.com/alphagov/notifications-api/pull/3260
2021-06-04 12:52:40 +01:00
Leo Hemsted
92f78b14fe redirect on login; flash errors on failure
the js `fetch` function will follow redirects blindly and return you the
final 200 response. when there's an error, we don't want to go anywhere,
and we want to use the flask `flash` functionality to pop up an error
page (the likely reason for seeing this is using a yubikey that isn't
associated with your user). using `flash` and then
`window.location.reload()` handles this fine.

However, when the user does log in succesfully we need to properly log
them in - this includes:

* checking their account isn't over the max login count
* resetting failed login count to 0 if not
* setting a new session id in the database (so other browser windows are
  logged out)
* checking if they need to revalidate their email access (every 90 days)
* clearing old user out of the cache

This code all happens in the ajax function rather than being in a
separate redirect, so that you can't just navigate to the login flow. I
wasn't able to unit test that function due how it uses the session and
other flask globals, so moved the auth into its own function so it's
easy to stub out all that CBOR nonsense.

TODO: We still need to pass any `next` URLs through the chain from login
page all the way through the javascript AJAX calls and redirects to the
log_in_user function
2021-06-02 11:51:10 +01:00
Andrew White
00c3943222 Disable the remaining messages check for uploads
The HTTP request for the statistics is taking more 30 seconds which leads to 504 errors from CloudFront.
2021-05-22 07:25:07 +01:00
Ben Thorner
5bfce61bcf Rename "app_" fixture to "notify_admin"
This naming was introduced in 2016 without explanation [1]. I find it
confusing because:

- It's reminiscent of "_app", which is a Python convention indicating
the variable is internal, so maybe avoid using it.

- It suggests there's some other "app" fixture I should be using (there
isn't, though).

The Python style guide describes using an underscore suffix to avoid
clashes with inbuilt names [1], which is sort of applicable if we need
to import the "app" module [2]. However, we can also avoid clashes by
choosing a different name, without the strange underscore.

[1]: 3b1d521c10
[2]: 78824f54fd/tests/app/main/views/test_forgot_password.py (L5)
2021-05-19 11:44:20 +01:00
Katie Smith
bafcc02b7d Integrate with the API for adding and getting webauthn creds
This links up the `get_webauthn_credentials_for_user` and
`create_webauthn_credential_for_user` methods of the user api client to
notifications-api.

To send data to the API we need strings to be unicode, so we call
decode('utf-8') on base64 objects.

Co-authored-by: Leo Hemsted <leo.hemsted@digital.cabinet-office.gov.uk>
2021-05-14 14:28:24 +01:00
Ben Thorner
957dba4356 Avoid registering the same authenticator twice
This passes existing credentials in the server response, to allow
the browser to prevent re-registering the same key for the same
user. Registering the same key multiple times doesn't seem to be
an issue technically; the user has likely got their keys mixed up.

- Chrome says "you don't need to register it again".
- Safari exits with an InvalidStateError.
- Firefox exits with a DOMException.
2021-05-13 10:22:24 +01:00
Ben Thorner
e2cf3e2c70 Support registering a new authenticator
This adds Yubico's FIDO2 library and two APIs for working with the
"navigator.credentials.create()" function in JavaScript. The GET
API uses the library to generate options for the "create()" function,
and the POST API decodes and verifies the resulting credential. While
the options and response are dict-like, CBOR is necessary to encode
some of the byte-level values, which can't be represented in JSON.

Much of the code here is based on the Yubico library example [1][2].

Implementation notes:

- There are definitely better ways to alert the user about failure, but
window.alert() will do for the time being. Using location.reload() is
also a bit jarring if the page scrolls, but not a major issue.

- Ideally we would use window.fetch() to do AJAX calls, but we don't
have a polyfill for this, and we use $.ajax() elsewhere [3]. We need
to do a few weird tricks [6] to stop jQuery trashing the data.

- The FIDO2 server doesn't serve web requests; it's just a "server" in
the sense of WebAuthn terminology. It lives in its own module, since it
needs to be initialised with the app / config.

- $.ajax returns a promise-like object. Although we've used ".fail()"
elsewhere [3], I couldn't find a stub object that supports it, so I've
gone for ".catch()", and used a Promise stub object in tests.

- WebAuthn only works over HTTPS, but there's an exception for "localhost"
[4].  However, the library is a bit too strict [5], so we have to disable
origin verification to avoid needing HTTPS for dev work.

[1]: c42d9628a4/examples/server/server.py
[2]: c42d9628a4/examples/server/static/register.html
[3]: 91453d3639/app/assets/javascripts/updateContent.js (L33)
[4]: https://stackoverflow.com/questions/55971593/navigator-credentials-is-null-on-local-server
[5]: c42d9628a4/fido2/rpid.py (L69)
[6]: https://stackoverflow.com/questions/12394622/does-jquery-ajax-or-load-allow-for-responsetype-arraybuffer
2021-05-13 10:22:23 +01:00
Ben Thorner
ebb82b2e80 Add page for security keys with stubbed data
This adds a new platform admin settings row, leading a page which
shows any existing keys and allows a new one to be registered. Until
the APIs for this are implemented, the user API client just returns
some stubbed data for manual testing.

This also includes a basic JavaScript module to do the main work of
registering a new authenticator, to be implemented in the next commits.

Some more minor notes:

- Setting the headings in the mapping_table is necessary to get the
horizontal rule along the top (to match the design).

- Setting caption to False in the mapping_table is necessary to stop
an extra margin appearing at the top.
2021-05-12 13:41:53 +01:00
Chris Hill-Scott
545f933e37 Cache the JSON in Redis
The endpoints are probably fast enough, but it seems risky to have a
public URL which causes a new query every time the page is loaded.
2021-03-12 14:43:58 +00:00
Chris Hill-Scott
25a6788d66 Use arguments rather than passing around a dict
This makes it harder to write code which will pass tests but fail in
real life.
2021-03-12 14:43:50 +00:00
Chris Hill-Scott
fce4082fff Rename to performance
This is consistent with the old performance platform URLs, which were
gov.uk/performance, and others that we have like /pricing and /features
2021-03-12 13:56:21 +00:00
Rebecca Law
3ca2840652 Rename to performance-dashboard 2021-03-12 11:17:51 +00:00
Rebecca Law
042527e74c Start to build a page to performance platform page. 2021-03-12 11:17:44 +00:00
Leo Hemsted
477129644d fix syntax 2021-03-05 15:05:48 +00:00
Leo Hemsted
4a624ace32 post to get user by email
that way we won't store any PII in logs
2021-03-05 12:43:15 +00:00
David McDonald
f8f3d44511 Add form to set service broadcast account type
Note, no option at the moment to set the service broadcast account type
as None, or back to without the broadcast permission. This has been done
for speed of development given the chance of us needing this is very
low. We can add it later if we need to.
2021-02-23 16:03:14 +00:00
Pea Tyczynska
42b17d40b4 Test allowed attributes are really allowed 2021-02-02 16:38:56 +00:00
Rebecca Law
01a3df6edc Update _delete_template_cache_for_service to delete all template version cache and not just the one ending in "None"
Update all methods that were previous calling @cache.delete('service-{service-id}-template-None') to instead call _delete_template_cache_for_service
Remove call to get service templates, it's not needed since all template version cache is being deleted.
2021-01-25 16:28:20 +00:00
Chris Hill-Scott
99b7d8a66f Add flow for composing an alert without a template
We think that in some cases alerts will be composed in the moment, and
therefore making people first create a template is:
- not a good use of their time
- adding some conceptual complexity which they don’t need

This commit makes it possible to type some words and have them go
straight into the `content` field in the database.

In the future we might want to progressively enhance the radio buttons
so they show on the same page (like we do with the grey buttons on the
templates page).
2021-01-18 17:09:01 +00:00
Rebecca Law
6639dc6061 Add a test that the redis delete cache is being called. 2021-01-12 15:39:51 +00:00
David McDonald
922d43ea1a Update tests/app/notify_client/test_service_api_client.py
Co-authored-by: Chris Hill-Scott <me@quis.cc>
2020-10-21 11:18:09 +01:00
David McDonald
2921c7302c Fix incorrect redis key deleting
We were trying to delete the old 'template-{template-id}' keys but
should have been deleting the new keys which have the service id as part
of the key name. This was causing the cache to not be correctly purged
when we did things like update sender names or set defaults. This should
fix it.
2020-10-21 11:14:23 +01:00
Leo Hemsted
8ec9fe96a9 Delete new format template cache when moving folders 2020-10-06 09:47:22 +01:00
David McDonald
7b82ca5083 Remove deleting of old redis key
At this point we are no longer setting this key, nor are we reading from
it so we are able to delete it.
2020-10-02 15:21:30 +01:00
David McDonald
a538329d0e Use new redis key for service templates and broadcasts
We can drop use of the old key as we no longer need to read data from
the old key. Either data exists in the new key and we read it from there
or data doesn't exist in the new key and we go to the API to get it and
then set it in redis.

Note, the previous commit is important because it means we aren't at
risk of when this commit is being deployed out, of us getting stale data
from the old key.
2020-09-21 17:37:27 +01:00
David McDonald
e3baa9ba35 Step 1 of renaming cache keys for templates
We want to change cache keys for templates and broadcasts to include
their service ID. So cache keys should change from
`template-{template_id}-versions` to
`service-{service_id}-template-{template_id}-versions`.

The first step of this which needs to be deployed as a change first is
to delete both keys when updating service templates (even if they key is
not yet set). This means that when we release code in the next PR to
start setting the new key, we won't run into a case where either the old
or the new key can remain set with stale data.
2020-09-21 14:04:10 +01:00
Leo Hemsted
7e15d0c928 delete template cache when reply_to stuff is updated
sms sender, email reply to, letter contact blocks.

These are all cached within template, under `template.reply_to` - if the
template doesnt have a specific default, then that field stores the
service default. So when service default changes, we need to clear the
template cache so that it is updated to reflect that.

We already use this pattern for deleting the template cache for a bunch
of templates in `template_folder_api_client.move_to_folder`
2020-08-18 14:47:12 +01:00
Chris Hill-Scott
b31fb7de66 Merge pull request #3546 from alphagov/redis-cache-broadcast-message
Cache broadcast messages in Redis
2020-08-04 16:17:21 +01:00
Chris Hill-Scott
058553b6ee Cache broadcast messages in Redis
This should make the pages slightly quicker to load, because Redis will
return the JSON string faster than the API.

The only change that can happen to a broadcast which doesn’t go through
the admin app is a broadcast ending at its scheduled time. So this could
result in a cached broadcast having a status of `broadcasting` when it
had in fact finished. We already account for this here though:
b2b58ec044/app/models/broadcast_message.py (L89-L94)
2020-08-03 11:38:10 +01:00
Chris Hill-Scott
e0cb487093 Use new guest list API URLs
The API now[1] accepts requests on `…/guest-list` as well as
`…/whitelist`. This commit starts using the former, which means:
- the use of ‘whitelist’ is fully gone from the admin app
- the API can stop using it, at least in URLs

1. As of https://github.com/alphagov/notifications-api/pull/2928
2020-07-27 13:24:37 +01:00
Chris Hill-Scott
51e99bd828 Ask API for less detailed JSON for all templates
This should speed things up by:
- less time waiting for big blobs of JSON to come from Redis or the API
- less time spent deserialising big blobs of JSON
2020-06-19 10:32:44 +01:00
Chris Hill-Scott
16cc640822 Rename API client methods to remove term ‘whitelist’
See c31264d4c for rationale. To avoid confusion the codebase should use
the same terminology as the UI.
2020-06-12 10:27:18 +01:00
David McDonald
ee14ae33dc Use redis_client rather than wrapper method
Fixes a bug where we were calling a wrapper method when instead we
should have been calling the redis_client. This had resulted in no
actual calls to redis happening.
2020-05-27 11:56:07 +01:00
David McDonald
0fdda016e2 Refactor archive to do one sync delete of all keys rather than many
Otherwise we could be waiting on 50 sync calls to redis to happen. This
way we do it in one sync call and follow the pattern of
b98f4561fa/app/notify_client/organisations_api_client.py (L56)
2020-05-22 17:12:00 +01:00
David McDonald
a65ada0d7e Delete cached users and templates when archiving a service
When the admin app gets user objects from the API, these include a dict
of permissions by service for what the user can do to that services.
Permissions for inactive services are not included in the response as
per:
87cb6f2597/app/dao/permissions_dao.py (L66)

However, this causes a bug where a service is archived but cached user
data still tells us that the user has permissions to view the service.
This should not be the case and causes errors where users can still see
the archived service page, it's settings, and even request to go live
for it, because they are using old cached data for the user.

We solve this by deleting the users who are part of the service from the
cache.

We also delete the templates for this service from the cache as the
templates are also archived when we ask the API to archive the service
as per:
d95c0131e0/app/service/rest.py (L597)

Note, one decision I had to make was whether to delete the user cache
for just active team members or also invited users. Assuming an invited
user can't see the service until they've accepted their invite anyway, it
shouldn't make any difference whether we delete their cache or not.
2020-05-22 16:27:05 +01:00
Chris Hill-Scott
7fb8e1de92 Use statistics for returned letters on dashboard
This should be faster and more accurate than querying all the reports.
2020-04-01 10:18:55 +01:00
Chris Hill-Scott
fc58547be3 Tell the API which contact list a job’s come from
So that we can make enhancements to the UI in the future, for example
grouping jobs within their associated contact list.
2020-03-16 17:56:55 +00:00
Chris Hill-Scott
af8395956e Cache returned letter summary in Redis
We’re going to start using the returned letters summary to show some
info on the dashboard.

This means we will be accessing it more often than it changes. And we
know exactly when it changes because it’s us manually submitting the
references we get from DVLA.

This makes it a good candidate for being cached, and Redis is where we
cache stuff that we’d otherwise go to the API for.
2020-02-12 11:42:06 +00:00
Rebecca Law
b242467d77 Change the content for the delete template confirmation dialog.
As per https://www.pivotaltracker.com/story/show/170796514 we want to make the delete template confirmation dialog box more consistent and clear.
The API has been updated with a new endpoint that only returns the last-used date, this date is more accurate since it goes to the ft_notification_status table, if the notification table is empty.
2020-02-06 10:16:00 +00:00
Chris Hill-Scott
721134dc17 Merge pull request #3251 from alphagov/job-model
Make models for individual jobs and collections of jobs
2020-01-16 15:52:21 +00:00
Chris Hill-Scott
7d52ac97f1 Move stats to the model
The API clients should just deal with calling the API and returning the
data from it.

Inferring things from the data is more logically done at the model
layer. But we couldn’t do that before, because we didn’t have a model
layer for jobs.
2020-01-13 15:10:16 +00:00
Rebecca Law
f8e7635a1d Show the first line of the address from the to field.
Now persisting the address to the "to" field of the Notification, after the notification has been validated.
If the letter is pending validation, then "Checking..." will appear as the identifier for the letter.
If the letter has passed validation, then the first line of the address (now persisted in the "to" field) will be displayed, with the client reference underneath.
If the letter has failed validation the "Provided as PDF" will show be displayed, which is now the initial value of the "to" field.
2020-01-10 16:00:40 +00:00
Katie Smith
e4134072d9 Reduce the errors related to user fixtures
We were using user fixtures in a lot of parameterized tests, but this is
no longer allowed in Pytest 5. To avoid having to split up the parametrized
tests (which would make the test files a lot longer and slightly more
difficult to read) this commit creates functions which return various types
of user json so that we can use these as the test parameters instead.
2019-12-19 16:59:07 +00:00
David McDonald
2b8b4c25aa Send postage value to API when sending pre compiled letter 2019-11-01 10:47:42 +00:00
David McDonald
3436a190a7 Send precompiled letters with a postage value to the API
We hardcode this as second class for the moment but eventually
will let the user pick.

Currently the API appears to do no validation, e.g. a json
schema, that rejects API calls with the extra key for postage.

Next steps will be to put a PR into the API that will expect a
postage value in the request and save it with the rest of the
notification. Then when that is done we can add the user interface
to the admin app to let the user pick the postage.
2019-10-18 16:35:16 +01:00
Pea Tyczynska
9058b13ff2 Get notification count from api instead of list of notifications
when checking if job can be cancelled. This makes query lighter,
less likely to fall over if job is large and removes
pagination bug.
2019-09-24 19:07:20 +01:00
Katie Smith
79053dec93 Allow uploaded letters to be sent if valid
Added a send button which only appears on the page if the query string
indicates that the PDF is valid. Before actually sending, we check that
the service has the right permissions and that the metadata for the
letter confirms the letter is valid (because the query string can be
changed).
2019-09-12 09:54:36 +01:00