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
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"]
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)
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
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
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
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
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
def _json_body__get(self): return json_decode(self.body.decode(self.charset or "utf-8"))
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)
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