예제 #1
0
def test_traverse_upper():

    actual = iterutil.traverse(
        {
            'a': 'one',
            'b': {
                'c': {
                    'd': 'two',
                    'e': 'three'
                },
                'f': 'four'
            },
            'g': 'five',
            'h': ['six', {
                'i': 'seven',
                'j': 'eight'
            }]
        }, lambda v, p: v.upper())

    assert actual == {
        'a': 'ONE',
        'b': {
            'c': {
                'd': 'TWO',
                'e': 'THREE'
            },
            'f': 'FOUR'
        },
        'g': 'FIVE',
        'h': ['SIX', {
            'i': 'SEVEN',
            'j': 'EIGHT'
        }]
    }
예제 #2
0
def dumps(obj: dict) -> str:

    obj = dictutil.flatten(obj)

    def _process(value, key):
        path = '_'.join(key).upper().replace('.', '_')
        return f'{path}={value}'

    return '\n'.join(iterutil.traverse(obj, _process).values())
예제 #3
0
def inject(template: Template,
           context: Dict[str, Any],
           strict: bool = True,
           calls: int = 0) -> Template:
    """
    Inject context to template.
    """

    # Traverse template values
    if isinstance(template, (list, dict)):
        return iterutil.traverse(
            template,
            lambda v, k: inject(template=v, context=context, strict=strict))

    # Return other types
    if not isinstance(template, str):
        return template

    result = KEY_RE.findall(template)

    # Increment recursive calls
    calls += 1

    # Skip parameters replace
    if not result:
        return template

    # Check circular injections
    if calls > CIRCULAR_THRESHOLD:
        if strict:
            raise CircularInjectError(_('Circular injections detected.'))
        return template

    # Replace template context
    for whole, key in result:
        try:
            value = inject(template=context[key],
                           context=context,
                           calls=calls,
                           strict=strict)
            str_value = str(value)
            template = template.replace(whole, str_value)
            if str_value == template:
                return value
        except KeyError:
            if strict:
                raise InvalidKey(_('Injected key `%(key)s` does not exist.') %
                                 {'key': key},
                                 key=key)

    return inject(template=template,
                  context=context,
                  calls=calls,
                  strict=strict)
예제 #4
0
def cleanse(data: dict, hidden='password', substitute='*****'):

    if isinstance(hidden, str):
        hidden = hidden.split()

    hidden_re = re.compile('|'.join(hidden), flags=re.IGNORECASE)

    def _replace(value, path: iterutil.IterPath):
        path = _str_path(path)
        if hidden_re.search(path):
            return substitute
        return value

    return iterutil.traverse(data, _replace)
예제 #5
0
def decrypt(data: dict, secure_keys: List[str]) -> dict:

    hidden_re = re.compile('|'.join(secure_keys), flags=re.IGNORECASE)

    def _process(value: Any, path: iterutil.IterPath) -> Any:

        if is_encrypted(value):
            path = _str_path(path)
            if hidden_re.search(path):
                encrypted_data = value.split(settings.ENCRYPT_PREFIX,
                                             maxsplit=1)[-1]
                obj = decrypt_data(encrypted_data)
                return json.loads(obj)['value']

        return value

    return iterutil.traverse(data, _process)
예제 #6
0
def encrypt(data: dict, secure_keys: List[str]) -> dict:

    if not secure_keys:
        return data

    hidden_re = re.compile('|'.join(secure_keys), flags=re.IGNORECASE)

    def _process(value: Any, path: iterutil.IterPath) -> str:

        if not is_encrypted(value):
            path = _str_path(path)
            if hidden_re.search(path):
                encrypted_data = encrypt_data(json.dumps({'value': value}))
                return f'{settings.ENCRYPT_PREFIX}{encrypted_data}'

        return value

    return iterutil.traverse(data, _process)
예제 #7
0
def get_all_data() -> Dict[str, Dict[str, dict]]:
    if hasattr(_cached_data, _cached_data_key):
        return getattr(_cached_data, _cached_data_key)
    data = _store.all()
    return iterutil.traverse(data, lambda value, path: json.loads(value))