Пример #1
0
def test_flatten_dict():

    actual = dictutil.flatten({
        'a': {
            'b': {
                'c': {
                    'd': 'e'
                }
            }
        },
        'f': 1,
        'g': [1, 2, 3],
        'h': {
            'i': 1,
            'j': 2
        }
    })

    assert actual == {
        'a.b.c.d': 'e',
        'f': 1,
        'g': [1, 2, 3],
        'h.i': 1,
        'h.j': 2,
    }
Пример #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_settings(environment: Environment,
                    data: dict,
                    components: Iterable[Component] = None,
                    strict: bool = True) -> dict:
    """
    Inject settings keys.
    """

    if components is None:
        components = Component.objects.all()

    env_settings = get_environment_settings(environment, components=components)
    context = dictutil.flatten(env_settings)

    return tplcontext.inject(template=data, context=context, strict=strict)
Пример #4
0
    def get_context_data(self, **kwargs):

        data = super().get_context_data(**kwargs)

        component = self.object  # type: Component
        environment = get_object_or_404(
            klass=self.request.view_environments,
            alias=self.kwargs['environment']
        )

        settings_dict = security.cleanse(
            data=get_settings(
                environment=environment,
                component=component,
            ),
            hidden=settings.SECURE_KEYS,
        )

        settings_dict = dictutil.flatten(settings_dict)
        settings_dict = inject_settings(
            environment=environment,
            data=settings_dict,
            components=self.request.components,
            strict=False
        )

        form = ComponentSettingsForm(
            component=component,
            environment=environment,
            initial={
                'settings': settings_dict
            }
        )

        checker = ObjectPermissionChecker(self.request.user)
        component_perms = checker.get_perms(component)
        environment_perms = checker.get_perms(environment)

        data.update({
            'current_environment': environment,
            'settings': settings_dict,
            'form': form,
            'component_perms': component_perms,
            'environment_perms': environment_perms
        })

        return data
Пример #5
0
 def _loads(self, data_json):
     if not data_json:
         return {}
     data = json.loads(data_json)
     if (self.content_type_id
             and self.content_type.model_class() is Component
             and 'settings' in data):
         try:
             environment_data = data['settings']
             environment = list(environment_data.keys())[0]
             if isinstance(environment_data[environment], str):
                 settings_data = json.loads(
                     decrypt_data(environment_data[environment]))
             else:
                 settings_data = environment_data[environment] or {}
             data['settings'][environment] = settings_data
         except (KeyError, IndexError):
             return {}
     return dictutil.flatten(data)
Пример #6
0
def validate_settings(environment: Environment, component: Component,
                      data: dict):
    """
    Update component settings.
    """

    # Validate settings format
    try:
        validate_settings_format(data)
    except ValidationError as exc:
        raise InvalidSettingsError(exc.message)

    # Validate changed component referred keys
    setting_keys = list(dictutil.flatten({component.alias: data}).keys())

    inject_keys = get_settings_inject_keys(
        environment, override_settings={component.alias: data})

    for component_alias, keys in inject_keys.items():
        for key in keys:
            if key.startswith(component.alias) and key not in setting_keys:
                raise InvalidSettingsError(
                    _('Component `%s` refers to changed key `%s`.') %
                    (component_alias, key), )

    # Validate injections
    try:
        data = inject_settings(environment=environment, data=data, strict=True)
    except tplcontext.InvalidKey as exc:
        raise InvalidSettingsError(
            _('Injected key `%(key)s` does not exist.') % {'key': exc.key})
    except tplcontext.CircularInjectError:
        raise InvalidSettingsError(_('Circular key injections detected.'))
    except Exception:
        raise InvalidSettingsError(_('Unknown settings validation error.'))

    # Validate JSON schema
    if component.require_schema:
        try:
            jsonschema.validate(instance=data, schema=component.schema)
        except (jsonschema.ValidationError, jsonschema.SchemaError) as exc:
            raise InvalidSettingsError(
                _('Invalid settings schema: %(error)s.') %
                {'error': exc.message})

    # Validate strict keys
    if component.strict_keys and not environment.is_base:

        base_settings = get_settings(
            environment=Environment.objects.base().get(),
            component=component,
        )

        diff = dictdiffer.diff(base_settings, data)

        add_keys = []
        remove_keys = []

        for summary in diff:
            if 'add' in summary:
                add_keys = [
                    add[0] for add in summary[2]
                    if not isinstance(add[0], int)
                ]
            if 'remove' in summary:
                remove_keys = [
                    remove[0] for remove in summary[2]
                    if not isinstance(remove[0], int)
                ]

        if add_keys:
            raise InvalidSettingsError(
                _('Cannot add new keys to environment configuration. '
                  'New key(s): <b>%(keys)s</b>.') %
                {'keys': ', '.join(add_keys)})

        if remove_keys:
            raise InvalidSettingsError(
                _('Cannot remove keys from environment configuration. '
                  'Removed key(s): <b>%(keys)s</b>.') %
                {'keys': ', '.join(remove_keys)})
Пример #7
0
 def get(self, request, environment: str, **kwargs):
     environment = get_object_or_404(self.environments, alias=environment)
     data = dictutil.flatten(get_environment_settings(environment))
     return Response(data)