Skip to content

Commit

Permalink
Add request encryption & decryption tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nanomad committed Jun 23, 2024
1 parent e2a47a7 commit 6058885
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/saic_ismart_client_ng/net/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ async def encrypt_request(
base_uri: str,
region: str,
tenant_id: str,
user_token: Optional[str],
class_name: str,
user_token: str = "",
class_name: str = "",
):
original_request_url = modified_request.url
original_content_type = modified_request.headers.get("Content-Type") # 'application/x-www-form-urlencoded'
Expand Down
157 changes: 116 additions & 41 deletions tests/security_test.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,123 @@
import datetime
import json
import unittest

import httpx
import pytest

from saic_ismart_client_ng.net import security


class TestGetAppVerificationString(unittest.TestCase):

def test_get_app_verification_string_valid(self):
clazz_simple_name = 'SampleClass'
request_path = '/api/v1/data'
current_ts = '20230514123000'
tenant_id = '1234'
content_type = 'application/json'
request_content = '{"key": "value"}'
user_token = 'dummy_token'

result = security.get_app_verification_string(clazz_simple_name, request_path, current_ts, tenant_id,
content_type, request_content, user_token)

self.assertEqual('afd4eaf98af2d964f8ea840fc144ee7bae95dbeeeb251d5e3a01371442f92eeb', result)

def test_with_empty_request_path(self):
clazz_simple_name = 'SampleClass'
request_path = ''
current_ts = '20230514123000'
tenant_id = '1234'
content_type = 'application/json'
request_content = '{"key": "value"}'
user_token = 'dummy_token'

result = security.get_app_verification_string(clazz_simple_name, request_path, current_ts, tenant_id,
content_type, request_content, user_token)
self.assertEqual('ff8cb13ebcce5958e7fbfe602716c653fd72ce78842be87b6d50dccede198735', result)

def test_with_no_request_content(self):
clazz_simple_name = 'SampleClass'
request_path = '/api/v1/data'
current_ts = '20230514123000'
tenant_id = '1234'
content_type = 'application/json'
request_content = ''
user_token = 'dummy_token'

result = security.get_app_verification_string(clazz_simple_name, request_path, current_ts, tenant_id,
content_type, request_content, user_token)
self.assertEqual('332c85836aa9afc864282436a740eb2cc778fafd1fea74dd887c1f8de5056de0', result)
def test_get_app_verification_string_valid():
clazz_simple_name = 'SampleClass'
request_path = '/api/v1/data'
current_ts = '20230514123000'
tenant_id = '1234'
content_type = 'application/json'
request_content = '{"key": "value"}'
user_token = 'dummy_token'

result = security.get_app_verification_string(clazz_simple_name, request_path, current_ts, tenant_id,
content_type, request_content, user_token)

assert 'afd4eaf98af2d964f8ea840fc144ee7bae95dbeeeb251d5e3a01371442f92eeb' == result


@pytest.mark.asyncio
async def test_a_request_should_encrypt_properly():
ts = datetime.datetime.now()
expected_json = {'change': 'me'}
base_uri = 'http://fake.server/'
original_request = httpx.Request(
url=f'{base_uri}with/path',
method='GET',
params={'vin': 'zevin'},
headers={'Content-Type': 'application/json'},
json=expected_json,
)
original_request_content = original_request.content.decode('utf-8').strip()
region = 'EU'
tenant_id = '2559'
computed_verification_string = security.get_app_verification_string(
"",
"/with/path?vin=zevin",
str(int(ts.timestamp() * 1000)),
tenant_id,
'application/json',
original_request_content, ''
)

await security.encrypt_request(
modified_request=original_request,
request_timestamp=ts,
base_uri=base_uri,
region=region,
tenant_id=tenant_id,
)
assert original_request != None

Check failure on line 57 in tests/security_test.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Ruff (E711)

tests/security_test.py:57:32: E711 Comparison to `None` should be `cond is not None`

Check failure on line 57 in tests/security_test.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Ruff (E711)

tests/security_test.py:57:32: E711 Comparison to `None` should be `cond is not None`
assert region == original_request.headers['REGION']
assert tenant_id == original_request.headers['tenant-id']
assert 'app' == original_request.headers['User-Type']
assert str(int(ts.timestamp() * 1000)) == original_request.headers['APP-SEND-DATE']
assert '1' == original_request.headers['APP-CONTENT-ENCRYPTED']
assert computed_verification_string == original_request.headers['APP-VERIFICATION-STRING']


@pytest.mark.asyncio
async def test_a_request_should_decrypt_properly():
ts = datetime.datetime.now()
expected_json = {'change': 'me'}
base_uri = 'http://fake.server/'
original_request = httpx.Request(
url=f'{base_uri}with/path',
method='GET',
params={'vin': 'zevin'},
headers={'Content-Type': 'application/json'},
json=expected_json,
)
region = 'EU'
tenant_id = '2559'

await security.encrypt_request(
modified_request=original_request,
request_timestamp=ts,
base_uri=base_uri,
region=region,
tenant_id=tenant_id,
)
decrypted = await security.decrypt_request(original_request, base_uri=base_uri)

assert decrypted != None

Check failure on line 90 in tests/security_test.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Ruff (E711)

tests/security_test.py:90:25: E711 Comparison to `None` should be `cond is not None`

Check failure on line 90 in tests/security_test.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Ruff (E711)

tests/security_test.py:90:25: E711 Comparison to `None` should be `cond is not None`
decrypted_json = json.loads(decrypted)
assert expected_json == decrypted_json


def test_with_empty_request_path():
clazz_simple_name = 'SampleClass'
request_path = ''
current_ts = '20230514123000'
tenant_id = '1234'
content_type = 'application/json'
request_content = '{"key": "value"}'
user_token = 'dummy_token'

result = security.get_app_verification_string(clazz_simple_name, request_path, current_ts, tenant_id,
content_type, request_content, user_token)
assert 'ff8cb13ebcce5958e7fbfe602716c653fd72ce78842be87b6d50dccede198735' == result


def test_with_no_request_content():
clazz_simple_name = 'SampleClass'
request_path = '/api/v1/data'
current_ts = '20230514123000'
tenant_id = '1234'
content_type = 'application/json'
request_content = ''
user_token = 'dummy_token'

result = security.get_app_verification_string(clazz_simple_name, request_path, current_ts, tenant_id,
content_type, request_content, user_token)
assert '332c85836aa9afc864282436a740eb2cc778fafd1fea74dd887c1f8de5056de0' == result


if __name__ == '__main__':
Expand Down

0 comments on commit 6058885

Please sign in to comment.