Exemplo n.º 1
0
    def test_create_authentication_signature_for_post(self):
        # TODO change meta info to something more sensible/python-like
        """Tests that the to_data_to_sign function correctly constructs a POST request for multiple headers"""
        authenticator = DefaultAuthenticator("apiKeyId", "secretApiKey",
                                             AuthorizationType.V1HMAC)
        http_headers = [
            RequestHeader(
                "X-GCS-ServerMetaInfo",
                "{\"platformIdentifier\":\"Windows 10/10.0.18362 Python/3.8.5 (CPython; MSC v.1916 32 bit (Intel))\","
                "\"sdkIdentifier\":\"OnlinePaymentsPython3ServerSDK/v1.0.0\"}"
            ),
            RequestHeader("Content-Type", "application/json"),
            RequestHeader("X-GCS-ClientMetaInfo", "{\"aap\",\"noot\"}"),
            RequestHeader("User-Agent", "Apache-HttpClient/4.3.4 (java 1.5)"),
            RequestHeader("Date", "Mon, 07 Jul 2014 12:12:40 GMT")
        ]
        expected_start = "POST\n" \
                         "application/json\n"
        expected_end = "x-gcs-clientmetainfo:{\"aap\",\"noot\"}\n" \
                       "x-gcs-servermetainfo:{\"platformIdentifier\":\"Windows 10/10.0.18362 Python/3.8.5 (CPython; MSC v.1916 32 bit (Intel))\"," \
                       "\"sdkIdentifier\":\"OnlinePaymentsPython3ServerSDK/v1.0.0\"}\n" \
                       "/v2/1/products%20bla?aap=noot&mies=geen%20noot\n"

        url = urllib.parse.urlparse(
            "http://localhost:8080/v2/1/products%20bla?aap=noot&mies=geen%20noot"
        )
        data_to_sign = authenticator.to_data_to_sign("POST", url, http_headers)

        actual_start = data_to_sign[:22]
        actual_end = data_to_sign[52:]
        self.assertEqual(expected_start, actual_start)
        self.assertEqual(expected_end, actual_end)
Exemplo n.º 2
0
 def test_constructor_with_prohibited_headers(self):
     """Tests that the MetaDataProvider constructor does not accept any headers marked as prohibited"""
     for name in MetaDataProvider.prohibited_headers:
         additional_headers = [RequestHeader("Header1", "Value1"),
                               RequestHeader(name, "should be slashed and burnt"),
                               RequestHeader("Header3", "Value3")]
         with self.assertRaises(Exception) as error:
             MetaDataProvider("OnlinePayments", None, additional_headers)
         self.assertIn(name, str(error.exception))
Exemplo n.º 3
0
    def test_unmarshal_string_success(self):
        helper = self.__create_helper()
        InMemorySecretKeyStore.INSTANCE().store_secret_key(
            self.__KEY_ID, self.__SECRET_KEY)
        body = self.__read_resource("valid-body")
        request_headers = [
            RequestHeader(self.__SIGNATURE_HEADER, self.__SIGNATURE),
            RequestHeader(self.__KEY_ID_HEADER, self.__KEY_ID)
        ]
        event = helper.unmarshal(body, request_headers)
        self.assertEqual("v1", event.api_version)
        self.assertEqual("8ee793f6-4553-4749-85dc-f2ef095c5ab0", event.id)
        self.assertEqual("2020-01-01T12:00:00.000+0100", event.created)
        self.assertEqual("1", event.merchant_id)
        self.assertEqual("payment.paid", event.type)

        self.assertIsNone(event.payout)
        self.assertIsNone(event.refund)
        self.assertIsNone(event.token)

        self.assertIsNotNone(event.payment)
        self.assertEqual("1_1", event.payment.id)
        self.assertIsNotNone(event.payment.payment_output)
        self.assertIsNotNone(event.payment.payment_output.amount_of_money)
        self.assertEqual(1000,
                         event.payment.payment_output.amount_of_money.amount)
        self.assertEqual(
            "EUR", event.payment.payment_output.amount_of_money.currency_code)
        self.assertIsNotNone(
            event.payment.payment_output.amount_of_money.currency_code)
        self.assertIsNotNone(event.payment.payment_output.references)
        self.assertEqual(
            "12345",
            event.payment.payment_output.references.merchant_reference)
        self.assertEqual("card", event.payment.payment_output.payment_method)

        self.assertIsNotNone(
            event.payment.payment_output.card_payment_method_specific_output)
        self.assertIsNone(event.payment.payment_output.
                          redirect_payment_method_specific_output)
        self.assertIsNone(event.payment.payment_output.
                          sepa_direct_debit_payment_method_specific_output)
        self.assertEqual(
            1, event.payment.payment_output.
            card_payment_method_specific_output.payment_product_id)

        self.assertEqual("CAPTURED", event.payment.status)
        self.assertIsNotNone(event.payment.status_output)
        self.assertEqual(False, event.payment.status_output.is_cancellable)
        self.assertEqual("COMPLETED",
                         event.payment.status_output.status_category)
        self.assertEqual(9, event.payment.status_output.status_code)
        self.assertEqual(
            "20200101120000",
            event.payment.status_output.status_code_change_date_time)
        self.assertEqual(True, event.payment.status_output.is_authorized)
Exemplo n.º 4
0
 def test_unmarshal_no_secret_key_available(self):
     self.clear_public_key_cache()
     helper = self.__create_helper()
     body = self.__read_resource("valid-body")
     request_headers = [
         RequestHeader(self.__SIGNATURE_HEADER, self.__SIGNATURE),
         RequestHeader(self.__KEY_ID_HEADER, self.__KEY_ID)
     ]
     self.assertRaises(SecretKeyNotAvailableException, helper.unmarshal,
                       body, request_headers)
Exemplo n.º 5
0
 def test_unmarshal_string_invalid_signature(self):
     helper = self.__create_helper()
     InMemorySecretKeyStore.INSTANCE().store_secret_key(
         self.__KEY_ID, self.__SECRET_KEY)
     body = self.__read_resource("valid-body")
     request_headers = [
         RequestHeader(self.__SIGNATURE_HEADER, "1" + self.__SIGNATURE),
         RequestHeader(self.__KEY_ID_HEADER, self.__KEY_ID)
     ]
     self.assertRaises(SignatureValidationException, helper.unmarshal, body,
                       request_headers)
Exemplo n.º 6
0
    def test_get_server_metadata_headers_additional_headers(self):
        """Tests that the MetaDataProvider can handle multiple additional headers"""
        additional_headers = [RequestHeader("Header1", "&=$%"), RequestHeader("Header2", "blah blah"),
                              RequestHeader("Header3", "foo")]
        meta_data_provider = MetaDataProvider("OnlinePayments", None, additional_headers)
        request_headers = meta_data_provider.meta_data_headers

        self.assertEqual(4, len(request_headers))

        for index in range(1, 4):
            self.assertEqual(additional_headers[index - 1].name, request_headers[index].name)
            self.assertEqual(additional_headers[index - 1].value, request_headers[index].value)
Exemplo n.º 7
0
    def test_create_simple_authentication_signature(self):
        """Tests if the default authenticator creates the correct signature (with an authorization type with different casing)."""
        authenticator = DefaultAuthenticator("apiKeyId", "secretApiKey", "v1hmac")
        headers = [
            RequestHeader("Date", "Wed, 01 Jan 2020 11:00:00 GMT"),
            RequestHeader("X-GCS-ClientMetaInfo", "processed header value"),
            RequestHeader("X-GCS-CustomerHeader", "processed header value"),
            RequestHeader("X-GCS-ServerMetaInfo", "processed header value")
        ]
        url = urlparse.urlparse("http://localhost/v2/1/tokens")

        authentication_signature = authenticator.create_simple_authentication_signature("DELETE", url, headers)

        self.assertEqual("GCS v1HMAC:apiKeyId:zcDsJLRYsh99pqyCFdrVLyLVi+4A+QLis14rEtV8c98=", authentication_signature)
Exemplo n.º 8
0
 def test_unmarshal_api_version_mismatch(self):
     marshaller = mock(Marshaller)
     event = WebhooksEvent()
     event.api_version = "v0"
     body = self.__read_resource("valid-body")
     when(marshaller).unmarshal(body, WebhooksEvent).thenReturn(event)
     helper = self.__create_helper(marshaller)
     InMemorySecretKeyStore.INSTANCE().store_secret_key(
         self.__KEY_ID, self.__SECRET_KEY)
     request_headers = [
         RequestHeader(self.__SIGNATURE_HEADER, self.__SIGNATURE),
         RequestHeader(self.__KEY_ID_HEADER, self.__KEY_ID)
     ]
     self.assertRaises(ApiVersionMismatchException, helper.unmarshal, body,
                       request_headers)
Exemplo n.º 9
0
 def to_data_to_sign(self, http_method, resource_uri, http_headers):
     content_type = None
     date = None
     canonicalized_headers = ""
     canonicalized_resource = self.__to_canonicalized_resource(resource_uri)
     xgcs_http_headers = []
     if http_headers is not None:
         for http_header in http_headers:
             if "Content-Type".lower() == http_header.name.lower():
                 content_type = http_header.value
             elif "Date".lower() == http_header.name.lower():
                 date = http_header.value
             else:
                 name = self.__to_canonicalize_header_name(http_header.name)
                 if name.startswith("x-gcs"):
                     value = self.to_canonicalize_header_value(
                         http_header.value)
                     xgcs_http_header = RequestHeader(name, value)
                     xgcs_http_headers.append(xgcs_http_header)
     xgcs_http_headers.sort(key=attrgetter('name'))
     for xgcs_http_header in xgcs_http_headers:
         canonicalized_headers += xgcs_http_header.name + ":" + xgcs_http_header.value + "\n"
     string = http_method.upper() + "\n"
     if content_type is not None:
         string += content_type + "\n"
     else:
         string += "\n"
     string += date + "\n"
     string += str(canonicalized_headers)
     string += canonicalized_resource + "\n"
     return str(string)
Exemplo n.º 10
0
 def test_get_header_list(self):
     """Tests get_header using a list of RequestHeader objects"""
     headers = [RequestHeader("Content-Type", "application/json")]
     self.assertEqual("Content-Type:application/json",
                      str(get_header(headers, "Content-Type")))
     self.assertEqual("Content-Type:application/json",
                      str(get_header(headers, "content-type")))
     self.assertIsNone(get_header_value(headers, "Content-Length"))
Exemplo n.º 11
0
 def _client_headers(self):
     if self._client_meta_info is not None:
         client_headers = [
             RequestHeader("X-GCS-ClientMetaInfo", self._client_meta_info)
         ]
         return client_headers
     else:
         return None
Exemplo n.º 12
0
 def assertClientHeaders(self, client, client_meta_info):
     """Checks that the 'ClientMetaInfo' header with client_meta_info is stored properly in the client"""
     headers = client._client_headers
     header_value = base64.b64encode(client_meta_info.encode("utf-8"))
     expected = RequestHeader("X-GCS-ClientMetaInfo", header_value)
     found = False
     for header in headers:
         if str(expected) == str(header):
             found = True
     self.assertTrue(
         found, "header {0} was not found in {1}".format(expected, headers))
Exemplo n.º 13
0
 def _add_generic_headers(self, http_method, uri, request_headers, context):
     """
     Adds the necessary headers to the given list of headers. This includes
     the authorization header, which uses other headers, so when you need to
     override this method, make sure to call super.addGenericHeaders at the
     end of your overridden method.
     """
     # add server meta info header
     request_headers.extend(self.meta_data_provider.meta_data_headers)
     # add date header
     request_headers.append(
         RequestHeader("Date", self._get_header_date_string()))
     if context is not None and context.idempotence_key is not None:
         # add context specific headers
         request_headers.append(
             RequestHeader("X-GCS-Idempotence-Key",
                           context.idempotence_key))
     # add signature
     authentication_signature = \
         self.authenticator.create_simple_authentication_signature(http_method, uri, request_headers)
     request_headers.append(
         RequestHeader("Authorization", authentication_signature))
Exemplo n.º 14
0
    def __init__(self, integrator, shopping_cart_extension=None, additional_request_headers=()):
        MetaDataProvider.__validate_additional_request_headers(additional_request_headers)

        def subber(name_or_value):
            return re.sub(r'\r?\n(?:(?![\r\n])\s)*', " ", name_or_value).strip()

        additional_request_headers = [RequestHeader(subber(header.name), subber(header.value))
                                      for header in additional_request_headers]

        server_meta_info = self.ServerMetaInfo()
        server_meta_info.platform_identifier = self._platform_identifier
        server_meta_info.sdk_identifier = self._sdk_identifier
        server_meta_info.sdk_creator = "OnlinePayments"
        server_meta_info.integrator = integrator
        server_meta_info.shopping_cart_extension = shopping_cart_extension

        server_meta_info_string = DefaultMarshaller.INSTANCE().marshal(server_meta_info)
        server_meta_info_header = RequestHeader(self.__SERVER_META_INFO_HEADER, b64encode(server_meta_info_string.encode('utf-8')))
        if not additional_request_headers:
            self.__meta_data_headers = tuple([server_meta_info_header])
        else:
            request_headers = [server_meta_info_header]
            request_headers.extend(additional_request_headers)
            self.__meta_data_headers = tuple(request_headers)
Exemplo n.º 15
0
    def _put(self, relative_path, request_headers, request_parameters,
             request_body, context):
        if request_parameters is None:
            request_parameter_list = None
        else:
            request_parameter_list = request_parameters.to_request_parameters()
        uri = self._to_absolute_uri(relative_path, request_parameter_list)
        if request_headers is None:
            request_headers = []

        body = None
        if request_body is not None:
            request_headers.append(
                RequestHeader("Content-Type", "application/json"))
            body = self.__marshaller.marshal(request_body)

        self._add_generic_headers("PUT", uri, request_headers, context)
        return self.connection.put(uri, request_headers, body)