diff --git a/README.md b/README.md index 9886a94..bcf57c7 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Authentication is done transparently, so you don't need to worry about it. #### Registering New Signup -This method registers a new signup for the given installation and a structured address, an address +This method registers a new signup for the given request token and a structured address, an address line or coordinates, returning a `dict`, containing the risk assessment and supporting evidence: ```python3 @@ -56,30 +56,30 @@ structured_address: StructuredAddress = { 'complements': 'Floor 2', 'postal_code': '10001' } -assessment: dict = api.register_new_signup('installation-id', structured_address=structured_address) +assessment: dict = api.register_new_signup('request-token', structured_address=structured_address) # with address line: address_line: str = '350 Fifth Avenue, Manhattan, New York 10118' -assessment: dict = api.register_new_signup('installation-id', address_line=address_line) +assessment: dict = api.register_new_signup('request-token', address_line=address_line) # with coordinates, a dict: coordinates: Coordinates = { 'lat': 40.74836007062138, 'lng': -73.98509720487937 } -assessment: dict = api.register_new_signup('installation-id', address_coordinates=coordinates) +assessment: dict = api.register_new_signup('request-token', address_coordinates=coordinates) # with external_id: external_id: str = 'external-id' -assessment: dict = api.register_new_signup('installation-id', external_id=external_id) +assessment: dict = api.register_new_signup('request-token', external_id=external_id) # with policy_id: policy_id: str = 'policy-id' -assessment: dict = api.register_new_signup('installation-id', policy_id=policy_id) +assessment: dict = api.register_new_signup('request-token', policy_id=policy_id) # with account_id: account_id: str = 'account-id' -assessment: dict = api.register_new_signup('installation-id', account_id=account_id) +assessment: dict = api.register_new_signup('request-token', account_id=account_id) ``` @@ -97,13 +97,13 @@ api = IncogniaAPI('client-id', 'client-secret') api.register_feedback(FeedbackEvents.ACCOUNT_TAKEOVER, occurred_at=dt.datetime(2024, 7, 22, 15, 20, 0, tzinfo=dt.timezone.utc), - installation_id='installation-id', + request_token='request-token', account_id='account-id') ``` #### Registering Payment -This method registers a new payment for the given installation and account, returning a `dict`, +This method registers a new payment for the given request token and account, returning a `dict`, containing the risk assessment and supporting evidence. ```python3 @@ -164,7 +164,7 @@ payment_methods: List[PaymentMethod] = [ policy_id: str = 'policy-id' -assessment: dict = api.register_payment('installation-id', +assessment: dict = api.register_payment('request-token', 'account-id', 'external-id', addresses=addresses, @@ -175,7 +175,7 @@ assessment: dict = api.register_payment('installation-id', #### Registering Login -This method registers a new login for the given installation and account, returning a `dict`, +This method registers a new login for the given request token and account, returning a `dict`, containing the risk assessment and supporting evidence. ```python3 @@ -185,7 +185,7 @@ api = IncogniaAPI('client-id', 'client-secret') policy_id: str = 'policy-id' -assessment: dict = api.register_login('installation-id', +assessment: dict = api.register_login('request-token', 'account-id', 'external-id', policy_id='policy_id') diff --git a/incognia/api.py b/incognia/api.py index 8814d60..0a05d5e 100644 --- a/incognia/api.py +++ b/incognia/api.py @@ -20,29 +20,27 @@ def __get_authorization_header(self) -> dict: return {'Authorization': f'{token_type} {access_token}'} def register_new_signup(self, - installation_id: str, + request_token: Optional[str], address_line: Optional[str] = None, structured_address: Optional[StructuredAddress] = None, address_coordinates: Optional[Coordinates] = None, external_id: Optional[str] = None, policy_id: Optional[str] = None, - account_id: Optional[str] = None, - request_token: Optional[str] = None) -> dict: - if not installation_id: - raise IncogniaError('installation_id is required.') + account_id: Optional[str] = None) -> dict: + if not request_token: + raise IncogniaError('request_token is required.') try: headers = self.__get_authorization_header() headers.update(JSON_CONTENT_HEADER) body = { - 'installation_id': installation_id, + 'request_token': request_token, 'address_line': address_line, 'structured_address': structured_address, 'address_coordinates': address_coordinates, 'external_id': external_id, 'policy_id': policy_id, - 'account_id': account_id, - 'request_token': request_token + 'account_id': account_id } data = encode(body) return self.__request.post(Endpoints.SIGNUPS, headers=headers, data=data) @@ -59,7 +57,6 @@ def register_feedback(self, signup_id: Optional[str] = None, account_id: Optional[str] = None, installation_id: Optional[str] = None, - session_token: Optional[str] = None, request_token: Optional[str] = None, occurred_at: dt.datetime = None, expires_at: dt.datetime = None) -> None: @@ -83,7 +80,6 @@ def register_feedback(self, 'signup_id': signup_id, 'account_id': account_id, 'installation_id': installation_id, - 'session_token': session_token, 'request_token': request_token } if timestamp is not None: @@ -99,17 +95,16 @@ def register_feedback(self, raise IncogniaHTTPError(e) from None def register_payment(self, - installation_id: str, + request_token: str, account_id: str, external_id: Optional[str] = None, addresses: Optional[List[TransactionAddress]] = None, payment_value: Optional[PaymentValue] = None, payment_methods: Optional[List[PaymentMethod]] = None, evaluate: Optional[bool] = None, - policy_id: Optional[str] = None, - request_token: Optional[str] = None) -> dict: - if not installation_id: - raise IncogniaError('installation_id is required.') + policy_id: Optional[str] = None) -> dict: + if not request_token: + raise IncogniaError('request_token is required.') if not account_id: raise IncogniaError('account_id is required.') @@ -119,14 +114,13 @@ def register_payment(self, params = None if evaluate is None else {'eval': evaluate} body = { 'type': 'payment', - 'installation_id': installation_id, + 'request_token': request_token, 'account_id': account_id, 'external_id': external_id, 'addresses': addresses, 'payment_value': payment_value, 'payment_methods': payment_methods, - 'policy_id': policy_id, - 'request_token': request_token + 'policy_id': policy_id } data = encode(body) return self.__request.post(Endpoints.TRANSACTIONS, headers=headers, params=params, @@ -136,14 +130,13 @@ def register_payment(self, raise IncogniaHTTPError(e) from None def register_login(self, - installation_id: str, + request_token: str, account_id: str, external_id: Optional[str] = None, evaluate: Optional[bool] = None, - policy_id: Optional[str] = None, - request_token: Optional[str] = None) -> dict: - if not installation_id: - raise IncogniaError('installation_id is required.') + policy_id: Optional[str] = None) -> dict: + if not request_token: + raise IncogniaError('request_token is required.') if not account_id: raise IncogniaError('account_id is required.') @@ -153,11 +146,10 @@ def register_login(self, params = None if evaluate is None else {'eval': evaluate} body = { 'type': 'login', - 'installation_id': installation_id, + 'request_token': request_token, 'account_id': account_id, 'external_id': external_id, - 'policy_id': policy_id, - 'request_token': request_token + 'policy_id': policy_id } data = encode(body) return self.__request.post(Endpoints.TRANSACTIONS, headers=headers, params=params, @@ -167,14 +159,13 @@ def register_login(self, raise IncogniaHTTPError(e) from None def register_web_login(self, - session_token: str, + request_token: str, account_id: str, external_id: Optional[str] = None, evaluate: Optional[bool] = None, - policy_id: Optional[str] = None, - request_token: Optional[str] = None) -> dict: - if not session_token: - raise IncogniaError('session_token is required.') + policy_id: Optional[str] = None) -> dict: + if not request_token: + raise IncogniaError('request_token is required.') if not account_id: raise IncogniaError('account_id is required.') @@ -184,11 +175,10 @@ def register_web_login(self, params = None if evaluate is None else {'eval': evaluate} body = { 'type': 'login', - 'session_token': session_token, + 'request_token': request_token, 'account_id': account_id, 'external_id': external_id, - 'policy_id': policy_id, - 'request_token': request_token + 'policy_id': policy_id } data = encode(body) return self.__request.post(Endpoints.TRANSACTIONS, headers=headers, params=params, diff --git a/tests/test_api.py b/tests/test_api.py index a7952cd..4b0ce32 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -15,10 +15,8 @@ class TestIncogniaAPI(TestCase): CLIENT_ID: Final[str] = 'ANY_ID' CLIENT_SECRET: Final[str] = 'ANY_SECRET' INSTALLATION_ID: Final[str] = 'ANY_INSTALLATION_ID' - SESSION_TOKEN: Final[str] = 'ANY_SESSION_TOKEN' REQUEST_TOKEN: Final[str] = 'ANY_REQUEST_TOKEN' - INVALID_INSTALLATION_ID: Final[str] = 'INVALID_INSTALLATION_ID' - INVALID_SESSION_TOKEN: Final[str] = 'INVALID_SESSION_TOKEN' + INVALID_REQUEST_TOKEN: Final[str] = 'INVALID_REQUEST_TOKEN' ACCOUNT_ID: Final[str] = 'ANY_ACCOUNT_ID' INVALID_ACCOUNT_ID: Final[str] = 'INVALID_ACCOUNT_ID' ADDRESS_LINE: Final[str] = 'ANY_ADDRESS_LINE' @@ -57,17 +55,19 @@ class TestIncogniaAPI(TestCase): 'Content-Type': 'application/json' } REGISTER_SIGNUP_DATA: Final[bytes] = encode({ - 'installation_id': f'{INSTALLATION_ID}' + 'request_token': f'{REQUEST_TOKEN}' + }) + REGISTER_INVALID_SIGNUP_DATA: Final[bytes] = encode({ + 'request_token': f'{INVALID_REQUEST_TOKEN}' }) FULL_REGISTER_SIGNUP_DATA: Final[bytes] = encode({ - 'installation_id': f'{INSTALLATION_ID}', + 'request_token': f'{REQUEST_TOKEN}', 'address_line': f'{ADDRESS_LINE}', 'structured_address': STRUCTURED_ADDRESS, 'address_coordinates': ADDRESS_COORDINATES, 'external_id': f'{EXTERNAL_ID}', 'policy_id': f'{POLICY_ID}', - 'account_id': f'{ACCOUNT_ID}', - 'request_token': f'{REQUEST_TOKEN}' + 'account_id': f'{ACCOUNT_ID}' }) OK_STATUS_CODE: Final[int] = 200 CLIENT_ERROR_CODE: Final[int] = 400 @@ -88,7 +88,6 @@ class TestIncogniaAPI(TestCase): 'signup_id': f'{SIGNUP_ID}', 'account_id': f'{ACCOUNT_ID}', 'installation_id': f'{INSTALLATION_ID}', - 'session_token': f'{SESSION_TOKEN}', 'request_token': f'{REQUEST_TOKEN}', 'timestamp': int(( TIMESTAMP - dt.datetime.fromtimestamp(0, dt.timezone.utc)).total_seconds() * 1000.0), @@ -100,50 +99,47 @@ class TestIncogniaAPI(TestCase): }) REGISTER_VALID_PAYMENT_DATA: Final[bytes] = encode({ 'type': 'payment', - 'installation_id': f'{INSTALLATION_ID}', + 'request_token': f'{REQUEST_TOKEN}', 'account_id': f'{ACCOUNT_ID}', 'policy_id': f'{POLICY_ID}', - 'request_token': f'{REQUEST_TOKEN}', }) REGISTER_INVALID_PAYMENT_DATA: Final[bytes] = encode({ 'type': 'payment', - 'installation_id': f'{INVALID_INSTALLATION_ID}', + 'request_token': f'{INVALID_REQUEST_TOKEN}', 'account_id': f'{INVALID_ACCOUNT_ID}' }) REGISTER_VALID_LOGIN_DATA: Final[bytes] = encode({ 'type': 'login', - 'installation_id': f'{INSTALLATION_ID}', + 'request_token': f'{REQUEST_TOKEN}', 'account_id': f'{ACCOUNT_ID}', - 'policy_id': f'{POLICY_ID}', - 'request_token': f'{REQUEST_TOKEN}' + 'policy_id': f'{POLICY_ID}' }) REGISTER_VALID_WEB_LOGIN_DATA: Final[bytes] = encode({ 'type': 'login', - 'session_token': f'{SESSION_TOKEN}', + 'request_token': f'{REQUEST_TOKEN}', 'account_id': f'{ACCOUNT_ID}', - 'policy_id': f'{POLICY_ID}', - 'request_token': f'{REQUEST_TOKEN}' + 'policy_id': f'{POLICY_ID}' }) REGISTER_INVALID_LOGIN_DATA: Final[bytes] = encode({ 'type': 'login', - 'installation_id': f'{INVALID_INSTALLATION_ID}', + 'request_token': f'{INVALID_REQUEST_TOKEN}', 'account_id': f'{INVALID_ACCOUNT_ID}' }) REGISTER_INVALID_WEB_LOGIN_DATA: Final[bytes] = encode({ 'type': 'login', - 'session_token': f'{INVALID_SESSION_TOKEN}', + 'request_token': f'{INVALID_REQUEST_TOKEN}', 'account_id': f'{INVALID_ACCOUNT_ID}' }) DEFAULT_PARAMS: Final[None] = None @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) - def test_register_new_signup_when_installation_id_is_valid_should_return_a_valid_dict( + def test_register_new_signup_when_request_token_is_valid_should_return_a_valid_dict( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): mock_base_request_post.configure_mock(return_value=self.JSON_RESPONSE) api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - response = api.register_new_signup(installation_id=self.INSTALLATION_ID) + response = api.register_new_signup(request_token=self.REQUEST_TOKEN) mock_token_manager_get.assert_called() mock_base_request_post.assert_called_with(Endpoints.SIGNUPS, @@ -154,13 +150,12 @@ def test_register_new_signup_when_installation_id_is_valid_should_return_a_valid @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) - def test_register_new_signup_when_installation_id_is_valid_should_return_full_valid_dict_( + def test_register_new_signup_when_request_token_is_valid_should_return_full_valid_dict_( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): mock_base_request_post.configure_mock(return_value=self.JSON_RESPONSE) api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - response = api.register_new_signup(installation_id=self.INSTALLATION_ID, - address_line=self.ADDRESS_LINE, + response = api.register_new_signup(address_line=self.ADDRESS_LINE, structured_address=self.STRUCTURED_ADDRESS, address_coordinates=self.ADDRESS_COORDINATES, external_id=self.EXTERNAL_ID, @@ -177,29 +172,29 @@ def test_register_new_signup_when_installation_id_is_valid_should_return_full_va @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) - def test_register_new_signup_when_installation_id_is_invalid_should_raise_an_IncogniaHTTPError( + def test_register_new_signup_when_request_token_is_empty_should_raise_an_IncogniaError( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): - mock_base_request_post.configure_mock(side_effect=IncogniaHTTPError) - api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaHTTPError, api.register_new_signup, self.INSTALLATION_ID) + self.assertRaises(IncogniaError, api.register_new_signup, request_token='') - mock_token_manager_get.assert_called() - mock_base_request_post.assert_called_with(Endpoints.SIGNUPS, - headers=self.AUTH_AND_JSON_CONTENT_HEADERS, - data=self.REGISTER_SIGNUP_DATA) + mock_token_manager_get.assert_not_called() + mock_base_request_post.assert_not_called() @patch.object(BaseRequest, 'post') - @patch.object(TokenManager, 'get') - def test_register_new_signup_when_installation_id_is_empty_should_raise_an_IncogniaError( + @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) + def test_register_new_signup_when_request_token_is_invalid_should_raise_an_IncogniaHTTPError( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): + mock_base_request_post.configure_mock(side_effect=IncogniaHTTPError) + api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_new_signup, '') + self.assertRaises(IncogniaHTTPError, api.register_new_signup, self.INVALID_REQUEST_TOKEN) - mock_token_manager_get.assert_not_called() - mock_base_request_post.assert_not_called() + mock_token_manager_get.assert_called() + mock_base_request_post.assert_called_with(Endpoints.SIGNUPS, + headers=self.AUTH_AND_JSON_CONTENT_HEADERS, + data=self.REGISTER_INVALID_SIGNUP_DATA) @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) @@ -230,7 +225,6 @@ def test_register_feedback_when_all_fields_are_valid_should_work( signup_id=self.SIGNUP_ID, account_id=self.ACCOUNT_ID, installation_id=self.INSTALLATION_ID, - session_token=self.SESSION_TOKEN, request_token=self.REQUEST_TOKEN) mock_token_manager_get.assert_called() @@ -315,10 +309,9 @@ def test_register_payment_when_required_fields_are_valid_should_work( api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - request_response = api.register_payment(self.INSTALLATION_ID, + request_response = api.register_payment(self.REQUEST_TOKEN, self.ACCOUNT_ID, - policy_id=self.POLICY_ID, - request_token=self.REQUEST_TOKEN) + policy_id=self.POLICY_ID) mock_token_manager_get.assert_called() mock_base_request_post.assert_called_with(Endpoints.TRANSACTIONS, @@ -330,11 +323,12 @@ def test_register_payment_when_required_fields_are_valid_should_work( @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) - def test_register_payment_when_installation_id_is_empty_should_raise_an_IncogniaError( + def test_register_payment_when_request_token_is_empty_should_raise_an_IncogniaError( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_payment, installation_id='', + self.assertRaises(IncogniaError, api.register_payment, + request_token='', account_id=self.ACCOUNT_ID) mock_token_manager_get.assert_not_called() @@ -346,7 +340,8 @@ def test_register_payment_when_account_id_is_empty_should_raise_an_IncogniaError self, mock_token_manager_get: Mock, mock_base_request_post: Mock): api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_payment, installation_id=self.INSTALLATION_ID, + self.assertRaises(IncogniaError, api.register_payment, + request_token=self.REQUEST_TOKEN, account_id='') mock_token_manager_get.assert_not_called() @@ -361,7 +356,7 @@ def test_register_payment_when_required_fields_are_invalid_should_raise_an_Incog api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) self.assertRaises(IncogniaHTTPError, api.register_payment, - installation_id=self.INVALID_INSTALLATION_ID, + request_token=self.INVALID_REQUEST_TOKEN, account_id=self.INVALID_ACCOUNT_ID) mock_token_manager_get.assert_called() @@ -378,10 +373,9 @@ def test_register_login_when_required_fields_are_valid_should_work( api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - request_response = api.register_login(self.INSTALLATION_ID, + request_response = api.register_login(self.REQUEST_TOKEN, self.ACCOUNT_ID, - policy_id=self.POLICY_ID, - request_token=self.REQUEST_TOKEN) + policy_id=self.POLICY_ID) mock_token_manager_get.assert_called() mock_base_request_post.assert_called_with(Endpoints.TRANSACTIONS, @@ -393,11 +387,12 @@ def test_register_login_when_required_fields_are_valid_should_work( @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) - def test_register_login_when_installation_id_is_empty_should_raise_an_IncogniaError( + def test_register_login_when_request_token_is_empty_should_raise_an_IncogniaError( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_login, installation_id='', + self.assertRaises(IncogniaError, api.register_login, + request_token='', account_id=self.ACCOUNT_ID) mock_token_manager_get.assert_not_called() @@ -409,7 +404,8 @@ def test_register_login_when_account_id_is_empty_should_raise_an_IncogniaError( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_login, installation_id=self.INSTALLATION_ID, + self.assertRaises(IncogniaError, api.register_login, + request_token=self.REQUEST_TOKEN, account_id='') mock_token_manager_get.assert_not_called() @@ -424,7 +420,7 @@ def test_register_login_when_required_fields_are_invalid_should_raise_an_Incogni api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) self.assertRaises(IncogniaHTTPError, api.register_login, - installation_id=self.INVALID_INSTALLATION_ID, + request_token=self.INVALID_REQUEST_TOKEN, account_id=self.INVALID_ACCOUNT_ID) mock_token_manager_get.assert_called() @@ -441,10 +437,9 @@ def test_register_web_login_when_required_fields_are_valid_should_work( api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - request_response = api.register_web_login(self.SESSION_TOKEN, + request_response = api.register_web_login(self.REQUEST_TOKEN, self.ACCOUNT_ID, - policy_id=self.POLICY_ID, - request_token=self.REQUEST_TOKEN) + policy_id=self.POLICY_ID) mock_token_manager_get.assert_called() mock_base_request_post.assert_called_with(Endpoints.TRANSACTIONS, @@ -456,11 +451,12 @@ def test_register_web_login_when_required_fields_are_valid_should_work( @patch.object(BaseRequest, 'post') @patch.object(TokenManager, 'get', return_value=TOKEN_VALUES) - def test_register_web_login_when_session_token_is_empty_should_raise_an_IncogniaError( + def test_register_web_login_when_request_token_is_empty_should_raise_an_IncogniaError( self, mock_token_manager_get: Mock, mock_base_request_post: Mock): api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_web_login, session_token='', + self.assertRaises(IncogniaError, api.register_web_login, + request_token='', account_id=self.ACCOUNT_ID) mock_token_manager_get.assert_not_called() @@ -472,7 +468,8 @@ def test_register_web_login_when_account_id_is_empty_should_raise_an_IncogniaErr self, mock_token_manager_get: Mock, mock_base_request_post: Mock): api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) - self.assertRaises(IncogniaError, api.register_web_login, session_token=self.SESSION_TOKEN, + self.assertRaises(IncogniaError, api.register_web_login, + request_token=self.REQUEST_TOKEN, account_id='') mock_token_manager_get.assert_not_called() @@ -487,8 +484,8 @@ def test_register_web_login_when_required_fields_are_invalid_should_raise_an_Inc api = IncogniaAPI(self.CLIENT_ID, self.CLIENT_SECRET) self.assertRaises(IncogniaHTTPError, api.register_web_login, - session_token=self.INVALID_SESSION_TOKEN, - account_id=self.INVALID_ACCOUNT_ID) + account_id=self.INVALID_ACCOUNT_ID, + request_token=self.INVALID_REQUEST_TOKEN) mock_token_manager_get.assert_called() mock_base_request_post.assert_called_with(Endpoints.TRANSACTIONS,