# Path: ingenico/connect/sdk/webhooks/web_hooks_helper.py
# class WebhooksHelper:
#     """
#     Ingenico ePayments platform webhooks helper.
#     """
# 
#     def __init__(self, marshaller, secret_key_store):
#         if marshaller is None:
#             raise ValueError("marshaller is requried")
#         if secret_key_store is None:
#             raise ValueError("secret_key_store is required")
#         self.__marshaller = marshaller
#         self.__secret_key_store = secret_key_store
# 
#     # body as InputStream
# 
#     def unmarshal(self, body, request_headers):
#         """
#         Unmarshals the given body, while also validating it using the given request headers.
# 
#         :raise: SignatureValidationException: If the body could not be validated successfully.
#         :raise: ApiVersionMismatchException: If the resulting event has an API
#          version that this version of the SDK does not support.
#         :return: The body unmarshalled as a WebhooksEvent.
#         """
#         self._validate(body, request_headers)
#         event = self.__marshaller.unmarshal(body.decode("utf-8"), WebhooksEvent)
#         self.__validate_api_version(event)
#         return event
# 
#     def _validate(self, param, request_headers):
#         """
#         Validates the given body using the given request headers.
# 
#         :raise: SignatureValidationException: If the body could not be validated
#          successfully.
#         """
#         # if isinstance(param, str):
#         #     self._validate(param.encode('UTF-8'), request_headers)
#         # else:
#         # try:
#         self.__validate_body(param, request_headers)
#         # except Exception as e:
#         #     raise SignatureValidationException(e)
# 
#     # validation utility methods
# 
#     def __validate_body(self, body, request_headers):
#         signature = self.__get_header_value(request_headers, "X-GCS-Signature")
#         key_id = self.__get_header_value(request_headers, "X-GCS-KeyId")
#         secret_key = self.__secret_key_store.get_secret_key(key_id)
#         unencoded_result = hmac.new(secret_key.encode("utf-8"), body, hashlib.sha256).digest()
#         expected_signature = b64encode(unencoded_result)
#         is_valid = hmac.compare_digest(signature.encode("utf-8"), expected_signature)
#         if is_valid is False:
#             raise SignatureValidationException("failed to validate signature: " + signature)
# 
#     @staticmethod
#     def are_equal_signatures(signature, expected_signature):
#         # don't use a simple equals call, as that may leak timing information
#         # (it fails fast)
#         length = len(signature)
#         expected_length = len(expected_signature)
# 
#         # always check at least 256 characters, to also not leak timing
#         # information about the length of the expected signature
#         limit = max(max(length, expected_length), 256)
# 
#         result = True
# 
#         # the loop below uses result &= false instead of result = false and
#         # result &= true instead of nothing because those might leak timing
#         # information
#         for i in range(0, limit):
#             if i < length and i < expected_length:
#                 # both within string boundaries
#                 result = result and (signature[i] == expected_signature[i])
#             elif i >= length and i >= expected_length:
#                 # past both string boundaries
#                 result = result and True
#             else:
#                 # i >= length || i >= expected_length but not both
#                 result = result and False
# 
#         return result
# 
#     # general utility methods
# 
#     def __validate_api_version(self, event):
#         if not Client.API_VERSION() == event.api_version:
#             raise ApiVersionMismatchException(event.api_version,
#                                               Client.API_VERSION())
# 
#     def __get_header_value(self, request_headers, header_name):
#         value = None
#         for header in request_headers:
#             if header_name.lower() == header.name.lower():
#                 if value is None:
#                     value = header.value
#                 else:
#                     raise SignatureValidationException(
#                         "encountered multiple occurrences of header '"
#                         + header_name + "'")
#         if value is None:
#             raise SignatureValidationException(
#                 "could not find header '" + header_name + "'")
#         return value
# 
#     # Used for unit tests
#     @property
#     def marshaller(self):
#         return self.__marshaller
# 
#     @property
#     def secret_key_store(self):
#         return self.__secret_key_store


from .web_hooks_helper import WebhooksHelper


class WebhooksHelperBuilder:
    """
    Builder for a WebhooksHelper object.
    """
    __marshaller = None
    __secret_key_store = None

    def with_marshaller(self, marshaller):
        """
        Sets the Marshaller to use.
        """
        self.__marshaller = marshaller
        return self

    def with_secret_key_store(self, secret_key_store):
        """
        Sets the SecretKeyStore to use.
        """
        self.__secret_key_store = secret_key_store
        return self

    def build(self):
        """
        Creates a fully initialized WebhooksHelper object.

        :raise: ValueError: if not all required components are set
        """

# Path: ingenico/connect/sdk/webhooks/web_hooks_helper.py
# class WebhooksHelper:
#     """
#     Ingenico ePayments platform webhooks helper.
#     """
# 
#     def __init__(self, marshaller, secret_key_store):
#         if marshaller is None:
#             raise ValueError("marshaller is requried")
#         if secret_key_store is None:
#             raise ValueError("secret_key_store is required")
#         self.__marshaller = marshaller
#         self.__secret_key_store = secret_key_store
# 
#     # body as InputStream
# 
#     def unmarshal(self, body, request_headers):
#         """
#         Unmarshals the given body, while also validating it using the given request headers.
# 
#         :raise: SignatureValidationException: If the body could not be validated successfully.
#         :raise: ApiVersionMismatchException: If the resulting event has an API
#          version that this version of the SDK does not support.
#         :return: The body unmarshalled as a WebhooksEvent.
#         """
#         self._validate(body, request_headers)
#         event = self.__marshaller.unmarshal(body.decode("utf-8"), WebhooksEvent)
#         self.__validate_api_version(event)
#         return event
# 
#     def _validate(self, param, request_headers):
#         """
#         Validates the given body using the given request headers.
# 
#         :raise: SignatureValidationException: If the body could not be validated
#          successfully.
#         """
#         # if isinstance(param, str):
#         #     self._validate(param.encode('UTF-8'), request_headers)
#         # else:
#         # try:
#         self.__validate_body(param, request_headers)
#         # except Exception as e:
#         #     raise SignatureValidationException(e)
# 
#     # validation utility methods
# 
#     def __validate_body(self, body, request_headers):
#         signature = self.__get_header_value(request_headers, "X-GCS-Signature")
#         key_id = self.__get_header_value(request_headers, "X-GCS-KeyId")
#         secret_key = self.__secret_key_store.get_secret_key(key_id)
#         unencoded_result = hmac.new(secret_key.encode("utf-8"), body, hashlib.sha256).digest()
#         expected_signature = b64encode(unencoded_result)
#         is_valid = hmac.compare_digest(signature.encode("utf-8"), expected_signature)
#         if is_valid is False:
#             raise SignatureValidationException("failed to validate signature: " + signature)
# 
#     @staticmethod
#     def are_equal_signatures(signature, expected_signature):
#         # don't use a simple equals call, as that may leak timing information
#         # (it fails fast)
#         length = len(signature)
#         expected_length = len(expected_signature)
# 
#         # always check at least 256 characters, to also not leak timing
#         # information about the length of the expected signature
#         limit = max(max(length, expected_length), 256)
# 
#         result = True
# 
#         # the loop below uses result &= false instead of result = false and
#         # result &= true instead of nothing because those might leak timing
#         # information
#         for i in range(0, limit):
#             if i < length and i < expected_length:
#                 # both within string boundaries
#                 result = result and (signature[i] == expected_signature[i])
#             elif i >= length and i >= expected_length:
#                 # past both string boundaries
#                 result = result and True
#             else:
#                 # i >= length || i >= expected_length but not both
#                 result = result and False
# 
#         return result
# 
#     # general utility methods
# 
#     def __validate_api_version(self, event):
#         if not Client.API_VERSION() == event.api_version:
#             raise ApiVersionMismatchException(event.api_version,
#                                               Client.API_VERSION())
# 
#     def __get_header_value(self, request_headers, header_name):
#         value = None
#         for header in request_headers:
#             if header_name.lower() == header.name.lower():
#                 if value is None:
#                     value = header.value
#                 else:
#                     raise SignatureValidationException(
#                         "encountered multiple occurrences of header '"
#                         + header_name + "'")
#         if value is None:
#             raise SignatureValidationException(
#                 "could not find header '" + header_name + "'")
#         return value
# 
#     # Used for unit tests
#     @property
#     def marshaller(self):
#         return self.__marshaller
# 
#     @property
#     def secret_key_store(self):
#         return self.__secret_key_store


# Path: ingenico/connect/sdk/webhooks/web_hooks_helper_builder.py
from .web_hooks_helper import WebhooksHelper



class WebhooksHelperBuilder:
    """
    Builder for a WebhooksHelper object.
    """
    __marshaller = None
    __secret_key_store = None

    def with_marshaller(self, marshaller):
        """
        Sets the Marshaller to use.
        """
        self.__marshaller = marshaller
        return self

    def with_secret_key_store(self, secret_key_store):
        """
        Sets the SecretKeyStore to use.
        """
        self.__secret_key_store = secret_key_store
        return self

    def build(self):
        """
        Creates a fully initialized WebhooksHelper object.

        :raise: ValueError: if not all required components are set
        """

        return WebhooksHelper(self.__marshaller, self.__secret_key_store)