This isn't used and showing priorities when we only have a single
provider or where they have no effect is unnecessarily confusing.
Removing the form makes it clearer that there's only one way to
adjust priorities for domestic SMS providers.
If we add another email or international SMS provider in future,
we would need to rewrite the form here anyway as the priorities
need to be adjusted in tandem, not individually.
This made it easier to debug a problem with the functional tests
due to the fixtures not working correctly [^1]. It's a platform
admin only convenience over knowing the page URL.
We may want to expose the top-level "/api-integration" page but
that will require more work to show which broadcasts were sent with
which key - currently it's oriented around "messages". For now I
think it's useful to see what keys a service has.
[^1]: https://github.com/alphagov/notifications-functional-tests/pull/411#pullrequestreview-920069799
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
So we do not have to go into the db when we need to change user
auth.
We do not allow this for users who use webauthn. We do not want to
enable security downgrade for those users.
The endpoint to change the email branding to "GOV.UK" branding and
"GOV.UK and organisation" branding was the same but with a query string
used to determine which of the two options had been selected. This makes
them two separate endpoints, which makes the code a bit simpler and
hopefully means there is less chance of things not working as expected.
We were showing the form to request email branding with a button which
submits your choice immediately. Now, we only submit the form
immediately if "Something else" is the only branding option available to
you. If you select any other radio button (or select "Something else"
when it's not the only option) we take you to another page which either
contains more information or a textbox to fill in the details for the
branding you want.
There is currently some duplication between the new pages and their
tests, but these will be changed in future versions of the work so will
start to differ more.
The endpoint used to handle both email and letter branding, but this
replaces `.branding_request` with `.email_branding_request` and
`.letter_branding_request` instead. This is in preparation for changing
how email branding works.
The `from_template` arg was only possible for letter branding, so I've
removed that from the `.email_branding_request` endpoint.
This adds a link next to the organisation team members which lets
them be removed from the organisation. Service team members have
their own page and the link to remove them appears there. For
organisation team members, we don't currently have any other
information we want to show or any other actions to perform. As
a result, this change uses the 'Team members' page to show the
confirmation banner.
The endpoint called 'edit_user_org_permissions' was renamed to
'edit_organisation_user' and some of the existing code around deleting
org users (which didn't work) was changed.
Note that this is copied from the same change made to the rename service
page:
1190e4541b
The original idea behind was to always ask users to re-enter their
password any time:
- we want them to be sure that they want to do what they’re about to do
- we want to be sure it’s really the user trying to do the thing (and
not someone malicious)
In reality we:
- removed this from the initial place it was added (a descendent of the
‘suspend service’ feature)
- only ever added it to the ‘rename service’ and ‘rename organisation’
features
So in reality it’s not a pattern we have persisted with. Arguably there
are several things you can now do in the admin app without re-entering
your password which are much more high consequence than changing the
service name.
Also, with browser autofill there’s a lot less chance that forcing
someone to re-enter a password really gives much defence against an
unattended laptop, for example.
So this commit removes the need to re-enter your password when renaming
an organisation.
We want organisation team members to be able to see the MOU details for
their organisation. This change creates a new page called billing, which
contains these details. It's only visible to platform admin users now -
the plan is to add more information to this page, then to make it visible
to all organisation users.
The page showing the MOU covers the case of when agreement_signed is
True, when an agreement_signed is False, and when agreement_signed is
None. The case when an agreement_signed is None is very rare - it
signifies that the agreement is not signed but that we have some
service-specific agreements in place. We only have a few organisations
in this state, so it's unlikely that the content for this scenario will
be seen.
When an organisation has signed the agreement we may know the full
details (signing date, version signed, the person who signed it or who it
was signed on behalf of), or we may only have the name of the person who
signed the agreement. We show the more detailed content if possible, and
a less detailed version of the content if not.
There's a new route for downloading the agreement which is almost
identical to the existing `.service_download_agreement` route (plus the
test is almost the same), except that it takes an organisation ID
instead of a service ID.
The original idea behind was to always ask users to re-enter their
password any time:
- we want them to be sure that they want to do what they’re about to do
- we want to be sure it’s really the user trying to do the thing (and
not someone malicious)
In reality we:
- removed this from the initial place it was added (a descendent of the
‘suspend service’ feature)
- only ever added it to the ‘rename service’ feature
So in reality it’s not a pattern we have persisted with. Arguably there
are several things you can now do in the admin app without re-entering
your password which are much more high consequence than changing the
service name.
Also, with browser autofill there’s a lot less chance that forcing
someone to re-enter a password really gives much defence against an
unatteneded laptop, for example.
I also wonder whether we might get people to give better service names
if we make the process of renaming the service less intimidating.
So this commit removes the need to re-enter your password when renaming
a service.
Note that re-naming an organisation still has the same check, but I
haven’t removed that too for the sake of keeping scope of the PR small.
This is so org level users can use this data easier for things
like determining spending per service.
We do not include sms fragments sent column and remove other sms columns
consistency.
Do not add sms fragments sent column for now until we agree on an
unambiguous name for it. The data in this column is sms billing units
multiplied by international sms weighing. My favourite for a clear
name would be 'text message credits used', but we need a naming
strategy for this.
The flow of the code is roughly as follows:
user clicks button on webauthn page
js sends GET request
python reads GET request, sets up login challenge
python returns login challenge in response
js reads GET response, passes login challenge to browser
browser asks user to touch yubikey
browser returns yubikey challenge response data to js
js sends POST request with yubikey challenge response data
python reads yubikey challenge and compares with users creds from db
if its a match, python signs user in
The login challenge is a PublicKeyCredentialRequestOptions: [1]
The browser function we call is navigator.credentials.get(): [2]
The response to the challenge from the browser is a PublicKeyCredential: [3]
The python server does all the work setting those up and tearing them
back down again (and checking them against the values we have stored in
the database), but we need to do work to convert them to-and-from CBOR.
[1] https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialRequestOptions
[2] https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get
[3] https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential
if user has `webauthn_auth` as their auth type, then redirect them to an
interstitial that prompts them to click on a button which right now just
logs to the JS console, but in a future commit will open up the webauthn
browser prompt
content is unsurprisingly not final.
At the moment if you’re invited to a live broadcast service you get the
training mode tour. This is misleading, and could make people think they
weren’t in danger of sending a real alert.
This commit adds a short, 2 step tour for users invited to a live
broadcast service.
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
Only the test channel has the option to isolate messages to one network.
This commits makes the choices less confusing by only showing the
network choice to those who have selected the test channel.
It feels quite dangerous that it’s just one click to make an emergency
alerts service live.
This commit adds a confirmation step which explains the consequences of
what you’re about to do.
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.
For someone who has retrieved a template ID from their system the only
way to find it in Notify is:
- hack the URL
- click through every template, visually inspecting the ID shown on the
page until you find the right one
Neither of these is ideal.
This commit adds searching by ID, for those services who have an API
integration. This means we don’t need to confuse teams who aren’t using
the API by talking about IDs.
This is similar to how we let these teams search for notifications by
reference[1]
1. https://github.com/alphagov/notifications-admin/pull/3223/files
Previously each navigation class had a list of endpoint to "exclude",
which was only used in tests to ensure that all endpoints in the app
were covered: either they are present in navigation, or excluded.
However, over time the "exclude" lists have grown long and repetitive,
and maintaining each of them individually adds extra work [1][2]. This
switches to a more DRY approach, where the list of excluded endpoints
is defined once, close to the single point of use in the test.
Note the resulting test is _slightly_ less prescriptive, as it will now
pass if an endpoint exist one in navigation, even if it should also
exist in another. This seems a reasonable compromise.
[1]: https://github.com/alphagov/notifications-admin/pull/3788/files#r572809972
[2]: https://github.com/alphagov/notifications-admin/pull/3794/files#diff-39387df3a9f89b313976957e7b5457be20deab1017b2d895541b142b957f1972
The dashboard for normal services is quite general, because it tells
you a bit about channels, templates and spend.
What is now the dashboard for broadcast services is much more specific,
therefore less like a dashboard. We can reflect this by giving it a more
specific name. This should reduce the amount of navigation surfing
people need to do in order to find the thing they’re looking for.
Previous alerts are much less important than ones that are live or
waiting for approval.
Therefore we can make the dashboard more focused by moving previous
alerts to their own page.
Services doing broadcasts wont:
- incur costs, so don’t need to see the usage page
- be sending anything by uploading, so don’t need to see the uploads
page
- (for now) be sending anything using the API, so don’t need to see the
API integration page
We’ve done this already for services with the upload letters permission.
And all services can upload letters now.
But we’re still returning it in the JSON response we use to AJAX-ify the
page.
Since the jobs response can query stats for up to 50 jobs at a time this
puts some load on the API/database. Hopefully this might drop that load
a bit.
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.