Source code for worldline.connect.sdk.log.body_obfuscator

import codecs
import re

from obfuscation_rule import obfuscate_all, obfuscate_with_fixed_length, obfuscate_all_but_first, obfuscate_all_but_last


[docs]class BodyObfuscator(object): """ A class that can be used to obfuscate properties in JSON bodies. """ __obfuscation_rules = None __property_pattern = None
[docs] def __init__(self, additional_rules=None): """ Creates a new body obfuscator. This will contain some pre-defined obfuscation rules, as well as any provided custom rules :param additional_rules: An optional mapping from property names to obfuscation rules, where an obfuscation rule is a function that obfuscates a single string, """ self.__obfuscation_rules = { "cardNumber": obfuscate_all_but_last(4), "expiryDate": obfuscate_all_but_last(2), "cvv": obfuscate_all(), "iban": obfuscate_all_but_last(4), "accountNumber": obfuscate_all_but_last(4), "reformattedAccountNumber": obfuscate_all_but_last(4), "bin": obfuscate_all_but_first(6), "value": obfuscate_all(), "keyId": obfuscate_with_fixed_length(8), "secretKey": obfuscate_with_fixed_length(8), "publicKey": obfuscate_with_fixed_length(8), "userAuthenticationToken": obfuscate_with_fixed_length(8), "encryptedPayload": obfuscate_with_fixed_length(8), "decryptedPayload": obfuscate_with_fixed_length(8), "encryptedCustomerInput": obfuscate_with_fixed_length(8), } if additional_rules: for name, rule in additional_rules.iteritems(): self.__obfuscation_rules[name] = rule property_names = tuple(self.__obfuscation_rules.keys()) self.__property_pattern = self.__build_property_pattern(property_names)
@staticmethod def __build_property_pattern(property_names): if not property_names: return re.compile("$^") s = "([\"'])(" for p in property_names: s += '|' + re.escape(p) s += ")\\1\\s*:\\s*(?:([\"'])(.*?)(?<!\\\\)\\3|([^\"'\\s\\[\\{]((?!,)\\S)*))" return re.compile(s, re.DOTALL) def __obfuscate_value(self, property_name, value): obfuscation_rule = self.__obfuscation_rules.get(property_name) if obfuscation_rule: return obfuscation_rule(value) return value
[docs] def obfuscate_body(self, body, charset=None): """ Obfuscates the body from the given stream as necessary. :param body: The body to obfuscate, as string or bytes. :param charset: The charset to use to read the body bytes. """ if charset: body = codecs.decode(body, charset) if body is None: return None if not body: return "" index = 0 s_obfuscate = "" matcher = self.__property_pattern.finditer(body) for x in matcher: property_name = x.group(2) value = x.group(4) value_start = x.start(4) value_end = x.end(4) if not value: value = x.group(5) value_start = x.start(5) value_end = x.end(5) obfuscated_value = self.__obfuscate_value(property_name, value) s_obfuscate += body[index:value_start] + obfuscated_value index = value_end return s_obfuscate + body[index:]
[docs] @staticmethod def default_body_obfuscator(): return _DEFAULT_BODY_OBFUSCATOR
_DEFAULT_BODY_OBFUSCATOR = BodyObfuscator()