Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: configurable sub format #99

Merged
merged 5 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eligibility_server/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
43 changes: 23 additions & 20 deletions eligibility_server/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(settings.SUB_FORMAT_REGEX, 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
Expand All @@ -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)
Copy link
Member

@thekaveman thekaveman Aug 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine some of this will be cleaned up when eligibility-api is introduced.

It could be useful to split the logic of creating the response token from validating the eligibility / doing that check, for testing etc.

else:
return "Invalid token format", 400
1 change: 1 addition & 0 deletions tests/.env.settingstest
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
IMPORT_FILE_PATH=data/server.csv
INPUT_HASH_ALGO=sha512
SUB_FORMAT_REGEX=test\\
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
coverage
pytest
pytest-mock
5 changes: 5 additions & 0 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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\\"
23 changes: 23 additions & 0 deletions tests/test_verify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import json
import uuid

from eligibility_server.verify import Verify


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