Move relationships() to DataSources
parent
f9ad7ceb65
commit
55cf00d7f0
|
@ -2,7 +2,6 @@ import copy
|
||||||
|
|
||||||
from .core import parse as _parse
|
from .core import parse as _parse
|
||||||
from .sources import CompositeDataSource, DataStore
|
from .sources import CompositeDataSource, DataStore
|
||||||
from .sources.filters import Filter
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectFactory(object):
|
class ObjectFactory(object):
|
||||||
|
@ -173,41 +172,9 @@ class Environment(object):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def relationships(self, obj, relationship_type=None, source_only=False, target_only=False):
|
def relationships(self, *args, **kwargs):
|
||||||
"""Retrieve Relationships involving the given STIX object.
|
|
||||||
|
|
||||||
Only one of `source_only` and `target_only` may be `True`.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
|
||||||
relationships will be looked up.
|
|
||||||
relationship_type (str): Only retrieve Relationships of this type.
|
|
||||||
source_only (bool): Only retrieve Relationships for which this
|
|
||||||
object is the source_ref. Default: False.
|
|
||||||
target_only (bool): Only retrieve Relationships for which this
|
|
||||||
object is the target_ref. Default: False.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List of Relationship objects involving the given STIX object.
|
|
||||||
|
|
||||||
"""
|
|
||||||
results = []
|
|
||||||
filters = [Filter('type', '=', 'relationship')]
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
obj_id = obj.get('id', '')
|
return self.source.relationships(*args, **kwargs)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
obj_id = obj
|
raise AttributeError('Environment has no data source')
|
||||||
|
relationships.__doc__ = DataStore.relationships.__doc__
|
||||||
if relationship_type:
|
|
||||||
filters.append(Filter('relationship_type', '=', relationship_type))
|
|
||||||
|
|
||||||
if source_only and target_only:
|
|
||||||
raise ValueError("Search either source only or target only, but not both")
|
|
||||||
|
|
||||||
if not target_only:
|
|
||||||
results.extend(self.query(filters + [Filter('source_ref', '=', obj_id)]))
|
|
||||||
if not source_only:
|
|
||||||
results.extend(self.query(filters + [Filter('target_ref', '=', obj_id)]))
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import uuid
|
||||||
|
|
||||||
from six import with_metaclass
|
from six import with_metaclass
|
||||||
|
|
||||||
|
from stix2.sources.filters import Filter
|
||||||
from stix2.utils import deduplicate
|
from stix2.utils import deduplicate
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +90,28 @@ class DataStore(object):
|
||||||
"""
|
"""
|
||||||
return self.source.query(*args, **kwargs)
|
return self.source.query(*args, **kwargs)
|
||||||
|
|
||||||
|
def relationships(self, *args, **kwargs):
|
||||||
|
"""Retrieve Relationships involving the given STIX object.
|
||||||
|
|
||||||
|
Translate relationships() call to the appropriate DataSource call.
|
||||||
|
|
||||||
|
Only one of `source_only` and `target_only` may be `True`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
||||||
|
relationships will be looked up.
|
||||||
|
relationship_type (str): Only retrieve Relationships of this type.
|
||||||
|
source_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the source_ref. Default: False.
|
||||||
|
target_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the target_ref. Default: False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(list): List of Relationship objects involving the given STIX object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.source.relationships(*args, **kwargs)
|
||||||
|
|
||||||
def add(self, *args, **kwargs):
|
def add(self, *args, **kwargs):
|
||||||
"""Method for storing STIX objects.
|
"""Method for storing STIX objects.
|
||||||
|
|
||||||
|
@ -191,6 +214,28 @@ class DataSource(with_metaclass(ABCMeta)):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def relationships(self, obj, relationship_type=None, source_only=False, target_only=False):
|
||||||
|
"""
|
||||||
|
Implement: The specific data source API calls, processing,
|
||||||
|
functionality required for dereferencing relationships.
|
||||||
|
|
||||||
|
Only one of `source_only` and `target_only` may be `True`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
||||||
|
relationships will be looked up.
|
||||||
|
relationship_type (str): Only retrieve Relationships of this type.
|
||||||
|
source_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the source_ref. Default: False.
|
||||||
|
target_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the target_ref. Default: False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(list): List of Relationship objects involving the given STIX object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class CompositeDataSource(DataSource):
|
class CompositeDataSource(DataSource):
|
||||||
"""Controller for all the attached DataSources.
|
"""Controller for all the attached DataSources.
|
||||||
|
@ -354,6 +399,49 @@ class CompositeDataSource(DataSource):
|
||||||
|
|
||||||
return all_data
|
return all_data
|
||||||
|
|
||||||
|
def relationships(self, obj, relationship_type=None, source_only=False, target_only=False):
|
||||||
|
"""Retrieve Relationships involving the given STIX object.
|
||||||
|
|
||||||
|
Only one of `source_only` and `target_only` may be `True`.
|
||||||
|
|
||||||
|
Federated relationships retrieve method - iterates through all
|
||||||
|
DataSources defined in "data_sources".
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
||||||
|
relationships will be looked up.
|
||||||
|
relationship_type (str): Only retrieve Relationships of this type.
|
||||||
|
source_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the source_ref. Default: False.
|
||||||
|
target_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the target_ref. Default: False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(list): List of Relationship objects involving the given STIX object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
results = []
|
||||||
|
filters = [Filter('type', '=', 'relationship')]
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj_id = obj.get('id', '')
|
||||||
|
except AttributeError:
|
||||||
|
obj_id = obj
|
||||||
|
|
||||||
|
if relationship_type:
|
||||||
|
filters.append(Filter('relationship_type', '=', relationship_type))
|
||||||
|
|
||||||
|
if source_only and target_only:
|
||||||
|
raise ValueError("Search either source only or target only, but not both")
|
||||||
|
|
||||||
|
for ds in self.data_sources:
|
||||||
|
if not target_only:
|
||||||
|
results.extend(ds.query(filters + [Filter('source_ref', '=', obj_id)]))
|
||||||
|
if not source_only:
|
||||||
|
results.extend(ds.query(filters + [Filter('target_ref', '=', obj_id)]))
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def add_data_source(self, data_source):
|
def add_data_source(self, data_source):
|
||||||
"""Attach a DataSource to CompositeDataSource instance
|
"""Attach a DataSource to CompositeDataSource instance
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,45 @@ class FileSystemSource(DataSource):
|
||||||
|
|
||||||
return stix_objs
|
return stix_objs
|
||||||
|
|
||||||
|
def relationships(self, obj, relationship_type=None, source_only=False, target_only=False):
|
||||||
|
"""Retrieve Relationships involving the given STIX object.
|
||||||
|
|
||||||
|
Only one of `source_only` and `target_only` may be `True`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
||||||
|
relationships will be looked up.
|
||||||
|
relationship_type (str): Only retrieve Relationships of this type.
|
||||||
|
source_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the source_ref. Default: False.
|
||||||
|
target_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the target_ref. Default: False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(list): List of Relationship objects involving the given STIX object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
results = []
|
||||||
|
filters = [Filter('type', '=', 'relationship')]
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj_id = obj.get('id', '')
|
||||||
|
except AttributeError:
|
||||||
|
obj_id = obj
|
||||||
|
|
||||||
|
if relationship_type:
|
||||||
|
filters.append(Filter('relationship_type', '=', relationship_type))
|
||||||
|
|
||||||
|
if source_only and target_only:
|
||||||
|
raise ValueError("Search either source only or target only, but not both")
|
||||||
|
|
||||||
|
if not target_only:
|
||||||
|
results.extend(self.query(filters + [Filter('source_ref', '=', obj_id)]))
|
||||||
|
if not source_only:
|
||||||
|
results.extend(self.query(filters + [Filter('target_ref', '=', obj_id)]))
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def _parse_file_filters(self, query):
|
def _parse_file_filters(self, query):
|
||||||
"""Extract STIX common filters.
|
"""Extract STIX common filters.
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,45 @@ class MemorySource(DataSource):
|
||||||
|
|
||||||
return all_data
|
return all_data
|
||||||
|
|
||||||
|
def relationships(self, obj, relationship_type=None, source_only=False, target_only=False):
|
||||||
|
"""Retrieve Relationships involving the given STIX object.
|
||||||
|
|
||||||
|
Only one of `source_only` and `target_only` may be `True`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
||||||
|
relationships will be looked up.
|
||||||
|
relationship_type (str): Only retrieve Relationships of this type.
|
||||||
|
source_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the source_ref. Default: False.
|
||||||
|
target_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the target_ref. Default: False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(list): List of Relationship objects involving the given STIX object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
results = []
|
||||||
|
filters = [Filter('type', '=', 'relationship')]
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj_id = obj.get('id', '')
|
||||||
|
except AttributeError:
|
||||||
|
obj_id = obj
|
||||||
|
|
||||||
|
if relationship_type:
|
||||||
|
filters.append(Filter('relationship_type', '=', relationship_type))
|
||||||
|
|
||||||
|
if source_only and target_only:
|
||||||
|
raise ValueError("Search either source only or target only, but not both")
|
||||||
|
|
||||||
|
if not target_only:
|
||||||
|
results.extend(self.query(filters + [Filter('source_ref', '=', obj_id)]))
|
||||||
|
if not source_only:
|
||||||
|
results.extend(self.query(filters + [Filter('target_ref', '=', obj_id)]))
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def load_from_file(self, file_path, allow_custom=False, version=None):
|
def load_from_file(self, file_path, allow_custom=False, version=None):
|
||||||
file_path = os.path.abspath(file_path)
|
file_path = os.path.abspath(file_path)
|
||||||
stix_data = json.load(open(file_path, "r"))
|
stix_data = json.load(open(file_path, "r"))
|
||||||
|
|
|
@ -222,6 +222,45 @@ class TAXIICollectionSource(DataSource):
|
||||||
|
|
||||||
return stix_objs
|
return stix_objs
|
||||||
|
|
||||||
|
def relationships(self, obj, relationship_type=None, source_only=False, target_only=False):
|
||||||
|
"""Retrieve Relationships involving the given STIX object.
|
||||||
|
|
||||||
|
Only one of `source_only` and `target_only` may be `True`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj (STIX object OR dict OR str): The STIX object (or its ID) whose
|
||||||
|
relationships will be looked up.
|
||||||
|
relationship_type (str): Only retrieve Relationships of this type.
|
||||||
|
source_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the source_ref. Default: False.
|
||||||
|
target_only (bool): Only retrieve Relationships for which this
|
||||||
|
object is the target_ref. Default: False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(list): List of Relationship objects involving the given STIX object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
results = []
|
||||||
|
filters = [Filter('type', '=', 'relationship')]
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj_id = obj.get('id', '')
|
||||||
|
except AttributeError:
|
||||||
|
obj_id = obj
|
||||||
|
|
||||||
|
if relationship_type:
|
||||||
|
filters.append(Filter('relationship_type', '=', relationship_type))
|
||||||
|
|
||||||
|
if source_only and target_only:
|
||||||
|
raise ValueError("Search either source only or target only, but not both")
|
||||||
|
|
||||||
|
if not target_only:
|
||||||
|
results.extend(self.query(filters + [Filter('source_ref', '=', obj_id)]))
|
||||||
|
if not source_only:
|
||||||
|
results.extend(self.query(filters + [Filter('target_ref', '=', obj_id)]))
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def _parse_taxii_filters(self, query):
|
def _parse_taxii_filters(self, query):
|
||||||
"""Parse out TAXII filters that the TAXII server can filter on.
|
"""Parse out TAXII filters that the TAXII server can filter on.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue