diff --git a/app/main/views/register.py b/app/main/views/register.py index 5bd4d08c7..1df991733 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -17,9 +17,8 @@ from flask_login import current_user from app import user_api_client from app.main import main -from app.main.forms import ( +from app.main.forms import ( # RegisterUserFromInviteForm, RegisterUserForm, - RegisterUserFromInviteForm, RegisterUserFromOrgInviteForm, SetupUserProfileForm, ) @@ -43,39 +42,10 @@ def register(): return render_template("views/register.html", form=form) -@main.route("/register-from-invite", methods=["GET", "POST"]) -# TODO This is deprecated, we are now handling invites in the -# login.gov workflow -def register_from_invite(): - invited_user = InvitedUser.from_session() - if not invited_user: - abort(404) - - form = RegisterUserFromInviteForm(invited_user) - - if form.validate_on_submit(): - if ( - form.service.data != invited_user.service - or form.email_address.data != invited_user.email_address - ): - abort(400) - _do_registration(form, send_email=False, send_sms=invited_user.sms_auth) - invited_user.accept_invite() - if invited_user.sms_auth: - return redirect(url_for("main.verify")) - else: - # we've already proven this user has email because they clicked the invite link, - # so just activate them straight away - return activate_user(session["user_details"]["id"]) - - return render_template( - "views/register-from-invite.html", invited_user=invited_user, form=form - ) - - @main.route("/register-from-org-invite", methods=["GET", "POST"]) # TODO This is deprecated, we are now handling invites in the -# login.gov workflow +# login.gov workflow. Leaving it here until we write the new +# org registration. def register_from_org_invite(): invited_org_user = InvitedOrgUser.from_session() if not invited_org_user: @@ -178,27 +148,35 @@ def invited_user_accept_invite(invited_user_id): invited_user.accept_invite() +def debug_msg(msg): + current_app.logger.debug(hilite(msg)) + + def _handle_login_dot_gov_invite(code, state, form): access_token = sign_in._get_access_token(code, state) + debug_msg("Got the access token for login.gov") user_email, user_uuid = sign_in._get_user_email_and_uuid(access_token) + debug_msg( + f"Got the user_email {user_email} and user_uuid {user_uuid} from login.gov" + ) invite_data = state.encode("utf8") invite_data = base64.b64decode(invite_data) invite_data = json.loads(invite_data) invited_user_id = invite_data["invited_user_id"] invited_user_email_address = get_invited_user_email_address(invited_user_id) + debug_msg(f"email address from the invite_date is {invited_user_email_address}") if user_email.lower() != invited_user_email_address.lower(): + debug_msg("invited user email did not match expected email, abort(403)") flash("You cannot accept an invite for another person.") session.pop("invited_user_id", None) abort(403) else: invited_user_accept_invite() - current_app.logger.debug( - hilite( - f"INVITED USER {invited_user_email_address} to service {invite_data['service_id']}" - ) + debug_msg( + f"invited user {invited_user_email_address} to service {invite_data['service_id']}" ) - current_app.logger.debug(hilite("ACCEPTED INVITE")) + debug_msg("accepted invite") user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email) if user is None: user = User.register( @@ -208,10 +186,12 @@ def _handle_login_dot_gov_invite(code, state, form): password=str(uuid.uuid4()), auth_type="sms_auth", ) + debug_msg(f"registered user {form.name.data} with email {user_email}") # activate the user user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email) activate_user(user["id"]) + debug_msg("activated user") usr = User.from_id(user["id"]) usr.add_to_service( invite_data["service_id"], @@ -219,9 +199,7 @@ def _handle_login_dot_gov_invite(code, state, form): invite_data["folder_permissions"], invite_data["from_user_id"], ) - current_app.logger.debug( - hilite( - f"Added user {usr.email_address} to service {invite_data['service_id']}" - ) + debug_msg( + f"Added user {usr.email_address} to service {invite_data['service_id']}" ) return redirect(url_for("main.show_accounts_or_dashboard")) diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py index 38202dfb2..a6d622c12 100644 --- a/tests/app/main/views/test_accept_invite.py +++ b/tests/app/main/views/test_accept_invite.py @@ -431,71 +431,6 @@ def test_existing_signed_out_user_accept_invite_redirects_to_sign_in( ) -@pytest.mark.usefixtures("_mock_no_users_for_service") -def test_new_user_accept_invite_calls_api_and_redirects_to_registration( - client_request, - service_one, - mock_check_invite_token, - mock_dont_get_user_by_email, - mock_add_user_to_service, - mock_get_service, - mocker, -): - client_request.logout() - client_request.get( - "main.accept_invite", - token="thisisnotarealtoken", - _expected_redirect="/register-from-invite", - ) - - mock_check_invite_token.assert_called_with("thisisnotarealtoken") - mock_dont_get_user_by_email.assert_called_with("invited_user@test.gsa.gov") - - -@pytest.mark.usefixtures("_mock_no_users_for_service") -def test_new_user_accept_invite_calls_api_and_views_registration_page( - client_request, - service_one, - sample_invite, - mock_check_invite_token, - mock_dont_get_user_by_email, - mock_get_invited_user_by_id, - mock_add_user_to_service, - mock_get_service, - mocker, -): - client_request.logout() - page = client_request.get( - "main.accept_invite", - token="thisisnotarealtoken", - _follow_redirects=True, - ) - - mock_check_invite_token.assert_called_with("thisisnotarealtoken") - mock_dont_get_user_by_email.assert_called_with("invited_user@test.gsa.gov") - mock_get_invited_user_by_id.assert_called_once_with(sample_invite["id"]) - - assert page.h1.string.strip() == "Create an account" - - assert normalize_spaces(page.select_one("main p").text) == ( - "Your account will be created with this email address: " - "invited_user@test.gsa.gov" - ) - - form = page.find("form") - name = form.find("input", id="name") - password = form.find("input", id="password") - service = form.find("input", type="hidden", id="service") - email = form.find("input", type="hidden", id="email_address") - - assert email - assert email.attrs["value"] == "invited_user@test.gsa.gov" - assert name - assert password - assert service - assert service.attrs["value"] == service_one["id"] - - def test_cancelled_invited_user_accepts_invited_redirect_to_cancelled_invitation( client_request, mock_get_user, @@ -562,65 +497,6 @@ def test_new_user_accept_invite_with_malformed_token( ) -@pytest.mark.usefixtures("_mock_no_users_for_service") -def test_new_user_accept_invite_completes_new_registration_redirects_to_verify( - client_request, - service_one, - sample_invite, - api_user_active, - mock_check_invite_token, - mock_dont_get_user_by_email, - mock_email_is_not_already_in_use, - mock_register_user, - mock_send_verify_code, - mock_get_invited_user_by_id, - mock_accept_invite, - mock_add_user_to_service, - mock_get_service, - mocker, -): - client_request.logout() - expected_redirect_location = "/register-from-invite" - - client_request.get( - "main.accept_invite", - token="thisisnotarealtoken", - _expected_redirect=expected_redirect_location, - ) - with client_request.session_transaction() as session: - assert session.get("invited_user_id") == sample_invite["id"] - - data = { - "service": sample_invite["service"], - "email_address": sample_invite["email_address"], - "from_user": sample_invite["from_user"], - "password": "longpassword", - "mobile_number": "+12027890123", - "name": "Invited User", - "auth_type": "email_auth", - } - - expected_redirect_location = "/verify" - client_request.post( - "main.register_from_invite", - _data=data, - _expected_redirect=expected_redirect_location, - ) - - mock_send_verify_code.assert_called_once_with(ANY, "sms", data["mobile_number"]) - mock_get_invited_user_by_id.assert_called_once_with(sample_invite["id"]) - - mock_register_user.assert_called_with( - data["name"], - data["email_address"], - data["mobile_number"], - data["password"], - data["auth_type"], - ) - - assert mock_accept_invite.call_count == 1 - - def test_signed_in_existing_user_cannot_use_anothers_invite( client_request, mocker, diff --git a/tests/app/main/views/test_register.py b/tests/app/main/views/test_register.py index 2a13ebb9d..b491a1b53 100644 --- a/tests/app/main/views/test_register.py +++ b/tests/app/main/views/test_register.py @@ -219,144 +219,6 @@ def test_register_with_existing_email_sends_emails( ) -@pytest.mark.parametrize( - ("email_address", "expected_value"), - [ - ("first.last@example.com", "First Last"), - ("first.middle.last@example.com", "First Middle Last"), - ("first.m.last@example.com", "First Last"), - ("first.last-last@example.com", "First Last-Last"), - ("first.o'last@example.com", "First O’Last"), - ("first.last+testing@example.com", "First Last"), - ("first.last+testing+testing@example.com", "First Last"), - ("first.last6@example.com", "First Last"), - ("first.last.212@example.com", "First Last"), - ("first.2.last@example.com", "First Last"), - ("first.2b.last@example.com", "First Last"), - ("first.1.2.3.last@example.com", "First Last"), - ("first.last.1.2.3@example.com", "First Last"), - # Instances where we can’t make a good-enough guess: - ("example123@example.com", None), - ("f.last@example.com", None), - ("f.m.last@example.com", None), - ], -) -def test_shows_name_on_registration_page_from_invite( - client_request, - fake_uuid, - email_address, - expected_value, - sample_invite, - mock_get_invited_user_by_id, -): - sample_invite["email_address"] = email_address - with client_request.session_transaction() as session: - session["invited_user_id"] = sample_invite - - page = client_request.get("main.register_from_invite") - assert page.select_one("input[name=name]").get("value") == expected_value - - -def test_shows_hidden_email_address_on_registration_page_from_invite( - client_request, - fake_uuid, - sample_invite, - mock_get_invited_user_by_id, -): - with client_request.session_transaction() as session: - session["invited_user_id"] = sample_invite - - page = client_request.get("main.register_from_invite") - assert normalize_spaces(page.select_one("main p").text) == ( - "Your account will be created with this email address: invited_user@test.gsa.gov" - ) - hidden_input = page.select_one("form .usa-sr-only input") - for attr, value in ( - ("type", "email"), - ("name", "username"), - ("id", "username"), - ("value", "invited_user@test.gsa.gov"), - ("disabled", "disabled"), - ("tabindex", "-1"), - ("aria-hidden", "true"), - ("autocomplete", "username"), - ): - assert hidden_input[attr] == value - - -@pytest.mark.parametrize( - "extra_data", - [ - {}, - # The username field is present in the page but the POST request - # should ignore it - {"username": "invited@user.com"}, - {"username": "anythingelse@example.com"}, - ], -) -def test_register_from_invite( - client_request, - fake_uuid, - mock_email_is_not_already_in_use, - mock_register_user, - mock_send_verify_code, - mock_accept_invite, - mock_get_invited_user_by_id, - sample_invite, - extra_data, -): - client_request.logout() - with client_request.session_transaction() as session: - session["invited_user_id"] = sample_invite["id"] - client_request.post( - "main.register_from_invite", - _data=dict( - name="Registered in another Browser", - email_address=sample_invite["email_address"], - mobile_number="+12024900460", - service=sample_invite["service"], - password="somreallyhardthingtoguess", - auth_type="sms_auth", - **extra_data, - ), - _expected_redirect=url_for("main.verify"), - ) - mock_register_user.assert_called_once_with( - "Registered in another Browser", - sample_invite["email_address"], - "+12024900460", - "somreallyhardthingtoguess", - "sms_auth", - ) - mock_get_invited_user_by_id.assert_called_once_with(sample_invite["id"]) - - -def test_register_from_invite_when_user_registers_in_another_browser( - client_request, - api_user_active, - mock_get_user_by_email, - mock_accept_invite, - mock_get_invited_user_by_id, - sample_invite, -): - client_request.logout() - sample_invite["email_address"] = api_user_active["email_address"] - with client_request.session_transaction() as session: - session["invited_user_id"] = sample_invite["id"] - client_request.post( - "main.register_from_invite", - _data={ - "name": "Registered in another Browser", - "email_address": api_user_active["email_address"], - "mobile_number": api_user_active["mobile_number"], - "service": sample_invite["service"], - "password": "somreallyhardthingtoguess", - "auth_type": "sms_auth", - }, - _expected_redirect=url_for("main.verify"), - ) - - @pytest.mark.parametrize( "invite_email_address", ["gov-user@gsa.gov", "non-gov-user@example.com"] ) @@ -520,24 +382,6 @@ def test_cannot_register_with_sms_auth_and_missing_mobile_number( assert err.attrs["data-error-label"] == "mobile_number" -def test_register_from_invite_form_doesnt_show_mobile_number_field_if_email_auth( - client_request, - sample_invite, - mock_get_invited_user_by_id, -): - client_request.logout() - sample_invite["auth_type"] = "email_auth" - with client_request.session_transaction() as session: - session["invited_user_id"] = sample_invite["id"] - - page = client_request.get("main.register_from_invite") - - assert ( - page.find("input", attrs={"name": "auth_type"}).attrs["value"] == "email_auth" - ) - assert page.find("input", attrs={"name": "mobile_number"}) is None - - def test_handle_login_dot_gov_invite_bad_email(client_request, mocker): mocker.patch( diff --git a/tests/app/test_navigation.py b/tests/app/test_navigation.py index 4634a65cf..6f1cf58eb 100644 --- a/tests/app/test_navigation.py +++ b/tests/app/test_navigation.py @@ -146,7 +146,6 @@ EXCLUDED_ENDPOINTS = tuple( "received_text_messages_callback", "redact_template", "register", - "register_from_invite", "register_from_org_invite", "registration_continue", "remove_user_from_organization",