Commit Graph

416 Commits

Author SHA1 Message Date
Chris Hill-Scott
223b275507 Merge pull request #4010 from alphagov/refactor-duplicate-method
Refactor `get_simple_polygons` method for reuse
2021-11-15 11:21:50 +00:00
Chris Hill-Scott
0c2b586e40 Make organisations natively sortable 2021-11-11 14:59:06 +00:00
Chris Hill-Scott
8934e402e8 Make a model collection for organisations
This makes returning a user’s organisations consistent with how we
return their services.
2021-11-09 15:05:43 +00:00
Chris Hill-Scott
029682d561 Rename model to AllOrganisations
This makes it clearer that this model collection isn’t the organisations
for a user or a service or some other entity, like most model
collections are.

It will also lets us make a separate Organisations model, without the
name conflicting.
2021-11-09 15:05:42 +00:00
Chris Hill-Scott
cbbc58e649 Make a model collection for services
This is tidier than having a manual loop.
2021-11-09 15:05:42 +00:00
Chris Hill-Scott
9281ca7d50 Sort services and orgs in presentation layer
The model layer shouldn’t need to be concerned with sorting. For
services this means we can make a `SerialisedModelCollection` rather
than writing a manual loop.
2021-11-09 15:05:42 +00:00
Chris Hill-Scott
4d4c9c0db2 Make services natively sortable 2021-11-09 15:05:42 +00:00
Chris Hill-Scott
18d14a06fa Refactor get_simple_polygons method for reuse
This means we:
- don’t need to pass the areas around as an argument
- keep all the complexity of combining polygons from different areas in
  one method
2021-11-09 15:05:27 +00:00
David McDonald
c6b884dcef Upgrade utils to 48.0.0
Fixes a bug with non breaking spaces being removed from templates
2021-11-01 10:22:58 +00:00
Chris Hill-Scott
1334538cad Prefer cap_event to reference when referring to an alert
`reference` isn’t very human-friendly – the Environment Agency just
supply a UUID in this field.

The Environment Agency also populate the `<event>`` field with some
human readable text, for example:

> 013 Issue Severe Flood Warning EA

(013 is an ‘area code’ which will be meaningful to the Flood Warning Service team)

This commit changes the frontend to display the value of the `cap_event`
field, if it’s present, which is where the API stores the value of the
`<event>` field from the original CAP XML.

***

Depends on:
- [x] https://github.com/alphagov/notifications-api/pull/3344/files
2021-10-28 10:24:32 +01:00
Chris Hill-Scott
e675500ac2 Move branding info from model
This was an awkward property to have in a model class because
- it’s presentation not data about the object
- it munged together data from a different object, so it wasn’t well
  encapsulated

This commit moves the logic to the template, where it can reference the
`Organisation` and `User` models directly.
2021-10-26 18:14:09 +01:00
Chris Hill-Scott
72742cf477 Move unknown organisation logic into Jinja
Human readable content like this doesn’t really belong in the model
layer, it’s more natural to have it in the presentation layer.
2021-10-15 09:23:31 +01:00
Chris Hill-Scott
eefc903b25 Move ‘can’t tell’ message to Jinja
Human readable content like this doesn’t really belong in the model
layer, it’s more natural to have it in the presentation layer.
2021-10-15 09:23:31 +01:00
Chris Hill-Scott
d76dacc41e Move ‘agreement signed’ message into Jinja
Human readable content like this doesn’t really belong in the model
layer, it’s more natural to have it in the presentation layer.
2021-10-15 09:23:31 +01:00
Chris Hill-Scott
1ab83c48e3 Move request to go live notes into template
We can make the `as_agreement_statement_for_go_live_request` method less
complex by offloading some of the content it returns to the presentation
layer.
2021-10-15 09:23:31 +01:00
Chris Hill-Scott
ec703c5998 Add details of MOU signatory to go live ticket
This will help us monitor organisations that have signed our MOU using a
shared inbox and prevent it happening in future.

https://www.pivotaltracker.com/story/show/179782040
2021-10-15 09:23:30 +01:00
Katie Smith
39c26f5bfb Create go-live support tickets using the new way
The new way of creating support tickets can be seen in
[notifications-utils](https://github.com/alphagov/notifications-utils/pull/899).

This changes tickets created when making a request to go live to use
the new way, while other tickets stay the same for now.

The go live tags have been removed. Some of these had become
unneccessary since you can't make the request to go live unless they are
true (e.g. `notify_go_live_email_reply_to`). Others will always get
added by a Zendesk macro when the ticket is replied to, so we don't need
to add them here.
2021-09-22 12:00:05 +01:00
Leo Hemsted
9e915703fd fix contact list bst bug
the api returns UTC timestamps, we should keep them as UTC timestamps
until the very last moment, and only convert them into BST when we know
we want to return to a user (ie: in contact-list.html and other places
like that)
2021-09-15 15:12:13 +01:00
Ben Thorner
c694529d2d Fix incorrect log message for dodgy broadcasts
This was logging the number of keys in the whole JSON blob, rather
than the number of IDs specified within it.
2021-09-08 15:22:40 +01:00
Ben Thorner
85aeebcdd5 Support broadcasts with unidentifiable areas
The original code to raise the exception was flawed: if a broadcast
only had a single area that was invalid, we would assume it was a
custom broadcast [1]. Since the recent changes [2] fixed the flaw
we're now getting exceptions for broadcasts of this kind.

It's not practical to go and manually fix the invalid broadcasts,
and the likelihood is there will be more in future as the set of
areas we support changes. This takes a pragmatic approach of simply
logging the issue and pretending such broadcasts are custom.

[1]: 926ada2f21
[2]: https://github.com/alphagov/notifications-admin/pull/4014/files#diff-2dd8f77d6df281e7674b20263cdf27a3d58b839dc5930c0087ac8b9749b313e4R92
2021-09-08 14:05:18 +01:00
Ben Thorner
cf3f69199a Support new broadcasts (without area IDs)
Previously we relied on the API defaulting this field to an empty
array [1], but that conflicts with using it to decide whether a
broadcast is custom or created in this app.

[1]: 3779146cc5/app/models.py (L2342)
2021-09-06 12:40:32 +01:00
Ben Thorner
baf20e0075 Support broadcasts with no areas data
Previously we used to return an empty CustomBroadcastAreas object,
which doesn't make sense for broadcasts created in this app.
2021-09-06 12:40:31 +01:00
Ben Thorner
411fda81c0 Support custom broadcasts (without area IDs)
Custom broadcasts created directly via the API app won't have area
IDs since [1], where we started to distinguish between "names" (all
broadcasts have these) and IDs (for broadcasts created in this app).
We forgot to propagate the distinction into the code here.

This code fixes the bug for all broadcasts created after [1]. Any
custom broadcasts created before [1] will have their "ids" field set
instead of "names" so we won't show anything for them. This seems
reasonable as we don't support custom broadcasts yet.

[1]: 023a06d5fb
2021-09-06 12:40:30 +01:00
Ben Thorner
4bae4eec6c Start sending aggregate area names to API
The aggregate names don't need to be sorted, but it helps to do
this for the tests, since the implementation of sets may not be
stable between machines and lead to sporadic test failures.

I did also toy with sorting granular area names so they have a
similar ordering, but this would take them out-of-order with IDs
and really the important thing is that the ordering is stable.
2021-09-02 12:59:18 +01:00
Ben Thorner
cfdd244325 Complete migration to new "areas" API format
Depends on: https://github.com/alphagov/notifications-api/pull/3314

Previously:

- We introduced a new "areas_2" API field that's can
populate the "areas" column in the same way.

- We updated the Admin app to use the new field, so that
the old "areas" and "simple_polygons" API fields are unused.

- We repurposed the unused "areas" API field to use
the new "areas_2" format.

This PR:

- We can switch the Admin app back to the "areas" field,
but in the new format.

Future PRs:

- Remove support for the unused "areas_2" field (migration complete)
2021-08-27 14:34:49 +01:00
Ben Thorner
9667433b7e Add temporary command to migrate data for "areas"
This will be run with a CSV of all broadcast messages. Since very
few users are creating or updating broadcasts, it's highly unlikely
we'll encounter a race condition during the update.
2021-08-26 13:08:05 +01:00
Ben Thorner
7dbe3afa19 Include area names in data we send to API
These will be used as a fallback for display in gov.uk/alerts. It
also helps to have them in the DB to aid in quickly identifying
where an alert was sent, which is hard from the IDs.

We will look at backfilling names for past alerts in future work.
2021-08-26 12:49:54 +01:00
Ben Thorner
ae7f23d4cb DRY-up sending area updates to the API 2021-08-26 12:49:53 +01:00
Ben Thorner
73f31ef2fd DRY-up getting and setting area_ids
Previously we just held the new area_ids in memory. Setting them
on the object means we can reuse its functionality to get polygons
and also avoids confusion if in future we try to continue using
the object after calling "add_areas" or "remove_areas".
2021-08-26 12:49:52 +01:00
Ben Thorner
11cbee5843 Switch to using temporary "areas_2" API field
Depends on: https://github.com/alphagov/notifications-api/pull/3312

This is part of a multi-stage migration where we want to repurpose
the "areas" field in the existing API to something like "areas_2".
2021-08-26 11:01:56 +01:00
Ben Thorner
de9d1f991b Stop saying "areas" when we mean "area_ids"
"areas" normally means an instance of BroadcastArea or similar, so
we should be more accurate to avoid confusion.
2021-08-26 11:01:35 +01:00
Ben Thorner
d2784d0d8a Rename "parents" methods to "ancestors"
Resolves: https://github.com/alphagov/notifications-admin/pull/3980#discussion_r694002952

A grandparent is not a parent, so the return value of these methods
were misleading. This makes it clearer.
2021-08-23 16:50:18 +01:00
Chris Hill-Scott
5c1920fc20 Remove old method of updating email_access_validated_at
Previously we were passing a flag to the API which handled this. Now
we are doing it at the time of clicking the link, not at the time of
storing the new password. We don’t need to update the timestamp twice,
so this commit removes the code which tells the API to do it.
2021-08-19 11:14:47 +01:00
Chris Hill-Scott
cb59413581 Update email_access_validated_at on link click
When someone uses a fresh password reset link they have proved that they
have access to their inbox.

At the moment, when revalidating a user’s email address we wait until
after they’ve put in the 2FA code before updating the timestamp which
records when they last validated their email address[1].

We can’t think of a good reason that we need the extra assurance of a
valid 2FA code to assert that the user has access to their email –
they’ve done that just by clicking the link. When the user clicks the
link we already update their failed login count before they 2fa. Think
it makes sense to handle `email_access_validated_at` then too.

As a bonus, the functional tests never go as far as getting a 2FA code
after a password reset[2], so the functional test user never gets its
timestamp updated. This causes the functional tests start failing after
90 days. By moving the update to this point we ensure that the
functional tests will keep passing indefinitely.

1. This code in the API (91542ad33e/app/dao/users_dao.py (L131))
   which is called by this code in the admin app (9ba37249a4/app/utils/login.py (L26))
2. 5837eb01dc/tests/functional/preview_and_dev/test_email_auth.py (L43-L46)
2021-08-19 11:14:47 +01:00
Chris Hill-Scott
196da2b1b7 Reduce expiry time to 22 hours 30 minutes
Theoretically the maximum expiry time of a broadcast should be 24 hours.
If it goes over 24 hours there can be problems.

However we want to make it more conservative to mitigate two potential
issues:

1. The CBC has a repetition period (eg 60 seconds) and a count (eg
   1,440). If these were slightly innaccurate or generous it could take
   us over 24 hours. For this reason we should give ourselves half an
   hour of buffer.
2. It’s possibly that the CBC could interpret a UTC time as BST or vice
   versa. Until we’re sure that it’s using UTC everywhere, we need to
   remove another whole hour as buffer.

In total this means we remove 1 hour 30 minutes from 24 hours, giving an
expiry time of 22 hours 30 minutes.
2021-08-10 13:41:03 +01:00
Chris Hill-Scott
8ff7fecf40 Expire test and operator alerts after 4 hours
While testing alerts on these channels the MNOs sometimes need to
restart their CBCs to make sure everything is failing over properly.

If the CBC does not come back up, for whatever reason, then we are left
in a state where the alert can’t be cancelled.

To minimise the impact to the public in this scenario we should keep the
expiry time at 4 hours for alerts sent on test channels. We recently
increased it back up to 24 hours for all channels, so this in effect is
reverting that change for channels that won’t be used in a real
emergency.
2021-08-09 15:15:58 +01:00
Chris Hill-Scott
5e1b96a3a7 Remove argument unpacking from get_areas
Making it only callable in one way is just less stuff to understand.
2021-08-06 13:28:40 +01:00
Chris Hill-Scott
6c766c24b6 Ensure that phones are only counted once
The page which shows the count of phones does some logic based on how
close the ‘will get’ and ‘likely to get’ numbers are. This means it
accesses the `BroadcastMessage.count_of_phones` and
`BroadcastMessage.count_of_phones_likely` properties multiple times.

These properties are computed fresh every time, and are quite expensive
to compute. By caching them in memory we can cut the page load time
approximately in half.
2021-08-06 13:28:40 +01:00
Chris Hill-Scott
2446e97753 Revert "Reduce default broadcast expiry time" 2021-07-30 09:39:08 +01:00
Ben Thorner
dcfff87cc0 Continue to remove "roles" terminology
This renames the two functions we have to translate between UI and
DB permissions, as well as some of their associated variables to
make it clearer which kind of permission they contain.
2021-07-28 12:37:17 +01:00
Ben Thorner
ba9865e62e Start to remove use of the term "roles"
We don't use this term consistently and it's not defined anywhere.
Since most of the Admin app deals with user-facing permssions, it's
OK to just use the term "permissions". Where both types of permission
are present in the same file, we can more clearly distinguish them
as "UI permissions" and "DB permissions".
2021-07-28 12:37:16 +01:00
Ben Thorner
1127a03c32 Move and rename roles_and_permissions.py
This file does not represent a model, but rather a set of utilities
that are specific to user permissions (vs. service permissions).
2021-07-28 12:36:40 +01:00
Chris Hill-Scott
b71f0c6795 Disambiguate sent and created
At the moment we say that you either ‘add’ an alert or ‘send’ it.

This is confusing because:
- an alert isn’t received on people’s phones until it’s approved, so
  this is really when it is ‘sent’ conceptually
- an alert can be rejected before anyone receives it, so the UI can say
  an alert that no-one ever received was sent

This commit re-labels things so that the the first part of the process
is ‘creating’ the alert.

This makes all the permissions nice and distinct from each other. Adding
templates and adding alerts feel conceptually quite different things
(what are you adding the alert to?).
2021-07-23 10:07:05 +01:00
Chris Hill-Scott
694d7cc2ff Split the templates permission out again
It will likely be the same people who have permission to create alerts
and edit templates (maybe someone in a comms role).

But combining the two permissions makes the options presented in the
form feel clunky because ‘alerts’ and ‘templates’ are conceptually quite
different.

So I think it makes sense to keep the templates permission the same as
it is for regular Notify services.
2021-07-23 10:07:04 +01:00
Ben Thorner
832422fc66 Replace "admin roles" with "ui permissions"
In response to: [1].

While this does introduce a new term ("admin roles" is still used
elsewhere in the code), I plan to fix this in a follow-up PR (it
turned out to be quite a big change to do on this branch).

[1]: https://github.com/alphagov/notifications-admin/pull/3970#discussion_r673292339
2021-07-21 16:19:56 +01:00
Ben Thorner
9fafc092f7 Audit permissions when adding a user to a service
This is useful information to store for the event, which would be
lost if someone subsequently changed them.

Rather than updating lots of mock assertions, I've replaced them
with a single test / assert at a lower level, which is consistent
with auditing being a non-critical function.
2021-07-21 15:32:04 +01:00
Ben Thorner
171f911237 Audit when user permissions are changed
I've used the term "admin_roles" in the event data to try and show
that these are not the permissions we store in the DB. This is the
name we use for the abstracted form of permissions in the Admin app.
While we could store the DB permissions, that would be a bit more
effort and arguably it's clearer to keep the event data consistent
with the options the user actually saw / chose.
2021-07-21 15:32:03 +01:00
Ben Thorner
2241b119b0 Split (has_)permissions_for_service method
This avoids duplicating the code to get user permissions ("admin
roles") for a service, which we'll need in the next commit.
2021-07-21 15:32:02 +01:00
Ben Thorner
0f87ffe093 Move inline import to top of file
Usually we have imports at the top. It looks like the reason for
them being inline was to avoid a circular import, but we can also
avoid this by not importing everything from the app module.

Since we're about to add more imports from event_handlers, now is
a good time to refactor them. Note this matches how we import the
event handlers in every other module.
2021-07-21 15:32:01 +01:00
Katie Smith
a84705f834 Update the broadcast roles
We've added new broadcast roles in the database (`create_broadcasts` and
`approve_broadcasts`).

Adding these has meant we've needed to do a bit of a rewrite of the roles and
permissions code since this had been based on the assumption that each
database permission only belongs to one admin role - this is no longer true.
This means that flipping the roles dict round to create a dict which
contains database permissions as the keys is no longer possible. We can't
necessarily tell which admin role someone has given a database permission.

To check if a user has an admin role given a list of database permissions,
the user must now have ALL the database permissions mapped to that role
(instead of just one). This works because no one has the `manage_users`
permission without also having the `manage_settings` (and similar for
the other admin roles which map to multiple database permissions).

Some test data was changed because it was using admin roles where
database permissions are actually used when the app is running. I've kept
the functionality of the `translate_permissions_from_db_to_admin_roles`
function passing through any unknown roles it is passed as an argument.
This is not necessary, so can be changed later if we decide it will not
ever be used. However, removing it would require updating a lot of
tests since the tests rely on this behaviour.
2021-07-19 14:40:13 +01:00