Skip to content

Commit

Permalink
add support for basic header auth for messages and verify, move cover…
Browse files Browse the repository at this point in the history
…age config
  • Loading branch information
maxkahan committed Nov 20, 2024
1 parent 0937cc2 commit bd4fcb0
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 34 deletions.
3 changes: 3 additions & 0 deletions messages/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 1.3.0
- Add support for API key/secret header authentication

# 1.2.3
- Update dependency versions

Expand Down
2 changes: 1 addition & 1 deletion messages/src/vonage_messages/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.2.3'
__version__ = '1.3.0'
8 changes: 8 additions & 0 deletions messages/src/vonage_messages/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class Messages:

def __init__(self, http_client: HttpClient) -> None:
self._http_client = http_client
self._auth_type = 'jwt'

if self._http_client.auth.application_id is None:
self._auth_type = 'basic'

@property
def http_client(self) -> HttpClient:
Expand All @@ -42,7 +46,9 @@ def send(self, message: BaseMessage) -> SendMessageResponse:
self._http_client.api_host,
'/v1/messages',
message.model_dump(by_alias=True, exclude_none=True) or message,
self._auth_type,
)

return SendMessageResponse(**response)

@validate_call
Expand All @@ -63,6 +69,7 @@ def mark_whatsapp_message_read(self, message_uuid: str) -> None:
self._http_client.api_host,
f'/v1/messages/{message_uuid}',
{'status': 'read'},
self._auth_type,
)

@validate_call
Expand All @@ -83,4 +90,5 @@ def revoke_rcs_message(self, message_uuid: str) -> None:
self._http_client.api_host,
f'/v1/messages/{message_uuid}',
{'status': 'revoked'},
self._auth_type,
)
36 changes: 35 additions & 1 deletion messages/tests/test_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import responses
from pytest import raises
from vonage_http_client.auth import Auth
from vonage_http_client.errors import HttpRequestError
from vonage_http_client.http_client import HttpClient, HttpClientOptions
from vonage_messages.messages import Messages
Expand All @@ -13,14 +14,29 @@
)
from vonage_messages.responses import SendMessageResponse

from testutils import build_response, get_mock_jwt_auth
from testutils import build_response, get_mock_api_key_auth, get_mock_jwt_auth

path = abspath(__file__)


messages = Messages(HttpClient(get_mock_jwt_auth()))


@responses.activate
def test_default_auth_type():
messages = Messages(
HttpClient(
Auth(
api_key='asdf',
api_secret='asdf',
application_id='asdf',
private_key='-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDZz9Zz\n-----END PRIVATE-KEY----',
)
)
)
assert messages._auth_type == 'jwt'


@responses.activate
def test_send_message():
build_response(
Expand All @@ -34,6 +50,24 @@ def test_send_message():
response = messages.send(sms)
assert type(response) == SendMessageResponse
assert response.message_uuid == 'd8f86df1-dec6-442f-870a-2241be27d721'
assert messages._auth_type == 'jwt'


@responses.activate
def test_send_message_basic_auth():
build_response(
path, 'POST', 'https://api.nexmo.com/v1/messages', 'send_message.json', 202
)
messages = Messages(HttpClient(get_mock_api_key_auth()))
sms = Sms(
from_='Vonage APIs',
to='1234567890',
text='Hello, World!',
)
response = messages.send(sms)
assert type(response) == SendMessageResponse
assert response.message_uuid == 'd8f86df1-dec6-442f-870a-2241be27d721'
assert messages._auth_type == 'basic'


@responses.activate
Expand Down
26 changes: 1 addition & 25 deletions pants.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[GLOBAL]
pants_version = '2.23.0rc1'
pants_version = '2.23.0'

backend_packages = [
'pants.backend.python',
Expand Down Expand Up @@ -29,30 +29,6 @@ args = ['-vv', '--no-header']
[coverage-py]
interpreter_constraints = ['>=3.8']
report = ['html', 'console']
filter = [
'vonage/src',
'http_client/src',
'account/src',
'application/src',
'jwt/src',
'messages/src',
'network_auth/src',
'network_number_verification/src',
'network_sim_swap/src',
'number_insight/src',
'number_insight_v2/src',
'number_management/src',
'sms/src',
'subaccounts/src',
'users/src',
'utils/src',
'testutils',
'verify/src',
'verify_legacy/src',
'video/src',
'voice/src',
'vonage_utils/src',
]

[black]
args = ['--line-length=90', '--skip-string-normalization']
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tool.coverage.run]
omit = ['**/tests/*', '**/src/**/_version.py']
3 changes: 3 additions & 0 deletions verify/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 2.1.0
- Add support for API key/secret header authentication

# 2.0.0
- Rename `vonage-verify-v2` package -> `vonage-verify`, `VerifyV2` -> `Verify`, etc. This package now contains code for the Verify v2 API
- Update dependency versions
Expand Down
2 changes: 1 addition & 1 deletion verify/src/vonage_verify/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.0.0'
__version__ = '2.1.0'
17 changes: 15 additions & 2 deletions verify/src/vonage_verify/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class Verify:

def __init__(self, http_client: HttpClient) -> None:
self._http_client = http_client
self._auth_type = 'jwt'

if self._http_client.auth.application_id is None:
self._auth_type = 'basic'

@property
def http_client(self) -> HttpClient:
Expand Down Expand Up @@ -37,6 +41,7 @@ def start_verification(
self._http_client.api_host,
'/v2/verify',
verify_request.model_dump(by_alias=True, exclude_none=True),
self._auth_type,
)

return StartVerificationResponse(**response)
Expand All @@ -53,7 +58,10 @@ def check_code(self, request_id: str, code: str) -> CheckCodeResponse:
CheckCodeResponse: The response object containing the verification result.
"""
response = self._http_client.post(
self._http_client.api_host, f'/v2/verify/{request_id}', {'code': code}
self._http_client.api_host,
f'/v2/verify/{request_id}',
{'code': code},
self._auth_type,
)
return CheckCodeResponse(**response)

Expand All @@ -64,7 +72,11 @@ def cancel_verification(self, request_id: str) -> None:
Args:
request_id (str): The request ID.
"""
self._http_client.delete(self._http_client.api_host, f'/v2/verify/{request_id}')
self._http_client.delete(
self._http_client.api_host,
f'/v2/verify/{request_id}',
auth_type=self._auth_type,
)

@validate_call
def trigger_next_workflow(self, request_id: str) -> None:
Expand All @@ -77,4 +89,5 @@ def trigger_next_workflow(self, request_id: str) -> None:
self._http_client.post(
self._http_client.api_host,
f'/v2/verify/{request_id}/next_workflow',
auth_type=self._auth_type,
)
84 changes: 83 additions & 1 deletion verify/tests/test_verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,35 @@

import responses
from pytest import raises
from vonage_http_client.auth import Auth
from vonage_http_client.errors import HttpRequestError
from vonage_http_client.http_client import HttpClient
from vonage_verify.requests import *
from vonage_verify.verify import Verify

from testutils import build_response, get_mock_jwt_auth
from testutils import build_response, get_mock_api_key_auth, get_mock_jwt_auth

path = abspath(__file__)


verify = Verify(HttpClient(get_mock_jwt_auth()))


@responses.activate
def test_default_auth_type():
verify = Verify(
HttpClient(
Auth(
api_key='asdf',
api_secret='asdf',
application_id='asdf',
private_key='-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDZz9Zz\n-----END PRIVATE-KEY----',
)
)
)
assert verify._auth_type == 'jwt'


@responses.activate
def test_make_verify_request():
build_response(
Expand All @@ -37,6 +53,27 @@ def test_make_verify_request():
== 'https://api-eu-3.vonage.com/v2/verify/cfbc9a3b-27a2-40d4-a4e0-0c59b3b41901/silent-auth/redirect'
)
assert verify._http_client.last_response.status_code == 202
assert verify._auth_type == 'jwt'


@responses.activate
def test_make_verify_request_basic_auth():
build_response(
path, 'POST', 'https://api.nexmo.com/v2/verify', 'verify_request.json', 202
)
sms_channel = SmsChannel(channel=ChannelType.SMS, to='1234567890', from_='Vonage')
params = {
'brand': 'Vonage',
'workflow': [sms_channel],
}
request = VerifyRequest(**params)

verify = Verify(HttpClient(get_mock_api_key_auth()))

response = verify.start_verification(request)
assert response.request_id == '2c59e3f4-a047-499f-a14f-819cd1989d2e'
assert verify._http_client.last_response.status_code == 202
assert verify._auth_type == 'basic'


@responses.activate
Expand Down Expand Up @@ -108,6 +145,23 @@ def test_check_code():
assert response.status == 'completed'


@responses.activate
def test_check_code_basic_auth():
build_response(
path,
'POST',
'https://api.nexmo.com/v2/verify/36e7060d-2b23-4257-bad0-773ab47f85ef',
'check_code.json',
)
verify = Verify(HttpClient(get_mock_api_key_auth()))
response = verify.check_code(
request_id='36e7060d-2b23-4257-bad0-773ab47f85ef', code='1234'
)
assert response.request_id == '36e7060d-2b23-4257-bad0-773ab47f85ef'
assert response.status == 'completed'
assert verify._auth_type == 'basic'


@responses.activate
def test_check_code_invalid_code_error():
build_response(
Expand Down Expand Up @@ -153,6 +207,20 @@ def test_cancel_verification():
assert verify._http_client.last_response.status_code == 204


@responses.activate
def test_cancel_verification_basic_auth():
responses.add(
responses.DELETE,
'https://api.nexmo.com/v2/verify/36e7060d-2b23-4257-bad0-773ab47f85ef',
status=204,
)

verify = Verify(HttpClient(get_mock_api_key_auth()))
assert verify.cancel_verification('36e7060d-2b23-4257-bad0-773ab47f85ef') is None
assert verify._http_client.last_response.status_code == 204
assert verify._auth_type == 'basic'


@responses.activate
def test_trigger_next_workflow():
responses.add(
Expand All @@ -164,6 +232,20 @@ def test_trigger_next_workflow():
assert verify._http_client.last_response.status_code == 200


@responses.activate
def test_trigger_next_workflow_basic_auth():
responses.add(
responses.POST,
'https://api.nexmo.com/v2/verify/36e7060d-2b23-4257-bad0-773ab47f85ef/next_workflow',
status=200,
)

verify = Verify(HttpClient(get_mock_api_key_auth()))
assert verify.trigger_next_workflow('36e7060d-2b23-4257-bad0-773ab47f85ef') is None
assert verify._http_client.last_response.status_code == 200
assert verify._auth_type == 'basic'


@responses.activate
def test_trigger_next_event_error():
build_response(
Expand Down
3 changes: 3 additions & 0 deletions vonage/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 4.1.0
- Add support for API key/secret header authentication for the Messages and Verify APIs (JWT is the default and recommended method)

# 4.0.0
A complete, ground-up rewrite of the SDK.
Key changes:
Expand Down
4 changes: 2 additions & 2 deletions vonage/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies = [
"vonage-http-client>=1.4.3",
"vonage-account>=1.1.0",
"vonage-application>=2.0.0",
"vonage-messages>=1.2.3",
"vonage-messages>=1.3.0",
"vonage-network-auth>=1.0.1",
"vonage-network-sim-swap>=1.1.1",
"vonage-network-number-verification>=1.0.1",
Expand All @@ -18,7 +18,7 @@ dependencies = [
"vonage-sms>=1.1.4",
"vonage-subaccounts>=1.0.4",
"vonage-users>=1.2.0",
"vonage-verify>=2.0.0",
"vonage-verify>=2.1.0",
"vonage-verify-legacy>=1.0.0",
"vonage-video>=1.0.3",
"vonage-voice>=1.0.6",
Expand Down
2 changes: 1 addition & 1 deletion vonage/src/vonage/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '4.0.0'
__version__ = '4.1.0'

0 comments on commit bd4fcb0

Please sign in to comment.