Commit Graph

216 Commits

Author SHA1 Message Date
Chris Hill-Scott
e155794cbc Merge pull request #3333 from alphagov/uploads-page-ready
Redesign the uploads page to accommodate different kinds of uploads
2020-03-03 13:44:38 +00:00
Chris Hill-Scott
b1a97b0d69 Implement __radd__ on ModelList to make addition commutative
Because ModelList implements `__add__` we can do the following:

```python
ImmediateJobs() + ScheduledJobs()
ImmediateJobs() + []
```

Both of these call the `__add__` method of `ImmediateJobs`.

What we can’t do is this:
```python
[] + ScheduledJobs()
```

That tries to call the `__add__` method of list, which doesn’t know what
to do with an instance of `ModelList`.

The Pythonic way to deal with this is to implement `__radd__` (right
add) which is invoked when our instance is on the right hand side of the
addition operator.
2020-03-03 10:11:42 +00:00
Chris Hill-Scott
408fcf05eb Add financial year filter
Otherwise this page will become less useful come April 1st…
2020-02-28 12:46:50 +00:00
Chris Hill-Scott
ee8436ca85 Differentiate between different kinds of uploads
Knowing what kind of upload a thing is is useful.

And the information that is useful to show about each upload depends on
what kind of upload it is.
2020-02-27 17:34:51 +00:00
Chris Hill-Scott
eed5e0fdd7 Combine scheduled and already-sent jobs
I’m hoping that if I can design something that clearly differentiates
them then we won’t need to do so by putting them in separate tables,
which then need labelling, which would clutter up the page.
2020-02-27 17:33:41 +00:00
Chris Hill-Scott
f9310dd2ed Use template_type property directly from API
It’s included in the job/upload response now[1]. So we don’t need to
fetch the template every time we want to access it.

1. https://github.com/alphagov/notifications-api/pull/2728
2020-02-27 16:46:51 +00:00
Rebecca Law
4b11d776ee Add usage stats to organisation page. 2020-02-26 13:24:18 +00:00
Chris Hill-Scott
f369f76ae4 Count recently-returned letters on the dashboard
Currently you have no way of getting to the returned letter page. This
commit adds a link to it from the dashboard, following the pattern of
the new received text messages banner.
2020-02-20 11:58:57 +00:00
Chris Hill-Scott
74e70ed8bc Refactor summaries into model
This lets us encapsulate some of the logic that’s currently cluttering
up the view/template layer.
2020-02-20 11:58:57 +00:00
Pea Tyczynska
3a93fe6892 Fix reset password flow
It was broken because of mismatch in update password argument
2020-02-18 14:50:27 +00:00
Pea Tyczynska
caf77341b3 Send 2fa email and move user to waiting page when they need to re-validate email access 2020-02-17 11:34:24 +00:00
Rebecca Law
039628cff7 Reorder the methods called in sign out
We found another scenario where signing out of the db can cause a 500.
If the user archives their trial mode service, current_service.active = false, then signs out, the current user was being signed out client side first, meaning current_user is now an Anonymous user, next the call to the API is made to log out user on db, all calls to NotifyApiClient `check_inactive_service`, which is only authorised if user is platform_admin, but an AnonymousUser does not have that attribute, so a 500 is raise.
Seemed a bit cleaner to change the User.signout method to rather than the `check_inactive_service` method for current_user.is_authenticated.
2020-02-05 15:58:15 +00:00
Pea Tyczynska
9ebd18ea85 Add upload_type property to Job class 2020-02-04 15:36:55 +00:00
Rebecca Law
0e1ee504ac - Add unit test for when case when the cookie doesn't match the db.
- Move code into User.signout method to further encapsulate the code.
2020-02-03 15:08:55 +00:00
Rebecca Law
937c9f2adc Ensure that the session is logged out server side, not just client side.
Anytime a user clicks "sign out" we should be signing them out server side as well. This can be accomplished by setting the Users.current_session_id = null.
I found that the method User.logged_in_elsewhere doesn't need to check if the current_session_id is None. The current_session_ids in the cookie and db (redis or postgres) then the user should be forced to log in again.
2020-02-03 12:24:02 +00:00
Chris Hill-Scott
da2bc29b40 Merge pull request #3263 from alphagov/fix-new-jobs-showing-as-deleted
Use time to determine why notifications don’t exist
2020-01-24 15:27:29 +00:00
Pea M. Tyczynska
ba6b412bca Merge pull request #3268 from alphagov/proper-form-for-letter-branding
Parametrise branding request flow so it serves both email and letter branding
2020-01-23 16:50:41 +00:00
Leo Hemsted
5bbbdc3cd9 fix xss with service letter contact blocks
service contact blocks contain new lines - and jinja2 normally ignores
newlines (as in it keeps them as new lines) - but we need to turn them
into `<br>` tags so that we can show the formatting that the user has
added. We were previously just doing `{{ block | nl2br | safe }}`. nl2br
turns the new lines into `<br>` tags, and then `safe` tells jinja that
it doesn't need to escape the html.

this causes issues if the user adds `<script>alert(1)</script>` to their
contact block (or some other evil xss hack), where that will get let
through due to the safe flag

To solve this, use `Markup(html='escape')` to sanitise any html, and
then convert new lines to <br>.

bump utils

another xss
2020-01-21 17:34:49 +00:00
Pea Tyczynska
02cb6c9c38 Create a letter branding request flow to match email branding request
Test if service settings links to branding request page for letters

Parametrize all branding tests so they also work for letter branding
2020-01-21 16:47:14 +00:00
Chris Hill-Scott
291734b0c4 Merge branch 'master' into fix-new-jobs-showing-as-deleted 2020-01-21 14:24:40 +00:00
Chris Hill-Scott
f6a263a7b2 Rename property to more accurately describe purpose
`recently_created` says it would just be looking at the `created_at`
field to see if it's been created recently. Technically this method
isn't doing that, whilst its behaviour would be similar, it's actually
different and maybe therefore a bit misleading.
2020-01-21 14:07:23 +00:00
Chris Hill-Scott
d93866bc7e Use utils function to parse datetime strings
Rather than hard-coding a format string in a bunch of different places
we can use the function we already have in utils.

This commit also refactors some logic around password resets to put the
date-parsing changes in the most sensible bit of the codebase, so it’s
clearer what the intention of the view-layer code is.
2020-01-21 13:55:57 +00:00
Chris Hill-Scott
0202f73f9a Remove job_status from allowed properties
We can’t guarantee it’s always present, so shouldn’t allow direct access
to it.
2020-01-20 16:47:09 +00:00
Chris Hill-Scott
32105b3328 Don’t assume jobs status will be present
The API response for jobs includes a field called `job_status`. The API
response for uploads doesn’t.

The `Job` mode handles uploads and jobs, so it needs to account for the
possibility of the field not being there.
2020-01-20 15:25:47 +00:00
Chris Hill-Scott
87b2686875 Use time to determine why notifications don’t exist
Notifications won’t exist for a job if:
- it’s just started
- it started a long time ago (older than the retention period)

We have a bug where:
1. Job starts processing, puts notifications on queue
2. Job finishes processing, sets status to `finished`
3. First notification gets picked up off the queue and put in the
   database

In between 2. and 3. it’s possible for a job to be finished, but also to
have no notifications. We’re saying this is because the notifications
have been deleted, whereas really it’s because they haven’t been created
yet.

This commit fixes that bug by introducing the concept of recency for
jobs.

‘Recent’ is defined as 1 day, which is:
- a lot longer than it takes to create any notifications
- a bit shorter than anyone’s retention time

N.B. `processing_started` is defined here:
879ba1d5f0/app/models.py (L1194)

It can be `None` for scheduled jobs that haven’t started yet.
2020-01-17 13:27:20 +00:00
Chris Hill-Scott
a5fe50ce72 Merge pull request #3262 from alphagov/rename-model-property
Rename `client` property on `ModelLists`
2020-01-17 11:08:08 +00:00
Chris Hill-Scott
fa4fd1c896 Account for missing scheduled for field
Jobs have a `scheduled_for` field. Single letter uploads don’t.

At the moment we treat both of them as `Job`s. So the `Job` model needs
to account for when the `scheduled_for` field is missing.
2020-01-17 10:01:39 +00:00
Chris Hill-Scott
67b3619229 Remove redundant redefinition of __init__
At some point we made the __init__ method on the base class accept
`*args` as an argument, so we don’t need to define our own method here.
2020-01-16 16:34:49 +00:00
Chris Hill-Scott
c4818eb7f2 Rename property on ModelLists
The property doesn’t represent the whole client, but just one method on
it. So this commit renames the property to better describe what it is
designed to store.
2020-01-16 16:31:20 +00:00
Chris Hill-Scott
cbf0d905e3 Remove duplicative notifications_processed property
It returned the same value (and had the same code as
`.notifications_sent`).

I think `.notifications_sent` is a better name because it’s closer to
the language (‘sending’ and ‘sent’) that we use in the interface.
2020-01-16 15:40:49 +00:00
Chris Hill-Scott
fda979a5f2 Refactor again 2020-01-13 15:10:21 +00:00
Chris Hill-Scott
2f6a8a5864 Refactor stats calcualtions 2020-01-13 15:10:19 +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
Chris Hill-Scott
340cb33fdd Refactor ‘finished’ to the model layer
By moving it from the view we reduce the complexity of the methods in
the view layer, so it’s easier to see what they do.

This also renames the variable `finished` to the property
`processing_finished` to disambiguate from the `job_status` field in the
JSON, which can also have a value of `finished`.
2020-01-13 15:10:14 +00:00
Chris Hill-Scott
25464a141b Use a ModelList for lists of jobs
This follows the pattern of what we’ve done with services, users and
events.

It gives us a way of neatly instantiating a model for each item in the
list we get back from the API and reduces the complexity of the view
layer code.

Now is a good time to do this because we’re going to be making a bunch
of changes to the jobs pages, and those changes will be easier to code
and understand with a sensible model behind them.
2020-01-13 15:10:10 +00:00
Chris Hill-Scott
5e7ec3e30d Make a job model for individual jobs
This follows the pattern of what we’ve done with services, users and
events.

It gives us a better interface to the data we get back from the API than
dealing with the raw JSON directly.

Now is a good time to do this because we’re going to be making a bunch
of changes to the jobs pages, and those changes will be easier to code
and understand with a sesnsible model behind them.
2020-01-13 13:05:35 +00:00
Chris Hill-Scott
12b7c5d5e8 Remove notify_go_live_incomplete tag
The new taxonomy doesn't have a `notify_go_live_incomplete` tag. We
replaced this with `notify_go_live_incomplete_mou` because the only way
users can submit an incomplete request is if they do not agree to the
MOU.

These are the incomplete tags:

- `notify_go_live_incomplete_mou`
- `notify_go_live_incomplete_reply_to`
- `notify_go_live_incomplete_shared_email`
- `notify_go_live_incomplete_templates`

Of those, only the first one is applied automatically.
2019-11-19 16:42:25 +00:00
Chris Hill-Scott
7a5d301104 Update Zendesk tags to reflect new taxonomy
Requests to go live and email branding requests come through to Zendesk
with tags attached automatically.

With the revised taxonomy some of these tags need to be updated, as
summarised in this spreadsheet.

In addition, `notify_action` tag has to be added in each of those cases.

Old|New
---|---
`notify_request_to_go_live_complete`|`notify_go_live_complete`
`notify_request_to_go_live_incomplete`|`notify_go_live_incomplete`
`notify_action_add_branding`|`notify_branding`
`notify_request_to_go_live_incomplete_mou`|`notify_go_live_incomplete_mou`
`notify_request_to_go_live`|`notify_go_live`

– https://docs.google.com/spreadsheets/d/1o5ATsFsVK8Qpj7x8QvxX-SfEuBZ75028GEySVcdBFYU/edit#gid=0https://www.pivotaltracker.com/story/show/169842970
2019-11-19 15:46:29 +00:00
Chris Hill-Scott
554a852e2d Don’t return UUID objects from the UUID convertor
Because it means you often have to cast to string in your application
code just to get your tests passing.

The method being monkey patched is originally defined here: b81aa0f18c/src/werkzeug/routing.py (L1272)
2019-11-07 13:46:24 +00:00
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
7eb547a9e8 Put upload letters button on jobs page
This is going to become the one true ‘Uploads’ page, so it need the
sticky footer that takes users into the new upload letters journey.
2019-10-25 12:48:30 +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
d93ebd99d3 Refactor history off the service model
Directly referencing the `ModelList` instances will let us more easily
make choices at the view layer about which kinds of events to show, and
is one less layer of indirection to jump through.
2019-10-23 13:08:06 +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
7c2ecfa094 Use service model for history
Rather than have the view layer interact directly with the API client.
This will let us add extra transformation in the model layer at some
point.
2019-10-21 16:29:06 +01:00
Chris Hill-Scott
78e57dbff9 Clear service cache for when updating org branding
Updating an organisation’s branding might now also update the branding
of services associated to that organisation. This is similar to how
updating an organisation’s type can update the organisation type for its
services.

In the latter case we already make sure to clear the cached version of
these services which is held in Redis.

This commit does the same clearing of the caches when updating an
organisation’s branding (and does a bit of refactoring to do so without
duplication of code.)
2019-10-03 12:10:53 +01:00
Chris Hill-Scott
20f857753a Use constants for organisation type
This reduces the chances of making a typo, because doing so will raise
an exception rather than fail silently.
2019-09-16 11:33:50 +01:00
Chris Hill-Scott
077dc194c6 Tell people to change their branding
In some cases it’s not appropriate for teams to have GOV.UK branding.
But they all start with it by default, if we can’t make a better guess.
We should be more explicit about this to reduce the number of teams
sending emails with the wrong branding.
2019-09-16 11:21:28 +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
Chris Hill-Scott
29a0611e42 Refactor organisation branding into model
This is the same way we handle lazy-loading the branding in the service
model.
2019-09-16 11:02:34 +01:00