Commit Graph

8478 Commits

Author SHA1 Message Date
Ben Thorner
2fc0a105f4 Move branding choices logic into utility module
This was a lot of code to be in a form and it's going to get even
more complicated with email branding pools. Moving it out means we
can also simplify the tests that target this code.
2022-03-15 11:47:16 +00:00
Ben Thorner
a04ed3eca5 Use separate classes for branding option forms
These are about to become a lot less similar to each other when we
add email branding pools. Note that the optional *args and *kwargs
weren't used anywhere.
2022-03-15 11:47:15 +00:00
Ben Thorner
26d1222f1c Rename branding forms to clarify who they're for
I've often struggled to find the form associated with a particular
page due to the overlapping names e.g. "SetEmailBranding" sounds
more like the radio button form a user sees than "BrandingOptions".

Almost every form in forms.py also ends with "Form", so this also
makes the branding forms consistent with that naming convention.
2022-03-15 11:47:14 +00:00
Chris Hill-Scott
50015c3125 Pass admin URL to API for registration email
This follows the pattern for invite emails where the admin app tells the
API which domain to use when generating the link.
2022-03-07 15:11:50 +00:00
Ben Thorner
a5d18cf1a0 Simplify clearing the template cache
This is more consistent and more visible than a direct call to a
function. It makes use of the new decorator added in response to [^1].

[^1]: https://github.com/alphagov/notifications-admin/pull/4162#pullrequestreview-896208092
2022-03-07 14:42:55 +00:00
Ben Thorner
8aabaf1f49 Standardise when we clear template cache
This is consistent with all other methods: we clear the cache after
the actual change, not before it.

Since the new version of -utils, we're now catching redis exceptions
on delete, so this change has little effect on behaviour.
2022-03-07 13:54:01 +00:00
Ben Thorner
3f2b760efb Remove redundant deletion decorators
These are superseded by the "_delete_template_cache_for_service"
call in each of these methods.
2022-03-07 13:54:00 +00:00
Ben Thorner
81d9c73543 Bump -utils to 55.0.0
This renames "delete_cache_keys_by_pattern" to match the new method
name, which will also catch exceptions if Redis is down [1].

Note that this also includes a change to RecipientCSV [2], which has
no effect because the new default is the same as the old behaviour.

[1]: https://github.com/alphagov/notifications-utils/pull/949
[2]: https://github.com/alphagov/notifications-utils/pull/947/files#diff-a8a994bf655634f89dc7439880708b4ff0d780ac1bd8033827d8aaa2692a8e0fR373
2022-03-07 13:53:57 +00:00
Ben Thorner
f827a825a1 Merge pull request #4180 from alphagov/dedup-something-else-181415991
Link directly to email branding "something else"
2022-03-07 11:33:11 +00:00
Leo Hemsted
a7e6d5b442 Merge pull request #4177 from alphagov/41p-on-home-page
Update price of letters on home page
2022-03-03 17:15:10 +00:00
Pea Tyczynska
ae4fc977c1 Apply suggestions from code review
Co-authored-by: Ben Thorner <benthorner@users.noreply.github.com>
2022-03-03 17:02:26 +00:00
Pea Tyczynska
8112930e24 Do not verify sms for pending users with email auth
This is to fix a bug where a user creates an account but doesn't
complete registration, then they are invited to a service that
changes their auth to email_auth, and then when they try to
complete registration they are still asked for sms code.

It should save users some pain, and reduce number of support tickets.
2022-03-03 17:02:26 +00:00
Chris Hill-Scott
fb3f79d83c Update pricing of letters on settings page
Follows https://github.com/alphagov/notifications-admin/pull/4174/files
2022-03-03 16:41:06 +00:00
Chris Hill-Scott
59681a8bf2 Update pricing of letters on features page
Follows https://github.com/alphagov/notifications-admin/pull/4174/files
2022-03-03 16:03:33 +00:00
Chris Hill-Scott
357081602c Update price of letters on home page
Follows https://github.com/alphagov/notifications-admin/pull/4174/files
2022-03-03 16:03:31 +00:00
Pea Tyczynska
08f0393553 Allow platform admins to change user auth in the UI
So we do not have to go into the db when we need to change user
auth.

We do not allow this for users who use webauthn. We do not want to
enable security downgrade for those users.
2022-03-03 13:44:13 +00:00
Ben Thorner
8da8b167c9 Merge pull request #4169 from alphagov/downgrade-existing-letter-error
Downgrade error log for expected exception
2022-03-03 11:27:48 +00:00
Ben Thorner
33c6ca0989 Link directly to email branding "something else"
Previously we duplicated the "something else" email branding form
on its own page and embedded in the choices form (if it was the
only option). See [^1] for how this looks - it's inconsistent.

This DRYs-up the "something else" form by bypassing the choices
form when "something else" is the only option. I've also tweaked
the "Back" button to be consistent with this behaviour.

Making this change also simplifies the choices form, which we'll
be adding pool options to shortly. I'd like to make the letters
form consistent, but let's see how emails pan out first.

Note that the choices form will now show a single radio button if
"something else" is the only option. I think that's OK as nothing
will link to the page, and the form still works.

[^1]: https://github.com/alphagov/notifications-admin/pull/4163#issuecomment-1050088088
2022-03-03 10:18:58 +00:00
karlchillmaid
268feba6b5 Update ‘last updated’ information
Use same pattern as other Notify pages
2022-03-01 12:51:19 +00:00
karlchillmaid
7e98128e12 Update postage pricing table 2022-03-01 12:51:19 +00:00
Katie Smith
30cf97b6c0 Merge pull request #4168 from alphagov/free-allowance-0
Allow SMS fragment limit to be 0
2022-03-01 08:42:28 +00:00
Katie Smith
22d25b7a1c Use govukButton to display 'Preview this alert' button
There are no changes to appearance of the 'Preview this alert' button or
what it does, but this stops a CSRF token appearing in the query
string when you click the button. We don't need a CSRF token - it's
a simple GET request which doesn't change any data. Before, we had a form
with `method="get"` but because we were using a `page_footer` a CSRF
token was being added.

We can replace both the `<form>` element and `page_footer` with a
`govukButton`. This means that we make a GET request with no CSRF token
without changing the appearance of the button.
2022-02-25 16:30:08 +00:00
Ben Thorner
35e7e5e957 Downgrade error log for expected exception
Previously we weren't sure if the cause of this exception was what
the comment below suggested [1]. I've now verified this from:

        Letter not found for service 0bd1d970-f11c-40e1-8319-4baefe6239d7 and file aa07ed06-3161-4795-93b3-b45d7c576af9

I checked that aa07ed06-3161-4795-93b3-b45d7c576af9 exists already
as a notification i.e. the comment is correct and we're not sending
users to a 404 page. It's possible there are other scenarios where
the comment is wrong, but I don't think it's worth keeping the error.

[1]: https://github.com/alphagov/notifications-admin/pull/4159
2022-02-25 14:00:02 +00:00
Katie Smith
66382c240a Delete unused config variable 2022-02-25 11:37:23 +00:00
Katie Smith
9dc3252079 Allow free allowance to be set to 0
We want to be able to set the free allowance for a service to 0, but the
form was not allowing this - it gave an error message of `Cannot be
empty`. This can be fixed by changing the WTForms validator from
`DataRequired` (which coerces 0 to falsey) to the `InputRequired`
validator.
2022-02-25 11:27:56 +00:00
Katie Smith
05b8fd7c01 Merge pull request #4163 from alphagov/branding-previews
Show a preview of GOV.UK and NHS email branding and apply straight away
2022-02-24 11:31:53 +00:00
Ben Thorner
f94c6ded5c Merge pull request #4158 from alphagov/catch-missing-recipient
Fix 500 error due to inconsistent recipient check
2022-02-24 10:17:03 +00:00
Ben Thorner
468e42a12e Merge pull request #4159 from alphagov/catch-missing-letter
Catch error if letter does not exist on send
2022-02-24 10:16:54 +00:00
Ben Thorner
3effb75045 Clarify purpose of file_id in redirects
In response to: [1].

[1]: https://github.com/alphagov/notifications-admin/pull/4159/files#r813050941
2022-02-23 17:25:35 +00:00
Katie Smith
4e409f7d93 Show preview of current branding
This adds a preview of the current branding to users on the page where
they can select which new branding they want. Also includes a tiny
content change to match the new content doc for this story.
2022-02-22 14:57:49 +00:00
Katie Smith
77e1c015c4 Update GOV.UK and org email branding content
To make it consistent with the GOV.UK email branding page content.
2022-02-22 13:21:34 +00:00
Katie Smith
5ada431da9 NHS and GOV.UK email branding pages now show preview and apply branding
The pages you were redirected to if you selected either GOV.UK branding
or NHS branding used to give information about the branding and have a
button that submitted a Zendesk ticket. Now, we show a preview of the
new branding and the button applies it.
2022-02-22 13:18:21 +00:00
Katie Smith
87e6737f9e Highlight "Settings" in menu if visiting govuk and org branding page
This was accidentally missed out of a previous PR. It ensures that
when you visit the `.email_branding_govuk_and_org` endpoint "Settings"
is highlighted in the left hand menu.
2022-02-22 13:18:21 +00:00
Katie Smith
d75c1ea398 Split out the govuk and govuk_and_org branding templates
The `.email_branding_govuk` and `.email_branding_govuk_and_org` routes
shared a template since the content was the same - the only difference
was in the action of the button. However, since the pages will no longer
be so similar (e.g. the govuk page will show a preview) this splits them
up to use separate templates.

It may be the case that when the branding work is complete these pages
are fairly similar and we decided that one template between the two
endpoints is the best option again.
2022-02-22 11:39:53 +00:00
Ben Thorner
9f45e4c5be Merge pull request #4160 from alphagov/redis-clear-all
Make it easy to clear cache for all key formats
2022-02-21 15:18:32 +00:00
Ben Thorner
ebbfd20472 Make it easy to clear cache for all key formats
Having to submit the form for each choice separately slowed us down
during an incident where Redis was unavailable and came back with
stale data, which we had to clear manually.

Note: we don't want to use the "flush" feature in case there are other
keys in Redis, which may not be safe to remove.
2022-02-21 15:09:03 +00:00
Ben Thorner
8396412ce1 Report all cache keys that were deleted
This will make it easier to add another test / feature to clear all
the cache keys. It's debatable which of "sum" and "max" is useful:

- "max" is a better (although still not accurate) indicator of the
number of "things" affected e.g. templates, services, etc.

- "sum" makes sense in places where "max" doesn't e.g. when we clear
the "organisations" group, which doesn't equate to individual orgs.

Using "sum() ... across" seems like a reasonable compromise and makes
it clear that we're iterating over different kinds of keys.

While the pluralisation is nice, I don't think it's worth the effort
to make it work for both "object(s)" and "format(s)".
2022-02-21 14:11:49 +00:00
Ben Thorner
4fef2861c6 Catch error if letter does not exist on send
This repeats the pattern we already have for previewing a letter,
where we assume the error is because the notification has already
been sent and redirect the user to see it.

I've improved the original pattern a bit:

- I've DRYed-up the low-level boto code and moved the error handler
there so it can be reused.

- I've introduced a custom exception, which the calling code can
choose to log.

- I've introduced the moto library, which we use elsewhere, to make
it easier to test S3 code.

I've used an error level log when sending a notification - now that
we have a more descriptive log, we can verify the assumption is true
and then make an informed decision to downgrade the log.

In future we may want to merge this handler with the similar code
in utils [1], but we'll need to be careful as the utils handler is
superficial - it doesn't check the reason for the error.

[1]: bce0f4e596/notifications_utils/s3.py (L52)
2022-02-18 14:52:27 +00:00
Ben Thorner
a30a317153 Fix 500 error due to inconsistent recipient check
This strengthens the initial check of what's in the session to make
sure it contains some kind of recipient. Without this, we get:

    Traceback (most recent call last):
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
        rv = self.dispatch_request()
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/home/vcap/app/app/utils/user.py", line 26, in wrap_func
        return func(*args, **kwargs)
      File "/home/vcap/app/app/main/views/send.py", line 1041, in send_notification
        recipient=session['recipient'] or InsensitiveDict(session['placeholders'])['address line 1'],
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/notifications_utils/insensitive_dict.py", line 41, in __getitem__
        return super().__getitem__(self.make_key(key))
    KeyError: 'addressline1'

I'm not sure how to reproduce this, but this should at least give
the user a better experience, instead of a 500 page.
2022-02-18 12:44:01 +00:00
Tom Byers
8521d1e45f Add assertions against stray classes
In previous iterations of the classPersister, we
found issues with the implementation meant classes
it should have added back to elements were also
added to other elements. This adds tests for this
scenario to ensure it doesn't happen again.

Also includes changes to fix a linting error with
the JS which complained about a function being
defined in a loop while referencing variables in
the outer scope.
2022-02-18 12:07:41 +00:00
Tom Byers
85e14d302c Make a classesPersister per component instance
It makes more sense for something that operates on
a single component to be local to it.
2022-02-16 16:08:48 +00:00
Tom Byers
3a86bd1685 Change internals of classesPersister
The assumption that the classes you want to
persist will always have parity with the elements
that have those classes, at that point, won't
always be true.

Because of that, this changes the way elements
with those classes are stored, to be in a map
between classes and the elements with them (at
that point).

Also includes an extra test for a scenario where
more than one updating component is in the page
with classes that need to persist through updates.
2022-02-16 15:59:29 +00:00
Tom Byers
8c253309e4 Fix error in updateContent code
This was missed from these changes:

9646e17b03
2022-02-15 16:35:45 +00:00
Tom Byers
1d69f7ab61 Fix focus style gap at top in keyline-block
File-list items contained by div.keyline-block's
are pushed down 3px more than elsewhere which
creates a gap between the top of the focus style
and the keyline above. This extends the part of
the focus style made up by a box-shadow by 3px so
it covers the gap.
2022-02-15 13:02:39 +00:00
Tom Byers
776f210e7b Add comments about deleting this code in future
If the :has pseudo-class becomes available in the
browsers we support in future, the code this
branch/pull request adds will be redundant as its
behaviour will be possible only using CSS.

This adds comments to note this to the parts of
the code you'd need to remove.
2022-02-15 11:26:17 +00:00
Tom Byers
467be3a339 Fixes for updateContent based on PR comments
Includes the following:

Guard for adding duplicate classNames

Stops the code that allows classNames to persist
across updates to the component HTML from adding a
className multiple times to the list of those to
persist. From this comment on the associated pull
request:

https://github.com/alphagov/notifications-admin/pull/4155#discussion_r804639058

Add comment explaining guard for operations on
elements no longer in the DOM

The value of this guard can be unclear and why it
is needed so we add a comment to explain this.
From this comment on the associated pull request:

https://github.com/alphagov/notifications-admin/pull/4155#discussion_r804697189
2022-02-15 11:11:45 +00:00
Tom Byers
9646e17b03 Make classNames used by classesPersister private
Both the remove and replace methods rely on it
having parity with the $els array property so it
is a good idea to stop it, and $els, being
changable by other code. As noted in:

https://github.com/alphagov/notifications-admin/pull/4155#discussion_r804639058
2022-02-11 15:40:47 +00:00
Tom Byers
4f59396a00 Change classesToPersist to classesPersister
Makes it sounds less like a list and more like a
thing that makes classes persist, as noted in:

https://github.com/alphagov/notifications-admin/pull/4155#discussion_r804638407
2022-02-11 15:35:04 +00:00
Tom Byers
99df8542b4 Add guard against elements removed from the DOM
We can't guarantee that elements we stored a
reference to with `classesToPersist.remove` will
still exist so we need to guard against this.

Note: it checks for whether the node is still
attached to the DOM rather than whether it exists
because the standard way to delete a node just
detaches it from the DOM and relies on garbage
collection to delete it from memory.
2022-02-11 12:30:07 +00:00
Tom Byers
476ed1593c Make updateContent handle all AJAX the same
The current updateContent JS replaces the in-page
HTML with the HTML from the server the first time
an AJAX request is fired, even if the HTML from
the server has no changes. This is because the
code that compares the two operates on two
different things:

The HTML in the page is the component HTML, with
all the data attributes and the partial HTML
(marked with the 'ajax-block-container' class) as
its first child:

```
<div data-module="update-content" data-url="...">
  <div class="ajax-block-container">
    ...
  </div>
</div>
```

The HTML from the server only contains the
partial:

```
<div class="ajax-block-container">
  ...
</div>
```

The diffing code just sees them as different at
the top level so replaces the page HTML with the
partial from the server. This means all subsequent
diffs are between partial HTML and partial HTML so
only update on actual changes.

These replace the component with the partial, as
part of the component initialising. This means all
code that runs on an AJAX response will only
compare like-for-like so will result in actual
changes (or none at all), not just swapping one
element out for another.

Note: this commit also removes the
aria-live="polite" from the ajax_block component.
It has always been overwritten by the first
response so never announces anything to assistive
technologies. Removing it makes this more clear.
2022-02-09 12:25:15 +00:00