Skip to content

Commit

Permalink
Merge pull request #1386 from GSA/USN-COMPLY-51-Verify_State
Browse files Browse the repository at this point in the history
Verify state for login.gov
  • Loading branch information
ccostino authored Nov 7, 2024
2 parents cc30e7d + 1571143 commit 28d8469
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion app/service/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def add_user_to_service(service_id, user_id):
service = dao_fetch_service_by_id(service_id)
user = get_user_by_id(user_id=user_id)
if user in service.users:
error = "User id: {} already part of service id: {}".format(user_id, service_id)
error = f"User id: {user_id} already part of service id: {service_id}"
raise InvalidRequest(error, status_code=400)

data = request.get_json()
Expand Down
37 changes: 29 additions & 8 deletions app/service_invite/rest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import base64
import json
import os
from urllib.parse import unquote

from flask import Blueprint, current_app, jsonify, request
from itsdangerous import BadData, SignatureExpired
Expand Down Expand Up @@ -32,7 +33,7 @@
register_errors(service_invite)


def _create_service_invite(invited_user, nonce):
def _create_service_invite(invited_user, nonce, state):

template_id = current_app.config["INVITATION_EMAIL_TEMPLATE_ID"]

Expand All @@ -52,13 +53,14 @@ def _create_service_invite(invited_user, nonce):
data["invited_user_id"] = str(invited_user.id)
data["invited_user_email"] = invited_user.email_address

invite_redis_key = f"invite-data-{unquote(state)}"
redis_store.set(invite_redis_key, get_user_data_url_safe(data))

url = os.environ["LOGIN_DOT_GOV_REGISTRATION_URL"]

url = url.replace("NONCE", nonce) # handed from data sent from admin.

user_data_url_safe = get_user_data_url_safe(data)

url = url.replace("STATE", user_data_url_safe)
url = url.replace("STATE", state)

personalisation = {
"user_name": invited_user.from_user.name,
Expand All @@ -85,6 +87,8 @@ def _create_service_invite(invited_user, nonce):
)
send_notification_to_queue(saved_notification, queue=QueueNames.NOTIFY)

return data


@service_invite.route("/service/<service_id>/invite", methods=["POST"])
def create_invited_user(service_id):
Expand All @@ -94,13 +98,18 @@ def create_invited_user(service_id):
except KeyError:
current_app.logger.exception("nonce not found in submitted data.")
raise
try:
state = request_json.pop("state")
except KeyError:
current_app.logger.exception("state not found in submitted data.")
raise

invited_user = invited_user_schema.load(request_json)
save_invited_user(invited_user)

_create_service_invite(invited_user, nonce)
invite_data = _create_service_invite(invited_user, nonce, state)

return jsonify(data=invited_user_schema.dump(invited_user)), 201
return jsonify(data=invited_user_schema.dump(invited_user), invite=invite_data), 201


@service_invite.route("/service/<service_id>/invite/expired", methods=["GET"])
Expand Down Expand Up @@ -148,6 +157,18 @@ def resend_service_invite(service_id, invited_user_id):
Note:
This ignores the POST data entirely.
"""
request_json = request.get_json()
try:
nonce = request_json.pop("nonce")
except KeyError:
current_app.logger.exception("nonce not found in submitted data.")
raise
try:
state = request_json.pop("state")
except KeyError:
current_app.logger.exception("state not found in submitted data.")
raise

fetched = get_expired_invite_by_service_and_id(
service_id=service_id,
invited_user_id=invited_user_id,
Expand All @@ -161,9 +182,9 @@ def resend_service_invite(service_id, invited_user_id):

save_invited_user(update_dict)

_create_service_invite(fetched, current_app.config["ADMIN_BASE_URL"])
invite_data = _create_service_invite(fetched, nonce, state)

return jsonify(data=invited_user_schema.dump(fetched)), 200
return jsonify(data=invited_user_schema.dump(fetched), invite=invite_data), 200


def invited_user_url(invited_user_id, invite_link_host=None):
Expand Down
4 changes: 4 additions & 0 deletions tests/app/service_invite/test_service_invite_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def test_create_invited_user(
auth_type=AuthType.EMAIL,
folder_permissions=["folder_1", "folder_2", "folder_3"],
nonce="FakeNonce",
state="FakeState",
**extra_args,
)

Expand Down Expand Up @@ -110,6 +111,7 @@ def test_create_invited_user_without_auth_type(
"permissions": "send_messages,manage_service,manage_api_keys",
"folder_permissions": [],
"nonce": "FakeNonce",
"state": "FakeState",
}

json_resp = admin_request.post(
Expand All @@ -134,6 +136,7 @@ def test_create_invited_user_invalid_email(client, sample_service, mocker, fake_
"permissions": "send_messages,manage_service,manage_api_keys",
"folder_permissions": [fake_uuid, fake_uuid],
"nonce": "FakeNonce",
"state": "FakeState",
}

data = json.dumps(data)
Expand Down Expand Up @@ -235,6 +238,7 @@ def test_resend_expired_invite(
response = client.post(
url,
headers=[("Content-Type", "application/json"), auth_header],
data='{"nonce": "FakeNonce", "state": "FakeState"}',
)

assert response.status_code == 200
Expand Down

0 comments on commit 28d8469

Please sign in to comment.