From a2518b822998086e57886a0160c52b0d8b214504 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 24 Apr 2024 10:51:47 -0700 Subject: [PATCH 1/3] fix service invites --- app/organization/invite_rest.py | 8 ----- poetry.lock | 2 +- .../test_service_invite_rest.py | 31 ------------------- 3 files changed, 1 insertion(+), 40 deletions(-) diff --git a/app/organization/invite_rest.py b/app/organization/invite_rest.py index af20ab08f..9889bb157 100644 --- a/app/organization/invite_rest.py +++ b/app/organization/invite_rest.py @@ -89,14 +89,6 @@ def invite_user_to_org(organization_id): ex=1800, ) - # This is for the login.gov path, note 24 hour expiry to match - # The expiration of invitations. - redis_key = f"organization-invite-{invited_org_user.email_address}" - redis_store.set( - redis_key, - organization_id, - ex=3600 * 24, - ) send_notification_to_queue(saved_notification, queue=QueueNames.NOTIFY) return jsonify(data=invited_org_user.serialize()), 201 diff --git a/poetry.lock b/poetry.lock index bc810f891..5f002b800 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2490,6 +2490,7 @@ files = [ {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] @@ -3531,7 +3532,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, diff --git a/tests/app/service_invite/test_service_invite_rest.py b/tests/app/service_invite/test_service_invite_rest.py index 17f8a553c..e736a3042 100644 --- a/tests/app/service_invite/test_service_invite_rest.py +++ b/tests/app/service_invite/test_service_invite_rest.py @@ -398,34 +398,3 @@ def test_get_invited_user_404s_if_invite_doesnt_exist( _expected_status=404, ) assert json_resp["result"] == "error" - - -def test_get_service_invite_data_with_invite(admin_request, mocker): - redis_key = "service-invite-j.k@fake.gov" - expected_user_data = b'{"from_user_id": ["7480cdcf-fa31-42b8-a4bf-2cd4d7a9b4f4"], "service_id": "721b0aa6-2447-4bcd-91fc-26d576f2bbff", "permissions": ["manage_api_keys"], "folder_permissions": []}' # noqa - expected_status = 200 - - mocker.patch( - "app.service_invite.rest.redis_store.raw_get", return_value=expected_user_data - ) - json_resp = json.loads( - admin_request.get( - "service_invite.get_service_invite_data", - redis_key=redis_key, - _expected_status=expected_status, - ) - ) - assert json_resp["permissions"] == ["manage_api_keys"] - - -def test_get_service_invite_data_without_invite(admin_request, mocker): - redis_key = "service-invite-j.k@fake.gov" - - mocker.patch("app.service_invite.rest.redis_store.raw_get", return_value=None) - with pytest.raises(BaseException, match="No service invite data"): - json.loads( - admin_request.get( - "service_invite.get_service_invite_data", - redis_key=redis_key, - ) - ) From f1f2f728af5d9ea91afb953b0c22c5758910fa5e Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 24 Apr 2024 14:06:43 -0700 Subject: [PATCH 2/3] cleanup --- app/service_invite/rest.py | 61 ++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index da7fe5794..333c5dbac 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -1,3 +1,4 @@ +import base64 import json import os from datetime import datetime @@ -48,9 +49,28 @@ def _create_service_invite(invited_user, invite_link_host): current_app.config["SECRET_KEY"], current_app.config["DANGEROUS_SALT"], ) + + # The raw permissions are in the form "a,b,c,d" + # but need to be in the form ["a", "b", "c", "d"] + data = {} + permissions = invited_user.permissions + permissions = permissions.split(",") + permission_list = [] + for permission in permissions: + permission_list.append(f"{permission}") + data["from_user_id"] = (str(invited_user.from_user.id),) + data["service_id"] = str(invited_user.service.id) + data["permissions"] = permission_list + data["folder_permissions"] = invited_user.folder_permissions + data["invited_user_id"] = str(invited_user.id) + data["invited_user_email"] = invited_user.email_address + url = os.environ["LOGIN_DOT_GOV_REGISTRATION_URL"] url = url.replace("NONCE", token) - url = url.replace("STATE", token) + + user_data_url_safe = get_user_data_url_safe(data) + + url = url.replace("STATE", user_data_url_safe) personalisation = { "user_name": invited_user.from_user.name, @@ -75,32 +95,6 @@ def _create_service_invite(invited_user, invite_link_host): json.dumps(personalisation), ex=1800, ) - # The raw permissions are in the form "a,b,c,d" - # but need to be in the form ["a", "b", "c", "d"] - data = {} - permissions = invited_user.permissions - permissions = permissions.split(",") - permission_list = [] - for permission in permissions: - permission_list.append(f"{permission}") - data["from_user_id"] = (str(invited_user.from_user.id),) - data["service_id"] = str(invited_user.service.id) - data["permissions"] = permission_list - data["folder_permissions"] = invited_user.folder_permissions - - # This is for the login.gov service invite on the - # "Set Up Your Profile" path. - redis_key = f"service-invite-{invited_user.email_address}" - redis_store.raw_set( - redis_key, - json.dumps(data), - ex=3600 * 24, - ) - # TODO REMOVE DEBUG - print(hilite(f"Save this data {data} with this redis_key {redis_key}")) - did_we_save_it = redis_store.raw_get(redis_key) - print(hilite(f"Did we save the data successfully? {did_we_save_it}")) - # END DEBUG send_notification_to_queue(saved_notification, queue=QueueNames.NOTIFY) @@ -225,12 +219,7 @@ def validate_service_invitation_token(token): return jsonify(data=invited_user_schema.dump(invited_user)), 200 -@service_invite.route("/service/invite/redis/", methods=["GET"]) -def get_service_invite_data(redis_key): - service_invite_data = redis_store.raw_get(redis_key) - # We can't log this because key may contain PII (email address) - if service_invite_data is None: - raise Exception("No service invite data") - else: - service_invite_data = service_invite_data.decode("utf8") - return jsonify(service_invite_data), 200 +def get_user_data_url_safe(data): + data = json.dumps(data) + data = base64.b64encode(data.encode("utf8")) + return data.decode("utf8") From bd80ef16bab41e403d32be8660726a81523246ee Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 25 Apr 2024 13:21:26 -0700 Subject: [PATCH 3/3] code review feedback --- app/service_invite/rest.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index 333c5dbac..b61d131ee 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -55,12 +55,9 @@ def _create_service_invite(invited_user, invite_link_host): data = {} permissions = invited_user.permissions permissions = permissions.split(",") - permission_list = [] - for permission in permissions: - permission_list.append(f"{permission}") - data["from_user_id"] = (str(invited_user.from_user.id),) + data["from_user_id"] = (str(invited_user.from_user.id)) data["service_id"] = str(invited_user.service.id) - data["permissions"] = permission_list + data["permissions"] = permissions data["folder_permissions"] = invited_user.folder_permissions data["invited_user_id"] = str(invited_user.id) data["invited_user_email"] = invited_user.email_address