Skip to content

Commit

Permalink
working on signing requests
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed Mar 19, 2024
1 parent 7d6eafd commit 9788ca4
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 7 deletions.
23 changes: 16 additions & 7 deletions http_client/src/vonage_http_client/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ def __init__(
application_id: Optional[str] = None,
private_key: Optional[str] = None,
signature_secret: Optional[str] = None,
signature_method: Optional[Literal['md5', 'sha1', 'sha256', 'sha512']] = None,
signature_method: Optional[Literal['md5', 'sha1', 'sha256', 'sha512']] = 'md5',
) -> None:
self._validate_input_combinations(
api_key, api_secret, application_id, private_key
api_key, api_secret, application_id, private_key, signature_secret
)

self._api_key = api_key
Expand Down Expand Up @@ -110,18 +110,27 @@ def sign_params(self, params: dict) -> dict:

if self._signature_method is None:
hasher.update(self._signature_secret.encode())

return hasher.hexdigest()

def check_signature(self, params) -> bool:
params = dict(params)
signature = params.pop('sig', '').lower()
return hmac.compare_digest(signature, self.signature(params))

def _validate_input_combinations(
self, api_key, api_secret, application_id, private_key
self, api_key, api_secret, application_id, private_key, signature_secret
):
if (api_key and not api_secret) or (not api_key and api_secret):
if (api_secret or signature_secret) and not api_key:
raise InvalidAuthError(
'`api_key` must be set when `api_secret` or `signature_secret` is set.'
)

if api_key and not (api_secret or signature_secret):
raise InvalidAuthError(
'Both api_key and api_secret must be set or both must be None.'
'At least one of `api_secret` and `signature_secret` must be set if `api_key` is set.'
)

if (application_id and not private_key) or (not application_id and private_key):
raise InvalidAuthError(
'Both application_id and private_key must be set or both must be None.'
'Both `application_id` and `private_key` must be set or both must be None.'
)
5 changes: 5 additions & 0 deletions http_client/src/vonage_http_client/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ def make_request(
self._headers['Authorization'] = self._auth.create_basic_auth_string()
elif auth_type == 'signature':
params = self._auth.sign_params(params)

print(params)
print(self._auth.check_signature(params))

with self._session.request(
request_type,
url,
Expand All @@ -161,6 +165,7 @@ def _parse_response(self, response: Response) -> Union[dict, None]:
logger.debug(
f'Response received from {response.url} with status code: {response.status_code}; headers: {response.headers}'
)
print(response.request.headers)
content_type = response.headers['Content-Type'].split(';', 1)[0]
if 200 <= response.status_code < 300:
if response.status_code == 204:
Expand Down
4 changes: 4 additions & 0 deletions http_client/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def read_file(path):
api_secret = '1234qwerasdfzxcv'
application_id = 'asdfzxcv'
private_key = read_file('data/dummy_private_key.txt')
signature_secret = 'signature_secret'
signature_method = 'sha256'


def test_create_auth_class_and_get_objects():
Expand All @@ -27,6 +29,8 @@ def test_create_auth_class_and_get_objects():
api_secret=api_secret,
application_id=application_id,
private_key=private_key,
signature_secret=signature_secret,
signature_method=signature_method,
)

assert auth.api_key == api_key
Expand Down
27 changes: 27 additions & 0 deletions http_client/tests/test_http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,33 @@ def test_make_post_request():
assert loads(responses.calls[0].request.body) == params


@responses.activate
def test_make_post_request_with_signature():
build_response(
path, 'POST', 'https://example.com/post_signed_params', 'example_post.json'
)
client = HttpClient(
Auth(
api_key='asdfzxcv', signature_secret='qwerasdfzxcv', signature_method='sha256'
),
http_client_options={'api_host': 'example.com'},
)
params = {
'test': 'post request',
'testing': 'http client',
}

res = client.post(
host='example.com',
request_path='/post_signed_params',
params=params,
auth_type='signature',
)
assert res['hello'] == 'world!'

assert loads(responses.calls[0].request.body) == params


@responses.activate
def test_http_response_general_error():
build_response(path, 'GET', 'https://example.com/get_json', '400.json', 400)
Expand Down

0 comments on commit 9788ca4

Please sign in to comment.