Commit Graph

118 Commits

Author SHA1 Message Date
Chris Hill-Scott
e7abebebf3 Pass API correct attribute to search inbound SMS
It’s `phone_number` here:
1250e47cc7/app/inbound_sms/rest.py (L33)
2019-04-02 09:17:13 +01:00
Leo Hemsted
53cdbad2cc make inbound search a POST
that way it doesn't expose PII to our logs
2019-03-29 15:16:29 +00:00
Chris Hill-Scott
8fb576e60a Allow excluding services from live services count
Adds a front end for:
https://github.com/alphagov/notifications-api/pull/2417

> Sometimes we have to make a few services for what really is one
> service, for example GOV.UK Pay and GOV.UK Pay Direct Debit. We also
> have our own test services which aren’t included in the count of live
> services. We currently count these as one service by not including
> them in the beta partners spreadsheet.
2019-03-25 15:46:35 +00:00
Chris Hill-Scott
8791134c60 Move the ‘estimated usage’ questions
We get a bunch of requests to go live where people have told us they're
going to send email but there is no email reply-to address present.

These come from 2 scenarios:

1. when there are email templates, and no reply to address – but they
   ignore the checklist
2. when there are no email templates (yet) but they provide anticipated
   volumes for email

At the moment we only auto-check for a reply to address when they have
email templates. And because the question about anticipated volumes
follows the checklist, you'll get a checklist that passes (reply
addresses not required as no templates present) - but your future intent
that differs (reply address IS required because you have anticipated
volumes).

So let’s bring the request for anticipated volumes into the checklist,
that way we can dynamically add the requirement for a reply to address
if they say they will send email but don't have templates yet.

We should begin storing it in the database against the service to stop
people having to re-enter it each time they try to complete the go live
screens.

This also means moving the ‘consent to research question’ along with
the questions about volume, because
- we want people to answer both before going live
- we don’t want to clutter up the summary page by asking questions there
  too
2019-02-27 13:17:28 +00:00
Katie Smith
31a1c1ca51 Pass service domain to api when adding a new service
We need to pass the domain to api when adding a service so that api can
link the domain of the service with a letter brand.
2019-02-12 14:59:29 +00:00
Leo Hemsted
8266635a7a remove dvla_organisation and other unused things
dvla_organisation, branding_dict, a weird `branding` property on
update_service. all gone 💥
2019-02-07 11:38:20 +00:00
Leo Hemsted
a1caf77b0e use new letter branding instead of dvla organisation id
new code is copied stylistically from the email branding patterns.
Instead of `service.dvla_organisation`, there's now
`service.letter_branding` and `service.letter_branding_id`. However,
unlike email branding we're not currently showing a preview of the
logo. That can come later when we work out how we want to do it.
2019-02-07 11:30:18 +00:00
Pea Tyczynska
b07f16b9a0 Don't use service default postage, but template postage instead 2019-02-06 11:40:50 +00:00
Pea Tyczynska
20ae200de9 Remove choosing postage from edit template content flow 2019-02-04 14:45:33 +00:00
Pea Tyczynska
db5378bac2 Edit template postage from a separate view 2019-02-04 14:45:33 +00:00
Chris Hill-Scott
1d3a4e5043 Inherit don’t duplicate API client constructor
This removes some code which is duplicative and obscure (ie it’s not
very clear why we do `"a" * 73` even though there is a Very Good Reason
for doing so).
2019-01-29 12:11:27 +00:00
Pea Tyczynska
85b8b343e2 Service deafault radio checked by default, existing tests pass. 2018-12-21 17:13:18 +00:00
Pea Tyczynska
695f1150b5 service_default postage resets template postage to None 2018-12-19 12:24:02 +00:00
Pea Tyczynska
687e9e5866 Change postage while editing template 2018-12-18 18:22:03 +00:00
Alexey Bezhan
7a7a9ae854 Cache service data retention in Redis
Adds caching for service data retention. This removes separate API
client methods to retrieve individual data retention records by id
or type in favor of a single method that fetches and caches all
retention settings configured for the service. This makes it much
easier to invalidate cache when settings change.

Lookup by id or type is provided by helper methods in the service
model.
2018-12-03 17:57:02 +00:00
Rebecca Law
146c7915b2 Create a template in a folder. 2018-11-08 15:53:33 +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
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
Katie Smith
9660f372f3 Change naming in code to use 'postage'
Renamed everything that was previously called 'letter class' or 'postage
class' to 'postage', which is the new name we have decided to use.
2018-09-19 09:20:09 +01:00
Katie Smith
de9759b99a Add letter class row to settings page, visible to platform admin
Added a new row to the settings table, 'Post class', which shows the
default letter class of a service and is only visible to Platform Admin.

Also added a new page to enable Platform Admin users to change the
default letter class for a service - this only has two options at the
moment, 1st class only and 2nd class only.
2018-09-18 10:31:01 +01:00
Alexey Bezhan
52d48ad679 Add API client method to fetch service data retention by type 2018-08-13 17:06:16 +01:00
Alexey Bezhan
28b03fe748 Add limit_days argument to statistics API client method
Allows getting notification counts for a given number of days to
support services with custom data retention periods (admin
dashboard page should still display counts for the last 7 days,
while the notifications page displays all stored notifications).
2018-08-13 17:04:40 +01:00
Rebecca Law
18750585c4 Reduced the size of the pull request by only dealing with adding the data retention form. 2018-08-06 16:04:31 +01:00
Rebecca Law
0081a70d4b Fix the link on the data-retention/edit.html
Adding new service_api_client methods to get data for the right amount of days.
2018-07-19 17:09:52 +01:00
Rebecca Law
13d05c5461 Allow a platform admin user to set flexible data retention for a service for a specified notification type.
Still a work in progress
2018-07-13 16:47:26 +01:00
Katie Smith
3bbc73dfd2 Use new platform-admin page
We had kept the original platform-admin page at `/platform-admin` and
created a new page, `/platform-admin-new` for the new platform admin
page. Now that the numbers on both pages look ok we no longer need both
pages, so can replace the original page.
2018-07-10 14:39:54 +01:00
Chris Hill-Scott
c2dbc1934f Allow callbacks to be removed
We’ve had a user who’s said:

> Seems configured callbacks cannot be removed once they’re set as the
> fields have a presence check. Is that intentional?

This means it’s not working as they expect. Rather than have to go and
change stuff in the database for them, let’s make it work as they’d
expect.

Only lets you clear the form if you remove both the token and the URL.
2018-07-05 11:41:43 +01:00
Katie Smith
e1d4181be3 Add page to change a service's contact link
Added a page which lets users with the 'manage_service' permission change the
contact link for their service. There are no links to this page yet
since only services using document download will need to set a contact
link.
2018-06-11 10:36:18 +01:00
Leo Hemsted
78a6f86043 use service statistics endpoint instead of detailed service
we're not actually looking at the detailed service aspects - just
the stats. We're doing this in three places:

* dashboard
* notification activity page
* when checking jobs to see if we're over the daily limit

change these places to use a new api endpoint (service/id/statistics),
which hopefully be a little more performant, and will definitely be a
little more organised - moving away from generic endpoints with loads
of optional parameters.

We still need the detailed endpoints for the platform admin page tho.

Depends on https://github.com/alphagov/notifications-api/pull/1865
2018-05-09 14:00:24 +01:00
Katie Smith
0e370d511e Update service_api_client to use new endpoints
API now has separate endpoints to archive email reply-to addresses and
SMS senders, so we no longer need to use the endpoints for updating.
2018-05-01 08:38:54 +01:00
Chris Hill-Scott
965bc76c42 Allow delete email reply to address, SMS senders
For both SMS senders and email reply to addresses this commit adds:
- a delete link
- a confirmation loop

It doesn’t let users delete:
- default SMS senders or reply to addresses (they always have to have
  one)
- inbound numbers

It assumes that the API will allow updating of an attribute named
`active` on the respective database rows. It could work in a different
way. We can’t do complete deletion though because these will still be
keyed to notifications.
2018-05-01 08:38:54 +01:00
Chris Hill-Scott
06de94f1c5 Rewrite cache decorator to use format string
This is easier to read than having to understand the arguments 1…n of
the cache decorator are ‘magic’, and gives us more flexibility about
how the cache keys are formatted, eg being able to add words in the
middle of them.

Also changes the key format for all templates to be
`service-{service_id}-templates` instead of `templates-{service_id}`
because then it’s clearer what the ID represents.
2018-04-20 16:32:02 +01:00
Chris Hill-Scott
cea7a027e3 Add caching of templates in Redis
A lot of the frequently-used pages in the admin app rely on the API to
get templates.

So this commit adds three new caches:
- a single template version (including a key without a version number,
  which is the current version)
- all the templates for a service
- all versions of a template

The first will be the most crucial for performance, but there’s not much
cost to adding the other two.
2018-04-19 13:58:40 +01:00
Chris Hill-Scott
6101e5da43 Rewrite cache decorator to reference args by name
`@cache.delete('user', 'user_id')` is easier to read and understand than
`@cache.delete('user', key_from_args=[1])`. This will become even more
apparent if we have to start doing stuff like `key_from_args=[1, 5]`,
which is a lot more opaque than just saying
`'service_id', 'template_id'`.

It does make the implementation a bit more complex, but I’m not too
worried about that because:
- the tests are solid
- it’s nicely encapsulated
2018-04-19 13:58:40 +01:00
Chris Hill-Scott
6c8fea1ee8 Remove splatting on get template methods
This `*params` argument seems to be copy/pasted boilerplate. It’s not
used by any consumers of this client, and makes it harder to write a
decorator for this function.
2018-04-19 13:58:39 +01:00
Chris Hill-Scott
1c91e10d5d Clear user cache when deleting a service
The user JSON has a list of service IDs
2018-04-19 13:25:04 +01:00
Chris Hill-Scott
eb9aed6d01 Cache GET /user response in Redis
In the same way, and for the same reasons that we’re caching the service
object.

Here’s a sample of the data returned by the API – so we should make sure
that any changes to this data invalidate the cache.

If we ever change a user’s phone number (for example) directly in the
database, then we will need to invalidate this cache manually.

```python
{  
   'data':{  
      'organisations':[  
         '4c707b81-4c6d-4d33-9376-17f0de6e0405'
      ],
      'logged_in_at':'2018-04-10T11:41:03.781990Z',
      'id':'2c45486e-177e-40b8-997d-5f4f81a461ca',
      'email_address':'test@example.gov.uk',
      'platform_admin':False,
      'password_changed_at':'2018-01-01 10:10:10.100000',
      'permissions':{  
         '42a9d4f2-1444-4e22-9133-52d9e406213f':[  
            'manage_api_keys',
            'send_letters',
            'manage_users',
            'manage_templates',
            'view_activity',
            'send_texts',
            'send_emails',
            'manage_settings'
         ],
         'a928eef8-0f25-41ca-b480-0447f29b2c20':[  
            'manage_users',
            'manage_templates',
            'manage_settings',
            'send_texts',
            'send_emails',
            'send_letters',
            'manage_api_keys',
            'view_activity'
         ],
      },
      'state':'active',
      'mobile_number':'07700900123',
      'failed_login_count':0,
      'name':'Example',
      'services':[  
         '6078a8c0-52f5-4c4f-b724-d7d1ff2d3884',
         '6afe3c1c-7fda-4d8d-aa8d-769c4bdf7803',
      ],
      'current_session_id':'fea2ade1-db0a-4c90-93e7-c64a877ce83e',
      'auth_type':'sms_auth'
   }
}
```
2018-04-18 13:27:11 +01:00
Chris Hill-Scott
24dbe7b7b1 Add Redis cache between admin and API
Most of the time spent by the admin app to generate a page is spent
waiting for the API. This is slow for three reasons:

1. Talking to the API means going out to the internet, then through
   nginx, the Flask app, SQLAlchemy, down to the database, and then
   serialising the result to JSON and making it into a HTTP response
2. Each call to the API is synchronous, therefore if a page needs 3 API
   calls to render then the second API call won’t be made until the
   first has finished, and the third won’t start until the second has
   finished
3. Every request for a service page in the admin app makes a minimum
   of two requests to the API (`GET /service/…` and `GET /user/…`)

Hitting the database will always be the slowest part of an app like
Notify. But this slowness is exacerbated by 2. and 3. Conversely every
speedup made to 1. is multiplied by 2. and 3.

So this pull request aims to make 1. a _lot_ faster by taking nginx,
Flask, SQLAlchemy and the database out of the equation. It replaces them
with Redis, which as an in-memory key/value store is a lot faster than
Postgres. There is still the overhead of going across the network to
talk to Redis, but the net improvement is vast.

This commit only caches the `GET /service` response, but is written in
such a way that we can easily expand to caching other responses down the
line.

The tradeoff here is that our code is more complex, and we risk
introducing edge cases where a cache becomes stale. The mitigations
against this are:
- invalidating all caches after 24h so a stale cache doesn’t remain
  around indefinitely
- being careful when we add new stuff to the service response

---

Some indicative numbers, based on:
- `GET http://localhost:6012/services/<service_id>/template/<template_id>`
- with the admin app running locally
- talking to Redis running locally
- also talking to the API running locally, itself talking to a local
  Postgres instance
- times measured with Chrome web inspector, average of 10 requests

╲ | No cache | Cache service | Cache service and user | Cache service, user and template
-- | -- | -- | -- | --
**Request time** | 136ms | 97ms | 73ms | 37ms
**Improvement** | 0% | 41% | 88% | 265%

---

Estimates of how much storage this requires:

- Services: 1,942 on production × 2kb = 4Mb
- Users: 4,534 on production × 2kb = 9Mb
- Templates: 7,079 on production × 4kb = 28Mb
2018-04-10 12:58:35 +01:00
chrisw
78d16709d6 reading messages for inbox from new most_recent endpoint
avoids us having to work out and display most recent messages
only on the front-end - it's now all done in api
2018-04-05 13:54:37 +01:00
chrisw
f5c467e4ff add pagination to inbox page 2018-04-04 15:41:17 +01:00
Chris Waszczuk
6153389e01 Revert "add pagination to inbox page" 2018-04-04 14:18:03 +01:00
chrisw
50661faac0 add pagination to inbox page 2018-04-03 12:12:30 +01:00
Leo Hemsted
1cd8000236 remove browsableitem
it was only used by the choose service page, and then only in kludgy
ways (eg: creating a list containing one item called "add service"),
so lets rip it out and make this page bespoke. Especially now that it's
changed so much.
2018-03-14 15:39:55 +00:00
Alexey Bezhan
acfe8092fc Add route secret key header to the API requests
Currently requests to the API made from the admin app are going from
PaaS admin app to the nginx router ELB, which then routes them back
to the api app on PaaS.

This makes sense for external requests, but for requests made from
the admin app we could skip nginx and go directly to the api PaaS
host, which should reduce load on the nginx instances and
potentially reduce latency of the api requests.

API apps on PaaS are checking the X-Custom-Forwarder header (which
is set by nginx on proxy_pass requests) to only allow requests going
through the proxy.

This adds the custom header to the API client requests, so that they
can pass that header check without going through nginx.
2018-02-28 11:28:46 +00:00
Chris Hill-Scott
f3a0c505bd Enforce order and style of imports
Done using isort[1], with the following command:
```
isort -rc ./app ./tests
```

Adds linting to the `run_tests.sh` script to stop badly-sorted imports
getting re-introduced.

Chosen style is ‘Vertical Hanging Indent’ with trailing commas, because
I think it gives the cleanest diffs, eg:
```
from third_party import (
    lib1,
    lib2,
    lib3,
    lib4,
)
```

1. https://pypi.python.org/pypi/isort
2018-02-27 16:35:13 +00:00
Chris Hill-Scott
51f0320aec Add API client method to count templates
When users request to go live we check stuff like:
- if they’ve added templates
- if they have email templates (then we can check their reply to
  address)

This commit adds a method to do this programatically rather than
manually.

We _could_ do this in SQL, but for page that’s used intermittently it
doesn’t feel worth the work/optimisation (and the client method is at
least in place now if we do ever need to lean on this code more
heavily).
2018-02-26 08:53:45 +00:00
Katie Smith
84d810b981 Pass service_id through to API '/service/unique' endpoint
Notifications-api now needs the service_id to check the uniqueness of
the service name when trying to change it. This is to allow a user to
successfully change the pluralization or the case of their service name.
2018-02-13 15:57:19 +00:00
chrisw
9ad4435d94 Change organisations to email branding 2018-02-07 17:41:23 +00:00
chrisw
7271d4fbde Allow letter templates to select the default contact block from the list 2018-01-10 11:20:40 +00:00
chrisw
43c14fb756 Allow service to set callback url for notifications 2017-12-08 10:52:50 +00:00