Commit Graph

224 Commits

Author SHA1 Message Date
Kenneth Kehl
e884f31fa0 write test 2024-07-26 09:49:12 -07:00
Kenneth Kehl
34d727748b cleanup notify-compliance-46 2024-07-26 09:15:09 -07:00
Kenneth Kehl
058a999ed0 ugh 2024-07-11 09:38:32 -07:00
samathad2023
c3bb44129c tests and orderedset updates for 3.12 upgrade 2024-03-08 15:00:48 -08:00
stvnrlly
f600dd95d6 remove email branding 2023-12-18 16:10:12 -05:00
Kenneth Kehl
50ccd994d0 fix scheduled jobs time 2023-11-30 14:41:44 -08:00
Kenneth Kehl
90025ded54 notify-admin-866 improve tests with noqa comments 2023-10-26 08:33:59 -07:00
Carlo Costino
72c8a46b8c Reformatted a handful more tests
Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
2023-10-12 10:24:48 -04:00
Kenneth Kehl
8c9721d8e2 notify-api-412 use black to enforce python coding style 2023-08-25 09:12:23 -07:00
Kenneth Kehl
c6eb007386 merge from main 2023-08-25 08:57:24 -07:00
Carlo Costino
9e609efa1c Remove webauthn hooks
This changeset removes webauthn from the Notify.gov admin app.  We are not using webauthn at all in our implementation and will be looking at an entirely different authentication system in the near future.

Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
2023-08-14 16:59:38 -04:00
Steven Reilly
13d0e46b52 blunt rename of org (#620) 2023-07-12 12:09:44 -04:00
Ryan Ahearn
de668d7aba Remove contact-list references from code 2023-04-12 15:35:14 -04:00
Ryan Ahearn
2ad21a6f4f Replace UK phone numbers in tests with US numbers 2023-01-06 11:19:56 -05:00
stvnrlly
944715ac46 big commit with letters removal 2022-12-05 15:33:44 -05:00
stvnrlly
f16b5dd1c4 remove broadcast-related code 2022-10-04 03:04:13 +00:00
jimmoffet
69abec0bb3 change dashboard test to reflect demo changes to uploads view 2022-09-09 17:02:48 -07:00
Ryan Ahearn
d3fa9318ef Changes to make isort happy 2022-08-09 14:31:04 +00:00
jimmoffet
b465131338 all tests passing 2022-08-05 01:22:32 -07:00
Leo Hemsted
ebc005005b refactor: DRY up billing api client test
at the same time add the new daily_sms_provider_volumes_report func to
the tests.
2022-04-11 14:40:32 +01:00
Rebecca Law
de46fb6477 Merge pull request #4183 from alphagov/volume_reports
Report for total notifications sent per day for each channel.
2022-03-09 15:15:03 +00:00
Chris Hill-Scott
50015c3125 Pass admin URL to API for registration email
This follows the pattern for invite emails where the admin app tells the
API which domain to use when generating the link.
2022-03-07 15:11:50 +00:00
Rebecca Law
971cb745c9 Report for total notifications sent per day for each channel.
Daily volumes report: total volumes across the platform aggregated by whole business day (bst_date)
Volumes by service report: total volumes per service aggregated by the date range given.

NB: start and end dates are inclusive
2022-03-07 14:30:11 +00:00
Ben Thorner
3f2b760efb Remove redundant deletion decorators
These are superseded by the "_delete_template_cache_for_service"
call in each of these methods.
2022-03-07 13:54:00 +00:00
Ben Thorner
81d9c73543 Bump -utils to 55.0.0
This renames "delete_cache_keys_by_pattern" to match the new method
name, which will also catch exceptions if Redis is down [1].

Note that this also includes a change to RecipientCSV [2], which has
no effect because the new default is the same as the old behaviour.

[1]: https://github.com/alphagov/notifications-utils/pull/949
[2]: https://github.com/alphagov/notifications-utils/pull/947/files#diff-a8a994bf655634f89dc7439880708b4ff0d780ac1bd8033827d8aaa2692a8e0fR373
2022-03-07 13:53:57 +00:00
Chris Hill-Scott
70186dbe9f Pass admin URL to API when resetting password
This follows the pattern for invite emails where the admin app tells the
API which domain to use when generating the link.
2022-02-02 16:55:44 +00:00
Katie Smith
5b658d924c Tweak and add test for OrganisationsClient.remove_user_from_organisation
This stops adding the current user to the data sent to the API when
removing a user from an organisation. API only needs to know the
organisation_id and the id of the user we want to remove from
the organisation, so we don't need to pass through the id of the
current user too.

The other change made is to clear the user cache of the user who has
been removed from the org. We don't need to clear any of the organisation
caches, since these values don't contain lists of users for the orgs.
2022-01-13 14:08:37 +00:00
Chris Hill-Scott
a09af2acc8 Remove update_organisation_name model method
It’s weird to have a method just for updating one attribute. I think
the reason for doing this was to only invalidate the
`organisation-{}-name` cache when absolutely necessary, but:
- we don’t need a separate method to check whether it’s the name being
  updated
- it was easy to get around this by calling
  `OrganisationsClient.update_organisation` directly, leaving a stale
  value in the cache
2022-01-13 10:16:06 +00:00
Chris Hill-Scott
0706664be4 Stop using logged_in_client fixture
We have a `client_request` fixture which does a bunch of useful stuff
like:
- checking the status code of the response
- returning a `BeautifulSoup` object

Lots of our tests still use an older fixture called `logged_in_client`.
This is not as good because:
- it returns a raw `Response` object
- doesn’t do the additional checks
- means our tests contain a lot of repetetive boilerplate like `page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')`

This commit converts all the tests using `logged_in_client` to:
use `client_request` instead.
2022-01-10 14:39:44 +00:00
David McDonald
04fa99b3dc Update get_notifications_for_service to make POST requests
This updates the `get_notifications_for_service` of the
`NotificationApiClient` to make POST request to the api when the `to`
field is provided. This is done so that we avoid logging personal
details such as email addreses.

If the `to` field is not present, the method will make a GET reqeust and
there will be no change to how it works.
2022-01-04 11:14:16 +00:00
David McDonald
e7d8918f7f Refactor test assertions
Doing this to reduce the use of overly verbose `call()` to match
assertions in test_status_api_client.
2021-12-08 16:01:26 +00:00
David McDonald
20cc1e230f Reduce TTL to 1 hour for get_count_of_live_services_and_organisations
This stat is shown on a few of our pages, such as our homepage,
the performance page and also a platform admin page
and is currently catched for the
default TTL of 1 week. I think there is no reason we can't make
this only cache once an hour and give slightly more up to date stats
which will update more regularly.

This mimics the approach and also the TTL choice of 1 hour that has
been added for the performance page (although there is no
particular bug here to fix, it is just nice to have slightly more up
up to date data).

Note, the API call only takes about 0.3 seconds at the moment
so it is not particularly intensive on the DB to run this more
regularly.
2021-12-08 15:39:10 +00:00
David McDonald
6acc7838e2 Add tests for existing status api client
Essentially copies the tests found in the performance_platform
api client.
2021-12-08 15:36:28 +00:00
David McDonald
2767328e79 Reduce impact of stale cache for performance page
I came across a bug where the performance page might be visited
on say the 22nd and we expect it to show data for yesterday and
the past 7 days (so the 21st and back 7 days) but instead it
only shows it for the 20th and then back 6 days.

The cause is that we have nightly tasks that run to
calculate the number of notifications sent per service (the
ft_notification_status table)
calculate the number of notifications sent within 10 seconds
(the ft_processing_time table)
Both of these tables get filled between the hours of midnight and
2:30am. The first seems to be filled by about 12:30 every night
whereas the processing stats seems to be filled about 2am every
night.

The admin app currently caches the results of the call to the API
(https://github.com/alphagov/notifications-api/blob/master/app/performance_dashboard/rest.py#L24)
to get this data with the key
performance-stats-{start_date}-to-{end_date}.

Now the issue here is that if the performance page is visited at
00:01 on the 23rd, it will call the API for data on the 22nd and
backwards 7 days. The data it gets at 00:01 will not yet have the
data for the 22nd, it will only go as far as the 21st, because
the overnight jobs to put data in the tables have not run yet. The
admin app then caches this data, meaning that for the rest of the
day the page will be missing data for the 22nd, even though it
becomes available after approx 2am. We have seen it a few times
in production where the performance page has indeed been visited
before say 2 am, leaving the page with missing data.

In terms of solutions, there are several potential options.

1. Remove the caching that we do in redis. The downside of this is
that we will hit the API more (currently once a day for the first
visitor to the performance page). We have had 255 requests
to the performance page in the last week and when there is no value
in redis, the call to the API takes approximately 1-2 seconds.
Removing the caching would against why the caching was originally
added which was to act as a basic protection against malicious
DOS attempts.

2. Make the admin app only set the cache value if it is after
2:30am. This one feels a bit gross and snowflakey.

3. The API flushes the redis cache after it has finished its nightly
tasks. We don't have that much precedent of the API interacting
with redis, it is mostly the admin app that does but this is still
a valid option.

4. Cache in redis the data for 2 days ago to 7 days ago and then
get the data for yesterday freshly every time. This would mean
some things are still cached but the smallest bit that we can't rely
on can be gathered fresh.

5. Remove the caching we do in redis but then try and optimise the
API endpoint to return results even faster and with less
interaction with the DB. My hypothesis is that the slowest part
is where the API has to calculate how many notifications Notify
has ever sent
(https://github.com/alphagov/notifications-api/blob/master/app/performance_dashboard/rest.py#L36)
and so we could potentially try and store these totals in the DB
every night and update them nightly rather than having to query all
the data in the table to figure them out every time.

6. Reduce the expiry time of the cache key so although the bug will
still exist, it will only exist for a much shorter time.

In the end, we've gone for option 6. The user impact of
this bug sticking around for an hour is minimal, in particular
because that would be in the early hours of the morning. The solution
is also quick to implement and keeps the protection against a DOS attack.

The value of 1 hour for expiry was a fairly abitrary choice, it could
have been as little as 1 minute or as much as 6 hours.
2021-12-07 12:44:36 +00:00
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