From b68caf94d63919198482902ece3d98dd9844f748 Mon Sep 17 00:00:00 2001 From: Angela Tran Date: Mon, 25 Jul 2022 21:59:29 +0000 Subject: [PATCH 1/5] refactor: extract logic for returning response into separate function --- eligibility_server/verify.py | 43 +++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/eligibility_server/verify.py b/eligibility_server/verify.py index dd867e70..22131237 100644 --- a/eligibility_server/verify.py +++ b/eligibility_server/verify.py @@ -81,6 +81,28 @@ def _make_token(self, payload): encrypted_token.make_encrypted_token(client_public_key) return encrypted_token.serialize() + def _get_response(self, token_payload): + try: + # craft the response payload using parsed request token + sub, name, eligibility = token_payload["sub"], token_payload["name"], list(token_payload["eligibility"]) + resp_payload = dict( + jti=token_payload["jti"], + iss=settings.APP_NAME, + iat=int(datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).timestamp()), + ) + # sub format check + if re.match(r"^[A-Z]\d{7}$", sub): + # eligibility check against db + resp_payload["eligibility"] = self._db.check_user(sub, name, eligibility) + code = 200 + else: + resp_payload["error"] = {"sub": "invalid"} + code = 400 + # make a response token with appropriate response code + return self._make_token(resp_payload), code + except Exception as ex: + return str(ex), 500 + def get(self): """Respond to a verification request.""" # introduce small fake delay @@ -102,25 +124,6 @@ def get(self): return str(ex), 400 if token_payload: - try: - # craft the response payload using parsed request token - sub, name, eligibility = token_payload["sub"], token_payload["name"], list(token_payload["eligibility"]) - resp_payload = dict( - jti=token_payload["jti"], - iss=settings.APP_NAME, - iat=int(datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).timestamp()), - ) - # sub format check - if re.match(r"^[A-Z]\d{7}$", sub): - # eligibility check against db - resp_payload["eligibility"] = self._db.check_user(sub, name, eligibility) - code = 200 - else: - resp_payload["error"] = {"sub": "invalid"} - code = 400 - # make a response token with appropriate response code - return self._make_token(resp_payload), code - except Exception as ex: - return str(ex), 500 + return self._get_response(token_payload) else: return "Invalid token format", 400 From b3b39f6aefd0ec6fb9f88c0db8970d71aa2e1494 Mon Sep 17 00:00:00 2001 From: Angela Tran Date: Mon, 25 Jul 2022 22:22:11 +0000 Subject: [PATCH 2/5] test: add test for extracted function --- tests/test_verify.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/test_verify.py diff --git a/tests/test_verify.py b/tests/test_verify.py new file mode 100644 index 00000000..ad0959f5 --- /dev/null +++ b/tests/test_verify.py @@ -0,0 +1,12 @@ +import json +import uuid + +from eligibility_server.verify import Verify + + +def test_Verify_get_response(): + token_payload = json.loads(json.dumps(dict(sub="A1234567", name="Garcia", eligibility=["type1"], jti=str(uuid.uuid4())))) + + response = Verify()._get_response(token_payload) + + assert response[1] == 200 From 9f9ec1b0ae45bd23ba45f471754bc2cbbaee0d79 Mon Sep 17 00:00:00 2001 From: Angela Tran Date: Mon, 25 Jul 2022 22:51:37 +0000 Subject: [PATCH 3/5] feat: add SUB_FORMAT_REGEX setting and use in verify module --- eligibility_server/settings.py | 1 + eligibility_server/verify.py | 2 +- tests/requirements.txt | 1 + tests/test_verify.py | 3 ++- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/eligibility_server/settings.py b/eligibility_server/settings.py index dfca5f41..b23ab493 100644 --- a/eligibility_server/settings.py +++ b/eligibility_server/settings.py @@ -23,6 +23,7 @@ JWE_CEK_ENC = "A256CBC-HS512" JWE_ENCRYPTION_ALG = "RSA-OAEP" JWS_SIGNING_ALG = "RS256" +SUB_FORMAT_REGEX = os.environ.get("SUB_FORMAT_REGEX", ".*") # Hash Configs from .env file diff --git a/eligibility_server/verify.py b/eligibility_server/verify.py index 22131237..649fc880 100644 --- a/eligibility_server/verify.py +++ b/eligibility_server/verify.py @@ -91,7 +91,7 @@ def _get_response(self, token_payload): iat=int(datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).timestamp()), ) # sub format check - if re.match(r"^[A-Z]\d{7}$", sub): + if re.match(settings.SUB_FORMAT_REGEX, sub): # eligibility check against db resp_payload["eligibility"] = self._db.check_user(sub, name, eligibility) code = 200 diff --git a/tests/requirements.txt b/tests/requirements.txt index 7093b61a..8be74ac0 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,2 +1,3 @@ coverage pytest +pytest-mock diff --git a/tests/test_verify.py b/tests/test_verify.py index ad0959f5..6376605f 100644 --- a/tests/test_verify.py +++ b/tests/test_verify.py @@ -4,7 +4,8 @@ from eligibility_server.verify import Verify -def test_Verify_get_response(): +def test_Verify_get_response(mocker): + mocker.patch("eligibility_server.settings.SUB_FORMAT_REGEX", r"^[A-Z]\d{7}$") token_payload = json.loads(json.dumps(dict(sub="A1234567", name="Garcia", eligibility=["type1"], jti=str(uuid.uuid4())))) response = Verify()._get_response(token_payload) From 40ab13fcd29cde39a31e5e4108a28f9d6031ab8e Mon Sep 17 00:00:00 2001 From: Angela Tran Date: Mon, 25 Jul 2022 22:52:53 +0000 Subject: [PATCH 4/5] test: add unit test for new setting being read from env file --- tests/.env.settingstest | 1 + tests/test_settings.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/tests/.env.settingstest b/tests/.env.settingstest index 3c2419b3..59fd636e 100644 --- a/tests/.env.settingstest +++ b/tests/.env.settingstest @@ -1,2 +1,3 @@ IMPORT_FILE_PATH=data/server.csv INPUT_HASH_ALGO=sha512 +SUB_FORMAT_REGEX=test\\ diff --git a/tests/test_settings.py b/tests/test_settings.py index 83244d10..5cd07ce9 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -33,3 +33,8 @@ def test_hash_settings_env(): def test_debug(): if settings.DEBUG_MODE: assert True + + +@pytest.mark.settingstest +def test_sub_format_regex_env(): + assert settings.SUB_FORMAT_REGEX == "test\\" From 5351f17fb0c1b14436e1751523cbec1716d070f3 Mon Sep 17 00:00:00 2001 From: Angela Tran Date: Wed, 27 Jul 2022 22:59:05 +0000 Subject: [PATCH 5/5] test: add unit test for when sub does not match configured format --- tests/test_verify.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_verify.py b/tests/test_verify.py index 6376605f..e5874f97 100644 --- a/tests/test_verify.py +++ b/tests/test_verify.py @@ -4,10 +4,20 @@ from eligibility_server.verify import Verify -def test_Verify_get_response(mocker): +def test_Verify_get_response_sub_format_match(mocker): mocker.patch("eligibility_server.settings.SUB_FORMAT_REGEX", r"^[A-Z]\d{7}$") token_payload = json.loads(json.dumps(dict(sub="A1234567", name="Garcia", eligibility=["type1"], jti=str(uuid.uuid4())))) response = Verify()._get_response(token_payload) assert response[1] == 200 + + +def test_Verify_get_response_sub_format_no_match(mocker): + mocker.patch("eligibility_server.settings.SUB_FORMAT_REGEX", r"^[A-Z]\d{7}$") + # "sub" value does not match the format regex + token_payload = json.loads(json.dumps(dict(sub="nomatch", name="Garcia", eligibility=["type1"], jti=str(uuid.uuid4())))) + + response = Verify()._get_response(token_payload) + + assert response[1] == 400