Skip to content

Commit

Permalink
update signing and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed Mar 20, 2024
1 parent 9788ca4 commit 691835e
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
25 changes: 11 additions & 14 deletions http_client/src/vonage_http_client/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,33 +89,30 @@ def sign_params(self, params: dict) -> dict:
dict: The signed message parameters.
"""

if self._signature_method:
hasher = hmac.new(
self._signature_secret.encode(),
digestmod=self._signature_method,
)
else:
hasher = hashlib.md5()
hasher = hmac.new(
self._signature_secret.encode(),
digestmod=self._signature_method,
)

if not params.get("timestamp"):
params["timestamp"] = int(time())
if not params.get('timestamp'):
params['timestamp'] = int(time())

for key in sorted(params):
value = params[key]

if isinstance(value, str):
value = value.replace("&", "_").replace("=", "_")
value = value.replace('&', '_').replace('=', '_')

hasher.update(f"&{key}={value}".encode("utf-8"))
hasher.update(f'&{key}={value}'.encode('utf-8'))

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

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

def _validate_input_combinations(
self, api_key, api_secret, application_id, private_key, signature_secret
Expand Down
8 changes: 2 additions & 6 deletions http_client/src/vonage_http_client/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,8 @@ def make_request(
elif auth_type == 'basic':
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))

params['api_key'] = self._auth.api_key
params['sig'] = self._auth.sign_params(params)
with self._session.request(
request_type,
url,
Expand All @@ -165,7 +162,6 @@ 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
62 changes: 61 additions & 1 deletion http_client/tests/test_auth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from os.path import dirname, join
from unittest.mock import patch
import hashlib

import hmac

from pydantic import ValidationError
from pytest import raises
Expand Down Expand Up @@ -160,3 +160,63 @@ def test_auth_init_with_invalid_combinations():
assert auth._jwt_client is None
assert auth._signature_secret == signature_secret
assert auth._signature_method is None


def test_sign_params():
auth = Auth(signature_secret='signature_secret', signature_method='sha256')

params = {'param1': 'value1', 'param2': 'value2', 'timestamp': 1234567890}

signed_params = auth.sign_params(params)

assert signed_params == 'asdf'


def test_sign_params_default_sig_method():
auth = Auth()

params = {'param1': 'value1', 'param2': 'value2', 'timestamp': 1234567890}

signed_params = auth.sign_params(params)

assert signed_params == 'asdf'


def test_sign_params_with_special_characters():
auth = Auth(signature_secret='signature_secret', signature_method='sha1')

params = {'param1': 'value&1', 'param2': 'value=2', 'timestamp': 1234567890}

signed_params = auth.sign_params(params)

assert signed_params == 'asdf'


# def test_check_signature_with_valid_signature():
# auth = Auth(signature_secret='signature_secret')
# params = {'param1': 'value1', 'param2': 'value2', 'sig': 'valid_signature'}
# expected_signature = hmac.new(
# b'signature_secret', b'param1value1param2value2', hashlib.sha256
# ).hexdigest()

# assert auth.check_signature(params) == True


# def test_check_signature_with_invalid_signature():
# auth = Auth(signature_secret='signature_secret')
# params = {'param1': 'value1', 'param2': 'value2', 'sig': 'invalid_signature'}
# expected_signature = hmac.new(
# b'signature_secret', b'param1value1param2value2', hashlib.sha256
# ).hexdigest()

# assert auth.check_signature(params) == False


# def test_check_signature_with_empty_signature():
# auth = Auth(signature_secret='signature_secret')
# params = {'param1': 'value1', 'param2': 'value2', 'sig': ''}
# expected_signature = hmac.new(
# b'signature_secret', b'param1value1param2value2', hashlib.sha256
# ).hexdigest()

# assert auth.check_signature(params) == False
4 changes: 2 additions & 2 deletions http_client/tests/test_http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ def test_make_post_request_with_signature():
auth_type='signature',
)
assert res['hello'] == 'world!'

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


@responses.activate
Expand Down

0 comments on commit 691835e

Please sign in to comment.