diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index 8ae3a9770..d948f459e 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -109,7 +109,7 @@ def _do_login_dot_gov(): # $ pragma: no cover raise Exception(f"Could not login with login.gov {login_gov_error}") elif code and state: state_key = f"login-state-{unquote(state)}" - stored_state = redis_client.get(state_key).decode("utf8") + stored_state = unquote(redis_client.get(state_key).decode("utf8")) if state != stored_state: current_app.logger.error(f"State Error: {state} != {stored_state}") abort(403) diff --git a/app/notify_client/invite_api_client.py b/app/notify_client/invite_api_client.py index d45137981..5ae1c2807 100644 --- a/app/notify_client/invite_api_client.py +++ b/app/notify_client/invite_api_client.py @@ -88,7 +88,27 @@ class InviteApiClient(NotifyAdminAPIClient): self.post(url=f"/service/{service_id}/invite/{invited_user_id}", data=data) def resend_invite(self, service_id, invited_user_id): - self.post(url=f"/service/{service_id}/invite/{invited_user_id}/resend", data={}) + # make and store the state + state = generate_token( + str(request.remote_addr), + current_app.config["SECRET_KEY"], + current_app.config["DANGEROUS_SALT"], + ) + state_key = f"login-state-{unquote(state)}" + redis_client.set(state_key, state) + + # make and store the nonce + nonce = secrets.token_urlsafe() + nonce_key = f"login-nonce-{unquote(nonce)}" + redis_client.set(nonce_key, nonce) + + data = { + "nonce": nonce, + "state": state, + } + self.post( + url=f"/service/{service_id}/invite/{invited_user_id}/resend", data=data + ) @cache.delete("service-{service_id}") @cache.delete("user-{invited_user_id}") diff --git a/tests/app/notify_client/test_invite_client.py b/tests/app/notify_client/test_invite_client.py index 4bc81e127..4cf21c9e1 100644 --- a/tests/app/notify_client/test_invite_client.py +++ b/tests/app/notify_client/test_invite_client.py @@ -1,5 +1,7 @@ from unittest.mock import ANY +from flask import current_app + from app import invite_api_client @@ -10,7 +12,6 @@ def test_client_creates_invite( sample_invite, ): mocker.patch("app.notify_client.current_user") - mocker.patch("flask.request") mock_post = mocker.patch( "app.invite_api_client.post", @@ -38,15 +39,23 @@ def test_client_creates_invite( fake_state = "0987654321" mock_token_urlsafe.return_value = fake_nonce - mock_generate_token = mocker.patch("notifications_utils.url_safe_token.generate_token") + mock_generate_token = mocker.patch( + "app.notify_client.invite_api_client.generate_token" + ) mock_generate_token.return_value = fake_state - invite_api_client.create_invite( - "12345", "67890", "test@example.com", {"send_messages"}, "sms_auth", [fake_uuid] - ) + with current_app.test_request_context("/whatever"): + invite_api_client.create_invite( + "12345", + "67890", + "test@example.com", + {"send_messages"}, + "sms_auth", + [fake_uuid], + ) mock_post.assert_called_once_with( - url="/service/{}/invite".format("67890"), + url=f"/service/{"67890"}/invite", data={ "auth_type": "sms_auth", "email_address": "test@example.com",