Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide method for getting namespace from any ID #176

Open
bworrell opened this issue Aug 19, 2014 · 2 comments
Open

Provide method for getting namespace from any ID #176

bworrell opened this issue Aug 19, 2014 · 2 comments
Assignees

Comments

@bworrell
Copy link
Contributor

STIX IDs are QNames, which contain namespaces as part of their form. We should provide either a utility method or a new class for IDs that has a method for returning the namespace along with the id itself.

@bworrell
Copy link
Contributor Author

Something like...

stix_package.id_.get_namespace() # returns {'namespace': 'http://example.com', 'alias': 'example'}

# OR

stix.utils.get_id_namespace(stix_package.id_)  # returns {'namespace': 'http://example.com', 'alias': 'example'}

@usrlocalben
Copy link
Contributor

Here's my hack for id/idref namespaces... read-only, diff only includes Indicator.

diff --git a/stix/bindings/stix_common.py b/stix/bindings/stix_common.py
index f550507..069ed79 100644
--- a/stix/bindings/stix_common.py
+++ b/stix/bindings/stix_common.py
@@ -342,6 +342,31 @@ def find_attr_value_(attr_name, node):
             value = attrs.get('{%s}%s' % (namespace, name, ))
     return value

+def find_attr_value_qname(attr_name, node):
+    attrs = node.attrib
+    attr_parts = attr_name.split(':')
+    value = None
+    if len(attr_parts) == 1:
+        value = attrs.get(attr_name)
+    elif len(attr_parts) == 2:
+        prefix, name = attr_parts
+        namespace = node.nsmap.get(prefix)
+        if namespace is not None:
+            value = attrs.get('{%s}%s' % (namespace, name, ))
+    if value is None:
+        return None, None
+    val_parts = value.split(':')
+    if len(val_parts) == 1:
+        return value, None
+    elif len(val_parts) == 2:
+        prefix, data = val_parts
+        namespace = node.nsmap.get(prefix)
+        if namespace is not None:
+            return value, namespace
+        else:
+            raise ValueError("No namespace defined for qname prefix %s" % (prefix))
+    else:
+        raise ValueError("Malformed qname %s" % (value))

 class GDSParseError(Exception):
     pass
@@ -2617,9 +2642,11 @@ class IndicatorBaseType(GeneratedsSuper):
     specified elsewhere."""
     subclass = None
     superclass = None
-    def __init__(self, idref=None, id=None, timestamp=None):
+    def __init__(self, idref=None, id=None, timestamp=None, idrefns=None, idns=None):
         self.idref = _cast(None, idref)
+        self.idrefns = _cast(None, idrefns)
         self.id = _cast(None, id)
+        self.idns = _cast(None, idns)
         self.timestamp = _cast(None, timestamp)
     def factory(*args_, **kwargs_):
         if IndicatorBaseType.subclass:
@@ -2627,9 +2654,9 @@ class IndicatorBaseType(GeneratedsSuper):
         else:
             return IndicatorBaseType(*args_, **kwargs_)
     factory = staticmethod(factory)
-    def get_idref(self): return self.idref
+    def get_idref(self): return self.idref, self.idrefns
     def set_idref(self, idref): self.idref = idref
-    def get_id(self): return self.id
+    def get_id(self): return self.id, self.idns
     def set_id(self, id): self.id = id
     def get_timestamp(self): return self.timestamp
     def set_timestamp(self, timestamp): self.timestamp = timestamp
@@ -2674,14 +2701,16 @@ class IndicatorBaseType(GeneratedsSuper):
             nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
             self.buildChildren(child, node, nodeName_)
     def buildAttributes(self, node, attrs, already_processed):
-        value = find_attr_value_('idref', node)
+        value, ns = find_attr_value_qname('idref', node)
         if value is not None and 'idref' not in already_processed:
             already_processed.add('idref')
             self.idref = value
-        value = find_attr_value_('id', node)
+            self.idrefns = ns
+        value, ns = find_attr_value_qname('id', node)
         if value is not None and 'id' not in already_processed:
             already_processed.add('id')
             self.id = value
+            self.idns = ns
         value = find_attr_value_('timestamp', node)
         if value is not None and 'timestamp' not in already_processed:
             already_processed.add('timestamp')
diff --git a/stix/indicator/indicator.py b/stix/indicator/indicator.py
index f3ab87f..517a50f 100644
--- a/stix/indicator/indicator.py
+++ b/stix/indicator/indicator.py
@@ -513,8 +513,8 @@ class Indicator(stix.Entity):
         if not return_obj:
             return_obj = cls()

-        return_obj.id_              = obj.get_id()
-        return_obj.idref            = obj.get_idref()
+        return_obj.id_,return_obj.id_ns = obj.get_id()
+        return_obj.idref,return_obj.idref_ns = obj.get_idref()
         return_obj.timestamp        = obj.get_timestamp()

         if isinstance(obj, cls._binding_class):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants