예제 #1
0
    def test_nsinfo_collect(self):
        """Tests that the NamespaceInfo.collect() method correctly ascends the MRO
        of input objects.

        """
        nsinfo = NamespaceCollector()

        # Collect classes
        nsinfo.collect(C())

        # Parse collected classes
        nsinfo._parse_collected_classes()

        self.assertEqual(len(nsinfo._collected_namespaces), 3)  # noqa
예제 #2
0
    def test_namespace_collect(self):
        """Test that NamespaceInfo correctly pulls namespaces from all classes
        in an objects MRO.

        """
        nsinfo = NamespaceCollector()

        # Collect classes
        nsinfo.collect(C())

        # finalize the namespace dictionary
        nsinfo.finalize(ns_dict=NSMAP, schemaloc_dict=SCHEMALOCS)
        namespaces = nsinfo.binding_namespaces.keys()

        self.assertTrue(all(ns in namespaces for ns in six.iterkeys(NSMAP)))
예제 #3
0
파일: base.py 프로젝트: sgml/python-stix
    def to_xml(self,
               include_namespaces=True,
               include_schemalocs=False,
               ns_dict=None,
               schemaloc_dict=None,
               pretty=True,
               auto_namespace=True,
               encoding='utf-8'):
        """Serializes a :class:`Entity` instance to an XML string.

        The default character encoding is ``utf-8`` and can be set via the
        `encoding` parameter. If `encoding` is ``None``, a string (unicode in
        Python 2, str in Python 3) is returned.

        Args:
            auto_namespace: Automatically discover and export XML namespaces
                for a STIX :class:`Entity` instance.
            include_namespaces: Export namespace definitions in the output
                XML. Default is ``True``.
            include_schemalocs: Export ``xsi:schemaLocation`` attribute
                in the output document. This will attempt to associate
                namespaces declared in the STIX document with schema locations.
                If a namespace cannot be resolved to a schemaLocation, a
                Python warning will be raised. Schemalocations will only be
                exported if `include_namespaces` is also ``True``.
            ns_dict: Dictionary of XML definitions (namespace is key, alias is
                value) to include in the exported document. This must be
                passed in if `auto_namespace` is ``False``.
            schemaloc_dict: Dictionary of XML ``namespace: schema location``
                mappings to include in the exported document. These will
                only be included if `auto_namespace` is ``False``.
            pretty: Pretty-print the XML.
            encoding: The output character encoding. Default is ``utf-8``. If
                `encoding` is set to ``None``, a string (unicode in Python 2,
                str in Python 3) is returned.

        Returns:
            An XML string for this
            :class:`Entity` instance. Default character encoding is ``utf-8``.

        """

        from mixbox.entities import NamespaceCollector

        if (not auto_namespace) and (not ns_dict):
            raise Exception(
                "Auto-namespacing was disabled but ns_dict was empty "
                "or missing.")

        ns_info = NamespaceCollector()

        obj = self.to_obj(ns_info=ns_info if auto_namespace else None)

        ns_info.finalize(ns_dict=ns_dict, schemaloc_dict=schemaloc_dict)

        if auto_namespace:
            obj_ns_dict = ns_info.binding_namespaces
        else:
            obj_ns_dict = dict(
                itertools.chain(iteritems(ns_info.binding_namespaces),
                                iteritems(namespaces.get_full_ns_map())))

        namespace_def = ""
        if include_namespaces:
            delim = "\n\t" if pretty else " "
            xmlns = ns_info.get_xmlns_string(delim)
            namespace_def += (delim + xmlns)
            if include_schemalocs:
                schemaloc = ns_info.get_schema_location_string(delim)
                namespace_def += (delim + schemaloc)

        with binding_utils.save_encoding(encoding):
            sio = StringIO()
            obj.export(
                sio.write,  # output buffer
                0,  # output level
                obj_ns_dict,  # namespace dictionary
                pretty_print=pretty,  # pretty printing
                namespacedef_=namespace_def  # namespace/schemaloc def string
            )

        # Ensure that the StringIO buffer is unicode
        s = text_type(sio.getvalue())

        if encoding:
            return s.encode(encoding)

        return s
예제 #4
0
def round_trip(o, output=False, list_=False):
    """ Performs all eight conversions to verify import/export functionality.

    1. cybox.Entity -> dict/list
    2. dict/list -> JSON string
    3. JSON string -> dict/list
    4. dict/list -> cybox.Entity
    5. cybox.Entity -> Bindings Object
    6. Bindings Object -> XML String
    7. XML String -> Bindings Object
    8. Bindings object -> cybox.Entity

    It returns the final object, so tests which call this function can check to
    ensure it was not modified during any of the transforms.
    """

    klass = o.__class__
    if output:
        print("Class: ", klass)
        print("-" * 40)

    # 1. cybox.Entity -> dict/list
    if list_:
        d = o.to_list()
    else:
        d = o.to_dict()

    # 2. dict/list -> JSON string
    json_string = json.dumps(d)

    if output:
        print(json_string)
        print("-" * 40)

    # Before parsing the JSON, make sure the cache is clear
    cybox.utils.cache_clear()

    # 3. JSON string -> dict/list
    d2 = json.loads(json_string)

    # 4. dict/list -> cybox.Entity
    if list_:
        o2 = klass.from_list(d2)
    else:
        o2 = klass.from_dict(d2)

    # 5. Entity -> Bindings Object
    ns_info = NamespaceCollector()
    xobj = o2.to_obj(ns_info=ns_info)

    try:
        # 6. Bindings Object -> XML String
        xml_string = o2.to_xml(encoding=ExternalEncoding)

        if not isinstance(xml_string, text_type):
            xml_string = xml_string.decode(ExternalEncoding)

    except KeyError as ex:
        print(str(ex))
        ns_info.finalize()
        print(ns_info.binding_namespaces)
        raise ex

    if output:
        print(xml_string)
        print("-" * 40)

    # Before parsing the XML, make sure the cache is clear
    cybox.utils.cache_clear()

    # 7. XML String -> Bindings Object
    xobj2 = klass._binding.parseString(xml_string)

    # 8. Bindings object -> cybox.Entity
    o3 = klass.from_obj(xobj2)

    return o3
예제 #5
0
def round_trip(o, output=False, list_=False):
    """ Performs all eight conversions to verify import/export functionality.

    1. cybox.Entity -> dict/list
    2. dict/list -> JSON string
    3. JSON string -> dict/list
    4. dict/list -> cybox.Entity
    5. cybox.Entity -> Bindings Object
    6. Bindings Object -> XML String
    7. XML String -> Bindings Object
    8. Bindings object -> cybox.Entity

    It returns the final object, so tests which call this function can check to
    ensure it was not modified during any of the transforms.
    """

    klass = o.__class__
    if output:
        print("Class: ", klass)
        print("-" * 40)

    # 1. cybox.Entity -> dict/list
    if list_:
        d = o.to_list()
    else:
        d = o.to_dict()

    # 2. dict/list -> JSON string
    json_string = json.dumps(d)

    if output:
        print(json_string)
        print("-" * 40)

    # Before parsing the JSON, make sure the cache is clear
    cybox.utils.cache_clear()

    # 3. JSON string -> dict/list
    d2 = json.loads(json_string)

    # 4. dict/list -> cybox.Entity
    if list_:
        o2 = klass.from_list(d2)
    else:
        o2 = klass.from_dict(d2)

    # 5. Entity -> Bindings Object
    ns_info = NamespaceCollector()
    xobj = o2.to_obj(ns_info=ns_info)

    try:
        # 6. Bindings Object -> XML String
        xml_string = o2.to_xml(encoding=ExternalEncoding)

        if not isinstance(xml_string, text_type):
            xml_string = xml_string.decode(ExternalEncoding)

    except KeyError as ex:
        print(str(ex))
        ns_info.finalize()
        print(ns_info.binding_namespaces)
        raise ex

    if output:
        print(xml_string)
        print("-" * 40)

    # Before parsing the XML, make sure the cache is clear
    cybox.utils.cache_clear()

    # 7. XML String -> Bindings Object
    xobj2 = klass._binding.parseString(xml_string)

    # 8. Bindings object -> cybox.Entity
    o3 = klass.from_obj(xobj2)

    return o3