From 4428df7dd5bdfe90f1fe43c019a8fbf6fe562007 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 26 Mar 2024 15:06:26 +0000 Subject: [PATCH 1/5] Reformat nested list --- docs/login_dot_gov.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/login_dot_gov.md b/docs/login_dot_gov.md index 5f985faa4..29b65d989 100644 --- a/docs/login_dot_gov.md +++ b/docs/login_dot_gov.md @@ -4,11 +4,11 @@ How to integrate with the login.gov sandbox: https://dashboard.int.identitysand 1. Create a team and a user over in the login.gov sandbox. 2. Create a test app: - a. you will need to create a unique client id that looks like: urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov - b. Select OpenIdConnect and private key JWT - c. select authentication only - d. select MFA required + remember device 30 days only (AAL1) - e. set redirect urls like: http://localhost:6012/sign-in + - you will need to create a unique client id that looks like: urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:test_notify_gov + - Select OpenIdConnect and private key JWT + - select authentication only + - select MFA required + remember device 30 days only (AAL1) + - set redirect urls like: http://localhost:6012/sign-in 3. generate a cert: openssl req -nodes -x509 -days 365 -newkey rsa:2048 -keyout private.pem -out public.crt 4. Upload the public.crt to your app in the sandbox 5. put the private.pem contents and public.crt contents in github secrets (?) From b29c2a3a623827355ad1533f1d30fd299f4c5da0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 28 Mar 2024 11:15:10 -0700 Subject: [PATCH 2/5] debug staging --- app/main/views/verify.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/main/views/verify.py b/app/main/views/verify.py index f6bb47ab7..85c138ea9 100644 --- a/app/main/views/verify.py +++ b/app/main/views/verify.py @@ -9,6 +9,7 @@ from app.extensions import redis_client from app.main import main from app.main.forms import TwoFactorForm from app.models.user import InvitedOrgUser, InvitedUser, User +from app.utils import hilite from app.utils.login import redirect_to_sign_in @@ -67,9 +68,10 @@ def activate_user(user_id): user = User.from_id(user_id) # This is the login.gov path - login_gov_invite_data = redis_client.get(f"service-invite-{user.email_address}") + login_gov_invite_data = redis_client.raw_get(f"service-invite-{user.email_address}") if login_gov_invite_data: login_gov_invite_data = json.loads(login_gov_invite_data.decode("utf8")) + current_app.logger.info(hilite(f"LOGIN_GOV_INVITE_DATA {login_gov_invite_data}")) # This is the deprecated path for organization invites where we get id from session session["current_session_id"] = user.current_session_id @@ -85,6 +87,7 @@ def activate_user(user_id): return redirect(url_for("main.service_dashboard", service_id=service_id)) elif login_gov_invite_data: service_id = login_gov_invite_data["service_id"] + current_app.logger.info(hilite(f"SERVICE_ID={service_id}")) user.add_to_service( service_id, @@ -98,8 +101,11 @@ def activate_user(user_id): invited_org_user = InvitedOrgUser.from_session() if invited_org_user: user_api_client.add_user_to_organization(invited_org_user.organization, user_id) - elif redis_client.get(f"organization-invite-{user.email_address}"): - organization_id = redis_client.get(f"organization-invite-{user.email_address}") + elif redis_client.raw_get(f"organization-invite-{user.email_address}"): + organization_id = redis_client.raw_get( + f"organization-invite-{user.email_address}" + ) + current_app.logger.info(hilite(f"ORGANIZATION_ID FROM REDIS {organization_id}")) user_api_client.add_user_to_organization( organization_id.decode("utf8"), user_id ) From 9b1c9b8ccf0b30655a1ede7fb15fd2cf0e7b9830 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 28 Mar 2024 11:35:25 -0700 Subject: [PATCH 3/5] ugh --- app/main/views/verify.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/main/views/verify.py b/app/main/views/verify.py index 85c138ea9..1250db150 100644 --- a/app/main/views/verify.py +++ b/app/main/views/verify.py @@ -68,7 +68,7 @@ def activate_user(user_id): user = User.from_id(user_id) # This is the login.gov path - login_gov_invite_data = redis_client.raw_get(f"service-invite-{user.email_address}") + login_gov_invite_data = redis_client.get(f"service-invite-{user.email_address}") if login_gov_invite_data: login_gov_invite_data = json.loads(login_gov_invite_data.decode("utf8")) current_app.logger.info(hilite(f"LOGIN_GOV_INVITE_DATA {login_gov_invite_data}")) @@ -101,7 +101,7 @@ def activate_user(user_id): invited_org_user = InvitedOrgUser.from_session() if invited_org_user: user_api_client.add_user_to_organization(invited_org_user.organization, user_id) - elif redis_client.raw_get(f"organization-invite-{user.email_address}"): + elif redis_client.get(f"organization-invite-{user.email_address}"): organization_id = redis_client.raw_get( f"organization-invite-{user.email_address}" ) From f092ad8f98e70692ad170ed3e6636761826d8556 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 28 Mar 2024 13:20:22 -0700 Subject: [PATCH 4/5] handle case where existing user is invited to another service --- app/main/views/register.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/main/views/register.py b/app/main/views/register.py index 7069270ea..e6350c8f7 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -160,13 +160,16 @@ def set_up_your_profile(): # create the user # TODO we have to provide something for password until that column goes away # TODO ideally we would set the user's preferred timezone here as well - user = User.register( - name=form.name.data, - email_address=user_email, - mobile_number=form.mobile_number.data, - password=str(uuid.uuid4()), - auth_type="sms_auth", - ) + + user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email) + if user is None: + user = User.register( + name=form.name.data, + email_address=user_email, + mobile_number=form.mobile_number.data, + password=str(uuid.uuid4()), + auth_type="sms_auth", + ) # activate the user user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email) From e5136d9fa7ecc8dd039f2971e6f3dff5467e2ed2 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 29 Mar 2024 07:45:16 -0700 Subject: [PATCH 5/5] return None if no user --- app/notify_client/user_api_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/notify_client/user_api_client.py b/app/notify_client/user_api_client.py index a17059e52..e85225838 100644 --- a/app/notify_client/user_api_client.py +++ b/app/notify_client/user_api_client.py @@ -50,8 +50,8 @@ class UserApiClient(NotifyAdminAPIClient): "/user/get-login-gov-user", data={"login_uuid": user_uuid, "email": email_address}, ) - if user_data is None: - raise Exception("User not found") + if user_data is None or user_data.get("data") is None: + return None return user_data["data"] def get_user_by_email_or_none(self, email_address):