From 23e66db2a9da506639e989d0dd1e152ffe34118b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 2 Apr 2024 13:18:21 -0700 Subject: [PATCH 1/2] make state non-arbitrary --- app/dao/users_dao.py | 14 +++++++++++++- app/organization/invite_rest.py | 11 ++++++++++- app/service_invite/rest.py | 12 +++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/dao/users_dao.py b/app/dao/users_dao.py index 7b2f2e609..048c7ea22 100644 --- a/app/dao/users_dao.py +++ b/app/dao/users_dao.py @@ -2,6 +2,8 @@ import uuid from datetime import datetime, timedelta from secrets import randbelow +import sqlalchemy +from flask import current_app from sqlalchemy import func from sqlalchemy.orm import joinedload @@ -39,7 +41,17 @@ def get_login_gov_user(login_uuid, email_address): user = User.query.filter_by(login_uuid=login_uuid).first() if user: if user.email_address != email_address: - save_user_attribute(user, {"email_address": email_address}) + try: + save_user_attribute(user, {"email_address": email_address}) + except sqlalchemy.exc.IntegrityError as ie: + # We are trying to change the email address as a courtesy, + # based on the assumption that the user has somehow changed their + # address in login.gov. + # But if we cannot change the email address, at least we don't + # want to fail here, otherwise the user will be locked out. + current_app.logger.error(ie) + db.session.rollback() + return user # Remove this 1 July 2025, all users should have login.gov uuids by now user = User.query.filter_by(email_address=email_address).first() diff --git a/app/organization/invite_rest.py b/app/organization/invite_rest.py index d7c956ab0..af20ab08f 100644 --- a/app/organization/invite_rest.py +++ b/app/organization/invite_rest.py @@ -52,6 +52,15 @@ def invite_user_to_org(organization_id): current_app.config["ORGANIZATION_INVITATION_EMAIL_TEMPLATE_ID"] ) + token = generate_token( + str(invited_org_user.email_address), + current_app.config["SECRET_KEY"], + current_app.config["DANGEROUS_SALT"], + ) + url = os.environ["LOGIN_DOT_GOV_REGISTRATION_URL"] + url = url.replace("NONCE", token) + url = url.replace("STATE", token) + personalisation = { "user_name": ( "The Notify.gov team" @@ -59,7 +68,7 @@ def invite_user_to_org(organization_id): else invited_org_user.invited_by.name ), "organization_name": invited_org_user.organization.name, - "url": os.environ["LOGIN_DOT_GOV_REGISTRATION_URL"], + "url": url, } saved_notification = persist_notification( template_id=template.id, diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index 849261cb2..264fb4a4b 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -37,10 +37,20 @@ def _create_service_invite(invited_user, invite_link_host): template = dao_get_template_by_id(template_id) service = Service.query.get(current_app.config["NOTIFY_SERVICE_ID"]) + + token = generate_token( + str(invited_user.email_address), + current_app.config["SECRET_KEY"], + current_app.config["DANGEROUS_SALT"], + ) + url = os.environ["LOGIN_DOT_GOV_REGISTRATION_URL"] + url = url.replace("NONCE", token) + url = url.replace("STATE", token) + personalisation = { "user_name": invited_user.from_user.name, "service_name": invited_user.service.name, - "url": os.environ["LOGIN_DOT_GOV_REGISTRATION_URL"], + "url": url, } saved_notification = persist_notification( From 7c3c81b700998388a3d93b715093f4272eb3c015 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 2 Apr 2024 13:59:59 -0700 Subject: [PATCH 2/2] fix --- .github/workflows/deploy-demo.yml | 2 +- .github/workflows/deploy-prod.yml | 2 +- .github/workflows/deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index 1d2a7d4ac..d578cc356 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -57,7 +57,7 @@ jobs: NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} NOTIFY_E2E_TEST_EMAIL: ${{ secrets.NOTIFY_E2E_TEST_EMAIL }} NOTIFY_E2E_TEST_PASSWORD: ${{ secrets.NOTIFY_E2E_TEST_PASSWORD }} - LOGIN_DOT_GOV_REGISTRATION_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=01234567890123456789012345&prompt=select_account&redirect_uri=https://notify-demo.app.cloud.gov/set-up-your-profile&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop" + LOGIN_DOT_GOV_REGISTRATION_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-demo.app.cloud.gov/set-up-your-profile&response_type=code&scope=openid+email&state=STATE" with: cf_username: ${{ secrets.CLOUDGOV_USERNAME }} diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 8e18d729b..a1aa66559 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -61,7 +61,7 @@ jobs: NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} NOTIFY_E2E_TEST_EMAIL: ${{ secrets.NOTIFY_E2E_TEST_EMAIL }} NOTIFY_E2E_TEST_PASSWORD: ${{ secrets.NOTIFY_E2E_TEST_PASSWORD }} - LOGIN_DOT_GOV_REGISTRATION_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=01234567890123456789012345&prompt=select_account&redirect_uri=https://beta.notify.gov/set-up-your-profile&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop" + LOGIN_DOT_GOV_REGISTRATION_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://beta.notify.gov/set-up-your-profile&response_type=code&scope=openid+email&state=STATE" with: cf_username: ${{ secrets.CLOUDGOV_USERNAME }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 24c9118b3..63ca50df8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -62,7 +62,7 @@ jobs: NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} NOTIFY_E2E_TEST_EMAIL: ${{ secrets.NOTIFY_E2E_TEST_EMAIL }} NOTIFY_E2E_TEST_PASSWORD: ${{ secrets.NOTIFY_E2E_TEST_PASSWORD }} - LOGIN_DOT_GOV_REGISTRATION_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=01234567890123456789012345&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/set-up-your-profile&response_type=code&scope=openid+email&state=abcdefghijklmnopabcdefghijklmnop" + LOGIN_DOT_GOV_REGISTRATION_URL: "https://secure.login.gov/openid_connect/authorize?acr_values=http%3A%2F%2Fidmanagement.gov%2Fns%2Fassurance%2Fial%2F1&client_id=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:notify-gov&nonce=NONCE&prompt=select_account&redirect_uri=https://notify-staging.app.cloud.gov/set-up-your-profile&response_type=code&scope=openid+email&state=STATE" with: cf_username: ${{ secrets.CLOUDGOV_USERNAME }}