Commit Graph

527 Commits

Author SHA1 Message Date
Chris Hill-Scott
fcc84ac514 Do extra code style checks with flake8-bugbear
Flake8 Bugbear checks for some extra things that aren’t code style
errors, but are likely to introduce bugs or unexpected behaviour. A
good example is having mutable default function arguments, which get
shared between every call to the function and therefore mutating a value
in one place can unexpectedly cause it to change in another.

This commit enables all the extra warnings provided by Flake8 Bugbear,
except for the line length one (because we already lint for that
separately).

It disables:
- _B003: Assigning to os.environ_ because I don’t really understand this
- _B306: BaseException.message is removed in Python 3_ because I think
  our exceptions have a custom structure that means the `.message`
  attribute is still present
2019-11-01 10:43:01 +00:00
Chris Hill-Scott
0185270308 Fix sorting of events
Events should be sorted reverse-chronologically, no matter what order
they come back from the API in, or which field in the API response
they’ve been extracted from.
2019-10-23 15:05:26 +01:00
Chris Hill-Scott
600e3affc1 Show user names for events without API changes
This commit introduces a slightly hacky way of putting usernames against
events, given that the API only returns user IDs.

It does so without:
- making changes to the API
- making a pages that could potentially fire off dozens of API calls (ie
  one per user)

This comes with the limitation that it can only get names for those team
members who are still in the team. Otherwise it will say ‘Unknown’.

In the future the API should probably return the name and email address
for the user who initiated the event, and whether that user was acting
in a platform admin capacity.
2019-10-23 13:15:41 +01:00
Chris Hill-Scott
63f6a3ab12 Let users filter by type of event
At the moment we have two types of event, ‘service’ events and ‘API key’
events. They are munged together which is useful initially, but could
get noisy.

This commit adds filters (copied from the choose template page) that let
users narrow down the list to one of the two types of event. This might
help users get a clearer picture of what’s going on.
2019-10-23 13:09:47 +01:00
Chris Hill-Scott
b2ebaf153a Chunk events by day
Scanning the page is difficult at the moment because it’s hard to tell
how far apart in time events are, and thereby determine which events
might be related.

Grouping the events by day quickly lets users narrow their focus to
a meaningful subset of the events.
2019-10-23 13:06:25 +01:00
Chris Hill-Scott
59b4d60c91 Munge stuff into a consistent event data type
We store our audit history in two ways:

  1. A list of versions of a service
  2. A list of events to do with API keys

In the future there could be auditing data which we want to display that
is stored in other formats (for example the event table).

This commit adds some objects which wrap around the different types of
auditing data, and expose a consistent interface to them. This
architecture will let us:
- write clean code in the presentation layer to display these events on
  a page
- add more types of events in the future by subclassing the `Event` data
  type, without having to rewrite anything in the presentation layer
2019-10-23 13:02:11 +01:00
Chris Hill-Scott
8db94eafc8 Use service-specific page template for history 2019-10-21 16:29:05 +01:00
Chris Hill-Scott
bda2f41aac Merge pull request #3125 from alphagov/faster-tests
Create the app once per run, not once per test
2019-09-20 10:33:44 +01:00
Chris Hill-Scott
1a353d90eb Create the app once per run, not once per test
Turns out our tests spent a lot of time recreating the app for each test
case, which is quite intense.

This commit makes the fixture sessions level, so the app is only created
once per test session, not once per test function.

This cuts down the time taken to run the test suite to about 50 seconds.

It also makes the tests more parallelizable. Before this change going
from 4 to 8 processes made the tests slower. Now it cuts them down from
about 50 seconds to about 35 seconds[1]. So this commit also lets Pytest
choose the best number of processes to run, since on my machine it
chooses 8, which is the fastest.

Overall this means the

1. With a 2.2GHz quad-core Intel Core i7 processor on a 2015 MacBook Pro
2019-09-18 15:58:25 +01:00
Chris Hill-Scott
6d0d10e8de Only show relevant choices of email branding
Users who work in local government can’t have GOV.UK branding on their
emails. And only those working for Companies House (for example) can
request the Companies House branding.

This commit adds:
- new choices of email branding, which offer the name of the branding,
  rather than the style
- logic to filter this list to only the applicable options, based on
  what we know about the user, service and organisation

This is a change from the previous approach which put the onus on users
to figure out the style of branding they wanted, when we might already
know that a lot of the options weren’t available to them, or would be
inconsistent with the branding of other services in their organisation.
2019-09-16 11:03:52 +01:00
Leo Hemsted
b69321bf7a rename logged_in_platform_admin_client to platform_admin_client
of course it's logged in, it's a platform admin

also, reduce use of the `client` fixture in test_platform_admin
(replace it with platform_admin_client)
2019-08-27 16:02:15 +01:00
Rebecca Law
e0bcad77f5 Remove ft from method name and url, it doesn't add any meaning. 2019-07-22 14:34:15 +01:00
Chris Hill-Scott
c17aa249dc Make query string comparison ignore order
Query string ordering is non-deterministic. This can cause tests to fail
in a non helpful way when we’re comparing two URLs. The values in the
query string can match, but the string won’t because the order is
different. This commit adds some code to split up the URL and check that
each part of it matches, rather than checking the thing as a whole.
2019-07-15 14:38:01 +01:00
Chris Hill-Scott
886992af17 Merge pull request #3043 from alphagov/add-first-letter-contact-experience
Make adding a ‘letter contact block’ for the first time make sense
2019-07-12 15:14:18 +01:00
Chris Hill-Scott
6d5f542a88 Count of orgs and live services for platform admin
This makes it consistent that an option which contains more options has
a hint about how many options it contains.

Also adds a formatter to get us ready for 1,000 services 🎉
2019-07-08 12:31:31 +01:00
Chris Hill-Scott
7fef51aa6a Apply sender to template when adding
If you’ve come from a template to add a new letter sender then it’s
because you want those words on that template. This commit adds the
extra API call to make that happen.
2019-07-08 11:20:28 +01:00
Chris Hill-Scott
3968d5b766 Allow org team members to see team and usage
Organisation team members will be ultimately interested in the detailed
usage of each service, but shouldn't necessarily have access to the
personal data of that services users.

So we should allow these organisation team members to navigate to live
services usage page from the organisation page. They may need to contact
the team so they should also be able to view the team members page.

So they'll then see just usage and team members pages.

If they are actually a team member of the service they're viewing, then
they'll see the full range of options as usual.

This commit implement the above by adding an extra flag to the
`user.has_permissions` decorator which allows certain pages to be marked
as viewable by an organisation user. The default (for all other existing
pages) is that organisation users don’t have permission.
2019-06-20 15:37:52 +01:00
Katie Smith
5f2c869a1c Show organisation breadcrumbs
Added a breadcrumb link to a service's organisation to the
withnav_template. This will only show if a service has an organisation
and the current user is also a member of that org, or the current user
is a platform admin user.

Also removed a couple of unused fixtures from the client_request
fixture.
2019-06-20 12:11:13 +01:00
Chris Hill-Scott
0aea038d51 Use new fields for getting orgs and services
Uses https://github.com/alphagov/notifications-api/pull/2539 to reduce
the number of API calls we make.
2019-06-17 15:56:59 +01:00
Leo Hemsted
d752a6335f make sure tests all populate the platform admin field
it's always returned by the API
2019-06-14 15:14:00 +01:00
Leo Hemsted
7b02cb72c6 add option to suppress platform admin temporarily
so that platform admins (us) can view pages as regular users do easily.
Simply adds a flag in the session cookie that overrides the actual
platform admin flag on the user model if set. This way it's safe, since
this only downgrades existing functionality, so if someone managed to
alter it they could only get less permissions, not more.

You can change this value from the user profile page if either:

* you're a platform admin
* the flag is set (to any value) on the cookie.

This slightly weird check means that we don't check the underlying
`user._platform_admin` flag anywhere in the code, even when toggling
the suppression.
2019-06-14 11:59:12 +01:00
Chris Hill-Scott
1b395c04f3 Go straight into org if no trial mode services
You might still belong to some services, but because they’re live
they’re all in your organisation.
2019-06-13 13:47:28 +01:00
Chris Hill-Scott
3be1f79cf9 Add count of live services to organisations
This makes it clear that these are something different to the trial
mode services, in that they are a container of multiple things.
2019-06-13 13:42:11 +01:00
Chris Hill-Scott
6130004b0c Fix inviting existing users
The API needs the id of the user, not the id of the invite.

The problem with the tests is that the update mock returned a different
user ID than the user it was being passed. So the tests didn’t catch
this.
2019-06-06 17:24:48 +01:00
Katie Smith
a6f5abbf7e Only show archive user link for active users 2019-06-06 11:50:28 +01:00
Chris Hill-Scott
f34a252e72 Remove defaults from User model
the api always returns exactly:
```
id
name
email_address
auth_type
current_session_id
failed_login_count
logged_in_at
mobile_number
organisations
password_changed_at
permissions
platform_admin
services
state
```

it does this through `models.py::User.serialize` – there is an old
Marshmallow `user_schema` in `schemas.py` but this isn’t used for
dumping return data, only parsing the json in the create user rest
endpoint.

This means we can rely on these keys always being in the dictionary.
2019-06-05 14:55:43 +01:00
Chris Hill-Scott
bd9acb1310 Make invited user model inherit from JSONModel
This is more consistent, and less fiddly that always having to call it
with a dictionary expansion.
2019-06-05 14:39:02 +01:00
Chris Hill-Scott
628e344b36 Make user API client return JSON, not a model
The data flow of other bits of our application looks like this:
```
                         API (returns JSON)
                                  ⬇
          API client (returns a built in type, usually `dict`)
                                  ⬇
          Model (returns an instance, eg of type `Service`)
                                  ⬇
                         View (returns HTML)
```
The user API client was architected weirdly, in that it returned a model
directly, like this:

```
                         API (returns JSON)
                                  ⬇
    API client (returns a model, of type `User`, `InvitedUser`, etc)
                                  ⬇
                         View (returns HTML)
```

This mixing of different layers of the application is bad because it
makes it hard to write model code that doesn’t have circular
dependencies. As our application gets more complicated we will be
relying more on models to manage this complexity, so we should make it
easy, not hard to write them.

It also means that most of our mocking was of the User model, not just
the underlying JSON. So it would have been easy to introduce subtle bugs
to the user model, because it wasn’t being comprehensively tested. A lot
of the changed lines of code in this commit mean changing the tests to
mock only the JSON, which means that the model layer gets implicitly
tested.

For those reasons this commit changes the user API client to return
JSON, not an instance of `User` or other models.
2019-06-05 11:13:41 +01:00
Chris Hill-Scott
8835486d4e Look in organisation for whitelisted domains
At the moment we have to update a YAML file and deploy the change to get
a new domain whitelisted.

We already have a thing for adding new domains – the organisation stuff.

This commit extends the validation to look in the `domains` table on the
API if it can’t find anything in the YAML whitelist.

This has the advantage of:
- not having to deploy code to whitelist a new domain
- forcing us to create new organisations as they come along, so that
  users’ services automatically get allocated to the organisation once
  their domain is whitelisted
2019-06-03 11:41:13 +01:00
Pea Tyczynska
ed599f0c03 Save new reply-to email if test notification delivered
Also check if it should be a default reply-to email address
2019-05-23 15:34:24 +01:00
Pea Tyczynska
45ac0d7812 Waiting page shows correct messages 2019-05-23 15:34:23 +01:00
Chris Hill-Scott
9d1a7904a8 Fix duplicated H1 on ‘New letter branding’ page
For accessibility reasons a page should have one (and only one) H1. This
commit fixes an instance where the H1 was duplicated as a result of the
work done to componentize our page headings.

It also adds an extra check to `client_request` so that we don’t
introduce pages with multiple or no H1s in the future.
2019-05-21 16:09:00 +01:00
Chris Hill-Scott
34171f3038 Fix order of placeholders in the tour
Doing a lookup with `step_index - 1` means that on step `0` we were
looking up `placeholders[-1]`, ie we were making people fill in the last
placeholder first.

Fixing this reintroduces the bug fixed by this pull request:
https://github.com/alphagov/notifications-admin/pull/2551

So this commit also re-fixes that bug but in a different way.
2019-05-03 13:29:23 +01:00
Chris Hill-Scott
9e238a4f87 Merge pull request #2923 from alphagov/dont-ask-org-type
Don’t ask for organisation type when we know it
2019-04-30 11:22:21 +01:00
Chris Hill-Scott
f726551714 Remove unused method
We use `.get_free_sms_fragment_limit_for_year()` instead, which
functionally is the same thing (has a default argument of `year=None`).
2019-04-24 13:10:41 +01:00
Chris Hill-Scott
08e9b35d7a Don’t ask for organisation type when we know it
Every time someone adds a new service we ask them what kind of
organisation they work for.

We can look this up based on the user’s email address now. So we should
only ask the question if:
- we don’t know about the organisation
- or we haven’t set what type of organisation it is (this shouldn’t be
  possible on productions because we’ve populated the column for all
  existing organisations and it’s impossible to add a new one without
  setting it
2019-04-18 14:08:13 +01:00
Chris Hill-Scott
116f36192f Let inviting a user complete the go live checklist
At the moment you have to wait for whoever you’ve invited to accept the
invitation before you can go live. Since this check is mainly for the
benefit of the service, not us, we should trust that people’s intentions
are good when they invite someone.

So this commit also checks the invited users when counting how many team
members a service has.
2019-04-12 22:45:48 +01:00
Chris Hill-Scott
8084dce705 Merge pull request #2896 from alphagov/remove-domains-yml
Use organisations from database rather than YAML file
2019-04-12 16:37:15 +01:00
Chris Hill-Scott
470b8a2912 Remove domains from branding forms
We’re deprecating storing the domain as text on a branding in favour of
a database relationship between branding and organisation.

We need to do this now in order to remove the validation on these fields
(which depends on the data in `domains.yml`)
2019-04-12 15:23:07 +01:00
Chris Hill-Scott
3565ffc33f Remove dependence on domains.yml from settings
Settings looked at `domains.yml` when users were making go live requests
or email branding requests.

This will allow us to remove the `domains.yml` file, by using
information about organisations that is now stored in the database
instead.
2019-04-12 15:19:31 +01:00
Chris Hill-Scott
98249158cb Stop trying to infer branding when adding services
The API handles this now.
2019-04-12 14:08:33 +01:00
Chris Hill-Scott
72f49a9a1e Remove dependence on domains.yml from static pages
This will allow us to remove the `domains.yml` file, by using
information about organisations that is now stored in the database
instead.
2019-04-12 14:05:00 +01:00
Chris Hill-Scott
9863aa3c48 Automate counting of live services and orgs
Returns the data calculated by the API. Stored in Redis against a
hardcoded key so that no-one hammering the home page is directly hitting
the database.
2019-04-12 13:59:33 +01:00
Alexey Bezhan
35fb92c02c Replace sevice api client get template calls with Service methods
Instead of using the API client directly views are now calling one
of two Service model methods:

`get_template` is used for view actions, where the user should see
the template page even if they don't have access to the template
folder (since all templates are still inked from the dashboard or
the sent notifications pages).

`get_template_with_user_permission_or_403` will check if the user
has access to the template's folder first and return 403 otherwise.
This method is used for any endpoints that result in an action: editing
template attributes, deleting templates or sending messages.
2019-04-01 10:50:38 +01:00
Chris Hill-Scott
936883bf7b Allow editing of an organisation’s details
Adds a user interface for updating all the columns added in
https://github.com/alphagov/notifications-api/pull/2368

Sorry for the mega commit 😓
2019-03-22 14:23:24 +00:00
Pea (Malgorzata Tyczynska)
307e959fd6 Merge pull request #2862 from alphagov/show-templates-across-user-folders
When replying to inbound sms show templates in all user's folders
2019-03-22 14:15:13 +00:00
Pea Tyczynska
3fc4f6866c When replying to inbound sms show templates in all user's folders 2019-03-21 16:06:47 +00:00
Katie Smith
c39f6d49ea Set folder permissions when creating and accepting invites to services
Added a folder permissions form to the page to invite users to services.
This only shows if the service has 'edit_folder_permissions' enabled,
and all folder checkboxes are checked by default. This change means that
InviteApiClient.create_invite now sends folder_permissions through to
notifications_api (so invites get created with folder permissions).

Started passing the folder_permissions through to notifications-api when
accepting an invite. This changes UserApiClient.add_user_to_service to
send folder_permissions to notifications_api so that new users get folder
permissions when they are added to the service.
2019-03-21 10:17:05 +00:00
Katie Smith
782bd34394 Use folder_permissions in the InvitedUser model
We were already invitializing InvitedUser with folder_permissions
(defaulting to None), but this removes the default and adds
folder_permissions to the serialize method. Folder permissions should
now always be returned from api, either as an empty list or a list of
UUIDs.
2019-03-21 10:17:05 +00:00
Chris Hill-Scott
d82f410325 Don’t allow editing of users from other services
Currently when you load the ‘edit user’ page (which has a URL like
`/service/<service_id>/users/<user_id>`) we check that:
- you belong to the service represented by `service_id`
- you have permission to edit users on this service

We don’t check that:
- the user represented by `user_id` belongs to this service

This means that if you could somehow determine another user’s `user_id`
(which I don’t think is possible if you don’t already have the manage
service permission for that service) then you could:
- edit their permissions on your service (weird, but wouldn’t have any
  effect)
- change their email address (bad)

This commit adds checks to return a `404` any time you’re looking at a
service and trying to do stuff to a user who doesn’t belong to that
service.

We can’t add this check to the API easily because there are still times
that we want to get/modify users outside the context of a service (eg
platform admin pages, or users who have no services).
2019-02-25 17:19:07 +00:00