Commit Graph

13479 Commits

Author SHA1 Message Date
pyup-bot
1de542bd05 Update colorama from 0.4.3 to 0.4.4 2021-06-02 15:28:30 +01:00
pyup-bot
48ae94efa7 Update click from 7.1.2 to 8.0.1 2021-06-02 15:28:30 +01:00
pyup-bot
a6ea8dbe46 Update certifi from 2020.12.5 to 2021.5.30 2021-06-02 15:28:30 +01:00
pyup-bot
22adea55b0 Update cachetools from 4.2.1 to 4.2.2 2021-06-02 15:28:30 +01:00
pyup-bot
82d08522e6 Update botocore from 1.20.51 to 1.20.84 2021-06-02 15:28:30 +01:00
pyup-bot
176966ff83 Update boto3 from 1.17.51 to 1.17.84 2021-06-02 15:28:29 +01:00
pyup-bot
5b6125aef0 Update awscli from 1.19.51 to 1.19.84 2021-06-02 15:28:29 +01:00
pyup-bot
c832e11523 Update requests-mock from 1.8.0 to 1.9.3 2021-06-02 15:28:29 +01:00
pyup-bot
d4f11a3b40 Update flake8 from 3.9.0 to 3.9.2 2021-06-02 15:28:29 +01:00
pyup-bot
6177937014 Update pytest-mock from 3.5.1 to 3.6.1 2021-06-02 15:28:29 +01:00
pyup-bot
96e5950de7 Update pytest from 6.2.3 to 6.2.4 2021-06-02 15:28:29 +01:00
pyup-bot
164a44e41b Pin cryptography to latest version 3.4.7 2021-06-02 15:28:29 +01:00
pyup-bot
3cf17ff6bf Update itsdangerous from 1.1.0 to 2.0.1 2021-06-02 15:28:29 +01:00
pyup-bot
afcc1a90ed Update itsdangerous from 1.1.0 to 2.0.1 2021-06-02 15:28:29 +01:00
pyup-bot
14f5aadef3 Update notifications-python-client from 6.0.2 to 6.1.0 2021-06-02 15:28:29 +01:00
pyup-bot
e7893001f3 Update notifications-python-client from 6.0.2 to 6.1.0 2021-06-02 15:28:29 +01:00
pyup-bot
d86239566d Update flask-wtf from 0.14.3 to 0.15.1 2021-06-02 15:28:29 +01:00
pyup-bot
0345c95179 Update flask-wtf from 0.14.3 to 0.15.1 2021-06-02 15:28:29 +01:00
pyup-bot
c78ce2a482 Update flask from 1.1.2 to 2.0.1 2021-06-02 15:28:29 +01:00
pyup-bot
5d209a4ad9 Update flask from 1.1.2 to 2.0.1 2021-06-02 15:28:29 +01:00
pyup-bot
2a7a29a48b Update humanize from 3.4.0 to 3.6.0 2021-06-02 15:28:29 +01:00
pyup-bot
e26922e82a Update humanize from 3.4.0 to 3.6.0 2021-06-02 15:28:29 +01:00
Leo Hemsted
73a444b33a rename webauthn auth functions
_complete_webauthn_authentication -> _verify_webauthn_authentication

This function just does verification of the actual auth process -
checking the challenge is correct, the signature matches the public key
we have stored in our database, etc.

verify_webauthn_login -> _complete_webauthn_login_attempt

This function doesn't do any actual verification, we've already verified
the user is who they say they are (or not), it's about marking the
attempt, either unsuccessful (we bump the failed_login_count in the db)
or successful (we set the logged_in_at and current_session_id in the
db).

This change also informs changes to the names of methods on the user
model and in user_api_client.
2021-06-02 12:06:10 +01:00
Leo Hemsted
0ec92e8c2f DRY attested webauthn creds data 2021-06-02 12:06:10 +01:00
Leo Hemsted
e864100be7 make sure error message flashes work properly
flashes are consumed by the jinja template calling get_flashed_messages
in flash_messages.html.

When you call `abort(403)` the 403 error page is rendered, with the
flashed message on it. However, the webauthn endpoints just return that
page to the ajax `fetch`, which ignores the response and just reloads
the page.

Instead of calling abort, we can just return an empty response body and
the 403 error code, so that the flashed messages stay in the session and
will be rendered when the `GET /two-factor-webauthn` request happens
after the js reloads the page.
2021-06-02 12:06:09 +01:00
Leo Hemsted
a3870af87d allow password reset with webauthn login flow 2021-06-02 12:06:09 +01:00
Leo Hemsted
6a21915cee add webauthn authentication js tests
notably i had to change `window.location = foo` to
`window.location.assign` so that i could have something to spy on with
jest. mocking sucks. Otherwise this is pretty similar to the
registerSecurityKey.test.js file.
2021-06-02 12:06:09 +01:00
Leo Hemsted
e765f98a02 use mockImplementationOnce to define separate return vals for fetch
rather than having a gross if/else, we can define separately. This means
we can separate the asserts and test setups for the first fetch (get)
and the second fetch (post), which means we can arrange all the mocks in
the order they're called in the function, significantly enhancing
legibility of the tests
2021-06-02 11:54:18 +01:00
Leo Hemsted
d05f127e41 return 200 to js instead of 302 when logging in
the js fetch function is really not designed to work with 302s. when it
receives a 302, it automatically follows it and fetches the next page.
This is awkward because I don't want js to do all this in ajax, I want
the browser to get the new URL so it can load the page.

A better approach is to view the admin endpoint as a more pure API: the
js sends a request for authentication to the admin app, and the admin
app responds with a 200 indicating success, and then a payload of
relevant data with that.

The relevant data in this case is "Which URL should I redirect to", it
might be the user's list of services page, or it might be a page telling
them that their email needs revalidating.
2021-06-02 11:51:12 +01:00
Leo Hemsted
c29f87f55d increment failed login count on unsuccesful webauthn login
this doesn't include timeouts or other errors on the browser side - the
main thing this catches is if the token doesn't belong to the user.
However I'm not entirely clear if that's something that will be caught
at this point, or if the browser would reject that key as it's not in
the credentials passed in to the begin_authentication process.
2021-06-02 11:51:11 +01:00
Leo Hemsted
92f78b14fe redirect on login; flash errors on failure
the js `fetch` function will follow redirects blindly and return you the
final 200 response. when there's an error, we don't want to go anywhere,
and we want to use the flask `flash` functionality to pop up an error
page (the likely reason for seeing this is using a yubikey that isn't
associated with your user). using `flash` and then
`window.location.reload()` handles this fine.

However, when the user does log in succesfully we need to properly log
them in - this includes:

* checking their account isn't over the max login count
* resetting failed login count to 0 if not
* setting a new session id in the database (so other browser windows are
  logged out)
* checking if they need to revalidate their email access (every 90 days)
* clearing old user out of the cache

This code all happens in the ajax function rather than being in a
separate redirect, so that you can't just navigate to the login flow. I
wasn't able to unit test that function due how it uses the session and
other flask globals, so moved the auth into its own function so it's
easy to stub out all that CBOR nonsense.

TODO: We still need to pass any `next` URLs through the chain from login
page all the way through the javascript AJAX calls and redirects to the
log_in_user function
2021-06-02 11:51:10 +01:00
Pea Tyczynska
ac757b0fc1 Merge pull request #3904 from alphagov/platform-admin-reply-to
Let platform admins add or update service reply to email address without the need for verification.
2021-06-02 10:46:05 +01:00
Katie Smith
d9fd37a485 add test for succesfully logging in with security key
this is a bit complex, but essentially we're using the test variables
defined in the duolabs py_webauthn library [1]. We're already using
their test variables in tests/app/models/test_webauthn_credential.py and
in the webauthn_credential fixture in conftest.py. By using sample
signature, authenticatordata and clientdatajson from the same key we can
test that the library correctly verifies the signed challenge matches
the original.

We needed to transform some of this data as the yubico/fido2 library we
use has a slightly different way of formatting the fields for the
request body, which is why we're doing things like base64 decoding and
converting from hex to bytes in the post data.

The pytest fixture has changed - before it was incomplete/corrupted and
would error when trying to verify the signature. We took the
credential_data from the pytest fixture, converted it to an
AttestedCredentialData using WebauthnCredential.to_credential_data,
modified the public_key private dictionary to add `public_key[-1]: 1`,
and then called `AttestedCredentialData.create` to re-CBOR-encode the
blob.

The `-1: 1` is the numeric ID of the "SECP256R1" elliptic curve
algorithm. The py_webauthn library forces this particular algorithm,
which differs from the sample creds we took from the fido2 lib tests,
which is why we've had to update our data.

[1] https://github.com/duo-labs/py_webauthn/blob/master/tests/test_webauthn.py#L13-L32
2021-06-01 19:22:54 +01:00
Katie Smith
28ee2a1f9a Add tests for GET webauthn_begin_authentication 2021-06-01 19:08:58 +01:00
Leo Hemsted
a753e32c8d only let platform admins with webauthn access the sign in pages 2021-06-01 19:08:58 +01:00
Leo Hemsted
c26a596839 allow sign in via webauthn credentials
The flow of the code is roughly as follows:

  user clicks button on webauthn page
  js sends GET request
  python reads GET request, sets up login challenge
  python returns login challenge in response
  js reads GET response, passes login challenge to browser
  browser asks user to touch yubikey
  browser returns yubikey challenge response data to js
  js sends POST request with yubikey challenge response data
  python reads yubikey challenge and compares with users creds from db
  if its a match, python signs user in

The login challenge is a PublicKeyCredentialRequestOptions: [1]
The browser function we call is navigator.credentials.get(): [2]
The response to the challenge from the browser is a PublicKeyCredential: [3]

The python server does all the work setting those up and tearing them
back down again (and checking them against the values we have stored in
the database), but we need to do work to convert them to-and-from CBOR.

[1] https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialRequestOptions
[2] https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get
[3] https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential
2021-06-01 19:08:57 +01:00
Leo Hemsted
c203f624ca rename two_factor to two_factor_sms
it's a bit confusing now that there are three endpoints. the other two
are already renamed two_factor_email and two_factor_webauthn
2021-06-01 19:08:57 +01:00
Leo Hemsted
907a7dc363 create webauthn 2fa page
if user has `webauthn_auth` as their auth type, then redirect them to an
interstitial that prompts them to click on a button which right now just
logs to the JS console, but in a future commit will open up the webauthn
browser prompt

content is unsurprisingly not final.
2021-06-01 18:44:54 +01:00
Chris Hill-Scott
bd19806ebf Remove ‘(all networks)’ from settings label
I don’t think we need to say (all networks) in the header. The real
benefit of this change is forcing the platform admin person making the
change to explicitly give their choice of network.

And by not putting it in the label we don’t have future users from other
organisations wondering if there’s some option other than ‘all networks’
they need to think about.
2021-06-01 17:55:17 +01:00
Chris Hill-Scott
37b51099d1 Merge pull request #3903 from alphagov/optional-text-field-send-files
Use optional text field for send files setting
2021-06-01 15:11:18 +01:00
Chris Hill-Scott
fbf77a7482 Merge pull request #3902 from alphagov/webauthn-image
Designerise the pages for adding a security key
2021-06-01 15:10:52 +01:00
Chris Hill-Scott
77ea7af909 Fix double back link 2021-05-28 16:20:35 +01:00
Chris Hill-Scott
3f7124b04e Remove uneeded clearfix 2021-05-28 16:20:35 +01:00
Chris Hill-Scott
597846f657 Refactor error button and error messages into variable 2021-05-28 16:20:34 +01:00
Chris Hill-Scott
268a7d1881 Make image display smaller on mobile 2021-05-28 16:20:34 +01:00
Ben Thorner
68d923568c Merge pull request #3901 from alphagov/prevent-admin-auth-change
Prevent switching auth type for Platform Admins
2021-05-28 16:07:11 +01:00
Pea Tyczynska
4b3e826ec8 Let platform admins add or update service reply to email address
without the need for verification.

This is for when the email takes too long to arrive and the service
users cannot update it as a result.

A more streamlined solution has been proposed where we could send
a link in the verification email to the users and clicking that
link would add/update reply-email-to address.
That would require a bit more work so right now I am proposing this
as a quick stop gap so that we don't have to go to the database
manually to add the reply-to email address.
2021-05-28 15:06:31 +01:00
Chris Hill-Scott
68e7d2916e Fix nesting of if statement 2021-05-28 13:52:05 +01:00
Chris Hill-Scott
551b4ba8dc Use optional text field for send files setting
This follows the convention for if you have an empty setting, it is
greyed-out.
2021-05-28 09:48:14 +01:00
Chris Hill-Scott
7f88aa6759 Make listing of keys on user profile a bit nicer
We can use the `optional_text_field` macro to grey out the text when
nothing is set up. And adding ‘registered’ makes the language consistent
through to the next page.
2021-05-27 18:14:20 +01:00