Пример #1
0
def read_crypto_key(key_path):
    """
    Read crypto key from keyczar JSON key file format and return parsed AESKey object.

    :param key_path: Absolute path to file containing crypto key in Keyczar JSON format.
    :type key_path: ``str``

    :rtype: :class:`AESKey`
    """
    with open(key_path, "r") as fp:
        content = fp.read()

    content = json_decode(content)

    try:
        aes_key = AESKey(
            aes_key_string=content["aesKeyString"],
            hmac_key_string=content["hmacKey"]["hmacKeyString"],
            hmac_key_size=content["hmacKey"]["size"],
            mode=content["mode"].upper(),
            size=content["size"],
        )
    except KeyError as e:
        msg = 'Invalid or malformed key file "%s": %s' % (key_path,
                                                          six.text_type(e))
        raise KeyError(msg)

    return aes_key
Пример #2
0
def _render(node, render_context):
    """
    Render the node depending on its type
    """
    if "template" in node:
        complex_type = False

        if isinstance(node["template"], list) or isinstance(
                node["template"], dict):
            node["template"] = json_encode(node["template"])

            # Finds occurrences of "{{variable}}" and adds `to_complex` filter
            # so types are honored. If it doesn't follow that syntax then it's
            # rendered as a string.
            node["template"] = re.sub(r'"{{([A-z0-9_-]+)}}"',
                                      r"{{\1 | to_complex}}", node["template"])
            LOG.debug("Rendering complex type: %s", node["template"])
            complex_type = True

        LOG.debug("Rendering node: %s with context: %s", node, render_context)

        result = ENV.from_string(str(node["template"])).render(render_context)

        LOG.debug("Render complete: %s", result)

        if complex_type:
            result = json_decode(result)
            LOG.debug("Complex Type Rendered: %s", result)

        return result
    if "value" in node:
        return node["value"]
Пример #3
0
    def test_json_encode_decode_roundtrip_compatibility_between_different_libs(
            self):
        class ObjectWithJsonMethod(object):
            def __json__(self):
                return {"mah": "json", "1": 2}

        input_data = [
            "1",
            1,
            None,
            True,
            False,
            [1, "a", True, None, [1, 2], {
                "a": "b",
                "c": 3
            }],
            {
                "a": "b",
                "d": [1, 2, 3],
                "e": 5
            },
            ObjectWithJsonMethod(),
            b"bytes",
            ObjectId("5609e91832ed356d04a93cc0"),
        ]
        expected_data = [
            "1",
            1,
            None,
            True,
            False,
            [1, "a", True, None, [1, 2], {
                "a": "b",
                "c": 3
            }],
            {
                "a": "b",
                "d": [1, 2, 3],
                "e": 5
            },
            {
                "mah": "json",
                "1": 2
            },
            "bytes",
            "5609e91832ed356d04a93cc0",
        ]

        json_libraries = ["json", "orjson"]

        for json_library in json_libraries:
            jsonify.DEFAULT_JSON_LIBRARY = json_library

            result_encoded = jsonify.json_encode(input_data)
            result_decoded = jsonify.json_decode(result_encoded)
            result_decoded_native = json.loads(result_encoded)

            self.assertEqual(result_decoded, expected_data)
            self.assertEqual(result_decoded, result_decoded_native)
Пример #4
0
 def _cast_object(self, value):
     if isinstance(value, str) or isinstance(value, six.text_type):
         try:
             return json_decode(value)
         except:
             return ast.literal_eval(value)
     else:
         return value
Пример #5
0
def _cast_object(x):
    """
    Method for casting string to an object (dict) or array.

    Note: String can be either serialized as JSON or a raw Python output.
    """
    x = _cast_none(x)

    if isinstance(x, six.string_types):
        try:
            return json_decode(x)
        except:
            return ast.literal_eval(x)
    else:
        return x
Пример #6
0
    def get_all(
        self,
        exclude_attributes=None,
        include_attributes=None,
        requester_user=None,
        limit=None,
        **raw_filters,
    ):
        """Retrieve multiple Inquiries

        Handles requests:
            GET /inquiries/
        """

        # NOTE: This controller retrieves execution objects and returns a new model composed of
        # execution.result fields and that's why we pass empty value for include_fields and
        # exclude_fields.
        # We only need to retrieve "id" and "result" from database and perform actual field
        # filtering before returning the response.
        raw_inquiries = super(InquiriesController, self)._get_all(
            exclude_fields=[],
            include_fields=["id", "result"],
            limit=limit,
            raw_filters={
                "status": action_constants.LIVEACTION_STATUS_PENDING,
                "runner": INQUIRY_RUNNER,
            },
            requester_user=requester_user,
        )

        # Since "model" is set to InquiryAPI (for good reasons), _get_all returns a list of
        # InquiryAPI instances, already converted to JSON. So in order to convert these to
        # InquiryResponseAPI instances, we first have to convert raw_inquiries.body back to
        # a list of dicts, and then individually convert these to InquiryResponseAPI instances
        inquiries = [
            inqy_api_models.InquiryResponseAPI.from_model(raw_inquiry,
                                                          skip_db=True)
            for raw_inquiry in json_decode(raw_inquiries.body)
        ]

        # Repackage into Response with correct headers
        resp = api_router.Response(json=inquiries)
        resp.headers["X-Total-Count"] = raw_inquiries.headers["X-Total-Count"]

        if limit:
            resp.headers["X-Limit"] = str(limit)

        return resp
Пример #7
0
    def _render_criteria_pattern(self, criteria_pattern, criteria_context):
        # Note: Here we want to use strict comparison to None to make sure that
        # other falsy values such as integer 0 are handled correctly.
        if criteria_pattern is None:
            return None

        if not isinstance(criteria_pattern, six.string_types):
            # We only perform rendering if value is a string - rendering a non-string value
            # makes no sense
            return criteria_pattern

        LOG.debug(
            "Rendering criteria pattern (%s) with context: %s",
            criteria_pattern,
            criteria_context,
        )

        to_complex = False

        # Check if jinja variable is in criteria_pattern and if so lets ensure
        # the proper type is applied to it using to_complex jinja filter
        if len(re.findall(MATCH_CRITERIA, criteria_pattern)) > 0:
            LOG.debug("Rendering Complex")
            complex_criteria_pattern = re.sub(
                MATCH_CRITERIA, r"\1\2 | to_complex\3", criteria_pattern
            )

            try:
                criteria_rendered = render_template_with_system_context(
                    value=complex_criteria_pattern, context=criteria_context
                )
                criteria_rendered = json_decode(criteria_rendered)
                to_complex = True
            except ValueError as error:
                LOG.debug("Criteria pattern not valid JSON: %s", error)

        if not to_complex:
            criteria_rendered = render_template_with_system_context(
                value=criteria_pattern, context=criteria_context
            )

        LOG.debug("Rendered criteria pattern: %s", criteria_rendered)

        return criteria_rendered
Пример #8
0
    def to_serializable_dict(self, mask_secrets=False):
        """
        Serialize database model to a dictionary.

        :param mask_secrets: True to mask secrets in the resulting dict.
        :type mask_secrets: ``boolean``

        :rtype: ``dict``
        """
        serializable_dict = {}
        for k in sorted(six.iterkeys(self._fields)):  # pylint: disable=E1101
            v = getattr(self, k)
            if isinstance(v, JSON_UNFRIENDLY_TYPES):
                v = str(v)
            elif isinstance(v, me.EmbeddedDocument):
                v = json_decode(v.to_json())

            serializable_dict[k] = v

        if mask_secrets and cfg.CONF.log.mask_secrets:
            serializable_dict = self.mask_secrets(value=serializable_dict)

        return serializable_dict
Пример #9
0
 def _json_body__get(self):
     return json_decode(self.body.decode(self.charset or "utf-8"))
Пример #10
0
    def _get_output_values(self, exit_code, stdout, stderr, timed_out):
        """
        Return sanitized output values.

        :return: Tuple with status, output and None

        :rtype: ``tuple``
        """
        if timed_out:
            error = "Action failed to complete in %s seconds" % (self._timeout)
        else:
            error = None

        if exit_code == PYTHON_RUNNER_INVALID_ACTION_STATUS_EXIT_CODE:
            # TODO: Mark as failed instead
            raise ValueError(stderr)

        if ACTION_OUTPUT_RESULT_DELIMITER in stdout:
            split = stdout.split(ACTION_OUTPUT_RESULT_DELIMITER)
            if len(split) != 3:
                raise ValueError(
                    f"The result length should be 3, was {len(split)}.")
            action_result = split[1].strip()
            stdout = split[0] + split[2]
        else:
            # Timeout or similar
            action_result = None

        # Parse the serialized action result object (if available)
        if action_result:
            try:
                action_result = json_decode(action_result)
            except Exception as e:
                # Failed to de-serialize the result, probably it contains non-simple type or similar
                LOG.warning('Failed to de-serialize result "%s": %s' %
                            (str(action_result), six.text_type(e)))

        if action_result:
            if isinstance(action_result, dict):
                result = action_result.get("result", None)
                status = action_result.get("status", None)
            else:
                # Failed to de-serialize action result aka result is a string
                match = re.search("'result': (.*?)$", action_result or "")

                if match:
                    action_result = match.groups()[0]

                result = action_result
                status = None
        else:
            result = "None"
            status = None

        output = {
            "stdout": stdout,
            "stderr": stderr,
            "exit_code": exit_code,
            "result": result,
        }

        if error:
            output["error"] = error

        status = self._get_final_status(action_status=status,
                                        timed_out=timed_out,
                                        exit_code=exit_code)
        return (status, output, None)
Пример #11
0
def render_values(mapping=None, context=None, allow_undefined=False):
    """
    Render an incoming mapping using context provided in context using Jinja2. Returns a dict
    containing rendered mapping.

    :param mapping: Input as a dictionary of key value pairs.
    :type mapping: ``dict``

    :param context: Context to be used for dictionary.
    :type context: ``dict``

    :rtype: ``dict``
    """

    if not context or not mapping:
        return mapping

    # Add in special __context variable that provides an easy way to get access to entire context.
    # This mean __context is a reserve key word although backwards compat is preserved by making
    # sure that real context is updated later and therefore will override the __context value.
    super_context = {}
    super_context["__context"] = context
    super_context.update(context)

    env = get_jinja_environment(allow_undefined=allow_undefined)
    rendered_mapping = {}
    for k, v in six.iteritems(mapping):
        # jinja2 works with string so transform list and dict to strings.
        reverse_json_dumps = False
        if isinstance(v, dict) or isinstance(v, list):
            v = json_encode(v)
            reverse_json_dumps = True
        else:
            # Special case for text type to handle unicode
            if isinstance(v, six.string_types):
                v = to_unicode(v)
            else:
                # Other types (e.g. boolean, etc.)
                v = str(v)

        try:
            LOG.info("Rendering string %s. Super context=%s", v, super_context)
            rendered_v = env.from_string(v).render(super_context)
        except Exception as e:
            # Attach key and value which failed the rendering
            e.key = k
            e.value = v
            raise e

        # no change therefore no templatization so pick params from original to retain
        # original type
        if rendered_v == v:
            rendered_mapping[k] = mapping[k]
            continue
        if reverse_json_dumps:
            rendered_v = json_decode(rendered_v)
        rendered_mapping[k] = rendered_v
    LOG.info(
        "Mapping: %s, rendered_mapping: %s, context: %s",
        mapping,
        rendered_mapping,
        context,
    )
    return rendered_mapping