Merge pull request #482 from emmanvg/migrate-to-gh-actions

Migrate test to GitHub Actions, update test & check configuration
pull/1/head
Chris Lenk 2021-01-14 15:38:01 -05:00 committed by GitHub
commit 9ed62699ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 486 additions and 368 deletions

33
.github/workflows/python-ci-tests.yml vendored Normal file
View File

@ -0,0 +1,33 @@
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: cti-python-stix2 test harness
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
name: Python ${{ matrix.python-version }} Build
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install and update essential dependencies
run: |
pip install -U pip setuptools
pip install tox-gh-actions
pip install codecov
- name: Test with Tox
run: |
tox
- name: Upload coverage information to Codecov
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true # optional (default = false)
verbose: true # optional (default = false)

View File

@ -1,17 +1,25 @@
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v1.3.0 rev: v3.4.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: flake8
args:
- --max-line-length=160
- id: check-merge-conflict - id: check-merge-conflict
- repo: https://github.com/asottile/add-trailing-comma - repo: https://github.com/asottile/add-trailing-comma
rev: v0.6.4 rev: v2.0.2
hooks: hooks:
- id: add-trailing-comma - id: add-trailing-comma
- repo: https://github.com/FalconSocial/pre-commit-python-sorter - repo: https://github.com/PyCQA/flake8
sha: b57843b0b874df1d16eb0bef00b868792cb245c2 rev: 3.8.4
hooks: hooks:
- id: python-import-sorter - id: flake8
name: Check project styling
args:
- --max-line-length=160
- repo: https://github.com/PyCQA/isort
rev: 5.7.0
hooks:
- id: isort
name: Sort python imports (shows diff)
args: ["-c", "--diff"]
- id: isort
name: Sort python imports (fixes files)

View File

@ -1,19 +0,0 @@
os: linux
language: python
cache: pip
dist: bionic
python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
install:
- pip install -U pip setuptools
- pip install tox-travis
- pip install codecov
- pip install pre-commit
script:
- tox
- pre-commit run --all-files
after_success:
- codecov

View File

@ -163,8 +163,8 @@ questions about TC Open Repository participation to OASIS Staff at
repository-admin@oasis-open.org and any specific CLA-related questions repository-admin@oasis-open.org and any specific CLA-related questions
to repository-cla@oasis-open.org. to repository-cla@oasis-open.org.
.. |Build_Status| image:: https://travis-ci.org/oasis-open/cti-python-stix2.svg?branch=master .. |Build_Status| image:: https://github.com/oasis-open/cti-python-stix2/workflows/cti-python-stix2%20test%20harness/badge.svg
:target: https://travis-ci.org/oasis-open/cti-python-stix2 :target: https://github.com/oasis-open/cti-python-stix2/actions?query=workflow%3A%22cti-python-stix2+test+harness%22
:alt: Build Status :alt: Build Status
.. |Coverage| image:: https://codecov.io/gh/oasis-open/cti-python-stix2/branch/master/graph/badge.svg .. |Coverage| image:: https://codecov.io/gh/oasis-open/cti-python-stix2/branch/master/graph/badge.svg
:target: https://codecov.io/gh/oasis-open/cti-python-stix2 :target: https://codecov.io/gh/oasis-open/cti-python-stix2

View File

@ -40,10 +40,10 @@ setup(
'Topic :: Security', 'Topic :: Security',
'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: BSD License',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
], ],
keywords='stix stix2 json cti cyber threat intelligence', keywords='stix stix2 json cti cyber threat intelligence',
packages=find_packages(exclude=['*.test', '*.test.*']), packages=find_packages(exclude=['*.test', '*.test.*']),

View File

@ -164,8 +164,10 @@ class _STIXBase(Mapping):
defaulted = [] defaulted = []
for name, prop in self._properties.items(): for name, prop in self._properties.items():
try: try:
if (not prop.required and not hasattr(prop, '_fixed_value') and if (
prop.default() == setting_kwargs[name]): not prop.required and not hasattr(prop, '_fixed_value') and
prop.default() == setting_kwargs[name]
):
defaulted.append(name) defaulted.append(name)
except (AttributeError, KeyError): except (AttributeError, KeyError):
continue continue
@ -194,8 +196,10 @@ class _STIXBase(Mapping):
unpickling = '_inner' not in self.__dict__ unpickling = '_inner' not in self.__dict__
if not unpickling and name in self: if not unpickling and name in self:
return self.__getitem__(name) return self.__getitem__(name)
raise AttributeError("'%s' object has no attribute '%s'" % raise AttributeError(
(self.__class__.__name__, name)) "'%s' object has no attribute '%s'" %
(self.__class__.__name__, name),
)
def __setattr__(self, name, value): def __setattr__(self, name, value):
if not name.startswith("_"): if not name.startswith("_"):

View File

@ -75,8 +75,10 @@ class _ObjectFamily(object):
def add(self, obj): def add(self, obj):
self.all_versions[obj["modified"]] = obj self.all_versions[obj["modified"]] = obj
if (self.latest_version is None or if (
obj["modified"] > self.latest_version["modified"]): self.latest_version is None or
obj["modified"] > self.latest_version["modified"]
):
self.latest_version = obj self.latest_version = obj
def __str__(self): def __str__(self):
@ -188,11 +190,13 @@ class MemorySink(DataSink):
def save_to_file(self, path, encoding="utf-8"): def save_to_file(self, path, encoding="utf-8"):
path = os.path.abspath(path) path = os.path.abspath(path)
all_objs = list(itertools.chain.from_iterable( all_objs = list(
itertools.chain.from_iterable(
value.all_versions.values() if isinstance(value, _ObjectFamily) value.all_versions.values() if isinstance(value, _ObjectFamily)
else [value] else [value]
for value in self._data.values() for value in self._data.values()
)) ),
)
if any("spec_version" in x for x in all_objs): if any("spec_version" in x for x in all_objs):
bundle = v21.Bundle(all_objs, allow_custom=self.allow_custom) bundle = v21.Bundle(all_objs, allow_custom=self.allow_custom)

View File

@ -144,7 +144,7 @@ class ComparisonExpressionTransformer(Transformer):
class OrderDedupeTransformer( class OrderDedupeTransformer(
ComparisonExpressionTransformer ComparisonExpressionTransformer,
): ):
""" """
Canonically order the children of all nodes in the AST. Because the Canonically order the children of all nodes in the AST. Because the
@ -247,7 +247,7 @@ class FlattenTransformer(ComparisonExpressionTransformer):
class AbsorptionTransformer( class AbsorptionTransformer(
ComparisonExpressionTransformer ComparisonExpressionTransformer,
): ):
""" """
Applies boolean "absorption" rules for AST simplification. E.g.: Applies boolean "absorption" rules for AST simplification. E.g.:

View File

@ -152,9 +152,11 @@ class ObservationExpressionTransformer(Transformer):
changed = True changed = True
else: else:
raise TypeError("Not an observation expression: {}: {}".format( raise TypeError(
"Not an observation expression: {}: {}".format(
type(ast).__name__, str(ast), type(ast).__name__, str(ast),
)) ),
)
return result, changed return result, changed
@ -229,7 +231,7 @@ class FlattenTransformer(ObservationExpressionTransformer):
class OrderDedupeTransformer( class OrderDedupeTransformer(
ObservationExpressionTransformer ObservationExpressionTransformer,
): ):
""" """
Canonically order AND/OR expressions, and dedupe ORs. E.g.: Canonically order AND/OR expressions, and dedupe ORs. E.g.:
@ -272,7 +274,7 @@ class OrderDedupeTransformer(
class AbsorptionTransformer( class AbsorptionTransformer(
ObservationExpressionTransformer ObservationExpressionTransformer,
): ):
""" """
Applies boolean "absorption" rules for observation expressions, for AST Applies boolean "absorption" rules for observation expressions, for AST
@ -479,7 +481,7 @@ class DNFTransformer(ObservationExpressionTransformer):
class CanonicalizeComparisonExpressionsTransformer( class CanonicalizeComparisonExpressionsTransformer(
ObservationExpressionTransformer ObservationExpressionTransformer,
): ):
""" """
Canonicalize all comparison expressions. Canonicalize all comparison expressions.

View File

@ -186,8 +186,10 @@ def parse_observable(data, _valid_refs=None, allow_custom=False, version=None):
# flag allows for unknown custom objects too, but will not # flag allows for unknown custom objects too, but will not
# be parsed into STIX observable object, just returned as is # be parsed into STIX observable object, just returned as is
return obj return obj
raise ParseError("Can't parse unknown observable type '%s'! For custom observables, " raise ParseError(
"use the CustomObservable decorator." % obj['type']) "Can't parse unknown observable type '%s'! For custom observables, "
"use the CustomObservable decorator." % obj['type'],
)
return obj_class(allow_custom=allow_custom, **obj) return obj_class(allow_custom=allow_custom, **obj)
@ -283,8 +285,12 @@ def _register_observable(new_observable, version=stix2.DEFAULT_VERSION):
"'%s' is named like an object reference property but " "'%s' is named like an object reference property but "
"is not an ObjectReferenceProperty." % prop_name, "is not an ObjectReferenceProperty." % prop_name,
) )
elif (prop_name.endswith('_refs') and ('ListProperty' not in get_class_hierarchy_names(prop) or elif (
'ObjectReferenceProperty' not in get_class_hierarchy_names(prop.contained))): prop_name.endswith('_refs') and (
'ListProperty' not in get_class_hierarchy_names(prop) or
'ObjectReferenceProperty' not in get_class_hierarchy_names(prop.contained)
)
):
raise ValueError( raise ValueError(
"'%s' is named like an object reference list property but " "'%s' is named like an object reference list property but "
"is not a ListProperty containing ObjectReferenceProperty." % prop_name, "is not a ListProperty containing ObjectReferenceProperty." % prop_name,
@ -299,8 +305,12 @@ def _register_observable(new_observable, version=stix2.DEFAULT_VERSION):
"'%s' is named like a reference property but " "'%s' is named like a reference property but "
"is not a ReferenceProperty." % prop_name, "is not a ReferenceProperty." % prop_name,
) )
elif (prop_name.endswith('_refs') and ('ListProperty' not in get_class_hierarchy_names(prop) or elif (
'ReferenceProperty' not in get_class_hierarchy_names(prop.contained))): prop_name.endswith('_refs') and (
'ListProperty' not in get_class_hierarchy_names(prop) or
'ReferenceProperty' not in get_class_hierarchy_names(prop.contained)
)
):
raise ValueError( raise ValueError(
"'%s' is named like a reference list property but " "'%s' is named like a reference list property but "
"is not a ListProperty containing ReferenceProperty." % prop_name, "is not a ListProperty containing ReferenceProperty." % prop_name,

View File

@ -261,11 +261,13 @@ class STIXPatternVisitorForSTIX2():
property_path.append(self.instantiate("ListObjectPathComponent", current.property_name, next.getText())) property_path.append(self.instantiate("ListObjectPathComponent", current.property_name, next.getText()))
i += 2 i += 2
elif isinstance(next, IntegerConstant): elif isinstance(next, IntegerConstant):
property_path.append(self.instantiate( property_path.append(
self.instantiate(
"ListObjectPathComponent", "ListObjectPathComponent",
current.property_name if isinstance(current, BasicObjectPathComponent) else text_type(current), current.property_name if isinstance(current, BasicObjectPathComponent) else text_type(current),
next.value, next.value,
)) ),
)
i += 2 i += 2
else: else:
property_path.append(current) property_path.append(current)

View File

@ -247,9 +247,11 @@ class ListProperty(Property):
valid = self.contained(**item) valid = self.contained(**item)
else: else:
raise ValueError("Can't create a {} out of {}".format( raise ValueError(
"Can't create a {} out of {}".format(
self.contained._type, str(item), self.contained._type, str(item),
)) ),
)
result.append(valid) result.append(valid)
@ -688,8 +690,10 @@ class STIXObjectProperty(Property):
def clean(self, value): def clean(self, value):
# Any STIX Object (SDO, SRO, or Marking Definition) can be added to # Any STIX Object (SDO, SRO, or Marking Definition) can be added to
# a bundle with no further checks. # a bundle with no further checks.
if any(x in ('_DomainObject', '_RelationshipObject', 'MarkingDefinition') if any(
for x in get_class_hierarchy_names(value)): x in ('_DomainObject', '_RelationshipObject', 'MarkingDefinition')
for x in get_class_hierarchy_names(value)
):
# A simple "is this a spec version 2.1+ object" test. For now, # A simple "is this a spec version 2.1+ object" test. For now,
# limit 2.0 bundles to 2.0 objects. It's not possible yet to # limit 2.0 bundles to 2.0 objects. It's not possible yet to
# have validation co-constraints among properties, e.g. have # have validation co-constraints among properties, e.g. have

View File

@ -175,12 +175,14 @@ def test_memory_source_get_nonexistant_object(mem_source):
def test_memory_store_all_versions(mem_store): def test_memory_store_all_versions(mem_store):
# Add bundle of items to sink # Add bundle of items to sink
mem_store.add(dict( mem_store.add(
dict(
id="bundle--%s" % make_id(), id="bundle--%s" % make_id(),
objects=STIX_OBJS2, objects=STIX_OBJS2,
spec_version="2.0", spec_version="2.0",
type="bundle", type="bundle",
)) ),
)
resp = mem_store.all_versions("indicator--00000000-0000-4000-8000-000000000001") resp = mem_store.all_versions("indicator--00000000-0000-4000-8000-000000000001")
assert len(resp) == 3 assert len(resp) == 3

View File

@ -39,15 +39,19 @@ def ds2():
cam = stix2.v20.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) cam = stix2.v20.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS)
idy = stix2.v20.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) idy = stix2.v20.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS)
ind = stix2.v20.Indicator(id=INDICATOR_ID, created_by_ref=idy.id, **INDICATOR_KWARGS) ind = stix2.v20.Indicator(id=INDICATOR_ID, created_by_ref=idy.id, **INDICATOR_KWARGS)
indv2 = ind.new_version(external_references=[{ indv2 = ind.new_version(
external_references=[{
"source_name": "unknown", "source_name": "unknown",
"url": "https://examplewebsite.com/", "url": "https://examplewebsite.com/",
}]) }],
)
mal = stix2.v20.Malware(id=MALWARE_ID, created_by_ref=idy.id, **MALWARE_KWARGS) mal = stix2.v20.Malware(id=MALWARE_ID, created_by_ref=idy.id, **MALWARE_KWARGS)
malv2 = mal.new_version(external_references=[{ malv2 = mal.new_version(
external_references=[{
"source_name": "unknown", "source_name": "unknown",
"url": "https://examplewebsite2.com/", "url": "https://examplewebsite2.com/",
}]) }],
)
rel1 = stix2.v20.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) rel1 = stix2.v20.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0])
rel2 = stix2.v20.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) rel2 = stix2.v20.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1])
rel3 = stix2.v20.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) rel3 = stix2.v20.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2])

View File

@ -20,7 +20,8 @@ EXPECTED_INDICATOR = """{
] ]
}""" }"""
EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join(""" EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join(
"""
type='indicator', type='indicator',
id='indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7', id='indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7',
created='2017-01-01T00:00:01.000Z', created='2017-01-01T00:00:01.000Z',
@ -28,7 +29,8 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join("""
pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']", pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
valid_from='1970-01-01T00:00:01Z', valid_from='1970-01-01T00:00:01Z',
labels=['malicious-activity'] labels=['malicious-activity']
""".split()) + ")" """.split(),
) + ")"
def test_indicator_with_all_required_properties(): def test_indicator_with_all_required_properties():

View File

@ -1180,21 +1180,24 @@ def test_process_example_extensions_empty():
def test_process_example_with_WindowsProcessExt_Object(): def test_process_example_with_WindowsProcessExt_Object():
p = stix2.v20.Process(extensions={ p = stix2.v20.Process(
extensions={
"windows-process-ext": stix2.v20.WindowsProcessExt( "windows-process-ext": stix2.v20.WindowsProcessExt(
aslr_enabled=True, aslr_enabled=True,
dep_enabled=True, dep_enabled=True,
priority="HIGH_PRIORITY_CLASS", priority="HIGH_PRIORITY_CLASS",
owner_sid="S-1-5-21-186985262-1144665072-74031268-1309", owner_sid="S-1-5-21-186985262-1144665072-74031268-1309",
), # noqa ), # noqa
}) },
)
assert p.extensions["windows-process-ext"].dep_enabled assert p.extensions["windows-process-ext"].dep_enabled
assert p.extensions["windows-process-ext"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309" assert p.extensions["windows-process-ext"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309"
def test_process_example_with_WindowsServiceExt(): def test_process_example_with_WindowsServiceExt():
p = stix2.v20.Process(extensions={ p = stix2.v20.Process(
extensions={
"windows-service-ext": { "windows-service-ext": {
"service_name": "sirvizio", "service_name": "sirvizio",
"display_name": "Sirvizio", "display_name": "Sirvizio",
@ -1202,14 +1205,16 @@ def test_process_example_with_WindowsServiceExt():
"service_type": "SERVICE_WIN32_OWN_PROCESS", "service_type": "SERVICE_WIN32_OWN_PROCESS",
"service_status": "SERVICE_RUNNING", "service_status": "SERVICE_RUNNING",
}, },
}) },
)
assert p.extensions["windows-service-ext"].service_name == "sirvizio" assert p.extensions["windows-service-ext"].service_name == "sirvizio"
assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS" assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS"
def test_process_example_with_WindowsProcessServiceExt(): def test_process_example_with_WindowsProcessServiceExt():
p = stix2.v20.Process(extensions={ p = stix2.v20.Process(
extensions={
"windows-service-ext": { "windows-service-ext": {
"service_name": "sirvizio", "service_name": "sirvizio",
"display_name": "Sirvizio", "display_name": "Sirvizio",
@ -1223,7 +1228,8 @@ def test_process_example_with_WindowsProcessServiceExt():
"priority": "HIGH_PRIORITY_CLASS", "priority": "HIGH_PRIORITY_CLASS",
"owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309", "owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309",
}, },
}) },
)
assert p.extensions["windows-service-ext"].service_name == "sirvizio" assert p.extensions["windows-service-ext"].service_name == "sirvizio"
assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS" assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS"

View File

@ -306,10 +306,12 @@ def test_multiple_qualifiers():
def test_set_op(): def test_set_op():
exp = stix2.ObservationExpression(stix2.IsSubsetComparisonExpression( exp = stix2.ObservationExpression(
stix2.IsSubsetComparisonExpression(
"network-traffic:dst_ref.value", "network-traffic:dst_ref.value",
"2001:0db8:dead:beef:0000:0000:0000:0000/64", "2001:0db8:dead:beef:0000:0000:0000:0000/64",
)) ),
)
assert str(exp) == "[network-traffic:dst_ref.value ISSUBSET '2001:0db8:dead:beef:0000:0000:0000:0000/64']" assert str(exp) == "[network-traffic:dst_ref.value ISSUBSET '2001:0db8:dead:beef:0000:0000:0000:0000/64']"

View File

@ -71,7 +71,7 @@ def test_parse_datetime_invalid(ts):
{"a": 1}, {"a": 1},
'{"a": 1}', '{"a": 1}',
StringIO(u'{"a": 1}'), StringIO(u'{"a": 1}'),
[("a", 1,)], [("a", 1)],
], ],
) )
def test_get_dict(data): def test_get_dict(data):

View File

@ -46,10 +46,12 @@ def test_making_new_version_with_embedded_object():
**CAMPAIGN_MORE_KWARGS **CAMPAIGN_MORE_KWARGS
) )
campaign_v2 = campaign_v1.new_version(external_references=[{ campaign_v2 = campaign_v1.new_version(
external_references=[{
"source_name": "capec", "source_name": "capec",
"external_id": "CAPEC-164", "external_id": "CAPEC-164",
}]) }],
)
assert campaign_v1.id == campaign_v2.id assert campaign_v1.id == campaign_v2.id
assert campaign_v1.created_by_ref == campaign_v2.created_by_ref assert campaign_v1.created_by_ref == campaign_v2.created_by_ref
@ -237,8 +239,10 @@ def test_remove_custom_stix_property():
mal_nc = stix2.versioning.remove_custom_stix(mal) mal_nc = stix2.versioning.remove_custom_stix(mal)
assert "x_custom" not in mal_nc assert "x_custom" not in mal_nc
assert (stix2.utils.parse_into_datetime(mal["modified"], precision="millisecond") < assert (
stix2.utils.parse_into_datetime(mal_nc["modified"], precision="millisecond")) stix2.utils.parse_into_datetime(mal["modified"], precision="millisecond") <
stix2.utils.parse_into_datetime(mal_nc["modified"], precision="millisecond")
)
def test_remove_custom_stix_object(): def test_remove_custom_stix_object():

View File

@ -191,11 +191,13 @@ def test_memory_source_get_nonexistant_object(mem_source):
def test_memory_store_all_versions(mem_store): def test_memory_store_all_versions(mem_store):
# Add bundle of items to sink # Add bundle of items to sink
mem_store.add(dict( mem_store.add(
dict(
id="bundle--%s" % make_id(), id="bundle--%s" % make_id(),
objects=STIX_OBJS2, objects=STIX_OBJS2,
type="bundle", type="bundle",
)) ),
)
resp = mem_store.all_versions("indicator--00000000-0000-4000-8000-000000000001") resp = mem_store.all_versions("indicator--00000000-0000-4000-8000-000000000001")
assert len(resp) == 3 assert len(resp) == 3

View File

@ -20,7 +20,8 @@ EXPECTED_INDICATOR = """{
"valid_from": "1970-01-01T00:00:01Z" "valid_from": "1970-01-01T00:00:01Z"
}""" }"""
EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join(""" EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join(
"""
type='indicator', type='indicator',
spec_version='2.1', spec_version='2.1',
id='indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7', id='indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7',
@ -30,7 +31,8 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join("""
pattern_type='stix', pattern_type='stix',
pattern_version='2.1', pattern_version='2.1',
valid_from='1970-01-01T00:00:01Z' valid_from='1970-01-01T00:00:01Z'
""".split()) + ")" """.split(),
) + ")"
def test_indicator_with_all_required_properties(): def test_indicator_with_all_required_properties():

View File

@ -19,14 +19,16 @@ EXPECTED_LOCATION_1 = """{
"longitude": 2.3522 "longitude": 2.3522
}""" }"""
EXPECTED_LOCATION_1_REPR = "Location(" + " ".join(""" EXPECTED_LOCATION_1_REPR = "Location(" + " ".join(
"""
type='location', type='location',
spec_version='2.1', spec_version='2.1',
id='location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64', id='location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64',
created='2016-04-06T20:03:00.000Z', created='2016-04-06T20:03:00.000Z',
modified='2016-04-06T20:03:00.000Z', modified='2016-04-06T20:03:00.000Z',
latitude=48.8566, latitude=48.8566,
longitude=2.3522""".split()) + ")" longitude=2.3522""".split(),
) + ")"
EXPECTED_LOCATION_2 = """{ EXPECTED_LOCATION_2 = """{
"type": "location", "type": "location",
@ -38,13 +40,15 @@ EXPECTED_LOCATION_2 = """{
} }
""" """
EXPECTED_LOCATION_2_REPR = "Location(" + " ".join(""" EXPECTED_LOCATION_2_REPR = "Location(" + " ".join(
"""
type='location', type='location',
spec_version='2.1', spec_version='2.1',
id='location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64', id='location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64',
created='2016-04-06T20:03:00.000Z', created='2016-04-06T20:03:00.000Z',
modified='2016-04-06T20:03:00.000Z', modified='2016-04-06T20:03:00.000Z',
region='north-america'""".split()) + ")" region='north-america'""".split(),
) + ")"
def test_location_with_some_required_properties(): def test_location_with_some_required_properties():

View File

@ -496,12 +496,14 @@ def test_parse_email_message_not_multipart(data):
def test_parse_file_archive(data): def test_parse_file_archive(data):
odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED) odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED)
odata = stix2.parse(odata_str, version="2.1") odata = stix2.parse(odata_str, version="2.1")
assert all(x in odata.objects["3"].extensions['archive-ext'].contains_refs assert all(
x in odata.objects["3"].extensions['archive-ext'].contains_refs
for x in [ for x in [
"file--ecd47d73-15e4-5250-afda-ef8897b22340", "file--ecd47d73-15e4-5250-afda-ef8897b22340",
"file--65f2873d-38c2-56b4-bfa5-e3ef21e8a3c3", "file--65f2873d-38c2-56b4-bfa5-e3ef21e8a3c3",
"file--ef2d6dca-ec7d-5ab7-8dd9-ec9c0dee0eac", "file--ef2d6dca-ec7d-5ab7-8dd9-ec9c0dee0eac",
]) ]
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -904,14 +906,14 @@ def test_file_with_archive_ext_object():
f_obj = stix2.v21.File( f_obj = stix2.v21.File(
name="foo", extensions={ name="foo", extensions={
"archive-ext": { "archive-ext": {
"contains_refs": [ad, ], "contains_refs": [ad],
}, },
}, },
) )
f_ref = stix2.v21.File( f_ref = stix2.v21.File(
name="foo", extensions={ name="foo", extensions={
"archive-ext": { "archive-ext": {
"contains_refs": [ad.id, ], "contains_refs": [ad.id],
}, },
}, },
) )
@ -1229,9 +1231,11 @@ def test_process_example_empty_error():
def test_process_example_empty_with_extensions(): def test_process_example_empty_with_extensions():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.v21.Process(extensions={ stix2.v21.Process(
extensions={
"windows-process-ext": {}, "windows-process-ext": {},
}) },
)
assert excinfo.value.cls == stix2.v21.Process assert excinfo.value.cls == stix2.v21.Process
@ -1276,21 +1280,24 @@ def test_process_example_extensions_empty():
def test_process_example_with_WindowsProcessExt_Object(): def test_process_example_with_WindowsProcessExt_Object():
p = stix2.v21.Process(extensions={ p = stix2.v21.Process(
extensions={
"windows-process-ext": stix2.v21.WindowsProcessExt( "windows-process-ext": stix2.v21.WindowsProcessExt(
aslr_enabled=True, aslr_enabled=True,
dep_enabled=True, dep_enabled=True,
priority="HIGH_PRIORITY_CLASS", priority="HIGH_PRIORITY_CLASS",
owner_sid="S-1-5-21-186985262-1144665072-74031268-1309", owner_sid="S-1-5-21-186985262-1144665072-74031268-1309",
), # noqa ), # noqa
}) },
)
assert p.extensions["windows-process-ext"].dep_enabled assert p.extensions["windows-process-ext"].dep_enabled
assert p.extensions["windows-process-ext"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309" assert p.extensions["windows-process-ext"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309"
def test_process_example_with_WindowsServiceExt(): def test_process_example_with_WindowsServiceExt():
p = stix2.v21.Process(extensions={ p = stix2.v21.Process(
extensions={
"windows-service-ext": { "windows-service-ext": {
"service_name": "sirvizio", "service_name": "sirvizio",
"display_name": "Sirvizio", "display_name": "Sirvizio",
@ -1298,14 +1305,16 @@ def test_process_example_with_WindowsServiceExt():
"service_type": "SERVICE_WIN32_OWN_PROCESS", "service_type": "SERVICE_WIN32_OWN_PROCESS",
"service_status": "SERVICE_RUNNING", "service_status": "SERVICE_RUNNING",
}, },
}) },
)
assert p.extensions["windows-service-ext"].service_name == "sirvizio" assert p.extensions["windows-service-ext"].service_name == "sirvizio"
assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS" assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS"
def test_process_example_with_WindowsProcessServiceExt(): def test_process_example_with_WindowsProcessServiceExt():
p = stix2.v21.Process(extensions={ p = stix2.v21.Process(
extensions={
"windows-service-ext": { "windows-service-ext": {
"service_name": "sirvizio", "service_name": "sirvizio",
"display_name": "Sirvizio", "display_name": "Sirvizio",
@ -1319,7 +1328,8 @@ def test_process_example_with_WindowsProcessServiceExt():
"priority": "HIGH_PRIORITY_CLASS", "priority": "HIGH_PRIORITY_CLASS",
"owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309", "owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309",
}, },
}) },
)
assert p.extensions["windows-service-ext"].service_name == "sirvizio" assert p.extensions["windows-service-ext"].service_name == "sirvizio"
assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS" assert p.extensions["windows-service-ext"].service_type == "SERVICE_WIN32_OWN_PROCESS"

View File

@ -444,10 +444,12 @@ def test_multiple_qualifiers():
def test_set_op(): def test_set_op():
exp = stix2.ObservationExpression(stix2.IsSubsetComparisonExpression( exp = stix2.ObservationExpression(
stix2.IsSubsetComparisonExpression(
"network-traffic:dst_ref.value", "network-traffic:dst_ref.value",
"2001:0db8:dead:beef:0000:0000:0000:0000/64", "2001:0db8:dead:beef:0000:0000:0000:0000/64",
)) ),
)
assert str(exp) == "[network-traffic:dst_ref.value ISSUBSET '2001:0db8:dead:beef:0000:0000:0000:0000/64']" assert str(exp) == "[network-traffic:dst_ref.value ISSUBSET '2001:0db8:dead:beef:0000:0000:0000:0000/64']"
@ -712,12 +714,12 @@ def test_parsing_boolean():
def test_parsing_mixed_boolean_expression_1(): def test_parsing_mixed_boolean_expression_1():
patt_obj = create_pattern_object("[a:b = 1 AND a:b = 2 OR a:b = 3]",) patt_obj = create_pattern_object("[a:b = 1 AND a:b = 2 OR a:b = 3]")
assert str(patt_obj) == "[a:b = 1 AND a:b = 2 OR a:b = 3]" assert str(patt_obj) == "[a:b = 1 AND a:b = 2 OR a:b = 3]"
def test_parsing_mixed_boolean_expression_2(): def test_parsing_mixed_boolean_expression_2():
patt_obj = create_pattern_object("[a:b = 1 OR a:b = 2 AND a:b = 3]",) patt_obj = create_pattern_object("[a:b = 1 OR a:b = 2 AND a:b = 3]")
assert str(patt_obj) == "[a:b = 1 OR a:b = 2 AND a:b = 3]" assert str(patt_obj) == "[a:b = 1 OR a:b = 2 AND a:b = 3]"

View File

@ -71,7 +71,7 @@ def test_parse_datetime_invalid(ts):
{"a": 1}, {"a": 1},
'{"a": 1}', '{"a": 1}',
StringIO(u'{"a": 1}'), StringIO(u'{"a": 1}'),
[("a", 1,)], [("a", 1)],
], ],
) )
def test_get_dict(data): def test_get_dict(data):

View File

@ -50,10 +50,12 @@ def test_making_new_version_with_embedded_object():
**CAMPAIGN_MORE_KWARGS **CAMPAIGN_MORE_KWARGS
) )
campaign_v2 = campaign_v1.new_version(external_references=[{ campaign_v2 = campaign_v1.new_version(
external_references=[{
"source_name": "capec", "source_name": "capec",
"external_id": "CAPEC-164", "external_id": "CAPEC-164",
}]) }],
)
assert campaign_v1.id == campaign_v2.id assert campaign_v1.id == campaign_v2.id
assert campaign_v1.spec_version == campaign_v2.spec_version assert campaign_v1.spec_version == campaign_v2.spec_version

View File

@ -71,9 +71,11 @@ def _to_enum(value, enum_type, enum_default=None):
elif isinstance(value, six.string_types): elif isinstance(value, six.string_types):
value = enum_type[value.upper()] value = enum_type[value.upper()]
else: else:
raise TypeError("Not a valid {}: {}".format( raise TypeError(
"Not a valid {}: {}".format(
enum_type.__name__, value, enum_type.__name__, value,
)) ),
)
return value return value

View File

@ -440,24 +440,28 @@ class SocketExt(_Extension):
('is_blocking', BooleanProperty()), ('is_blocking', BooleanProperty()),
('is_listening', BooleanProperty()), ('is_listening', BooleanProperty()),
( (
'protocol_family', EnumProperty(allowed=[ 'protocol_family', EnumProperty(
allowed=[
"PF_INET", "PF_INET",
"PF_IPX", "PF_IPX",
"PF_APPLETALK", "PF_APPLETALK",
"PF_INET6", "PF_INET6",
"PF_AX25", "PF_AX25",
"PF_NETROM", "PF_NETROM",
]), ],
),
), ),
('options', DictionaryProperty(spec_version="2.0")), ('options', DictionaryProperty(spec_version="2.0")),
( (
'socket_type', EnumProperty(allowed=[ 'socket_type', EnumProperty(
allowed=[
"SOCK_STREAM", "SOCK_STREAM",
"SOCK_DGRAM", "SOCK_DGRAM",
"SOCK_RAW", "SOCK_RAW",
"SOCK_RDM", "SOCK_RDM",
"SOCK_SEQPACKET", "SOCK_SEQPACKET",
]), ],
),
), ),
('socket_descriptor', IntegerProperty()), ('socket_descriptor', IntegerProperty()),
('socket_handle', IntegerProperty()), ('socket_handle', IntegerProperty()),
@ -537,25 +541,30 @@ class WindowsServiceExt(_Extension):
('display_name', StringProperty()), ('display_name', StringProperty()),
('group_name', StringProperty()), ('group_name', StringProperty()),
( (
'start_type', EnumProperty(allowed=[ 'start_type', EnumProperty(
allowed=[
"SERVICE_AUTO_START", "SERVICE_AUTO_START",
"SERVICE_BOOT_START", "SERVICE_BOOT_START",
"SERVICE_DEMAND_START", "SERVICE_DEMAND_START",
"SERVICE_DISABLED", "SERVICE_DISABLED",
"SERVICE_SYSTEM_ALERT", "SERVICE_SYSTEM_ALERT",
]), ],
),
), ),
('service_dll_refs', ListProperty(ObjectReferenceProperty(valid_types='file'))), ('service_dll_refs', ListProperty(ObjectReferenceProperty(valid_types='file'))),
( (
'service_type', EnumProperty(allowed=[ 'service_type', EnumProperty(
allowed=[
"SERVICE_KERNEL_DRIVER", "SERVICE_KERNEL_DRIVER",
"SERVICE_FILE_SYSTEM_DRIVER", "SERVICE_FILE_SYSTEM_DRIVER",
"SERVICE_WIN32_OWN_PROCESS", "SERVICE_WIN32_OWN_PROCESS",
"SERVICE_WIN32_SHARE_PROCESS", "SERVICE_WIN32_SHARE_PROCESS",
]), ],
),
), ),
( (
'service_status', EnumProperty(allowed=[ 'service_status', EnumProperty(
allowed=[
"SERVICE_CONTINUE_PENDING", "SERVICE_CONTINUE_PENDING",
"SERVICE_PAUSE_PENDING", "SERVICE_PAUSE_PENDING",
"SERVICE_PAUSED", "SERVICE_PAUSED",
@ -563,7 +572,8 @@ class WindowsServiceExt(_Extension):
"SERVICE_START_PENDING", "SERVICE_START_PENDING",
"SERVICE_STOP_PENDING", "SERVICE_STOP_PENDING",
"SERVICE_STOPPED", "SERVICE_STOPPED",
]), ],
),
), ),
]) ])
@ -687,7 +697,8 @@ class WindowsRegistryValueType(_STIXBase20):
('name', StringProperty(required=True)), ('name', StringProperty(required=True)),
('data', StringProperty()), ('data', StringProperty()),
( (
'data_type', EnumProperty(allowed=[ 'data_type', EnumProperty(
allowed=[
"REG_NONE", "REG_NONE",
"REG_SZ", "REG_SZ",
"REG_EXPAND_SZ", "REG_EXPAND_SZ",
@ -701,7 +712,8 @@ class WindowsRegistryValueType(_STIXBase20):
"REG_RESOURCE_REQUIREMENTS_LIST", "REG_RESOURCE_REQUIREMENTS_LIST",
"REG_QWORD", "REG_QWORD",
"REG_INVALID_TYPE", "REG_INVALID_TYPE",
]), ],
),
), ),
]) ])
@ -790,11 +802,13 @@ def CustomObservable(type='x-custom-observable', properties=None):
""" """
def wrapper(cls): def wrapper(cls):
_properties = list(itertools.chain.from_iterable([ _properties = list(
itertools.chain.from_iterable([
[('type', TypeProperty(type, spec_version='2.0'))], [('type', TypeProperty(type, spec_version='2.0'))],
properties, properties,
[('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=type))], [('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=type))],
])) ]),
)
return _custom_observable_builder(cls, type, _properties, '2.0', _Observable) return _custom_observable_builder(cls, type, _properties, '2.0', _Observable)
return wrapper return wrapper

View File

@ -356,7 +356,8 @@ def CustomObject(type='x-custom-type', properties=None):
""" """
def wrapper(cls): def wrapper(cls):
_properties = list(itertools.chain.from_iterable([ _properties = list(
itertools.chain.from_iterable([
[ [
('type', TypeProperty(type, spec_version='2.0')), ('type', TypeProperty(type, spec_version='2.0')),
('id', IDProperty(type, spec_version='2.0')), ('id', IDProperty(type, spec_version='2.0')),
@ -373,6 +374,7 @@ def CustomObject(type='x-custom-type', properties=None):
('granular_markings', ListProperty(GranularMarking)), ('granular_markings', ListProperty(GranularMarking)),
], ],
sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]), sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]),
])) ]),
)
return _custom_object_builder(cls, type, _properties, '2.0', _DomainObject) return _custom_object_builder(cls, type, _properties, '2.0', _DomainObject)
return wrapper return wrapper

View File

@ -505,13 +505,15 @@ class SocketExt(_Extension):
('is_listening', BooleanProperty()), ('is_listening', BooleanProperty()),
('options', DictionaryProperty(spec_version='2.1')), ('options', DictionaryProperty(spec_version='2.1')),
( (
'socket_type', EnumProperty(allowed=[ 'socket_type', EnumProperty(
allowed=[
"SOCK_STREAM", "SOCK_STREAM",
"SOCK_DGRAM", "SOCK_DGRAM",
"SOCK_RAW", "SOCK_RAW",
"SOCK_RDM", "SOCK_RDM",
"SOCK_SEQPACKET", "SOCK_SEQPACKET",
]), ],
),
), ),
('socket_descriptor', IntegerProperty(min=0)), ('socket_descriptor', IntegerProperty(min=0)),
('socket_handle', IntegerProperty()), ('socket_handle', IntegerProperty()),
@ -612,12 +614,14 @@ class WindowsProcessExt(_Extension):
('window_title', StringProperty()), ('window_title', StringProperty()),
('startup_info', DictionaryProperty(spec_version='2.1')), ('startup_info', DictionaryProperty(spec_version='2.1')),
( (
'integrity_level', EnumProperty(allowed=[ 'integrity_level', EnumProperty(
allowed=[
"low", "low",
"medium", "medium",
"high", "high",
"system", "system",
]), ],
),
), ),
]) ])
@ -634,25 +638,30 @@ class WindowsServiceExt(_Extension):
('display_name', StringProperty()), ('display_name', StringProperty()),
('group_name', StringProperty()), ('group_name', StringProperty()),
( (
'start_type', EnumProperty(allowed=[ 'start_type', EnumProperty(
allowed=[
"SERVICE_AUTO_START", "SERVICE_AUTO_START",
"SERVICE_BOOT_START", "SERVICE_BOOT_START",
"SERVICE_DEMAND_START", "SERVICE_DEMAND_START",
"SERVICE_DISABLED", "SERVICE_DISABLED",
"SERVICE_SYSTEM_ALERT", "SERVICE_SYSTEM_ALERT",
]), ],
),
), ),
('service_dll_refs', ListProperty(ReferenceProperty(valid_types='file', spec_version="2.1"))), ('service_dll_refs', ListProperty(ReferenceProperty(valid_types='file', spec_version="2.1"))),
( (
'service_type', EnumProperty(allowed=[ 'service_type', EnumProperty(
allowed=[
"SERVICE_KERNEL_DRIVER", "SERVICE_KERNEL_DRIVER",
"SERVICE_FILE_SYSTEM_DRIVER", "SERVICE_FILE_SYSTEM_DRIVER",
"SERVICE_WIN32_OWN_PROCESS", "SERVICE_WIN32_OWN_PROCESS",
"SERVICE_WIN32_SHARE_PROCESS", "SERVICE_WIN32_SHARE_PROCESS",
]), ],
),
), ),
( (
'service_status', EnumProperty(allowed=[ 'service_status', EnumProperty(
allowed=[
"SERVICE_CONTINUE_PENDING", "SERVICE_CONTINUE_PENDING",
"SERVICE_PAUSE_PENDING", "SERVICE_PAUSE_PENDING",
"SERVICE_PAUSED", "SERVICE_PAUSED",
@ -660,7 +669,8 @@ class WindowsServiceExt(_Extension):
"SERVICE_START_PENDING", "SERVICE_START_PENDING",
"SERVICE_STOP_PENDING", "SERVICE_STOP_PENDING",
"SERVICE_STOPPED", "SERVICE_STOPPED",
]), ],
),
), ),
]) ])
@ -808,7 +818,8 @@ class WindowsRegistryValueType(_STIXBase21):
('name', StringProperty()), ('name', StringProperty()),
('data', StringProperty()), ('data', StringProperty()),
( (
'data_type', EnumProperty(allowed=[ 'data_type', EnumProperty(
allowed=[
"REG_NONE", "REG_NONE",
"REG_SZ", "REG_SZ",
"REG_EXPAND_SZ", "REG_EXPAND_SZ",
@ -822,7 +833,8 @@ class WindowsRegistryValueType(_STIXBase21):
"REG_RESOURCE_REQUIREMENTS_LIST", "REG_RESOURCE_REQUIREMENTS_LIST",
"REG_QWORD", "REG_QWORD",
"REG_INVALID_TYPE", "REG_INVALID_TYPE",
]), ],
),
), ),
]) ])
@ -935,13 +947,15 @@ def CustomObservable(type='x-custom-observable', properties=None, id_contrib_pro
""" """
def wrapper(cls): def wrapper(cls):
_properties = list(itertools.chain.from_iterable([ _properties = list(
itertools.chain.from_iterable([
[('type', TypeProperty(type, spec_version='2.1'))], [('type', TypeProperty(type, spec_version='2.1'))],
[('spec_version', StringProperty(fixed='2.1'))], [('spec_version', StringProperty(fixed='2.1'))],
[('id', IDProperty(type, spec_version='2.1'))], [('id', IDProperty(type, spec_version='2.1'))],
properties, properties,
[('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=type))], [('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=type))],
])) ]),
)
return _custom_observable_builder(cls, type, _properties, '2.1', _Observable, id_contrib_props) return _custom_observable_builder(cls, type, _properties, '2.1', _Observable, id_contrib_props)
return wrapper return wrapper

View File

@ -789,7 +789,8 @@ def CustomObject(type='x-custom-type', properties=None):
""" """
def wrapper(cls): def wrapper(cls):
_properties = list(itertools.chain.from_iterable([ _properties = list(
itertools.chain.from_iterable([
[ [
('type', TypeProperty(type, spec_version='2.1')), ('type', TypeProperty(type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')), ('spec_version', StringProperty(fixed='2.1')),
@ -809,7 +810,8 @@ def CustomObject(type='x-custom-type', properties=None):
('granular_markings', ListProperty(GranularMarking)), ('granular_markings', ListProperty(GranularMarking)),
], ],
sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]), sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]),
])) ]),
)
return _custom_object_builder(cls, type, _properties, '2.1', _DomainObject) return _custom_object_builder(cls, type, _properties, '2.1', _DomainObject)
return wrapper return wrapper

View File

@ -21,7 +21,9 @@
""" """
import functools import functools
import stix2 import stix2
from . import AttackPattern as _AttackPattern from . import AttackPattern as _AttackPattern
from . import Campaign as _Campaign from . import Campaign as _Campaign
from . import CourseOfAction as _CourseOfAction from . import CourseOfAction as _CourseOfAction
@ -40,24 +42,25 @@ from . import Report as _Report
from . import ThreatActor as _ThreatActor from . import ThreatActor as _ThreatActor
from . import Tool as _Tool from . import Tool as _Tool
from . import Vulnerability as _Vulnerability from . import Vulnerability as _Vulnerability
from . import ( # noqa: F401
from . import ( # noqa: F401 isort:skip
AlternateDataStream, ArchiveExt, Artifact, AutonomousSystem, AlternateDataStream, ArchiveExt, Artifact, AutonomousSystem,
Bundle, CustomExtension, CustomMarking, CustomObservable, Bundle, CustomExtension, CustomMarking, CustomObservable,
Directory, DomainName, EmailAddress, EmailMessage, Directory, DomainName, EmailAddress, EmailMessage,
EmailMIMEComponent, Environment, ExternalReference, File, EmailMIMEComponent, Environment, ExternalReference, File,
FileSystemSource, Filter, GranularMarking, HTTPRequestExt, FileSystemSource, Filter, GranularMarking, HTTPRequestExt,
ICMPExt, IPv4Address, IPv6Address, KillChainPhase, LanguageContent, MACAddress, ICMPExt, IPv4Address, IPv6Address, KillChainPhase, LanguageContent,
MarkingDefinition, MemoryStore, Mutex, NetworkTraffic, NTFSExt, MACAddress, MarkingDefinition, MemoryStore, Mutex, NetworkTraffic,
parse_observable, PDFExt, Process, RasterImageExt, Relationship, NTFSExt, parse_observable, PDFExt, Process, RasterImageExt, Relationship,
Sighting, SocketExt, Software, StatementMarking, Sighting, SocketExt, Software, StatementMarking,
TAXIICollectionSource, TCPExt, TLP_AMBER, TLP_GREEN, TLP_RED, TAXIICollectionSource, TCPExt, TLP_AMBER, TLP_GREEN, TLP_RED,
TLP_WHITE, TLPMarking, UNIXAccountExt, URL, UserAccount, TLP_WHITE, TLPMarking, UNIXAccountExt, URL, UserAccount,
WindowsPEBinaryExt, WindowsPEOptionalHeaderType, WindowsPEBinaryExt, WindowsPEOptionalHeaderType,
WindowsPESection, WindowsProcessExt, WindowsRegistryKey, WindowsPESection, WindowsProcessExt, WindowsRegistryKey,
WindowsRegistryValueType, WindowsServiceExt, X509Certificate, WindowsRegistryValueType, WindowsServiceExt, X509Certificate,
X509V3ExtensionsType X509V3ExtensionsType,
) )
from .datastore.filters import FilterSet from .datastore.filters import FilterSet # isort:skip
# Enable some adaptation to the current default supported STIX version. # Enable some adaptation to the current default supported STIX version.

33
tox.ini
View File

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py35,py36,py37,py38,style,isort-check,packaging envlist = py36,py37,py38,py39,packaging,pre-commit-check
[testenv] [testenv]
deps = deps =
@ -15,33 +15,24 @@ deps =
commands = commands =
python -m pytest --cov=stix2 stix2/test/ --cov-report term-missing -W ignore::stix2.exceptions.STIXDeprecationWarning python -m pytest --cov=stix2 stix2/test/ --cov-report term-missing -W ignore::stix2.exceptions.STIXDeprecationWarning
passenv = CI TRAVIS TRAVIS_* passenv = GITHUB_*
[testenv:style]
deps =
flake8
commands =
flake8
[flake8]
max-line-length = 160
[testenv:isort-check]
deps = isort
commands =
isort stix2 examples --df
isort stix2 examples -c
[testenv:packaging] [testenv:packaging]
deps = deps =
twine twine
commands = commands =
python setup.py bdist_wheel --universal python setup.py sdist bdist_wheel --universal
twine check dist/* twine check dist/*
[travis] [testenv:pre-commit-check]
deps =
pre-commit
commands =
pre-commit run --all-files
[gh-actions]
python = python =
3.5: py35
3.6: py36 3.6: py36
3.7: py37 3.7: py37
3.8: py38, style, packaging 3.8: py38
3.9: py39, packaging, pre-commit-check