From f3263a155ca890f9994cd2eea21ab0c7eecf6ecd Mon Sep 17 00:00:00 2001 From: Fang-Pen Lin Date: Wed, 31 May 2023 17:47:58 -0700 Subject: [PATCH] [PAYOP-1202] Add method for determining psp supports cryptogram or not (#340) * Add get psp type * Add supports_cryptogram method * Add test for supports_cryptogram * Add TODO --- larky/src/main/resources/vgs/nts.star | 44 ++++++++++++++++++- .../vgs_tests/nts/test_default_nts.star | 27 +++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/larky/src/main/resources/vgs/nts.star b/larky/src/main/resources/vgs/nts.star index 3e214585e..af8d427ce 100644 --- a/larky/src/main/resources/vgs/nts.star +++ b/larky/src/main/resources/vgs/nts.star @@ -1,10 +1,26 @@ load("@vgs//native_nts", _nts="native_nts") load("@vgs//vault", vault="vault") load("@stdlib//larky", larky="larky") +load("@stdlib//enum", enum="enum") +load("@stdlib//re", re="re") load("@vendor//jsonpath_ng", jsonpath_ng="jsonpath_ng") - VGS_NETWORK_TOKEN_HEADER = "vgs-network-token" +PSPType = enum.Enum('PSPType', [ + 'STRIPE', + 'ADYEN', + 'UNKNOWN', +]) +REGEX_PSP_TYPES = [ + (re.compile(r'^https:\/\/api\.stripe\.com'), PSPType.STRIPE), + (re.compile(r'^https:\/\/(.+)\.adyen\.com'), PSPType.ADYEN), + (re.compile(r'^https:\/\/(.+)\.adyenpayments\.com'), PSPType.ADYEN), + # TODO: extend this list to support detecting more PSPs here +] +CRYPTOGRAM_SUPPORTING_PSP_TYPES = { + PSPType.STRIPE: 1, + PSPType.ADYEN: 1, +} def render( @@ -106,6 +122,29 @@ def supports_dcvv(input, pan): return vault.reveal(jsonpath_ng.parse(pan).find(input).value).startswith("4") + +def supports_cryptogram(input): + """Check and see if the PSP determined by given input supports cryptogram or not + + :param input: the HTTP request input + :return: True if the PSP supports cryptogram otherwise False + """ + psp_type = get_psp_type(input) + return psp_type in CRYPTOGRAM_SUPPORTING_PSP_TYPES + + +def get_psp_type(input): + """Determine the PSP type based on the HTTP request input + + :param input: the HTTP request input + :return: PSP type based on request input values + """ + for regex, psp_type in REGEX_PSP_TYPES: + if regex.match(input.url): + return psp_type + return PSPType.UNKNOWN + + def use_network_token(headers): """Check value in the headers and determine whether is network token should be used or not @@ -117,8 +156,11 @@ def use_network_token(headers): nts = larky.struct( + PSPType=PSPType, get_network_token=_nts.get_network_token, render=render, supports_dcvv=supports_dcvv, + supports_cryptogram=supports_cryptogram, + get_psp_type=get_psp_type, use_network_token=use_network_token, ) diff --git a/larky/src/test/resources/vgs_tests/nts/test_default_nts.star b/larky/src/test/resources/vgs_tests/nts/test_default_nts.star index 40648c8a4..0e4d2d64b 100644 --- a/larky/src/test/resources/vgs_tests/nts/test_default_nts.star +++ b/larky/src/test/resources/vgs_tests/nts/test_default_nts.star @@ -1,3 +1,4 @@ +load("@stdlib//larky", "larky") load("@vendor//asserts", "asserts") load("@stdlib//unittest", "unittest") load("@vgs//nts", "nts") @@ -185,6 +186,17 @@ def _test_supports_dcvv_returns_false(): asserts.assert_that(nts.supports_dcvv(input, "$.payload.number")).is_false() +def _test_get_psp_type(): + for url, psp_type in [ + ("https://example.com", nts.PSPType.UNKNOWN), + ("https://api.stripe.com/v1/charges", nts.PSPType.STRIPE), + ("https://checkout-test.adyen.com/v68/payments", nts.PSPType.ADYEN), + ("https://checkoutshopper-test.adyen.com/v68/payments", nts.PSPType.ADYEN), + ("https://checkoutshopper-live.adyen.com/v68/payments", nts.PSPType.ADYEN), + ("https://checkoutshopper-live-us.adyen.com/v68/payments", nts.PSPType.ADYEN), + ]: + asserts.assert_that(nts.get_psp_type(larky.struct(url=url))).is_equal_to(psp_type) + def _test_use_network_token(): asserts.assert_that(nts.use_network_token({})).is_false() asserts.assert_that(nts.use_network_token({"vgs-network-token": ""})).is_false() @@ -196,6 +208,15 @@ def _test_use_network_token(): asserts.assert_that(nts.use_network_token({"VGS-NETWORK-TOKEN": "YES"})).is_true() +def _test_supports_cryptogram(): + for url, result in [ + ("https://example.com", False), + ("https://api.stripe.com/v1/charges", True), + ("https://checkout-test.adyen.com/v68/payments", True), + ]: + asserts.assert_that(nts.supports_cryptogram(larky.struct(url=url))).is_equal_to(result) + + def _suite(): _suite = unittest.TestSuite() @@ -214,8 +235,12 @@ def _suite(): # Support DCVV tests _suite.addTest(unittest.FunctionTestCase(_test_supports_dcvv_returns_true)) _suite.addTest(unittest.FunctionTestCase(_test_supports_dcvv_returns_false)) - # Is network token enabled tests + # Use network token tests _suite.addTest(unittest.FunctionTestCase(_test_use_network_token)) + # Get PSP type tests + _suite.addTest(unittest.FunctionTestCase(_test_get_psp_type)) + # Support cryptogram tests + _suite.addTest(unittest.FunctionTestCase(_test_supports_cryptogram)) return _suite