Commit Graph

281 Commits

Author SHA1 Message Date
Chris Hill-Scott
545b485d86 Add URL converters for template and file types
Sometimes we manually check that a URL parameter is in a required set.
Sometimes we don’t bother.

This commit adds a URL converter to do this so that:
- we don’t have to re-write the same code every time
- it’s easier to apply this check to other endpoints

This means endpoints that previously allowed a `template_type` or
`message_type` of `None` now 404. So I’ve had to add new routes for
with URLs that don’t include such parameters.

So this…:
```
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/sms.csv
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/None.csv
```

…becomes:
```
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/sms.csv
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications.csv
```

This matches what we do for the HTML-responding equivalent (see
265931d217/app/main/views/jobs.py (L215-L216))
2019-11-07 13:48:09 +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
a765920f65 Add years to old dates
Just to disambiguate things without introducing unnecessary noise.
2019-10-23 13:18:58 +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
Tom Byers
f6a0026d67 Add extension initialisation in app init 2019-10-07 16:35:56 +01:00
karlchillmaid
535fb0e024 Replace doesn't with does not 2019-09-23 13:22:17 +01:00
Chris Hill-Scott
959dd6ac38 Make one method for comma-formatting numbers
We were doing this a few different ways in different places.
2019-07-08 14:46:34 +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
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
Leo Hemsted
4375c3d151 move to model based code layout 2019-05-28 16:46:12 +01:00
Chris Hill-Scott
3c6598cbc2 Only link to message status if message has failed
This retores the behaviour to as it was before
https://github.com/alphagov/notifications-admin/pull/2962
which inadvertently started linking to the guidance for messages that
were delivered or in sending.
2019-05-13 13:29:47 +01:00
Katie Smith
f3f8f4085f Fix broken links
There were still a few links pointing to `/features/using-notify`
2019-05-10 09:05:07 +01:00
Alexey Bezhan
7e0529b600 Fix missing space in current_user context processor 2019-04-01 10:50:39 +01:00
Chris Hill-Scott
cff009bc0d Run isort 2019-03-25 11:23:58 +00:00
Katie Smith
c675925fd1 Upgrade pyexcel-io, which also upgrades Werkzeug
Upgraded pyexcel-io from 0.5.14 to 0.5.16. This change causes Werkzeug
to be upgraded from 0.14.1 to 0.15.1 which requires some changes:

* ProxyFix now needs to be imported from a different location
* The status code of RequestRedirect has changed from 301 to 308. Since
status code 308 is not currently supported on Internet Explorer with
Windows 7 and 8.1, this subclasses RequestRedirect to keep the status
code of 301.

changelog: https://werkzeug.palletsprojects.com/en/0.15.x/changes/#version-0-15-0
2019-03-22 14:18:44 +00:00
Leo Hemsted
f6367f2278 move (non-api) clients (inc redis) from app/__init__.py to extensions
when clients are defined in app/__init__.py, it increases the chance of 
cyclical imports. By moving module level client singletons out to a 
separate extensions file, we stop cyclical imports, but keep the same 
code flow - the clients are still initialised in `create_app` in 
`__init__.py`.

The redis client in particular is no longer separate - previously redis 
was set up on the `NotifyAdminAPIClient` base class, but now there's one 
singleton in `app.extensions`. This was done so that we can access redis 
from outside of the existing clients.
2019-02-15 11:44:08 +00:00
Chris Hill-Scott
17c6446b85 Organise client initialisation
- groups them into sensible chunks
- alphabetises them
2019-01-30 13:45:05 +00:00
Chris Hill-Scott
e211fb7f60 Remove duplicative calls to init_app
Easier to read without the repetitive boilerplate.
2019-01-29 12:14:36 +00:00
Katie Smith
0bf3a4b16d Refactor to add separate letter branding client
We were getting all letter logos from a method in the email branding
client. Since we will be adding more client methods to deal with
letters, it makes things clearer to separate the email and letter
branding clients.
2019-01-29 11:37:27 +00:00
Chris Hill-Scott
5c4ff09d48 Treat permanent failure for letters the same as cancelled 2019-01-14 10:16:01 +00:00
Chris Hill-Scott
989875294b Make technical failure letters show up on the activity page 2019-01-11 16:55:37 +00:00
Katie Smith
bb7e9726d3 Stop showing validation-failed letters as cancelled in table
Changed the table for displaying all notifications to show letters which
have the status of 'validation-failed' as 'Validation failed' instead of
'Cancelled'.

The individual notification page for a letter which has failed
validation has not been changed since this already has a description
(letter has content outside the printable area).
2019-01-09 13:10:36 +00:00
Katie Smith
429a23934d Display cancelled letters show as failed
In the long term, we don't want to show cancelled letters. But for now,
this changes cancelled letters to display in the same way that letters
with a status of permanent-failure, since we are currently giving
letters that we want to cancel the status of permanent failure.
2018-12-05 11:03:59 +00:00
Chris Hill-Scott
dd711f51b3 Fix asset path in asset fingeprinter
The asset fingerprinter was hard coded to always point to `/static`.

It needs to change depending on which environment the app is running
in.
2018-11-29 13:14:52 +00:00
Chris Hill-Scott
23cc182b6f Get config from current app 2018-11-29 12:07:48 +00:00
Chris Hill-Scott
bc6b9c7af7 Use named arguments for clearer string formatting
Helps when the string is long.

Also helps disambiguate between the CDN domain used for the logos and
those for CSS/JS.
2018-11-29 11:56:01 +00:00
Chris Hill-Scott
fe6610c221 Fix content security policy for the CDN
The CDN URLs aren’t in included in the content security policy. So
browsers will refuse to load them.

This commit:
- adds each of the CDN URLs to the
- only prepend URLs in CSS files with `/static/` if we’re running
  locally (because the CDN URLs are like `static.example.com` not
  `example.com/static`)
2018-11-29 11:29:52 +00:00
Chris Hill-Scott
b1c0778bde Since moving to putting the admin app on Cloudfront anything on the
`www.notifications.service.gov.uk` domain is:
- not gzipped

The PaaS proxy used to GZip and set headers for anything served from a
path starting with `/static/`:
76dd511a8a/ansible/roles/paas-proxy/templates/admin.conf.j2 (L53-L64)

Anything served from `static.notifications.service.gov.uk` is:
- GZipped
- and as a bonus, cached by Cloudfront where possible (meaning the
requests won’t ever hit our app)

This commit moves to serving static asset from `/static/` to
`static.notifications.service.gov.uk`, to get the above listed benefits.

***

We could do even better by setting long cache expiry headers on the static subdomain (currently they’re only set to cache for 60 seconds). But that’s out of scope for this commit.
2018-11-28 15:50:21 +00:00
Katie Smith
c48f54aba4 Bump notifications-utils to 30.7.0
Bumped the notifications-utils version. The `gmt_timezones` function in
this repo and the `utc_string_to_aware_gmt_datetime` in
notifications-utils are the same, so have updated the code to always use
the version in utils.
2018-11-26 14:43:42 +00:00
Leo Hemsted
7cbf5de240 add new template folder
The add new templates page now has option to add template folders.
Tweaked wording of other options and h1 to clarify options since it's
not all about templates any more.

Added api client and stuff for it
2018-11-06 13:13:12 +00:00
Chris Hill-Scott
e04b2b5631 Split models to prevent circular imports
This commit is the first step to disentangling the models from the API
clients. With the models in the same folder as the API clients it makes
it hard to import the API clients within the model without getting a
circular import.

After this commit the user API clients still has this problem, but at
least the service API client doesn’t.
2018-10-30 15:01:36 +00:00
Chris Hill-Scott
9e798506c5 Initialise clients outside the app
This avoids the annoying problem where you can’t import a client unless
the app has already been initialised.
2018-10-30 14:59:24 +00:00
Chris Hill-Scott
2bf2103cce Re-sort order in which clients are initialised
This separates the non-API clients from the API clients.
2018-10-30 14:57:16 +00:00
Chris Hill-Scott
d69e8b50cd Only initialised service model once per request
`_get_current_service` is a function which gets called every time
`current_service` is referenced in a view method or Jinja template.

Because the service model was getting initialised inside this function
it was being reconstructed many times in one request. On the service
settings page, for example, it was getting initialised 43 times, adding
about 200ms to the response time.

This commit moves its initialisation to the point where we’re getting
the data from the API, which only happens once per request.
2018-10-30 14:55:00 +00:00
Chris Hill-Scott
c01d761a3c Show if a letter has been cancelled
At the moment we are manually cancelling letters for people when they
ask us to. Once’s we’ve done this there is no indication that it’s
happened except for the date going red on the list of letters.

This commit adds some error messaging and styling to show when a letter
is cancelled.

Letting people cancel their own letters will be a future enhancement.
2018-10-29 11:51:41 +00:00
Pea Tyczynska
e6e363ba3f Add antivirus scan to letter validation preview view 2018-10-05 16:27:57 +01:00
Chris Hill-Scott
c2ef522986 Make task list read better for screen readers
This duplicates how the task list pattern is coded in the GOV.UK
Prototype kit[1]. It adds ARIA attributes and the use of a
semantically-meaningful element (`<strong>`) to give more information to
screen reader users.

1. https://govuk-prototype-kit.herokuapp.com/docs/templates/task-list
2018-09-25 10:31:40 +01:00
Chris Hill-Scott
c59142b871 Map ‘pending’ status to ‘sending’
For some reason we are getting pending back as a status from one of
our text message providers.

Because this is unrecognised by the admin app it shows up in the list of
messages as the raw status, styled like an error.

This commit maps it to sending instead, because the user doesn’t need to
know or care about the difference.
2018-09-11 13:46:33 +01:00
Alexey Bezhan
b75681dfbc Add a platform admin page to submit returned letter references
A platform admin form accepts a list of references (one per line)
received from DVLA and sends them to the API to update notification
statuses.

References we get from DVLA start with `NOTIFY00\d`, which isn't
part of the reference we store in the database, so we remove them
before sending the data to the API.

The new `returned-letter` status should be treated as `delivered`
for now until we decide a way to display returned letters to users.
2018-09-07 11:13:01 +01:00
Tom Byers
7b955ffad2 Add 'self' to 'frame-src' header
Allows iframes to contain pages from the same
domain as the parent page.
2018-08-07 16:56:36 +01:00
Rebecca Law
ae1f1c95d6 Merge branch 'master' into flexible-data-retention 2018-08-06 15:37:11 +01:00
Chris Hill-Scott
036923c382 Make a service model and use for permissions
Having the service floating about as JSON is a bit flakey. Could easily
introduce a mistake where you mistype the name of a key and silently
get `None`.

Also means doing awkward things like `if 'permission' in
current_service['permissions']`, whereas for users we can do the
much cleaner `user.has_permission()`.

So this commit:
- introduces a model
- adds a `.has_permission` method similar to the one we have for users
2018-07-30 14:56:36 +01:00
Rebecca Law
4b8b571a87 Adding views to view, add and edit service data retention policies.
Only visible to a platform admin.
A service can have a custom number of days to retain the notification data for each notification type.
2018-07-17 14:39:04 +01:00
Chris Hill-Scott
84de1c5625 Let caseworkers send one off messages
The main task that we think ‘caseworker’ users do is send one off
messages.

So this commit:
- makes sure users who don’t have the `view_activity` permission (ie
  not ‘admin’ users) can still send messages
- adds navigation so that these users have a place to go from which to
  start the process of sending a one off message
2018-07-05 11:53:42 +01:00
Katie Smith
ca16bef7f7 Add PlatformStatsAPIClient
In API, the endpoint for the new platform admin stats page has been
moved to a platform stats blueprint. This means we now need a platform
stats client.
2018-06-29 15:31:41 +01:00
Leo Hemsted
e81f302084 handle 405 METHOD NOT ALLOWEDs
(show the "something went wrong" error page).

also catch any other werkzeug http exceptions and show an appropriate
template, if it exists
2018-06-22 18:07:18 +01:00
Chris Hill-Scott
81dc9a0092 Merge pull request #2063 from alphagov/pyup-update-flask-0.12.2-to-1.0.2
Update flask to 1.0.2
2018-06-18 13:51:14 +01:00
Rebecca Law
84445d154d When someone complains about an email from the platform we get a callback from SES.
A new platform admin page Email complaints has been added to surface those complaints.
Eventually the complaints will be visible to the services so they can remove the email address from their mailing list.

Next thing to implement is "x email complaints" warning on the platform admin summary page.
2018-06-06 15:22:48 +01:00
Rebecca Law
886ed01638 Flask has change how it handles werkzeug.routing.RequestRedirect, we need to add an errorhandler so that the request does the right thing.
Refer to: https://github.com/pallets/flask/issues/671#issuecomment-305394901
2018-05-30 14:54:25 +01:00