First pass at making sure everything uses v21 classes and representations

stix2.1
Emmanuelle Vargas-Gonzalez 2018-07-03 09:40:51 -04:00
parent 3100fa1fb8
commit 04680d8a3d
62 changed files with 759 additions and 699 deletions

View File

@ -35,17 +35,17 @@ def uuid4(monkeypatch):
@pytest.fixture @pytest.fixture
def indicator(uuid4, clock): def indicator(uuid4, clock):
return stix2.Indicator(**INDICATOR_KWARGS) return stix2.v21.Indicator(**INDICATOR_KWARGS)
@pytest.fixture @pytest.fixture
def malware(uuid4, clock): def malware(uuid4, clock):
return stix2.Malware(**MALWARE_KWARGS) return stix2.v21.Malware(**MALWARE_KWARGS)
@pytest.fixture @pytest.fixture
def relationship(uuid4, clock): def relationship(uuid4, clock):
return stix2.Relationship(**RELATIONSHIP_KWARGS) return stix2.v21.Relationship(**RELATIONSHIP_KWARGS)
@pytest.fixture @pytest.fixture
@ -59,6 +59,7 @@ def stix_objs1():
"modified": "2017-01-27T13:49:53.935Z", "modified": "2017-01-27T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -71,6 +72,7 @@ def stix_objs1():
"modified": "2017-01-27T13:49:53.935Z", "modified": "2017-01-27T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -83,6 +85,7 @@ def stix_objs1():
"modified": "2017-01-27T13:49:53.936Z", "modified": "2017-01-27T13:49:53.936Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -95,6 +98,7 @@ def stix_objs1():
"modified": "2017-01-27T13:49:53.935Z", "modified": "2017-01-27T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -107,6 +111,7 @@ def stix_objs1():
"modified": "2017-01-27T13:49:53.935Z", "modified": "2017-01-27T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -124,6 +129,7 @@ def stix_objs2():
"modified": "2017-01-31T13:49:53.935Z", "modified": "2017-01-31T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -136,6 +142,7 @@ def stix_objs2():
"modified": "2017-01-27T13:49:53.935Z", "modified": "2017-01-27T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -148,6 +155,7 @@ def stix_objs2():
"modified": "2017-01-27T13:49:53.935Z", "modified": "2017-01-27T13:49:53.935Z",
"name": "Malicious site hosting downloader", "name": "Malicious site hosting downloader",
"pattern": "[url:value = 'http://x4z9arb.cn/4712']", "pattern": "[url:value = 'http://x4z9arb.cn/4712']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2017-01-27T13:49:53.935382Z" "valid_from": "2017-01-27T13:49:53.935382Z"
} }
@ -156,4 +164,4 @@ def stix_objs2():
@pytest.fixture @pytest.fixture
def real_stix_objs2(stix_objs2): def real_stix_objs2(stix_objs2):
return [stix2.parse(x) for x in stix_objs2] return [stix2.parse(x, version="2.1") for x in stix_objs2]

View File

@ -34,9 +34,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "attack-pattern" "type": "attack-pattern"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -29,9 +29,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "attack-pattern" "type": "attack-pattern"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -24,9 +24,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "attack-pattern" "type": "attack-pattern"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -24,9 +24,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "attack-pattern" "type": "attack-pattern"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -24,9 +24,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "attack-pattern" "type": "attack-pattern"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -24,9 +24,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "attack-pattern" "type": "attack-pattern"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -8,9 +8,9 @@
"id": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f", "id": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f",
"modified": "2017-05-31T21:30:26.495974Z", "modified": "2017-05-31T21:30:26.495974Z",
"name": "Rootkit Mitigation", "name": "Rootkit Mitigation",
"spec_version": "2.1",
"type": "course-of-action" "type": "course-of-action"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -5,5 +5,6 @@
"id": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd", "id": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd",
"modified": "2017-05-31T21:30:41.022744Z", "modified": "2017-05-31T21:30:41.022744Z",
"name": "Data from Network Shared Drive Mitigation", "name": "Data from Network Shared Drive Mitigation",
"spec_version": "2.1",
"type": "course-of-action" "type": "course-of-action"
} }

View File

@ -7,9 +7,9 @@
"identity_class": "organization", "identity_class": "organization",
"modified": "2017-06-01T00:00:00Z", "modified": "2017-06-01T00:00:00Z",
"name": "The MITRE Corporation", "name": "The MITRE Corporation",
"spec_version": "2.1",
"type": "identity" "type": "identity"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -46,9 +46,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "intrusion-set" "type": "intrusion-set"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -36,9 +36,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "intrusion-set" "type": "intrusion-set"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -26,10 +26,10 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "malware", "type": "malware",
"is_family": false "is_family": false
} }
], ],
"spec_version": "2.1",
"type": "bundle" "type": "bundle"
} }

View File

@ -26,10 +26,10 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "malware", "type": "malware",
"is_family": false "is_family": false
} }
], ],
"spec_version": "2.1",
"type": "bundle" "type": "bundle"
} }

View File

@ -26,10 +26,10 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "malware", "type": "malware",
"is_family": false "is_family": false
} }
], ],
"spec_version": "2.1",
"type": "bundle" "type": "bundle"
} }

View File

@ -26,10 +26,10 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "malware", "type": "malware",
"is_family": false "is_family": false
} }
], ],
"spec_version": "2.1",
"type": "bundle" "type": "bundle"
} }

View File

@ -8,9 +8,9 @@
}, },
"definition_type": "statement", "definition_type": "statement",
"id": "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168", "id": "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168",
"spec_version": "2.1",
"type": "marking-definition" "type": "marking-definition"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "uses", "relationship_type": "uses",
"source_ref": "attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a", "source_ref": "attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a",
"spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841", "target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "uses", "relationship_type": "uses",
"source_ref": "attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22", "source_ref": "attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22",
"target_ref": "tool--242f3da3-4425-4d11-8f5c-b842886da966", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "mitigates", "relationship_type": "mitigates",
"source_ref": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f", "source_ref": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f",
"target_ref": "attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "uses", "relationship_type": "uses",
"source_ref": "attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475", "source_ref": "attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475",
"target_ref": "tool--03342581-f790-4f03-ba41-e82e67392e23", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "uses", "relationship_type": "uses",
"source_ref": "attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9", "source_ref": "attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9",
"target_ref": "malware--6b616fc1-1505-48e3-8b2c-0d19337bff38", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "mitigates", "relationship_type": "mitigates",
"source_ref": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd", "source_ref": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd",
"target_ref": "attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "uses", "relationship_type": "uses",
"source_ref": "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064", "source_ref": "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064",
"target_ref": "malware--96b08451-b27a-4ff6-893f-790e26393a8e", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -11,10 +11,10 @@
], ],
"relationship_type": "uses", "relationship_type": "uses",
"source_ref": "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a", "source_ref": "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a",
"target_ref": "malware--b42378e0-f147-496f-992a-26a49705395b", "spec_version": "2.1",
"target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841",
"type": "relationship" "type": "relationship"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -31,9 +31,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "tool" "type": "tool"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -26,9 +26,9 @@
"object_marking_refs": [ "object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
], ],
"spec_version": "2.1",
"type": "tool" "type": "tool"
} }
], ],
"spec_version": "2.0",
"type": "bundle" "type": "bundle"
} }

View File

@ -25,7 +25,7 @@ EXPECTED = """{
def test_attack_pattern_example(): def test_attack_pattern_example():
ap = stix2.AttackPattern( ap = stix2.v21.AttackPattern(
id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061",
created="2016-05-12T08:17:27.000Z", created="2016-05-12T08:17:27.000Z",
modified="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z",
@ -44,6 +44,7 @@ def test_attack_pattern_example():
EXPECTED, EXPECTED,
{ {
"type": "attack-pattern", "type": "attack-pattern",
"spec_version": "2.1",
"id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", "id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061",
"created": "2016-05-12T08:17:27.000Z", "created": "2016-05-12T08:17:27.000Z",
"modified": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z",
@ -58,9 +59,10 @@ def test_attack_pattern_example():
}, },
]) ])
def test_parse_attack_pattern(data): def test_parse_attack_pattern(data):
ap = stix2.parse(data) ap = stix2.parse(data, version="2.1")
assert ap.type == 'attack-pattern' assert ap.type == 'attack-pattern'
assert ap.spec_version == '2.1'
assert ap.id == ATTACK_PATTERN_ID assert ap.id == ATTACK_PATTERN_ID
assert ap.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert ap.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
assert ap.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert ap.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
@ -72,7 +74,7 @@ def test_parse_attack_pattern(data):
def test_attack_pattern_invalid_labels(): def test_attack_pattern_invalid_labels():
with pytest.raises(stix2.exceptions.InvalidValueError): with pytest.raises(stix2.exceptions.InvalidValueError):
stix2.AttackPattern( stix2.v21.AttackPattern(
id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061",
created="2016-05-12T08:17:27Z", created="2016-05-12T08:17:27Z",
modified="2016-05-12T08:17:27Z", modified="2016-05-12T08:17:27Z",

View File

@ -88,7 +88,7 @@ EXPECTED_BUNDLE_DICT = {
def test_empty_bundle(): def test_empty_bundle():
bundle = stix2.Bundle() bundle = stix2.v21.Bundle()
assert bundle.type == "bundle" assert bundle.type == "bundle"
assert bundle.id.startswith("bundle--") assert bundle.id.startswith("bundle--")
@ -98,7 +98,7 @@ def test_empty_bundle():
def test_bundle_with_wrong_type(): def test_bundle_with_wrong_type():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Bundle(type="not-a-bundle") stix2.v21.Bundle(type="not-a-bundle")
assert excinfo.value.cls == stix2.Bundle assert excinfo.value.cls == stix2.Bundle
assert excinfo.value.prop_name == "type" assert excinfo.value.prop_name == "type"
@ -108,7 +108,7 @@ def test_bundle_with_wrong_type():
def test_bundle_id_must_start_with_bundle(): def test_bundle_id_must_start_with_bundle():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Bundle(id='my-prefix--') stix2.v21.Bundle(id='my-prefix--')
assert excinfo.value.cls == stix2.Bundle assert excinfo.value.cls == stix2.Bundle
assert excinfo.value.prop_name == "id" assert excinfo.value.prop_name == "id"
@ -117,59 +117,59 @@ def test_bundle_id_must_start_with_bundle():
def test_create_bundle1(indicator, malware, relationship): def test_create_bundle1(indicator, malware, relationship):
bundle = stix2.Bundle(objects=[indicator, malware, relationship]) bundle = stix2.v21.Bundle(objects=[indicator, malware, relationship])
assert str(bundle) == EXPECTED_BUNDLE assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle2(indicator, malware, relationship): def test_create_bundle2(indicator, malware, relationship):
bundle = stix2.Bundle(objects=[indicator, malware, relationship]) bundle = stix2.v21.Bundle(objects=[indicator, malware, relationship])
assert json.loads(bundle.serialize()) == EXPECTED_BUNDLE_DICT assert json.loads(bundle.serialize()) == EXPECTED_BUNDLE_DICT
def test_create_bundle_with_positional_args(indicator, malware, relationship): def test_create_bundle_with_positional_args(indicator, malware, relationship):
bundle = stix2.Bundle(indicator, malware, relationship) bundle = stix2.v21.Bundle(indicator, malware, relationship)
assert str(bundle) == EXPECTED_BUNDLE assert str(bundle) == EXPECTED_BUNDLE
def test_create_bundle_with_positional_listarg(indicator, malware, relationship): def test_create_bundle_with_positional_listarg(indicator, malware, relationship):
bundle = stix2.Bundle([indicator, malware, relationship]) bundle = stix2.v21.Bundle([indicator, malware, relationship])
assert str(bundle) == EXPECTED_BUNDLE assert str(bundle) == EXPECTED_BUNDLE
def test_create_bundle_with_listarg_and_positional_arg(indicator, malware, relationship): def test_create_bundle_with_listarg_and_positional_arg(indicator, malware, relationship):
bundle = stix2.Bundle([indicator, malware], relationship) bundle = stix2.v21.Bundle([indicator, malware], relationship)
assert str(bundle) == EXPECTED_BUNDLE assert str(bundle) == EXPECTED_BUNDLE
def test_create_bundle_with_listarg_and_kwarg(indicator, malware, relationship): def test_create_bundle_with_listarg_and_kwarg(indicator, malware, relationship):
bundle = stix2.Bundle([indicator, malware], objects=[relationship]) bundle = stix2.v21.Bundle([indicator, malware], objects=[relationship])
assert str(bundle) == EXPECTED_BUNDLE assert str(bundle) == EXPECTED_BUNDLE
def test_create_bundle_with_arg_listarg_and_kwarg(indicator, malware, relationship): def test_create_bundle_with_arg_listarg_and_kwarg(indicator, malware, relationship):
bundle = stix2.Bundle([indicator], malware, objects=[relationship]) bundle = stix2.v21.Bundle([indicator], malware, objects=[relationship])
assert str(bundle) == EXPECTED_BUNDLE assert str(bundle) == EXPECTED_BUNDLE
def test_create_bundle_invalid(indicator, malware, relationship): def test_create_bundle_invalid(indicator, malware, relationship):
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
stix2.Bundle(objects=[1]) stix2.v21.Bundle(objects=[1])
assert excinfo.value.reason == "This property may only contain a dictionary or object" assert excinfo.value.reason == "This property may only contain a dictionary or object"
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
stix2.Bundle(objects=[{}]) stix2.v21.Bundle(objects=[{}])
assert excinfo.value.reason == "This property may only contain a non-empty dictionary or object" assert excinfo.value.reason == "This property may only contain a non-empty dictionary or object"
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
stix2.Bundle(objects=[{'type': 'bundle'}]) stix2.v21.Bundle(objects=[{'type': 'bundle'}])
assert excinfo.value.reason == 'This property may not contain a Bundle object' assert excinfo.value.reason == 'This property may not contain a Bundle object'
@ -188,6 +188,7 @@ def test_parse_bundle(version):
def test_parse_unknown_type(): def test_parse_unknown_type():
unknown = { unknown = {
"type": "other", "type": "other",
"spec_version": "2.1",
"id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", "id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
"created": "2016-04-06T20:03:00Z", "created": "2016-04-06T20:03:00Z",
"modified": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z",
@ -197,12 +198,12 @@ def test_parse_unknown_type():
} }
with pytest.raises(stix2.exceptions.ParseError) as excinfo: with pytest.raises(stix2.exceptions.ParseError) as excinfo:
stix2.parse(unknown) stix2.parse(unknown, version="2.1")
assert str(excinfo.value) == "Can't parse unknown object type 'other'! For custom types, use the CustomObject decorator." assert str(excinfo.value) == "Can't parse unknown object type 'other'! For custom types, use the CustomObject decorator."
def test_stix_object_property(): def test_stix_object_property():
prop = stix2.v21.bundle.STIXObjectProperty() prop = stix2.v21.bundle.STIXObjectProperty()
identity = stix2.Identity(name="test", identity_class="individual") identity = stix2.v21.Identity(name="test", identity_class="individual")
assert prop.clean(identity) is identity assert prop.clean(identity) is identity

View File

@ -20,7 +20,7 @@ EXPECTED = """{
def test_campaign_example(): def test_campaign_example():
campaign = stix2.Campaign( campaign = stix2.v21.Campaign(
id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:00Z", created="2016-04-06T20:03:00Z",
@ -46,9 +46,10 @@ def test_campaign_example():
}, },
]) ])
def test_parse_campaign(data): def test_parse_campaign(data):
cmpn = stix2.parse(data) cmpn = stix2.parse(data, version="2.1")
assert cmpn.type == 'campaign' assert cmpn.type == 'campaign'
assert cmpn.spec_version == '2.1'
assert cmpn.id == CAMPAIGN_ID assert cmpn.id == CAMPAIGN_ID
assert cmpn.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert cmpn.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc)
assert cmpn.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert cmpn.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc)

View File

@ -20,7 +20,7 @@ EXPECTED = """{
def test_course_of_action_example(): def test_course_of_action_example():
coa = stix2.CourseOfAction( coa = stix2.v21.CourseOfAction(
id="course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:48.000Z", created="2016-04-06T20:03:48.000Z",
@ -46,9 +46,10 @@ def test_course_of_action_example():
}, },
]) ])
def test_parse_course_of_action(data): def test_parse_course_of_action(data):
coa = stix2.parse(data) coa = stix2.parse(data, version="2.1")
assert coa.type == 'course-of-action' assert coa.type == 'course-of-action'
assert coa.spec_version == '2.1'
assert coa.id == COURSE_OF_ACTION_ID assert coa.id == COURSE_OF_ACTION_ID
assert coa.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert coa.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)
assert coa.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert coa.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)

View File

@ -6,7 +6,7 @@ import stix2.v21.sdo
from .constants import FAKE_TIME, MARKING_DEFINITION_ID from .constants import FAKE_TIME, MARKING_DEFINITION_ID
IDENTITY_CUSTOM_PROP = stix2.Identity( IDENTITY_CUSTOM_PROP = stix2.v21.Identity(
name="John Smith", name="John Smith",
identity_class="individual", identity_class="individual",
x_foo="bar", x_foo="bar",
@ -16,7 +16,7 @@ IDENTITY_CUSTOM_PROP = stix2.Identity(
def test_identity_custom_property(): def test_identity_custom_property():
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
stix2.Identity( stix2.v21.Identity(
id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
created="2015-12-21T19:59:11Z", created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z",
@ -27,7 +27,7 @@ def test_identity_custom_property():
assert str(excinfo.value) == "'custom_properties' must be a dictionary" assert str(excinfo.value) == "'custom_properties' must be a dictionary"
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
stix2.Identity( stix2.v21.Identity(
id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
created="2015-12-21T19:59:11Z", created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z",
@ -40,7 +40,7 @@ def test_identity_custom_property():
) )
assert "Unexpected properties for Identity" in str(excinfo.value) assert "Unexpected properties for Identity" in str(excinfo.value)
identity = stix2.Identity( identity = stix2.v21.Identity(
id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
created="2015-12-21T19:59:11Z", created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z",
@ -55,7 +55,7 @@ def test_identity_custom_property():
def test_identity_custom_property_invalid(): def test_identity_custom_property_invalid():
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
stix2.Identity( stix2.v21.Identity(
id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
created="2015-12-21T19:59:11Z", created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z",
@ -63,13 +63,13 @@ def test_identity_custom_property_invalid():
identity_class="individual", identity_class="individual",
x_foo="bar", x_foo="bar",
) )
assert excinfo.value.cls == stix2.Identity assert excinfo.value.cls == stix2.v21.Identity
assert excinfo.value.properties == ['x_foo'] assert excinfo.value.properties == ['x_foo']
assert "Unexpected properties for" in str(excinfo.value) assert "Unexpected properties for" in str(excinfo.value)
def test_identity_custom_property_allowed(): def test_identity_custom_property_allowed():
identity = stix2.Identity( identity = stix2.v21.Identity(
id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
created="2015-12-21T19:59:11Z", created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z",
@ -84,6 +84,7 @@ def test_identity_custom_property_allowed():
@pytest.mark.parametrize("data", [ @pytest.mark.parametrize("data", [
"""{ """{
"type": "identity", "type": "identity",
"spec_version": "2.1",
"id": "identity--311b2d2d-f010-5473-83ec-1edf84858f4c", "id": "identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
"created": "2015-12-21T19:59:11Z", "created": "2015-12-21T19:59:11Z",
"modified": "2015-12-21T19:59:11Z", "modified": "2015-12-21T19:59:11Z",
@ -94,31 +95,31 @@ def test_identity_custom_property_allowed():
]) ])
def test_parse_identity_custom_property(data): def test_parse_identity_custom_property(data):
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
identity = stix2.parse(data) stix2.parse(data, version="2.1")
assert excinfo.value.cls == stix2.v21.sdo.Identity assert excinfo.value.cls == stix2.v21.Identity
assert excinfo.value.properties == ['foo'] assert excinfo.value.properties == ['foo']
assert "Unexpected properties for" in str(excinfo.value) assert "Unexpected properties for" in str(excinfo.value)
identity = stix2.parse(data, allow_custom=True) identity = stix2.parse(data, version="2.1", allow_custom=True)
assert identity.foo == "bar" assert identity.foo == "bar"
def test_custom_property_object_in_bundled_object(): def test_custom_property_object_in_bundled_object():
bundle = stix2.Bundle(IDENTITY_CUSTOM_PROP, allow_custom=True) bundle = stix2.v21.Bundle(IDENTITY_CUSTOM_PROP, allow_custom=True)
assert bundle.objects[0].x_foo == "bar" assert bundle.objects[0].x_foo == "bar"
assert '"x_foo": "bar"' in str(bundle) assert '"x_foo": "bar"' in str(bundle)
def test_custom_properties_object_in_bundled_object(): def test_custom_properties_object_in_bundled_object():
obj = stix2.Identity( obj = stix2.v21.Identity(
name="John Smith", name="John Smith",
identity_class="individual", identity_class="individual",
custom_properties={ custom_properties={
"x_foo": "bar", "x_foo": "bar",
} }
) )
bundle = stix2.Bundle(obj, allow_custom=True) bundle = stix2.v21.Bundle(obj, allow_custom=True)
assert bundle.objects[0].x_foo == "bar" assert bundle.objects[0].x_foo == "bar"
assert '"x_foo": "bar"' in str(bundle) assert '"x_foo": "bar"' in str(bundle)
@ -127,6 +128,7 @@ def test_custom_properties_object_in_bundled_object():
def test_custom_property_dict_in_bundled_object(): def test_custom_property_dict_in_bundled_object():
custom_identity = { custom_identity = {
'type': 'identity', 'type': 'identity',
'spec_version': '2.1',
'id': 'identity--311b2d2d-f010-5473-83ec-1edf84858f4c', 'id': 'identity--311b2d2d-f010-5473-83ec-1edf84858f4c',
'created': '2015-12-21T19:59:11Z', 'created': '2015-12-21T19:59:11Z',
'name': 'John Smith', 'name': 'John Smith',
@ -134,9 +136,9 @@ def test_custom_property_dict_in_bundled_object():
'x_foo': 'bar', 'x_foo': 'bar',
} }
with pytest.raises(stix2.exceptions.ExtraPropertiesError): with pytest.raises(stix2.exceptions.ExtraPropertiesError):
bundle = stix2.Bundle(custom_identity) stix2.v21.Bundle(custom_identity)
bundle = stix2.Bundle(custom_identity, allow_custom=True) bundle = stix2.v21.Bundle(custom_identity, allow_custom=True)
assert bundle.objects[0].x_foo == "bar" assert bundle.objects[0].x_foo == "bar"
assert '"x_foo": "bar"' in str(bundle) assert '"x_foo": "bar"' in str(bundle)
@ -144,6 +146,7 @@ def test_custom_property_dict_in_bundled_object():
def test_custom_properties_dict_in_bundled_object(): def test_custom_properties_dict_in_bundled_object():
custom_identity = { custom_identity = {
'type': 'identity', 'type': 'identity',
'spec_version': '2.1',
'id': 'identity--311b2d2d-f010-5473-83ec-1edf84858f4c', 'id': 'identity--311b2d2d-f010-5473-83ec-1edf84858f4c',
'created': '2015-12-21T19:59:11Z', 'created': '2015-12-21T19:59:11Z',
'name': 'John Smith', 'name': 'John Smith',
@ -152,19 +155,19 @@ def test_custom_properties_dict_in_bundled_object():
'x_foo': 'bar', 'x_foo': 'bar',
}, },
} }
bundle = stix2.Bundle(custom_identity) bundle = stix2.v21.Bundle(custom_identity)
assert bundle.objects[0].x_foo == "bar" assert bundle.objects[0].x_foo == "bar"
assert '"x_foo": "bar"' in str(bundle) assert '"x_foo": "bar"' in str(bundle)
def test_custom_property_in_observed_data(): def test_custom_property_in_observed_data():
artifact = stix2.File( artifact = stix2.v21.File(
allow_custom=True, allow_custom=True,
name='test', name='test',
x_foo='bar' x_foo='bar'
) )
observed_data = stix2.ObservedData( observed_data = stix2.v21.ObservedData(
allow_custom=True, allow_custom=True,
first_observed="2015-12-21T19:00:00Z", first_observed="2015-12-21T19:00:00Z",
last_observed="2015-12-21T19:00:00Z", last_observed="2015-12-21T19:00:00Z",
@ -177,16 +180,16 @@ def test_custom_property_in_observed_data():
def test_custom_property_object_in_observable_extension(): def test_custom_property_object_in_observable_extension():
ntfs = stix2.NTFSExt( ntfs = stix2.v21.NTFSExt(
allow_custom=True, allow_custom=True,
sid=1, sid=1,
x_foo='bar', x_foo='bar',
) )
artifact = stix2.File( artifact = stix2.v21.File(
name='test', name='test',
extensions={'ntfs-ext': ntfs}, extensions={'ntfs-ext': ntfs},
) )
observed_data = stix2.ObservedData( observed_data = stix2.v21.ObservedData(
allow_custom=True, allow_custom=True,
first_observed="2015-12-21T19:00:00Z", first_observed="2015-12-21T19:00:00Z",
last_observed="2015-12-21T19:00:00Z", last_observed="2015-12-21T19:00:00Z",
@ -200,7 +203,7 @@ def test_custom_property_object_in_observable_extension():
def test_custom_property_dict_in_observable_extension(): def test_custom_property_dict_in_observable_extension():
with pytest.raises(stix2.exceptions.ExtraPropertiesError): with pytest.raises(stix2.exceptions.ExtraPropertiesError):
artifact = stix2.File( stix2.v21.File(
name='test', name='test',
extensions={ extensions={
'ntfs-ext': { 'ntfs-ext': {
@ -210,7 +213,7 @@ def test_custom_property_dict_in_observable_extension():
}, },
) )
artifact = stix2.File( artifact = stix2.v21.File(
allow_custom=True, allow_custom=True,
name='test', name='test',
extensions={ extensions={
@ -221,7 +224,7 @@ def test_custom_property_dict_in_observable_extension():
} }
}, },
) )
observed_data = stix2.ObservedData( observed_data = stix2.v21.ObservedData(
allow_custom=True, allow_custom=True,
first_observed="2015-12-21T19:00:00Z", first_observed="2015-12-21T19:00:00Z",
last_observed="2015-12-21T19:00:00Z", last_observed="2015-12-21T19:00:00Z",
@ -239,15 +242,15 @@ def test_identity_custom_property_revoke():
def test_identity_custom_property_edit_markings(): def test_identity_custom_property_edit_markings():
marking_obj = stix2.MarkingDefinition( marking_obj = stix2.v21.MarkingDefinition(
id=MARKING_DEFINITION_ID, id=MARKING_DEFINITION_ID,
definition_type="statement", definition_type="statement",
definition=stix2.StatementMarking(statement="Copyright 2016, Example Corp") definition=stix2.v21.StatementMarking(statement="Copyright 2016, Example Corp")
) )
marking_obj2 = stix2.MarkingDefinition( marking_obj2 = stix2.v21.MarkingDefinition(
id=MARKING_DEFINITION_ID, id=MARKING_DEFINITION_ID,
definition_type="statement", definition_type="statement",
definition=stix2.StatementMarking(statement="Another one") definition=stix2.v21.StatementMarking(statement="Another one")
) )
# None of the following should throw exceptions # None of the following should throw exceptions
@ -261,7 +264,7 @@ def test_identity_custom_property_edit_markings():
def test_custom_marking_no_init_1(): def test_custom_marking_no_init_1():
@stix2.CustomMarking('x-new-obj', [ @stix2.CustomMarking('x-new-obj', [
('property1', stix2.properties.StringProperty(required=True)), ('property1', stix2.v21.properties.StringProperty(required=True)),
]) ])
class NewObj(): class NewObj():
pass pass
@ -272,7 +275,7 @@ def test_custom_marking_no_init_1():
def test_custom_marking_no_init_2(): def test_custom_marking_no_init_2():
@stix2.CustomMarking('x-new-obj2', [ @stix2.CustomMarking('x-new-obj2', [
('property1', stix2.properties.StringProperty(required=True)), ('property1', stix2.v21.properties.StringProperty(required=True)),
]) ])
class NewObj2(object): class NewObj2(object):
pass pass
@ -282,8 +285,8 @@ def test_custom_marking_no_init_2():
@stix2.sdo.CustomObject('x-new-type', [ @stix2.sdo.CustomObject('x-new-type', [
('property1', stix2.properties.StringProperty(required=True)), ('property1', stix2.v21.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()), ('property2', stix2.v21.properties.IntegerProperty()),
]) ])
class NewType(object): class NewType(object):
def __init__(self, property2=None, **kwargs): def __init__(self, property2=None, **kwargs):
@ -867,6 +870,7 @@ def test_extension_property_location():
@pytest.mark.parametrize("data", [ @pytest.mark.parametrize("data", [
"""{ """{
"type": "x-example", "type": "x-example",
"spec_version": "2.1",
"id": "x-example--336d8a9f-91f1-46c5-b142-6441bb9f8b8d", "id": "x-example--336d8a9f-91f1-46c5-b142-6441bb9f8b8d",
"created": "2018-06-12T16:20:58.059Z", "created": "2018-06-12T16:20:58.059Z",
"modified": "2018-06-12T16:20:58.059Z", "modified": "2018-06-12T16:20:58.059Z",
@ -880,7 +884,7 @@ def test_extension_property_location():
]) ])
def test_custom_object_nested_dictionary(data): def test_custom_object_nested_dictionary(data):
@stix2.sdo.CustomObject('x-example', [ @stix2.sdo.CustomObject('x-example', [
('dictionary', stix2.properties.DictionaryProperty()), ('dictionary', stix2.v21.properties.DictionaryProperty()),
]) ])
class Example(object): class Example(object):
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -3,7 +3,7 @@ import pytest
from stix2.datastore import (CompositeDataSource, DataSink, DataSource, from stix2.datastore import (CompositeDataSource, DataSink, DataSource,
DataStoreMixin) DataStoreMixin)
from stix2.datastore.filters import Filter from stix2.datastore.filters import Filter
from stix2.test.constants import CAMPAIGN_MORE_KWARGS from stix2.test.v21.constants import CAMPAIGN_MORE_KWARGS
def test_datasource_abstract_class_raises_error(): def test_datasource_abstract_class_raises_error():

View File

@ -4,13 +4,12 @@ import shutil
import pytest import pytest
from stix2 import (Bundle, Campaign, CustomObject, FileSystemSink, import stix2
FileSystemSource, FileSystemStore, Filter, Identity, from stix2.test.v21.constants import (CAMPAIGN_ID, CAMPAIGN_KWARGS,
Indicator, Malware, Relationship, properties) IDENTITY_ID, IDENTITY_KWARGS,
from stix2.test.constants import (CAMPAIGN_ID, CAMPAIGN_KWARGS, IDENTITY_ID, INDICATOR_ID, INDICATOR_KWARGS,
IDENTITY_KWARGS, INDICATOR_ID, MALWARE_ID, MALWARE_KWARGS,
INDICATOR_KWARGS, MALWARE_ID, MALWARE_KWARGS, RELATIONSHIP_IDS)
RELATIONSHIP_IDS)
FS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "stix2_data") FS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "stix2_data")
@ -18,7 +17,7 @@ FS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "stix2_data"
@pytest.fixture @pytest.fixture
def fs_store(): def fs_store():
# create # create
yield FileSystemStore(FS_PATH) yield stix2.FileSystemStore(FS_PATH)
# remove campaign dir # remove campaign dir
shutil.rmtree(os.path.join(FS_PATH, "campaign"), True) shutil.rmtree(os.path.join(FS_PATH, "campaign"), True)
@ -27,7 +26,7 @@ def fs_store():
@pytest.fixture @pytest.fixture
def fs_source(): def fs_source():
# create # create
fs = FileSystemSource(FS_PATH) fs = stix2.FileSystemSource(FS_PATH)
assert fs.stix_dir == FS_PATH assert fs.stix_dir == FS_PATH
yield fs yield fs
@ -38,7 +37,7 @@ def fs_source():
@pytest.fixture @pytest.fixture
def fs_sink(): def fs_sink():
# create # create
fs = FileSystemSink(FS_PATH) fs = stix2.FileSystemSink(FS_PATH)
assert fs.stix_dir == FS_PATH assert fs.stix_dir == FS_PATH
yield fs yield fs
@ -83,15 +82,15 @@ def bad_stix_files():
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def rel_fs_store(): def rel_fs_store():
cam = Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) cam = stix2.v21.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS)
idy = Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) idy = stix2.v21.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS)
ind = Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) ind = stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS)
mal = Malware(id=MALWARE_ID, **MALWARE_KWARGS) mal = stix2.v21.Malware(id=MALWARE_ID, **MALWARE_KWARGS)
rel1 = Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) rel1 = stix2.v21.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0])
rel2 = Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) rel2 = stix2.v21.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1])
rel3 = Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) rel3 = stix2.v21.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2])
stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3] stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3]
fs = FileSystemStore(FS_PATH) fs = stix2.FileSystemStore(FS_PATH)
for o in stix_objs: for o in stix_objs:
fs.add(o) fs.add(o)
yield fs yield fs
@ -102,13 +101,13 @@ def rel_fs_store():
def test_filesystem_source_nonexistent_folder(): def test_filesystem_source_nonexistent_folder():
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
FileSystemSource('nonexistent-folder') stix2.FileSystemSource('nonexistent-folder')
assert "for STIX data does not exist" in str(excinfo) assert "for STIX data does not exist" in str(excinfo)
def test_filesystem_sink_nonexistent_folder(): def test_filesystem_sink_nonexistent_folder():
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
FileSystemSink('nonexistent-folder') stix2.FileSystemSink('nonexistent-folder')
assert "for STIX data does not exist" in str(excinfo) assert "for STIX data does not exist" in str(excinfo)
@ -154,7 +153,7 @@ def test_filesytem_source_all_versions(fs_source):
def test_filesytem_source_query_single(fs_source): def test_filesytem_source_query_single(fs_source):
# query2 # query2
is_2 = fs_source.query([Filter("external_references.external_id", '=', "T1027")]) is_2 = fs_source.query([stix2.Filter("external_references.external_id", '=', "T1027")])
assert len(is_2) == 1 assert len(is_2) == 1
is_2 = is_2[0] is_2 = is_2[0]
@ -164,7 +163,7 @@ def test_filesytem_source_query_single(fs_source):
def test_filesytem_source_query_multiple(fs_source): def test_filesytem_source_query_multiple(fs_source):
# query # query
intrusion_sets = fs_source.query([Filter("type", '=', "intrusion-set")]) intrusion_sets = fs_source.query([stix2.Filter("type", '=', "intrusion-set")])
assert len(intrusion_sets) == 2 assert len(intrusion_sets) == 2
assert "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064" in [is_.id for is_ in intrusion_sets] assert "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064" in [is_.id for is_ in intrusion_sets]
assert "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a" in [is_.id for is_ in intrusion_sets] assert "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a" in [is_.id for is_ in intrusion_sets]
@ -176,9 +175,9 @@ def test_filesytem_source_query_multiple(fs_source):
def test_filesystem_sink_add_python_stix_object(fs_sink, fs_source): def test_filesystem_sink_add_python_stix_object(fs_sink, fs_source):
# add python stix object # add python stix object
camp1 = Campaign(name="Hannibal", camp1 = stix2.v21.Campaign(name="Hannibal",
objective="Targeting Italian and Spanish Diplomat internet accounts", objective="Targeting Italian and Spanish Diplomat internet accounts",
aliases=["War Elephant"]) aliases=["War Elephant"])
fs_sink.add(camp1) fs_sink.add(camp1)
@ -263,7 +262,7 @@ def test_filesystem_sink_add_json_stix_object(fs_sink, fs_source):
def test_filesystem_sink_json_stix_bundle(fs_sink, fs_source): def test_filesystem_sink_json_stix_bundle(fs_sink, fs_source):
# add json-encoded stix bundle # add json-encoded stix bundle
bund2 = '{"type": "bundle", "id": "bundle--332211b6-1132-4fb0-111b-b111107ca70a",' \ bund2 = '{"type": "bundle", "id": "bundle--332211b6-1132-4fb0-111b-b111107ca70a",' \
' "objects": [{"type": "campaign", "id": "campaign--155155b6-1112-4fb0-111b-b111107ca70a",' \ ' "objects": [{"type": "campaign", "spec_version": "2.1", "id": "campaign--155155b6-1112-4fb0-111b-b111107ca70a",' \
' "created":"2017-05-31T21:31:53.197755Z", "name": "Spartacus", "objective": "Oppressive regimes of Africa and Middle East"}]}' ' "created":"2017-05-31T21:31:53.197755Z", "name": "Spartacus", "objective": "Oppressive regimes of Africa and Middle East"}]}'
fs_sink.add(bund2) fs_sink.add(bund2)
@ -278,13 +277,14 @@ def test_filesystem_sink_json_stix_bundle(fs_sink, fs_source):
def test_filesystem_sink_add_objects_list(fs_sink, fs_source): def test_filesystem_sink_add_objects_list(fs_sink, fs_source):
# add list of objects # add list of objects
camp6 = Campaign(name="Comanche", camp6 = stix2.v21.Campaign(name="Comanche",
objective="US Midwest manufacturing firms, oil refineries, and businesses", objective="US Midwest manufacturing firms, oil refineries, and businesses",
aliases=["Horse Warrior"]) aliases=["Horse Warrior"])
camp7 = { camp7 = {
"name": "Napolean", "name": "Napolean",
"type": "campaign", "type": "campaign",
"spec_version": "2.1",
"objective": "Central and Eastern Europe military commands and departments", "objective": "Central and Eastern Europe military commands and departments",
"aliases": ["The Frenchmen"], "aliases": ["The Frenchmen"],
"id": "campaign--122818b6-1112-4fb0-111b-b111107ca70a", "id": "campaign--122818b6-1112-4fb0-111b-b111107ca70a",
@ -330,14 +330,14 @@ def test_filesystem_store_all_versions(fs_store):
def test_filesystem_store_query(fs_store): def test_filesystem_store_query(fs_store):
# query() # query()
tools = fs_store.query([Filter("labels", "in", "tool")]) tools = fs_store.query([stix2.Filter("labels", "in", "tool")])
assert len(tools) == 2 assert len(tools) == 2
assert "tool--242f3da3-4425-4d11-8f5c-b842886da966" in [tool.id for tool in tools] assert "tool--242f3da3-4425-4d11-8f5c-b842886da966" in [tool.id for tool in tools]
assert "tool--03342581-f790-4f03-ba41-e82e67392e23" in [tool.id for tool in tools] assert "tool--03342581-f790-4f03-ba41-e82e67392e23" in [tool.id for tool in tools]
def test_filesystem_store_query_single_filter(fs_store): def test_filesystem_store_query_single_filter(fs_store):
query = Filter("labels", "in", "tool") query = stix2.Filter("labels", "in", "tool")
tools = fs_store.query(query) tools = fs_store.query(query)
assert len(tools) == 2 assert len(tools) == 2
assert "tool--242f3da3-4425-4d11-8f5c-b842886da966" in [tool.id for tool in tools] assert "tool--242f3da3-4425-4d11-8f5c-b842886da966" in [tool.id for tool in tools]
@ -352,22 +352,22 @@ def test_filesystem_store_empty_query(fs_store):
def test_filesystem_store_query_multiple_filters(fs_store): def test_filesystem_store_query_multiple_filters(fs_store):
fs_store.source.filters.add(Filter("labels", "in", "tool")) fs_store.source.filters.add(stix2.Filter("labels", "in", "tool"))
tools = fs_store.query(Filter("id", "=", "tool--242f3da3-4425-4d11-8f5c-b842886da966")) tools = fs_store.query(stix2.Filter("id", "=", "tool--242f3da3-4425-4d11-8f5c-b842886da966"))
assert len(tools) == 1 assert len(tools) == 1
assert tools[0].id == "tool--242f3da3-4425-4d11-8f5c-b842886da966" assert tools[0].id == "tool--242f3da3-4425-4d11-8f5c-b842886da966"
def test_filesystem_store_query_dont_include_type_folder(fs_store): def test_filesystem_store_query_dont_include_type_folder(fs_store):
results = fs_store.query(Filter("type", "!=", "tool")) results = fs_store.query(stix2.Filter("type", "!=", "tool"))
assert len(results) == 24 assert len(results) == 24
def test_filesystem_store_add(fs_store): def test_filesystem_store_add(fs_store):
# add() # add()
camp1 = Campaign(name="Great Heathen Army", camp1 = stix2.v21.Campaign(name="Great Heathen Army",
objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England", objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England",
aliases=["Ragnar"]) aliases=["Ragnar"])
fs_store.add(camp1) fs_store.add(camp1)
camp1_r = fs_store.get(camp1.id) camp1_r = fs_store.get(camp1.id)
@ -379,11 +379,11 @@ def test_filesystem_store_add(fs_store):
def test_filesystem_store_add_as_bundle(): def test_filesystem_store_add_as_bundle():
fs_store = FileSystemStore(FS_PATH, bundlify=True) fs_store = stix2.FileSystemStore(FS_PATH, bundlify=True)
camp1 = Campaign(name="Great Heathen Army", camp1 = stix2.v21.Campaign(name="Great Heathen Army",
objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England", objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England",
aliases=["Ragnar"]) aliases=["Ragnar"])
fs_store.add(camp1) fs_store.add(camp1)
with open(os.path.join(FS_PATH, "campaign", camp1.id + ".json")) as bundle_file: with open(os.path.join(FS_PATH, "campaign", camp1.id + ".json")) as bundle_file:
@ -397,7 +397,7 @@ def test_filesystem_store_add_as_bundle():
def test_filesystem_add_bundle_object(fs_store): def test_filesystem_add_bundle_object(fs_store):
bundle = Bundle() bundle = stix2.v21.Bundle()
fs_store.add(bundle) fs_store.add(bundle)
@ -412,10 +412,10 @@ def test_filesystem_store_add_invalid_object(fs_store):
def test_filesystem_object_with_custom_property(fs_store): def test_filesystem_object_with_custom_property(fs_store):
camp = Campaign(name="Scipio Africanus", camp = stix2.v21.Campaign(name="Scipio Africanus",
objective="Defeat the Carthaginians", objective="Defeat the Carthaginians",
x_empire="Roman", x_empire="Roman",
allow_custom=True) allow_custom=True)
fs_store.add(camp, True) fs_store.add(camp, True)
@ -425,12 +425,12 @@ def test_filesystem_object_with_custom_property(fs_store):
def test_filesystem_object_with_custom_property_in_bundle(fs_store): def test_filesystem_object_with_custom_property_in_bundle(fs_store):
camp = Campaign(name="Scipio Africanus", camp = stix2.v21.Campaign(name="Scipio Africanus",
objective="Defeat the Carthaginians", objective="Defeat the Carthaginians",
x_empire="Roman", x_empire="Roman",
allow_custom=True) allow_custom=True)
bundle = Bundle(camp, allow_custom=True) bundle = stix2.v21.Bundle(camp, allow_custom=True)
fs_store.add(bundle) fs_store.add(bundle)
camp_r = fs_store.get(camp.id) camp_r = fs_store.get(camp.id)
@ -439,8 +439,8 @@ def test_filesystem_object_with_custom_property_in_bundle(fs_store):
def test_filesystem_custom_object(fs_store): def test_filesystem_custom_object(fs_store):
@CustomObject('x-new-obj', [ @stix2.CustomObject('x-new-obj', [
('property1', properties.StringProperty(required=True)), ('property1', stix2.v21.properties.StringProperty(required=True)),
]) ])
class NewObj(): class NewObj():
pass pass

View File

@ -27,6 +27,7 @@ stix_objs = [
"modified": "2014-05-08T09:00:00.000Z", "modified": "2014-05-08T09:00:00.000Z",
"name": "File hash for Poison Ivy variant", "name": "File hash for Poison Ivy variant",
"pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']", "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']",
"spec_version": "2.1",
"type": "indicator", "type": "indicator",
"valid_from": "2014-05-08T09:00:00.000000Z" "valid_from": "2014-05-08T09:00:00.000000Z"
}, },
@ -48,11 +49,13 @@ stix_objs = [
"relationship_type": "indicates", "relationship_type": "indicates",
"revoked": True, "revoked": True,
"source_ref": "indicator--a932fcc6-e032-176c-126f-cb970a5a1ade", "source_ref": "indicator--a932fcc6-e032-176c-126f-cb970a5a1ade",
"spec_version": "2.1",
"target_ref": "malware--fdd60b30-b67c-11e3-b0b9-f01faf20d111", "target_ref": "malware--fdd60b30-b67c-11e3-b0b9-f01faf20d111",
"type": "relationship" "type": "relationship"
}, },
{ {
"id": "vulnerability--ee916c28-c7a4-4d0d-ad56-a8d357f89fef", "id": "vulnerability--ee916c28-c7a4-4d0d-ad56-a8d357f89fef",
"spec_version": "2.1",
"created": "2016-02-14T00:00:00.000Z", "created": "2016-02-14T00:00:00.000Z",
"created_by_ref": "identity--00000000-0000-0000-0000-b8e91df99dc9", "created_by_ref": "identity--00000000-0000-0000-0000-b8e91df99dc9",
"modified": "2016-02-14T00:00:00.000Z", "modified": "2016-02-14T00:00:00.000Z",
@ -69,6 +72,7 @@ stix_objs = [
}, },
{ {
"type": "observed-data", "type": "observed-data",
"spec_version": "2.1",
"id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
"created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
"created": "2016-04-06T19:58:16.000Z", "created": "2016-04-06T19:58:16.000Z",
@ -422,6 +426,7 @@ def test_filters7(stix_objs2, real_stix_objs2):
# Test filtering on embedded property # Test filtering on embedded property
obsvd_data_obj = { obsvd_data_obj = {
"type": "observed-data", "type": "observed-data",
"spec_version": "2.1",
"id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
"created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
"created": "2016-04-06T19:58:16.000Z", "created": "2016-04-06T19:58:16.000Z",

View File

@ -28,7 +28,6 @@ def test_add_remove_composite_datasource():
def test_composite_datasource_operations(stix_objs1, stix_objs2): def test_composite_datasource_operations(stix_objs1, stix_objs2):
BUNDLE1 = dict(id="bundle--%s" % make_id(), BUNDLE1 = dict(id="bundle--%s" % make_id(),
objects=stix_objs1, objects=stix_objs1,
spec_version="2.0",
type="bundle") type="bundle")
cds1 = CompositeDataSource() cds1 = CompositeDataSource()
ds1_1 = MemorySource(stix_data=BUNDLE1) ds1_1 = MemorySource(stix_data=BUNDLE1)

View File

@ -5,8 +5,7 @@ import pytest
from requests.models import Response from requests.models import Response
from taxii2client import Collection, _filter_kwargs_to_query_params from taxii2client import Collection, _filter_kwargs_to_query_params
from stix2 import (Bundle, TAXIICollectionSink, TAXIICollectionSource, import stix2
TAXIICollectionStore, ThreatActor)
from stix2.datastore import DataSourceError from stix2.datastore import DataSourceError
from stix2.datastore.filters import Filter from stix2.datastore.filters import Filter
@ -39,7 +38,7 @@ class MockTAXIICollectionEndpoint(Collection):
[] []
) )
if objs: if objs:
return Bundle(objects=objs) return stix2.v21.Bundle(objects=objs)
else: else:
resp = Response() resp = Response()
resp.status_code = 404 resp.status_code = 404
@ -59,7 +58,7 @@ class MockTAXIICollectionEndpoint(Collection):
[] []
) )
if objs: if objs:
return Bundle(objects=objs) return stix2.v21.Bundle(objects=objs)
else: else:
resp = Response() resp = Response()
resp.status_code = 404 resp.status_code = 404
@ -101,65 +100,65 @@ def collection_no_rw_access(stix_objs1):
def test_ds_taxii(collection): def test_ds_taxii(collection):
ds = TAXIICollectionSource(collection) ds = stix2.TAXIICollectionSource(collection)
assert ds.collection is not None assert ds.collection is not None
def test_add_stix2_object(collection): def test_add_stix2_object(collection):
tc_sink = TAXIICollectionSink(collection) tc_sink = stix2.TAXIICollectionSink(collection)
# create new STIX threat-actor # create new STIX threat-actor
ta = ThreatActor(name="Teddy Bear", ta = stix2.v21.ThreatActor(name="Teddy Bear",
labels=["nation-state"], labels=["nation-state"],
sophistication="innovator", sophistication="innovator",
resource_level="government", resource_level="government",
goals=[ goals=[
"compromising environment NGOs", "compromising environment NGOs",
"water-hole attacks geared towards energy sector", "water-hole attacks geared towards energy sector",
]) ])
tc_sink.add(ta) tc_sink.add(ta)
def test_add_stix2_with_custom_object(collection): def test_add_stix2_with_custom_object(collection):
tc_sink = TAXIICollectionStore(collection, allow_custom=True) tc_sink = stix2.TAXIICollectionStore(collection, allow_custom=True)
# create new STIX threat-actor # create new STIX threat-actor
ta = ThreatActor(name="Teddy Bear", ta = stix2.v21.ThreatActor(name="Teddy Bear",
labels=["nation-state"], labels=["nation-state"],
sophistication="innovator", sophistication="innovator",
resource_level="government", resource_level="government",
goals=[ goals=[
"compromising environment NGOs", "compromising environment NGOs",
"water-hole attacks geared towards energy sector", "water-hole attacks geared towards energy sector",
], ],
foo="bar", foo="bar",
allow_custom=True) allow_custom=True)
tc_sink.add(ta) tc_sink.add(ta)
def test_add_list_object(collection, indicator): def test_add_list_object(collection, indicator):
tc_sink = TAXIICollectionSink(collection) tc_sink = stix2.TAXIICollectionSink(collection)
# create new STIX threat-actor # create new STIX threat-actor
ta = ThreatActor(name="Teddy Bear", ta = stix2.v21.ThreatActor(name="Teddy Bear",
labels=["nation-state"], labels=["nation-state"],
sophistication="innovator", sophistication="innovator",
resource_level="government", resource_level="government",
goals=[ goals=[
"compromising environment NGOs", "compromising environment NGOs",
"water-hole attacks geared towards energy sector", "water-hole attacks geared towards energy sector",
]) ])
tc_sink.add([ta, indicator]) tc_sink.add([ta, indicator])
def test_add_stix2_bundle_object(collection): def test_add_stix2_bundle_object(collection):
tc_sink = TAXIICollectionSink(collection) tc_sink = stix2.TAXIICollectionSink(collection)
# create new STIX threat-actor # create new STIX threat-actor
ta = ThreatActor(name="Teddy Bear", ta = stix2.v21.ThreatActor(name="Teddy Bear",
labels=["nation-state"], labels=["nation-state"],
sophistication="innovator", sophistication="innovator",
resource_level="government", resource_level="government",
@ -168,15 +167,16 @@ def test_add_stix2_bundle_object(collection):
"water-hole attacks geared towards energy sector", "water-hole attacks geared towards energy sector",
]) ])
tc_sink.add(Bundle(objects=[ta])) tc_sink.add(stix2.v21.Bundle(objects=[ta]))
def test_add_str_object(collection): def test_add_str_object(collection):
tc_sink = TAXIICollectionSink(collection) tc_sink = stix2.TAXIICollectionSink(collection)
# create new STIX threat-actor # create new STIX threat-actor
ta = """{ ta = """{
"type": "threat-actor", "type": "threat-actor",
"spec_version": "2.1",
"id": "threat-actor--eddff64f-feb1-4469-b07c-499a73c96415", "id": "threat-actor--eddff64f-feb1-4469-b07c-499a73c96415",
"created": "2018-04-23T16:40:50.847Z", "created": "2018-04-23T16:40:50.847Z",
"modified": "2018-04-23T16:40:50.847Z", "modified": "2018-04-23T16:40:50.847Z",
@ -196,10 +196,11 @@ def test_add_str_object(collection):
def test_add_dict_object(collection): def test_add_dict_object(collection):
tc_sink = TAXIICollectionSink(collection) tc_sink = stix2.TAXIICollectionSink(collection)
ta = { ta = {
"type": "threat-actor", "type": "threat-actor",
"spec_version": "2.1",
"id": "threat-actor--eddff64f-feb1-4469-b07c-499a73c96415", "id": "threat-actor--eddff64f-feb1-4469-b07c-499a73c96415",
"created": "2018-04-23T16:40:50.847Z", "created": "2018-04-23T16:40:50.847Z",
"modified": "2018-04-23T16:40:50.847Z", "modified": "2018-04-23T16:40:50.847Z",
@ -219,7 +220,7 @@ def test_add_dict_object(collection):
def test_add_dict_bundle_object(collection): def test_add_dict_bundle_object(collection):
tc_sink = TAXIICollectionSink(collection) tc_sink = stix2.TAXIICollectionSink(collection)
ta = { ta = {
"type": "bundle", "type": "bundle",
@ -227,6 +228,7 @@ def test_add_dict_bundle_object(collection):
"objects": [ "objects": [
{ {
"type": "threat-actor", "type": "threat-actor",
"spec_version": "2.1",
"id": "threat-actor--dc5a2f41-f76e-425a-81fe-33afc7aabd75", "id": "threat-actor--dc5a2f41-f76e-425a-81fe-33afc7aabd75",
"created": "2018-04-23T18:45:11.390Z", "created": "2018-04-23T18:45:11.390Z",
"modified": "2018-04-23T18:45:11.390Z", "modified": "2018-04-23T18:45:11.390Z",
@ -248,7 +250,7 @@ def test_add_dict_bundle_object(collection):
def test_get_stix2_object(collection): def test_get_stix2_object(collection):
tc_sink = TAXIICollectionSource(collection) tc_sink = stix2.TAXIICollectionSource(collection)
objects = tc_sink.get("indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f") objects = tc_sink.get("indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f")
@ -271,7 +273,7 @@ def test_parse_taxii_filters(collection):
Filter("version", "=", "first") Filter("version", "=", "first")
] ]
ds = TAXIICollectionSource(collection) ds = stix2.TAXIICollectionSource(collection)
taxii_filters = ds._parse_taxii_filters(query) taxii_filters = ds._parse_taxii_filters(query)
@ -279,7 +281,7 @@ def test_parse_taxii_filters(collection):
def test_add_get_remove_filter(collection): def test_add_get_remove_filter(collection):
ds = TAXIICollectionSource(collection) ds = stix2.TAXIICollectionSource(collection)
# First 3 filters are valid, remaining properties are erroneous in some way # First 3 filters are valid, remaining properties are erroneous in some way
valid_filters = [ valid_filters = [
@ -315,7 +317,7 @@ def test_add_get_remove_filter(collection):
def test_get_all_versions(collection): def test_get_all_versions(collection):
ds = TAXIICollectionStore(collection) ds = stix2.TAXIICollectionStore(collection)
indicators = ds.all_versions('indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f') indicators = ds.all_versions('indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f')
# There are 3 indicators but 2 share the same 'modified' timestamp # There are 3 indicators but 2 share the same 'modified' timestamp
@ -327,7 +329,7 @@ def test_can_read_error(collection_no_rw_access):
instance that does not have read access, check ValueError exception is raised""" instance that does not have read access, check ValueError exception is raised"""
with pytest.raises(DataSourceError) as excinfo: with pytest.raises(DataSourceError) as excinfo:
TAXIICollectionSource(collection_no_rw_access) stix2.TAXIICollectionSource(collection_no_rw_access)
assert "Collection object provided does not have read access" in str(excinfo.value) assert "Collection object provided does not have read access" in str(excinfo.value)
@ -336,7 +338,7 @@ def test_can_write_error(collection_no_rw_access):
instance that does not have write access, check ValueError exception is raised""" instance that does not have write access, check ValueError exception is raised"""
with pytest.raises(DataSourceError) as excinfo: with pytest.raises(DataSourceError) as excinfo:
TAXIICollectionSink(collection_no_rw_access) stix2.TAXIICollectionSink(collection_no_rw_access)
assert "Collection object provided does not have write access" in str(excinfo.value) assert "Collection object provided does not have write access" in str(excinfo.value)
@ -357,7 +359,7 @@ def test_get_404():
resp.status_code = 404 resp.status_code = 404
resp.raise_for_status() resp.raise_for_status()
ds = TAXIICollectionSource(TAXIICollection404()) ds = stix2.TAXIICollectionSource(TAXIICollection404())
# this will raise 404 from mock TAXII Client but TAXIICollectionStore # this will raise 404 from mock TAXII Client but TAXIICollectionStore
# should handle gracefully and return None # should handle gracefully and return None
@ -369,7 +371,7 @@ def test_all_versions_404(collection):
""" a TAXIICollectionSource.all_version() call that recieves an HTTP 404 """ a TAXIICollectionSource.all_version() call that recieves an HTTP 404
response code from the taxii2client should be returned as an exception""" response code from the taxii2client should be returned as an exception"""
ds = TAXIICollectionStore(collection) ds = stix2.TAXIICollectionStore(collection)
with pytest.raises(DataSourceError) as excinfo: with pytest.raises(DataSourceError) as excinfo:
ds.all_versions("indicator--1") ds.all_versions("indicator--1")
@ -381,7 +383,7 @@ def test_query_404(collection):
""" a TAXIICollectionSource.query() call that recieves an HTTP 404 """ a TAXIICollectionSource.query() call that recieves an HTTP 404
response code from the taxii2client should be returned as an exception""" response code from the taxii2client should be returned as an exception"""
ds = TAXIICollectionStore(collection) ds = stix2.TAXIICollectionStore(collection)
query = [Filter("type", "=", "malware")] query = [Filter("type", "=", "malware")]
with pytest.raises(DataSourceError) as excinfo: with pytest.raises(DataSourceError) as excinfo:

View File

@ -9,92 +9,92 @@ from .constants import (CAMPAIGN_ID, CAMPAIGN_KWARGS, FAKE_TIME, IDENTITY_ID,
@pytest.fixture @pytest.fixture
def ds(): def ds():
cam = stix2.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) cam = stix2.v21.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS)
idy = stix2.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) idy = stix2.v21.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS)
ind = stix2.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) ind = stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS)
mal = stix2.Malware(id=MALWARE_ID, **MALWARE_KWARGS) mal = stix2.v21.Malware(id=MALWARE_ID, **MALWARE_KWARGS)
rel1 = stix2.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) rel1 = stix2.v21.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0])
rel2 = stix2.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) rel2 = stix2.v21.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1])
rel3 = stix2.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) rel3 = stix2.v21.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2])
stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3] stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3]
yield stix2.MemoryStore(stix_objs) yield stix2.MemoryStore(stix_objs)
def test_object_factory_created_by_ref_str(): def test_object_factory_created_by_ref_str():
factory = stix2.ObjectFactory(created_by_ref=IDENTITY_ID) factory = stix2.ObjectFactory(created_by_ref=IDENTITY_ID)
ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
assert ind.created_by_ref == IDENTITY_ID assert ind.created_by_ref == IDENTITY_ID
def test_object_factory_created_by_ref_obj(): def test_object_factory_created_by_ref_obj():
id_obj = stix2.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) id_obj = stix2.v21.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS)
factory = stix2.ObjectFactory(created_by_ref=id_obj) factory = stix2.ObjectFactory(created_by_ref=id_obj)
ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
assert ind.created_by_ref == IDENTITY_ID assert ind.created_by_ref == IDENTITY_ID
def test_object_factory_override_default(): def test_object_factory_override_default():
factory = stix2.ObjectFactory(created_by_ref=IDENTITY_ID) factory = stix2.ObjectFactory(created_by_ref=IDENTITY_ID)
new_id = "identity--983b3172-44fe-4a80-8091-eb8098841fe8" new_id = "identity--983b3172-44fe-4a80-8091-eb8098841fe8"
ind = factory.create(stix2.Indicator, created_by_ref=new_id, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, created_by_ref=new_id, **INDICATOR_KWARGS)
assert ind.created_by_ref == new_id assert ind.created_by_ref == new_id
def test_object_factory_created(): def test_object_factory_created():
factory = stix2.ObjectFactory(created=FAKE_TIME) factory = stix2.ObjectFactory(created=FAKE_TIME)
ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
assert ind.created == FAKE_TIME assert ind.created == FAKE_TIME
assert ind.modified == FAKE_TIME assert ind.modified == FAKE_TIME
def test_object_factory_external_reference(): def test_object_factory_external_reference():
ext_ref = stix2.ExternalReference(source_name="ACME Threat Intel", ext_ref = stix2.v21.ExternalReference(source_name="ACME Threat Intel",
description="Threat report") description="Threat report")
factory = stix2.ObjectFactory(external_references=ext_ref) factory = stix2.ObjectFactory(external_references=ext_ref)
ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
assert ind.external_references[0].source_name == "ACME Threat Intel" assert ind.external_references[0].source_name == "ACME Threat Intel"
assert ind.external_references[0].description == "Threat report" assert ind.external_references[0].description == "Threat report"
ind2 = factory.create(stix2.Indicator, external_references=None, **INDICATOR_KWARGS) ind2 = factory.create(stix2.v21.Indicator, external_references=None, **INDICATOR_KWARGS)
assert 'external_references' not in ind2 assert 'external_references' not in ind2
def test_object_factory_obj_markings(): def test_object_factory_obj_markings():
stmt_marking = stix2.StatementMarking("Copyright 2016, Example Corp") stmt_marking = stix2.v21.StatementMarking("Copyright 2016, Example Corp")
mark_def = stix2.MarkingDefinition(definition_type="statement", mark_def = stix2.v21.MarkingDefinition(definition_type="statement",
definition=stmt_marking) definition=stmt_marking)
factory = stix2.ObjectFactory(object_marking_refs=[mark_def, stix2.TLP_AMBER]) factory = stix2.ObjectFactory(object_marking_refs=[mark_def, stix2.TLP_AMBER])
ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
assert mark_def.id in ind.object_marking_refs assert mark_def.id in ind.object_marking_refs
assert stix2.TLP_AMBER.id in ind.object_marking_refs assert stix2.TLP_AMBER.id in ind.object_marking_refs
factory = stix2.ObjectFactory(object_marking_refs=stix2.TLP_RED) factory = stix2.ObjectFactory(object_marking_refs=stix2.TLP_RED)
ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
assert stix2.TLP_RED.id in ind.object_marking_refs assert stix2.TLP_RED.id in ind.object_marking_refs
def test_object_factory_list_append(): def test_object_factory_list_append():
ext_ref = stix2.ExternalReference(source_name="ACME Threat Intel", ext_ref = stix2.v21.ExternalReference(source_name="ACME Threat Intel",
description="Threat report from ACME") description="Threat report from ACME")
ext_ref2 = stix2.ExternalReference(source_name="Yet Another Threat Report", ext_ref2 = stix2.v21.ExternalReference(source_name="Yet Another Threat Report",
description="Threat report from YATR") description="Threat report from YATR")
ext_ref3 = stix2.ExternalReference(source_name="Threat Report #3", ext_ref3 = stix2.v21.ExternalReference(source_name="Threat Report #3",
description="One more threat report") description="One more threat report")
factory = stix2.ObjectFactory(external_references=ext_ref) factory = stix2.ObjectFactory(external_references=ext_ref)
ind = factory.create(stix2.Indicator, external_references=ext_ref2, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, external_references=ext_ref2, **INDICATOR_KWARGS)
assert ind.external_references[1].source_name == "Yet Another Threat Report" assert ind.external_references[1].source_name == "Yet Another Threat Report"
ind = factory.create(stix2.Indicator, external_references=[ext_ref2, ext_ref3], **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, external_references=[ext_ref2, ext_ref3], **INDICATOR_KWARGS)
assert ind.external_references[2].source_name == "Threat Report #3" assert ind.external_references[2].source_name == "Threat Report #3"
def test_object_factory_list_replace(): def test_object_factory_list_replace():
ext_ref = stix2.ExternalReference(source_name="ACME Threat Intel", ext_ref = stix2.v21.ExternalReference(source_name="ACME Threat Intel",
description="Threat report from ACME") description="Threat report from ACME")
ext_ref2 = stix2.ExternalReference(source_name="Yet Another Threat Report", ext_ref2 = stix2.v21.ExternalReference(source_name="Yet Another Threat Report",
description="Threat report from YATR") description="Threat report from YATR")
factory = stix2.ObjectFactory(external_references=ext_ref, list_append=False) factory = stix2.ObjectFactory(external_references=ext_ref, list_append=False)
ind = factory.create(stix2.Indicator, external_references=ext_ref2, **INDICATOR_KWARGS) ind = factory.create(stix2.v21.Indicator, external_references=ext_ref2, **INDICATOR_KWARGS)
assert len(ind.external_references) == 1 assert len(ind.external_references) == 1
assert ind.external_references[0].source_name == "Yet Another Threat Report" assert ind.external_references[0].source_name == "Yet Another Threat Report"
@ -104,7 +104,7 @@ def test_environment_functions():
stix2.MemoryStore()) stix2.MemoryStore())
# Create a STIX object # Create a STIX object
ind = env.create(stix2.Indicator, id=INDICATOR_ID, **INDICATOR_KWARGS) ind = env.create(stix2.v21.Indicator, id=INDICATOR_ID, **INDICATOR_KWARGS)
assert ind.created_by_ref == IDENTITY_ID assert ind.created_by_ref == IDENTITY_ID
# Add objects to datastore # Add objects to datastore
@ -133,7 +133,7 @@ def test_environment_functions():
def test_environment_source_and_sink(): def test_environment_source_and_sink():
ind = stix2.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) ind = stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS)
env = stix2.Environment(source=stix2.MemorySource([ind]), sink=stix2.MemorySink([ind])) env = stix2.Environment(source=stix2.MemorySource([ind]), sink=stix2.MemorySink([ind]))
assert env.get(INDICATOR_ID).labels[0] == 'malicious-activity' assert env.get(INDICATOR_ID).labels[0] == 'malicious-activity'
@ -149,7 +149,7 @@ def test_environment_no_datastore():
env = stix2.Environment(factory=stix2.ObjectFactory()) env = stix2.Environment(factory=stix2.ObjectFactory())
with pytest.raises(AttributeError) as excinfo: with pytest.raises(AttributeError) as excinfo:
env.add(stix2.Indicator(**INDICATOR_KWARGS)) env.add(stix2.v21.Indicator(**INDICATOR_KWARGS))
assert 'Environment has no data sink to put objects in' in str(excinfo.value) assert 'Environment has no data sink to put objects in' in str(excinfo.value)
with pytest.raises(AttributeError) as excinfo: with pytest.raises(AttributeError) as excinfo:
@ -182,7 +182,7 @@ def test_environment_add_filters():
def test_environment_datastore_and_no_object_factory(): def test_environment_datastore_and_no_object_factory():
# Uses a default object factory # Uses a default object factory
env = stix2.Environment(store=stix2.MemoryStore()) env = stix2.Environment(store=stix2.MemoryStore())
ind = env.create(stix2.Indicator, id=INDICATOR_ID, **INDICATOR_KWARGS) ind = env.create(stix2.v21.Indicator, id=INDICATOR_ID, **INDICATOR_KWARGS)
assert ind.id == INDICATOR_ID assert ind.id == INDICATOR_ID
@ -203,6 +203,7 @@ def test_parse_malware():
mal = env.parse(data) mal = env.parse(data)
assert mal.type == 'malware' assert mal.type == 'malware'
assert mal.spec_version == '2.1'
assert mal.id == MALWARE_ID assert mal.id == MALWARE_ID
assert mal.created == FAKE_TIME assert mal.created == FAKE_TIME
assert mal.modified == FAKE_TIME assert mal.modified == FAKE_TIME
@ -211,40 +212,40 @@ def test_parse_malware():
def test_creator_of(): def test_creator_of():
identity = stix2.Identity(**IDENTITY_KWARGS) identity = stix2.v21.Identity(**IDENTITY_KWARGS)
factory = stix2.ObjectFactory(created_by_ref=identity.id) factory = stix2.ObjectFactory(created_by_ref=identity.id)
env = stix2.Environment(store=stix2.MemoryStore(), factory=factory) env = stix2.Environment(store=stix2.MemoryStore(), factory=factory)
env.add(identity) env.add(identity)
ind = env.create(stix2.Indicator, **INDICATOR_KWARGS) ind = env.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
creator = env.creator_of(ind) creator = env.creator_of(ind)
assert creator is identity assert creator is identity
def test_creator_of_no_datasource(): def test_creator_of_no_datasource():
identity = stix2.Identity(**IDENTITY_KWARGS) identity = stix2.v21.Identity(**IDENTITY_KWARGS)
factory = stix2.ObjectFactory(created_by_ref=identity.id) factory = stix2.ObjectFactory(created_by_ref=identity.id)
env = stix2.Environment(factory=factory) env = stix2.Environment(factory=factory)
ind = env.create(stix2.Indicator, **INDICATOR_KWARGS) ind = env.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
with pytest.raises(AttributeError) as excinfo: with pytest.raises(AttributeError) as excinfo:
env.creator_of(ind) env.creator_of(ind)
assert 'Environment has no data source' in str(excinfo.value) assert 'Environment has no data source' in str(excinfo.value)
def test_creator_of_not_found(): def test_creator_of_not_found():
identity = stix2.Identity(**IDENTITY_KWARGS) identity = stix2.v21.Identity(**IDENTITY_KWARGS)
factory = stix2.ObjectFactory(created_by_ref=identity.id) factory = stix2.ObjectFactory(created_by_ref=identity.id)
env = stix2.Environment(store=stix2.MemoryStore(), factory=factory) env = stix2.Environment(store=stix2.MemoryStore(), factory=factory)
ind = env.create(stix2.Indicator, **INDICATOR_KWARGS) ind = env.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
creator = env.creator_of(ind) creator = env.creator_of(ind)
assert creator is None assert creator is None
def test_creator_of_no_created_by_ref(): def test_creator_of_no_created_by_ref():
env = stix2.Environment(store=stix2.MemoryStore()) env = stix2.Environment(store=stix2.MemoryStore())
ind = env.create(stix2.Indicator, **INDICATOR_KWARGS) ind = env.create(stix2.v21.Indicator, **INDICATOR_KWARGS)
creator = env.creator_of(ind) creator = env.creator_of(ind)
assert creator is None assert creator is None

View File

@ -17,7 +17,7 @@ VERIS = """{
def test_external_reference_veris(): def test_external_reference_veris():
ref = stix2.ExternalReference( ref = stix2.v21.ExternalReference(
source_name="veris", source_name="veris",
external_id="0001AA7F-C601-424A-B2B8-BE6C9F5164E7", external_id="0001AA7F-C601-424A-B2B8-BE6C9F5164E7",
hashes={ hashes={
@ -36,7 +36,7 @@ CAPEC = """{
def test_external_reference_capec(): def test_external_reference_capec():
ref = stix2.ExternalReference( ref = stix2.v21.ExternalReference(
source_name="capec", source_name="capec",
external_id="CAPEC-550", external_id="CAPEC-550",
) )
@ -53,7 +53,7 @@ CAPEC_URL = """{
def test_external_reference_capec_url(): def test_external_reference_capec_url():
ref = stix2.ExternalReference( ref = stix2.v21.ExternalReference(
source_name="capec", source_name="capec",
external_id="CAPEC-550", external_id="CAPEC-550",
url="http://capec.mitre.org/data/definitions/550.html", url="http://capec.mitre.org/data/definitions/550.html",
@ -70,7 +70,7 @@ THREAT_REPORT = """{
def test_external_reference_threat_report(): def test_external_reference_threat_report():
ref = stix2.ExternalReference( ref = stix2.v21.ExternalReference(
source_name="ACME Threat Intel", source_name="ACME Threat Intel",
description="Threat report", description="Threat report",
url="http://www.example.com/threat-report.pdf", url="http://www.example.com/threat-report.pdf",
@ -87,7 +87,7 @@ BUGZILLA = """{
def test_external_reference_bugzilla(): def test_external_reference_bugzilla():
ref = stix2.ExternalReference( ref = stix2.v21.ExternalReference(
source_name="ACME Bugzilla", source_name="ACME Bugzilla",
external_id="1370", external_id="1370",
url="https://www.example.com/bugs/1370", url="https://www.example.com/bugs/1370",
@ -103,7 +103,7 @@ OFFLINE = """{
def test_external_reference_offline(): def test_external_reference_offline():
ref = stix2.ExternalReference( ref = stix2.v21.ExternalReference(
source_name="ACME Threat Intel", source_name="ACME Threat Intel",
description="Threat report", description="Threat report",
) )
@ -116,7 +116,7 @@ def test_external_reference_offline():
def test_external_reference_source_required(): def test_external_reference_source_required():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.ExternalReference() stix2.v21.ExternalReference()
assert excinfo.value.cls == stix2.ExternalReference assert excinfo.value.cls == stix2.v21.ExternalReference
assert excinfo.value.properties == ["source_name"] assert excinfo.value.properties == ["source_name"]

View File

@ -1,4 +1,3 @@
import pytest import pytest
from stix2 import TLP_RED, Malware, markings from stix2 import TLP_RED, Malware, markings
@ -1065,4 +1064,4 @@ def test_clear_marking_bad_selector(data, selector):
def test_clear_marking_not_present(data): def test_clear_marking_not_present(data):
"""Test clearing markings for a selector that has no associated markings.""" """Test clearing markings for a selector that has no associated markings."""
with pytest.raises(MarkingNotFoundError): with pytest.raises(MarkingNotFoundError):
data = markings.clear_markings(data, ["labels"]) markings.clear_markings(data, ["labels"])

View File

@ -19,7 +19,7 @@ EXPECTED = """{
def test_identity_example(): def test_identity_example():
identity = stix2.Identity( identity = stix2.v21.Identity(
id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c",
created="2015-12-21T19:59:11.000Z", created="2015-12-21T19:59:11.000Z",
modified="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z",
@ -43,9 +43,10 @@ def test_identity_example():
}, },
]) ])
def test_parse_identity(data): def test_parse_identity(data):
identity = stix2.parse(data) identity = stix2.parse(data, version="2.1")
assert identity.type == 'identity' assert identity.type == 'identity'
assert identity.spec_version == '2.1'
assert identity.id == IDENTITY_ID assert identity.id == IDENTITY_ID
assert identity.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) assert identity.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc)
assert identity.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) assert identity.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc)
@ -61,11 +62,11 @@ def test_parse_no_type():
"modified": "2015-12-21T19:59:11.000Z", "modified": "2015-12-21T19:59:11.000Z",
"name": "John Smith", "name": "John Smith",
"identity_class": "individual" "identity_class": "individual"
}""") }""", version="2.1")
def test_identity_with_custom(): def test_identity_with_custom():
identity = stix2.Identity( identity = stix2.v21.Identity(
name="John Smith", name="John Smith",
identity_class="individual", identity_class="individual",
custom_properties={'x_foo': 'bar'} custom_properties={'x_foo': 'bar'}

View File

@ -37,7 +37,7 @@ def test_indicator_with_all_required_properties():
now = dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc) now = dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
epoch = dt.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc) epoch = dt.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
ind = stix2.Indicator( ind = stix2.v21.Indicator(
type="indicator", type="indicator",
id=INDICATOR_ID, id=INDICATOR_ID,
created=now, created=now,
@ -55,6 +55,7 @@ def test_indicator_with_all_required_properties():
def test_indicator_autogenerated_properties(indicator): def test_indicator_autogenerated_properties(indicator):
assert indicator.type == 'indicator' assert indicator.type == 'indicator'
assert indicator.spec_version == '2.1'
assert indicator.id == 'indicator--00000000-0000-0000-0000-000000000001' assert indicator.id == 'indicator--00000000-0000-0000-0000-000000000001'
assert indicator.created == FAKE_TIME assert indicator.created == FAKE_TIME
assert indicator.modified == FAKE_TIME assert indicator.modified == FAKE_TIME
@ -63,6 +64,7 @@ def test_indicator_autogenerated_properties(indicator):
assert indicator.valid_from == FAKE_TIME assert indicator.valid_from == FAKE_TIME
assert indicator['type'] == 'indicator' assert indicator['type'] == 'indicator'
assert indicator['spec_version'] == '2.1'
assert indicator['id'] == 'indicator--00000000-0000-0000-0000-000000000001' assert indicator['id'] == 'indicator--00000000-0000-0000-0000-000000000001'
assert indicator['created'] == FAKE_TIME assert indicator['created'] == FAKE_TIME
assert indicator['modified'] == FAKE_TIME assert indicator['modified'] == FAKE_TIME
@ -73,9 +75,9 @@ def test_indicator_autogenerated_properties(indicator):
def test_indicator_type_must_be_indicator(): def test_indicator_type_must_be_indicator():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Indicator(type='xxx', **INDICATOR_KWARGS) stix2.v21.Indicator(type='xxx', **INDICATOR_KWARGS)
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.prop_name == "type" assert excinfo.value.prop_name == "type"
assert excinfo.value.reason == "must equal 'indicator'." assert excinfo.value.reason == "must equal 'indicator'."
assert str(excinfo.value) == "Invalid value for Indicator 'type': must equal 'indicator'." assert str(excinfo.value) == "Invalid value for Indicator 'type': must equal 'indicator'."
@ -83,9 +85,9 @@ def test_indicator_type_must_be_indicator():
def test_indicator_id_must_start_with_indicator(): def test_indicator_id_must_start_with_indicator():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Indicator(id='my-prefix--', **INDICATOR_KWARGS) stix2.v21.Indicator(id='my-prefix--', **INDICATOR_KWARGS)
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.prop_name == "id" assert excinfo.value.prop_name == "id"
assert excinfo.value.reason == "must start with 'indicator--'." assert excinfo.value.reason == "must start with 'indicator--'."
assert str(excinfo.value) == "Invalid value for Indicator 'id': must start with 'indicator--'." assert str(excinfo.value) == "Invalid value for Indicator 'id': must start with 'indicator--'."
@ -93,26 +95,26 @@ def test_indicator_id_must_start_with_indicator():
def test_indicator_required_properties(): def test_indicator_required_properties():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Indicator() stix2.v21.Indicator()
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.properties == ["labels", "pattern"] assert excinfo.value.properties == ["labels", "pattern"]
assert str(excinfo.value) == "No values for required properties for Indicator: (labels, pattern)." assert str(excinfo.value) == "No values for required properties for Indicator: (labels, pattern)."
def test_indicator_required_property_pattern(): def test_indicator_required_property_pattern():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Indicator(labels=['malicious-activity']) stix2.v21.Indicator(labels=['malicious-activity'])
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.properties == ["pattern"] assert excinfo.value.properties == ["pattern"]
def test_indicator_created_ref_invalid_format(): def test_indicator_created_ref_invalid_format():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Indicator(created_by_ref='myprefix--12345678', **INDICATOR_KWARGS) stix2.v21.Indicator(created_by_ref='myprefix--12345678', **INDICATOR_KWARGS)
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.prop_name == "created_by_ref" assert excinfo.value.prop_name == "created_by_ref"
assert excinfo.value.reason == "must start with 'identity'." assert excinfo.value.reason == "must start with 'identity'."
assert str(excinfo.value) == "Invalid value for Indicator 'created_by_ref': must start with 'identity'." assert str(excinfo.value) == "Invalid value for Indicator 'created_by_ref': must start with 'identity'."
@ -120,9 +122,9 @@ def test_indicator_created_ref_invalid_format():
def test_indicator_revoked_invalid(): def test_indicator_revoked_invalid():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Indicator(revoked='no', **INDICATOR_KWARGS) stix2.v21.Indicator(revoked='no', **INDICATOR_KWARGS)
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.prop_name == "revoked" assert excinfo.value.prop_name == "revoked"
assert excinfo.value.reason == "must be a boolean value." assert excinfo.value.reason == "must be a boolean value."
@ -136,16 +138,16 @@ def test_cannot_assign_to_indicator_attributes(indicator):
def test_invalid_kwarg_to_indicator(): def test_invalid_kwarg_to_indicator():
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
stix2.Indicator(my_custom_property="foo", **INDICATOR_KWARGS) stix2.v21.Indicator(my_custom_property="foo", **INDICATOR_KWARGS)
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.properties == ['my_custom_property'] assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Indicator: (my_custom_property)." assert str(excinfo.value) == "Unexpected properties for Indicator: (my_custom_property)."
def test_created_modified_time_are_identical_by_default(): def test_created_modified_time_are_identical_by_default():
"""By default, the created and modified times should be the same.""" """By default, the created and modified times should be the same."""
ind = stix2.Indicator(**INDICATOR_KWARGS) ind = stix2.v21.Indicator(**INDICATOR_KWARGS)
assert ind.created == ind.modified assert ind.created == ind.modified
@ -165,9 +167,10 @@ def test_created_modified_time_are_identical_by_default():
}, },
]) ])
def test_parse_indicator(data): def test_parse_indicator(data):
idctr = stix2.parse(data) idctr = stix2.parse(data, version="2.1")
assert idctr.type == 'indicator' assert idctr.type == 'indicator'
assert idctr.spec_version == '2.1'
assert idctr.id == INDICATOR_ID assert idctr.id == INDICATOR_ID
assert idctr.created == dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc) assert idctr.created == dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
assert idctr.modified == dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc) assert idctr.modified == dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
@ -178,19 +181,19 @@ def test_parse_indicator(data):
def test_invalid_indicator_pattern(): def test_invalid_indicator_pattern():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Indicator( stix2.v21.Indicator(
labels=['malicious-activity'], labels=['malicious-activity'],
pattern="file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e'", pattern="file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e'",
) )
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.prop_name == 'pattern' assert excinfo.value.prop_name == 'pattern'
assert 'input is missing square brackets' in excinfo.value.reason assert 'input is missing square brackets' in excinfo.value.reason
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Indicator( stix2.v21.Indicator(
labels=['malicious-activity'], labels=['malicious-activity'],
pattern='[file:hashes.MD5 = "d41d8cd98f00b204e9800998ecf8427e"]', pattern='[file:hashes.MD5 = "d41d8cd98f00b204e9800998ecf8427e"]',
) )
assert excinfo.value.cls == stix2.Indicator assert excinfo.value.cls == stix2.v21.Indicator
assert excinfo.value.prop_name == 'pattern' assert excinfo.value.prop_name == 'pattern'
assert 'mismatched input' in excinfo.value.reason assert 'mismatched input' in excinfo.value.reason

View File

@ -28,7 +28,7 @@ EXPECTED = """{
def test_intrusion_set_example(): def test_intrusion_set_example():
intrusion_set = stix2.IntrusionSet( intrusion_set = stix2.v21.IntrusionSet(
id="intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", id="intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:48.000Z", created="2016-04-06T20:03:48.000Z",
@ -67,6 +67,7 @@ def test_parse_intrusion_set(data):
intset = stix2.parse(data) intset = stix2.parse(data)
assert intset.type == "intrusion-set" assert intset.type == "intrusion-set"
assert intset.spec_version == '2.1'
assert intset.id == INTRUSION_SET_ID assert intset.id == INTRUSION_SET_ID
assert intset.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert intset.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)
assert intset.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert intset.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)

View File

@ -11,7 +11,7 @@ LMCO_RECON = """{
def test_lockheed_martin_cyber_kill_chain(): def test_lockheed_martin_cyber_kill_chain():
recon = stix2.KillChainPhase( recon = stix2.v21.KillChainPhase(
kill_chain_name="lockheed-martin-cyber-kill-chain", kill_chain_name="lockheed-martin-cyber-kill-chain",
phase_name="reconnaissance", phase_name="reconnaissance",
) )
@ -26,7 +26,7 @@ FOO_PRE_ATTACK = """{
def test_kill_chain_example(): def test_kill_chain_example():
preattack = stix2.KillChainPhase( preattack = stix2.v21.KillChainPhase(
kill_chain_name="foo", kill_chain_name="foo",
phase_name="pre-attack", phase_name="pre-attack",
) )
@ -37,25 +37,25 @@ def test_kill_chain_example():
def test_kill_chain_required_properties(): def test_kill_chain_required_properties():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.KillChainPhase() stix2.v21.KillChainPhase()
assert excinfo.value.cls == stix2.KillChainPhase assert excinfo.value.cls == stix2.v21.KillChainPhase
assert excinfo.value.properties == ["kill_chain_name", "phase_name"] assert excinfo.value.properties == ["kill_chain_name", "phase_name"]
def test_kill_chain_required_property_chain_name(): def test_kill_chain_required_property_chain_name():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.KillChainPhase(phase_name="weaponization") stix2.v21.KillChainPhase(phase_name="weaponization")
assert excinfo.value.cls == stix2.KillChainPhase assert excinfo.value.cls == stix2.v21.KillChainPhase
assert excinfo.value.properties == ["kill_chain_name"] assert excinfo.value.properties == ["kill_chain_name"]
def test_kill_chain_required_property_phase_name(): def test_kill_chain_required_property_phase_name():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.KillChainPhase(kill_chain_name="lockheed-martin-cyber-kill-chain") stix2.v21.KillChainPhase(kill_chain_name="lockheed-martin-cyber-kill-chain")
assert excinfo.value.cls == stix2.KillChainPhase assert excinfo.value.cls == stix2.v21.KillChainPhase
assert excinfo.value.properties == ["phase_name"] assert excinfo.value.properties == ["phase_name"]

View File

@ -45,7 +45,7 @@ TEST_LANGUAGE_CONTENT = u"""{
def test_language_content_campaign(): def test_language_content_campaign():
now = dt.datetime(2017, 2, 8, 21, 31, 22, microsecond=7000, tzinfo=pytz.utc) now = dt.datetime(2017, 2, 8, 21, 31, 22, microsecond=7000, tzinfo=pytz.utc)
lc = stix2.LanguageContent( lc = stix2.v21.LanguageContent(
type='language-content', type='language-content',
id=LANGUAGE_CONTENT_ID, id=LANGUAGE_CONTENT_ID,
created=now, created=now,
@ -64,7 +64,7 @@ def test_language_content_campaign():
} }
) )
camp = stix2.parse(TEST_CAMPAIGN) camp = stix2.parse(TEST_CAMPAIGN, version='2.1')
# In order to provide the same representation, we need to disable escaping # In order to provide the same representation, we need to disable escaping
# in json.dumps(). https://docs.python.org/3/library/json.html#json.dumps # in json.dumps(). https://docs.python.org/3/library/json.html#json.dumps

View File

@ -49,7 +49,7 @@ EXPECTED_LOCATION_2_REPR = "Location(" + " ".join("""
def test_location_with_some_required_properties(): def test_location_with_some_required_properties():
now = dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) now = dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc)
loc = stix2.Location( loc = stix2.v21.Location(
type="location", type="location",
id=LOCATION_ID, id=LOCATION_ID,
created=now, created=now,
@ -75,9 +75,10 @@ def test_location_with_some_required_properties():
} }
]) ])
def test_parse_location(data): def test_parse_location(data):
location = stix2.parse(data) location = stix2.parse(data, version="2.1")
assert location.type == 'location' assert location.type == 'location'
assert location.spec_version == '2.1'
assert location.id == LOCATION_ID assert location.id == LOCATION_ID
assert location.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert location.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc)
assert location.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert location.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc)

View File

@ -25,7 +25,7 @@ EXPECTED_MALWARE = """{
def test_malware_with_all_required_properties(): def test_malware_with_all_required_properties():
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
mal = stix2.Malware( mal = stix2.v21.Malware(
type="malware", type="malware",
id=MALWARE_ID, id=MALWARE_ID,
created=now, created=now,
@ -56,9 +56,9 @@ def test_malware_autogenerated_properties(malware):
def test_malware_type_must_be_malware(): def test_malware_type_must_be_malware():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Malware(type='xxx', **MALWARE_KWARGS) stix2.v21.Malware(type='xxx', **MALWARE_KWARGS)
assert excinfo.value.cls == stix2.Malware assert excinfo.value.cls == stix2.v21.Malware
assert excinfo.value.prop_name == "type" assert excinfo.value.prop_name == "type"
assert excinfo.value.reason == "must equal 'malware'." assert excinfo.value.reason == "must equal 'malware'."
assert str(excinfo.value) == "Invalid value for Malware 'type': must equal 'malware'." assert str(excinfo.value) == "Invalid value for Malware 'type': must equal 'malware'."
@ -66,9 +66,9 @@ def test_malware_type_must_be_malware():
def test_malware_id_must_start_with_malware(): def test_malware_id_must_start_with_malware():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Malware(id='my-prefix--', **MALWARE_KWARGS) stix2.v21.Malware(id='my-prefix--', **MALWARE_KWARGS)
assert excinfo.value.cls == stix2.Malware assert excinfo.value.cls == stix2.v21.Malware
assert excinfo.value.prop_name == "id" assert excinfo.value.prop_name == "id"
assert excinfo.value.reason == "must start with 'malware--'." assert excinfo.value.reason == "must start with 'malware--'."
assert str(excinfo.value) == "Invalid value for Malware 'id': must start with 'malware--'." assert str(excinfo.value) == "Invalid value for Malware 'id': must start with 'malware--'."
@ -76,17 +76,17 @@ def test_malware_id_must_start_with_malware():
def test_malware_required_properties(): def test_malware_required_properties():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Malware() stix2.v21.Malware()
assert excinfo.value.cls == stix2.Malware assert excinfo.value.cls == stix2.v21.Malware
assert excinfo.value.properties == ["is_family", "labels", "name"] assert excinfo.value.properties == ["is_family", "labels", "name"]
def test_malware_required_property_name(): def test_malware_required_property_name():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Malware(labels=['ransomware'], is_family=False) stix2.v21.Malware(labels=['ransomware'], is_family=False)
assert excinfo.value.cls == stix2.Malware assert excinfo.value.cls == stix2.v21.Malware
assert excinfo.value.properties == ["name"] assert excinfo.value.properties == ["name"]
@ -99,9 +99,9 @@ def test_cannot_assign_to_malware_attributes(malware):
def test_invalid_kwarg_to_malware(): def test_invalid_kwarg_to_malware():
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
stix2.Malware(my_custom_property="foo", **MALWARE_KWARGS) stix2.v21.Malware(my_custom_property="foo", **MALWARE_KWARGS)
assert excinfo.value.cls == stix2.Malware assert excinfo.value.cls == stix2.v21.Malware
assert excinfo.value.properties == ['my_custom_property'] assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Malware: (my_custom_property)." assert str(excinfo.value) == "Unexpected properties for Malware: (my_custom_property)."
@ -120,9 +120,10 @@ def test_invalid_kwarg_to_malware():
}, },
]) ])
def test_parse_malware(data): def test_parse_malware(data):
mal = stix2.parse(data) mal = stix2.parse(data, version="2.1")
assert mal.type == 'malware' assert mal.type == 'malware'
assert mal.spec_version == '2.1'
assert mal.id == MALWARE_ID assert mal.id == MALWARE_ID
assert mal.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert mal.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
assert mal.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert mal.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
@ -133,7 +134,7 @@ def test_parse_malware(data):
def test_parse_malware_invalid_labels(): def test_parse_malware_invalid_labels():
data = re.compile('\\[.+\\]', re.DOTALL).sub('1', EXPECTED_MALWARE) data = re.compile('\\[.+\\]', re.DOTALL).sub('1', EXPECTED_MALWARE)
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
stix2.parse(data) stix2.parse(data, version="2.1")
assert "Invalid value for Malware 'labels'" in str(excinfo.value) assert "Invalid value for Malware 'labels'" in str(excinfo.value)
@ -146,7 +147,7 @@ def test_parse_malware_kill_chain_phases():
} }
]""" ]"""
data = EXPECTED_MALWARE.replace('malware"', 'malware",%s' % kill_chain) data = EXPECTED_MALWARE.replace('malware"', 'malware",%s' % kill_chain)
mal = stix2.parse(data) mal = stix2.parse(data, version="2.1")
assert mal.kill_chain_phases[0].kill_chain_name == "lockheed-martin-cyber-kill-chain" assert mal.kill_chain_phases[0].kill_chain_name == "lockheed-martin-cyber-kill-chain"
assert mal.kill_chain_phases[0].phase_name == "reconnaissance" assert mal.kill_chain_phases[0].phase_name == "reconnaissance"
assert mal['kill_chain_phases'][0]['kill_chain_name'] == "lockheed-martin-cyber-kill-chain" assert mal['kill_chain_phases'][0]['kill_chain_name'] == "lockheed-martin-cyber-kill-chain"
@ -162,5 +163,5 @@ def test_parse_malware_clean_kill_chain_phases():
} }
]""" ]"""
data = EXPECTED_MALWARE.replace('2.1"', '2.1",%s' % kill_chain) data = EXPECTED_MALWARE.replace('2.1"', '2.1",%s' % kill_chain)
mal = stix2.parse(data) mal = stix2.parse(data, version="2.1")
assert mal['kill_chain_phases'][0]['phase_name'] == "1" assert mal['kill_chain_phases'][0]['phase_name'] == "1"

View File

@ -79,7 +79,7 @@ def test_marking_def_example_with_tlp():
def test_marking_def_example_with_statement_positional_argument(): def test_marking_def_example_with_statement_positional_argument():
marking_definition = stix2.MarkingDefinition( marking_definition = stix2.v21.MarkingDefinition(
id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
created="2017-01-20T00:00:00.000Z", created="2017-01-20T00:00:00.000Z",
definition_type="statement", definition_type="statement",
@ -91,7 +91,7 @@ def test_marking_def_example_with_statement_positional_argument():
def test_marking_def_example_with_kwargs_statement(): def test_marking_def_example_with_kwargs_statement():
kwargs = dict(statement="Copyright 2016, Example Corp") kwargs = dict(statement="Copyright 2016, Example Corp")
marking_definition = stix2.MarkingDefinition( marking_definition = stix2.v21.MarkingDefinition(
id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
created="2017-01-20T00:00:00.000Z", created="2017-01-20T00:00:00.000Z",
definition_type="statement", definition_type="statement",
@ -103,7 +103,7 @@ def test_marking_def_example_with_kwargs_statement():
def test_marking_def_invalid_type(): def test_marking_def_invalid_type():
with pytest.raises(ValueError): with pytest.raises(ValueError):
stix2.MarkingDefinition( stix2.v21.MarkingDefinition(
id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
created="2017-01-20T00:00:00.000Z", created="2017-01-20T00:00:00.000Z",
definition_type="my-definition-type", definition_type="my-definition-type",
@ -112,7 +112,7 @@ def test_marking_def_invalid_type():
def test_campaign_with_markings_example(): def test_campaign_with_markings_example():
campaign = stix2.Campaign( campaign = stix2.v21.Campaign(
id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:00Z", created="2016-04-06T20:03:00Z",
@ -125,7 +125,7 @@ def test_campaign_with_markings_example():
def test_granular_example(): def test_granular_example():
granular_marking = stix2.GranularMarking( granular_marking = stix2.v21.GranularMarking(
marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"] selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"]
) )
@ -135,19 +135,19 @@ def test_granular_example():
def test_granular_example_with_bad_selector(): def test_granular_example_with_bad_selector():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.GranularMarking( stix2.v21.GranularMarking(
marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
selectors=["abc[0]"] # missing "." selectors=["abc[0]"] # missing "."
) )
assert excinfo.value.cls == stix2.GranularMarking assert excinfo.value.cls == stix2.v21.GranularMarking
assert excinfo.value.prop_name == "selectors" assert excinfo.value.prop_name == "selectors"
assert excinfo.value.reason == "must adhere to selector syntax." assert excinfo.value.reason == "must adhere to selector syntax."
assert str(excinfo.value) == "Invalid value for GranularMarking 'selectors': must adhere to selector syntax." assert str(excinfo.value) == "Invalid value for GranularMarking 'selectors': must adhere to selector syntax."
def test_campaign_with_granular_markings_example(): def test_campaign_with_granular_markings_example():
campaign = stix2.Campaign( campaign = stix2.v21.Campaign(
id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:00Z", created="2016-04-06T20:03:00Z",
@ -155,7 +155,7 @@ def test_campaign_with_granular_markings_example():
name="Green Group Attacks Against Finance", name="Green Group Attacks Against Finance",
description="Campaign by Green Group against a series of targets in the financial services sector.", description="Campaign by Green Group against a series of targets in the financial services sector.",
granular_markings=[ granular_markings=[
stix2.GranularMarking( stix2.v21.GranularMarking(
marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
selectors=["description"]) selectors=["description"])
]) ])
@ -175,9 +175,10 @@ def test_campaign_with_granular_markings_example():
}, },
]) ])
def test_parse_marking_definition(data): def test_parse_marking_definition(data):
gm = stix2.parse(data) gm = stix2.parse(data, version="2.1")
assert gm.type == 'marking-definition' assert gm.type == 'marking-definition'
assert gm.spec_version == '2.1'
assert gm.id == MARKING_DEFINITION_ID assert gm.id == MARKING_DEFINITION_ID
assert gm.created == dt.datetime(2017, 1, 20, 0, 0, 0, tzinfo=pytz.utc) assert gm.created == dt.datetime(2017, 1, 20, 0, 0, 0, tzinfo=pytz.utc)
assert gm.definition.tlp == "white" assert gm.definition.tlp == "white"
@ -185,8 +186,8 @@ def test_parse_marking_definition(data):
@stix2.common.CustomMarking('x-new-marking-type', [ @stix2.common.CustomMarking('x-new-marking-type', [
('property1', stix2.properties.StringProperty(required=True)), ('property1', stix2.v21.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()), ('property2', stix2.v21.properties.IntegerProperty()),
]) ])
class NewMarking(object): class NewMarking(object):
def __init__(self, property2=None, **kwargs): def __init__(self, property2=None, **kwargs):
@ -197,7 +198,7 @@ class NewMarking(object):
def test_registered_custom_marking(): def test_registered_custom_marking():
nm = NewMarking(property1='something', property2=55) nm = NewMarking(property1='something', property2=55)
marking_def = stix2.MarkingDefinition( marking_def = stix2.v21.MarkingDefinition(
id="marking-definition--00000000-0000-0000-0000-000000000012", id="marking-definition--00000000-0000-0000-0000-000000000012",
created="2017-01-22T00:00:00.000Z", created="2017-01-22T00:00:00.000Z",
definition_type="x-new-marking-type", definition_type="x-new-marking-type",
@ -223,8 +224,8 @@ def test_not_registered_marking_raises_exception():
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
# Used custom object on purpose to demonstrate a not-registered marking # Used custom object on purpose to demonstrate a not-registered marking
@stix2.sdo.CustomObject('x-new-marking-type2', [ @stix2.sdo.CustomObject('x-new-marking-type2', [
('property1', stix2.properties.StringProperty(required=True)), ('property1', stix2.v21.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()), ('property2', stix2.v21.properties.IntegerProperty()),
]) ])
class NewObject2(object): class NewObject2(object):
def __init__(self, property2=None, **kwargs): def __init__(self, property2=None, **kwargs):
@ -232,7 +233,7 @@ def test_not_registered_marking_raises_exception():
no = NewObject2(property1='something', property2=55) no = NewObject2(property1='something', property2=55)
stix2.MarkingDefinition( stix2.v21.MarkingDefinition(
id="marking-definition--00000000-0000-0000-0000-000000000012", id="marking-definition--00000000-0000-0000-0000-000000000012",
created="2017-01-22T00:00:00.000Z", created="2017-01-22T00:00:00.000Z",
definition_type="x-new-marking-type2", definition_type="x-new-marking-type2",
@ -253,7 +254,7 @@ def test_marking_wrong_type_construction():
def test_campaign_add_markings(): def test_campaign_add_markings():
campaign = stix2.Campaign( campaign = stix2.v21.Campaign(
id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:00Z", created="2016-04-06T20:03:00Z",

View File

@ -52,7 +52,7 @@ EXPECTED_OPINION_REPR = "Note(" + " ".join(("""
def test_note_with_required_properties(): def test_note_with_required_properties():
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
note = stix2.Note( note = stix2.v21.Note(
type='note', type='note',
id=NOTE_ID, id=NOTE_ID,
created=now, created=now,
@ -99,9 +99,10 @@ def test_note_with_required_properties():
} }
]) ])
def test_parse_note(data): def test_parse_note(data):
note = stix2.parse(data) note = stix2.parse(data, version="2.1")
assert note.type == 'note' assert note.type == 'note'
assert note.spec_version == '2.1'
assert note.id == NOTE_ID assert note.id == NOTE_ID
assert note.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert note.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
assert note.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert note.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)

View File

@ -1,4 +1,3 @@
import pytest import pytest
from stix2 import TLP_AMBER, Malware, exceptions, markings from stix2 import TLP_AMBER, Malware, exceptions, markings

View File

@ -31,7 +31,7 @@ EXPECTED = """{
def test_observed_data_example(): def test_observed_data_example():
observed_data = stix2.ObservedData( observed_data = stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -77,7 +77,7 @@ EXPECTED_WITH_REF = """{
def test_observed_data_example_with_refs(): def test_observed_data_example_with_refs():
observed_data = stix2.ObservedData( observed_data = stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -103,7 +103,7 @@ def test_observed_data_example_with_refs():
def test_observed_data_example_with_bad_refs(): def test_observed_data_example_with_bad_refs():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.ObservedData( stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -124,14 +124,14 @@ def test_observed_data_example_with_bad_refs():
}, },
) )
assert excinfo.value.cls == stix2.ObservedData assert excinfo.value.cls == stix2.v21.ObservedData
assert excinfo.value.prop_name == "objects" assert excinfo.value.prop_name == "objects"
assert excinfo.value.reason == "Invalid object reference for 'Directory:contains_refs': '2' is not a valid object in local scope" assert excinfo.value.reason == "Invalid object reference for 'Directory:contains_refs': '2' is not a valid object in local scope"
def test_observed_data_example_with_non_dictionary(): def test_observed_data_example_with_non_dictionary():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.ObservedData( stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -142,14 +142,14 @@ def test_observed_data_example_with_non_dictionary():
objects="file: foo.exe", objects="file: foo.exe",
) )
assert excinfo.value.cls == stix2.ObservedData assert excinfo.value.cls == stix2.v21.ObservedData
assert excinfo.value.prop_name == "objects" assert excinfo.value.prop_name == "objects"
assert 'must contain a dictionary' in excinfo.value.reason assert 'must contain a dictionary' in excinfo.value.reason
def test_observed_data_example_with_empty_dictionary(): def test_observed_data_example_with_empty_dictionary():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.ObservedData( stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -160,7 +160,7 @@ def test_observed_data_example_with_empty_dictionary():
objects={}, objects={},
) )
assert excinfo.value.cls == stix2.ObservedData assert excinfo.value.cls == stix2.v21.ObservedData
assert excinfo.value.prop_name == "objects" assert excinfo.value.prop_name == "objects"
assert 'must contain a non-empty dictionary' in excinfo.value.reason assert 'must contain a non-empty dictionary' in excinfo.value.reason
@ -186,9 +186,10 @@ def test_observed_data_example_with_empty_dictionary():
}, },
]) ])
def test_parse_observed_data(data): def test_parse_observed_data(data):
odata = stix2.parse(data) odata = stix2.parse(data, version="2.1")
assert odata.type == 'observed-data' assert odata.type == 'observed-data'
assert odata.spec_version == '2.1'
assert odata.id == OBSERVED_DATA_ID assert odata.id == OBSERVED_DATA_ID
assert odata.created == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc) assert odata.created == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc)
assert odata.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc) assert odata.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc)
@ -215,7 +216,7 @@ def test_parse_observed_data(data):
]) ])
def test_parse_artifact_valid(data): def test_parse_artifact_valid(data):
odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED) odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED)
odata = stix2.parse(odata_str) odata = stix2.parse(odata_str, version="2.1")
assert odata.objects["0"].type == "artifact" assert odata.objects["0"].type == "artifact"
@ -237,12 +238,12 @@ def test_parse_artifact_valid(data):
def test_parse_artifact_invalid(data): def test_parse_artifact_invalid(data):
odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED) odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED)
with pytest.raises(ValueError): with pytest.raises(ValueError):
stix2.parse(odata_str) stix2.parse(odata_str, version="2.1")
def test_artifact_example_dependency_error(): def test_artifact_example_dependency_error():
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
stix2.Artifact(url="http://example.com/sirvizio.exe") stix2.v21.Artifact(url="http://example.com/sirvizio.exe")
assert excinfo.value.dependencies == [("hashes", "url")] assert excinfo.value.dependencies == [("hashes", "url")]
assert str(excinfo.value) == "The property dependencies for Artifact: (hashes, url) are not met." assert str(excinfo.value) == "The property dependencies for Artifact: (hashes, url) are not met."
@ -258,7 +259,7 @@ def test_artifact_example_dependency_error():
]) ])
def test_parse_autonomous_system_valid(data): def test_parse_autonomous_system_valid(data):
odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED) odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED)
odata = stix2.parse(odata_str) odata = stix2.parse(odata_str, version="2.1")
assert odata.objects["0"].type == "autonomous-system" assert odata.objects["0"].type == "autonomous-system"
assert odata.objects["0"].number == 15139 assert odata.objects["0"].number == 15139
assert odata.objects["0"].name == "Slime Industries" assert odata.objects["0"].name == "Slime Industries"
@ -357,7 +358,7 @@ def test_parse_email_message_not_multipart(data):
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
stix2.parse_observable(data, valid_refs) stix2.parse_observable(data, valid_refs)
assert excinfo.value.cls == stix2.EmailMessage assert excinfo.value.cls == stix2.v21.EmailMessage
assert excinfo.value.dependencies == [("is_multipart", "body")] assert excinfo.value.dependencies == [("is_multipart", "body")]
@ -401,7 +402,7 @@ 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) odata = stix2.parse(odata_str, version="2.1")
assert odata.objects["3"].extensions['archive-ext'].version == "5.0" assert odata.objects["3"].extensions['archive-ext'].version == "5.0"
@ -456,7 +457,7 @@ def test_parse_email_message_with_at_least_one_error(data):
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
stix2.parse_observable(data, valid_refs) stix2.parse_observable(data, valid_refs)
assert excinfo.value.cls == stix2.EmailMIMEComponent assert excinfo.value.cls == stix2.v21.EmailMIMEComponent
assert excinfo.value.properties == ["body", "body_raw_ref"] assert excinfo.value.properties == ["body", "body_raw_ref"]
assert "At least one of the" in str(excinfo.value) assert "At least one of the" in str(excinfo.value)
assert "must be populated" in str(excinfo.value) assert "must be populated" in str(excinfo.value)
@ -505,7 +506,7 @@ def test_parse_basic_tcp_traffic_with_error(data):
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
stix2.parse_observable(data, {"4": "network-traffic"}) stix2.parse_observable(data, {"4": "network-traffic"})
assert excinfo.value.cls == stix2.NetworkTraffic assert excinfo.value.cls == stix2.v21.NetworkTraffic
assert excinfo.value.properties == ["dst_ref", "src_ref"] assert excinfo.value.properties == ["dst_ref", "src_ref"]
@ -535,12 +536,13 @@ EXPECTED_PROCESS_OD = """{
"binary_ref": "0" "binary_ref": "0"
} }
}, },
"spec_version": "2.1",
"type": "observed-data" "type": "observed-data"
}""" }"""
def test_observed_data_with_process_example(): def test_observed_data_with_process_example():
observed_data = stix2.ObservedData( observed_data = stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -578,11 +580,11 @@ def test_observed_data_with_process_example():
# creating cyber observables directly # creating cyber observables directly
def test_artifact_example(): def test_artifact_example():
art = stix2.Artifact(mime_type="image/jpeg", art = stix2.v21.Artifact(mime_type="image/jpeg",
url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg", url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg",
hashes={ hashes={
"MD5": "6826f9a05da08134006557758bb3afbb" "MD5": "6826f9a05da08134006557758bb3afbb"
}) })
assert art.mime_type == "image/jpeg" assert art.mime_type == "image/jpeg"
assert art.url == "https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg" assert art.url == "https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg"
assert art.hashes["MD5"] == "6826f9a05da08134006557758bb3afbb" assert art.hashes["MD5"] == "6826f9a05da08134006557758bb3afbb"
@ -590,25 +592,25 @@ def test_artifact_example():
def test_artifact_mutual_exclusion_error(): def test_artifact_mutual_exclusion_error():
with pytest.raises(stix2.exceptions.MutuallyExclusivePropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MutuallyExclusivePropertiesError) as excinfo:
stix2.Artifact(mime_type="image/jpeg", stix2.v21.Artifact(mime_type="image/jpeg",
url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg", url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg",
hashes={ hashes={
"MD5": "6826f9a05da08134006557758bb3afbb" "MD5": "6826f9a05da08134006557758bb3afbb"
}, },
payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==") payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==")
assert excinfo.value.cls == stix2.Artifact assert excinfo.value.cls == stix2.v21.Artifact
assert excinfo.value.properties == ["payload_bin", "url"] assert excinfo.value.properties == ["payload_bin", "url"]
assert 'are mutually exclusive' in str(excinfo.value) assert 'are mutually exclusive' in str(excinfo.value)
def test_directory_example(): def test_directory_example():
dir = stix2.Directory(_valid_refs={"1": "file"}, dir = stix2.v21.Directory(_valid_refs={"1": "file"},
path='/usr/lib', path='/usr/lib',
created="2015-12-21T19:00:00Z", created="2015-12-21T19:00:00Z",
modified="2015-12-24T19:00:00Z", modified="2015-12-24T19:00:00Z",
accessed="2015-12-21T20:00:00Z", accessed="2015-12-21T20:00:00Z",
contains_refs=["1"]) contains_refs=["1"])
assert dir.path == '/usr/lib' assert dir.path == '/usr/lib'
assert dir.created == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) assert dir.created == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc)
@ -619,21 +621,21 @@ def test_directory_example():
def test_directory_example_ref_error(): def test_directory_example_ref_error():
with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo: with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo:
stix2.Directory(_valid_refs=[], stix2.v21.Directory(_valid_refs=[],
path='/usr/lib', path='/usr/lib',
created="2015-12-21T19:00:00Z", created="2015-12-21T19:00:00Z",
modified="2015-12-24T19:00:00Z", modified="2015-12-24T19:00:00Z",
accessed="2015-12-21T20:00:00Z", accessed="2015-12-21T20:00:00Z",
contains_refs=["1"]) contains_refs=["1"])
assert excinfo.value.cls == stix2.Directory assert excinfo.value.cls == stix2.v21.Directory
assert excinfo.value.prop_name == "contains_refs" assert excinfo.value.prop_name == "contains_refs"
def test_domain_name_example(): def test_domain_name_example():
dn = stix2.DomainName(_valid_refs={"1": 'domain-name'}, dn = stix2.v21.DomainName(_valid_refs={"1": 'domain-name'},
value="example.com", value="example.com",
resolves_to_refs=["1"]) resolves_to_refs=["1"])
assert dn.value == "example.com" assert dn.value == "example.com"
assert dn.resolves_to_refs == ["1"] assert dn.resolves_to_refs == ["1"]
@ -641,28 +643,28 @@ def test_domain_name_example():
def test_domain_name_example_invalid_ref_type(): def test_domain_name_example_invalid_ref_type():
with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo: with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo:
stix2.DomainName(_valid_refs={"1": "file"}, stix2.v21.DomainName(_valid_refs={"1": "file"},
value="example.com", value="example.com",
resolves_to_refs=["1"]) resolves_to_refs=["1"])
assert excinfo.value.cls == stix2.DomainName assert excinfo.value.cls == stix2.v21.DomainName
assert excinfo.value.prop_name == "resolves_to_refs" assert excinfo.value.prop_name == "resolves_to_refs"
def test_file_example(): def test_file_example():
f = stix2.File(name="qwerty.dll", f = stix2.v21.File(name="qwerty.dll",
hashes={ hashes={
"SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a"}, "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a"},
size=100, size=100,
magic_number_hex="1C", magic_number_hex="1C",
mime_type="application/msword", mime_type="application/msword",
created="2016-12-21T19:00:00Z", created="2016-12-21T19:00:00Z",
modified="2016-12-24T19:00:00Z", modified="2016-12-24T19:00:00Z",
accessed="2016-12-21T20:00:00Z", accessed="2016-12-21T20:00:00Z",
is_encrypted=True, is_encrypted=True,
encryption_algorithm="AES128-CBC", encryption_algorithm="AES128-CBC",
decryption_key="fred" decryption_key="fred"
) )
assert f.name == "qwerty.dll" assert f.name == "qwerty.dll"
assert f.size == 100 assert f.size == 100
@ -678,17 +680,17 @@ def test_file_example():
def test_file_example_with_NTFSExt(): def test_file_example_with_NTFSExt():
f = stix2.File(name="abc.txt", f = stix2.v21.File(name="abc.txt",
extensions={ extensions={
"ntfs-ext": { "ntfs-ext": {
"alternate_data_streams": [ "alternate_data_streams": [
{ {
"name": "second.stream", "name": "second.stream",
"size": 25536 "size": 25536
} }
] ]
} }
}) })
assert f.name == "abc.txt" assert f.name == "abc.txt"
assert f.extensions["ntfs-ext"].alternate_data_streams[0].size == 25536 assert f.extensions["ntfs-ext"].alternate_data_streams[0].size == 25536
@ -696,32 +698,32 @@ def test_file_example_with_NTFSExt():
def test_file_example_with_empty_NTFSExt(): def test_file_example_with_empty_NTFSExt():
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
stix2.File(name="abc.txt", stix2.v21.File(name="abc.txt",
extensions={ extensions={
"ntfs-ext": { "ntfs-ext": {
} }
}) })
assert excinfo.value.cls == stix2.NTFSExt assert excinfo.value.cls == stix2.NTFSExt
assert excinfo.value.properties == sorted(list(stix2.NTFSExt._properties.keys())) assert excinfo.value.properties == sorted(list(stix2.NTFSExt._properties.keys()))
def test_file_example_with_PDFExt(): def test_file_example_with_PDFExt():
f = stix2.File(name="qwerty.dll", f = stix2.v21.File(name="qwerty.dll",
extensions={ extensions={
"pdf-ext": { "pdf-ext": {
"version": "1.7", "version": "1.7",
"document_info_dict": { "document_info_dict": {
"Title": "Sample document", "Title": "Sample document",
"Author": "Adobe Systems Incorporated", "Author": "Adobe Systems Incorporated",
"Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh",
"Producer": "Acrobat Distiller 3.01 for Power Macintosh", "Producer": "Acrobat Distiller 3.01 for Power Macintosh",
"CreationDate": "20070412090123-02" "CreationDate": "20070412090123-02"
}, },
"pdfid0": "DFCE52BD827ECF765649852119D", "pdfid0": "DFCE52BD827ECF765649852119D",
"pdfid1": "57A1E0F9ED2AE523E313C" "pdfid1": "57A1E0F9ED2AE523E313C"
} }
}) })
assert f.name == "qwerty.dll" assert f.name == "qwerty.dll"
assert f.extensions["pdf-ext"].version == "1.7" assert f.extensions["pdf-ext"].version == "1.7"
@ -729,21 +731,20 @@ def test_file_example_with_PDFExt():
def test_file_example_with_PDFExt_Object(): def test_file_example_with_PDFExt_Object():
f = stix2.File(name="qwerty.dll", f = stix2.v21.File(name="qwerty.dll",
extensions={ extensions={
"pdf-ext": "pdf-ext":
stix2.PDFExt(version="1.7", stix2.v21.PDFExt(version="1.7",
document_info_dict={ document_info_dict={
"Title": "Sample document", "Title": "Sample document",
"Author": "Adobe Systems Incorporated", "Author": "Adobe Systems Incorporated",
"Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh",
"Producer": "Acrobat Distiller 3.01 for Power Macintosh", "Producer": "Acrobat Distiller 3.01 for Power Macintosh",
"CreationDate": "20070412090123-02" "CreationDate": "20070412090123-02"
}, },
pdfid0="DFCE52BD827ECF765649852119D", pdfid0="DFCE52BD827ECF765649852119D",
pdfid1="57A1E0F9ED2AE523E313C") pdfid1="57A1E0F9ED2AE523E313C")
})
})
assert f.name == "qwerty.dll" assert f.name == "qwerty.dll"
assert f.extensions["pdf-ext"].version == "1.7" assert f.extensions["pdf-ext"].version == "1.7"
@ -751,18 +752,18 @@ def test_file_example_with_PDFExt_Object():
def test_file_example_with_RasterImageExt_Object(): def test_file_example_with_RasterImageExt_Object():
f = stix2.File(name="qwerty.jpeg", f = stix2.v21.File(name="qwerty.jpeg",
extensions={ extensions={
"raster-image-ext": { "raster-image-ext": {
"bits_per_pixel": 123, "bits_per_pixel": 123,
"exif_tags": { "exif_tags": {
"Make": "Nikon", "Make": "Nikon",
"Model": "D7000", "Model": "D7000",
"XResolution": 4928, "XResolution": 4928,
"YResolution": 3264 "YResolution": 3264
} }
} }
}) })
assert f.name == "qwerty.jpeg" assert f.name == "qwerty.jpeg"
assert f.extensions["raster-image-ext"].bits_per_pixel == 123 assert f.extensions["raster-image-ext"].bits_per_pixel == 123
assert f.extensions["raster-image-ext"].exif_tags["XResolution"] == 4928 assert f.extensions["raster-image-ext"].exif_tags["XResolution"] == 4928
@ -770,6 +771,7 @@ def test_file_example_with_RasterImageExt_Object():
RASTER_IMAGE_EXT = """{ RASTER_IMAGE_EXT = """{
"type": "observed-data", "type": "observed-data",
"spec_version": "2.1",
"id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
"created": "2016-04-06T19:58:16.000Z", "created": "2016-04-06T19:58:16.000Z",
"modified": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z",
@ -804,150 +806,148 @@ RASTER_IMAGE_EXT = """{
def test_raster_image_ext_parse(): def test_raster_image_ext_parse():
obj = stix2.parse(RASTER_IMAGE_EXT) obj = stix2.parse(RASTER_IMAGE_EXT, version="2.1")
assert obj.objects["0"].extensions['raster-image-ext'].image_width == 1024 assert obj.objects["0"].extensions['raster-image-ext'].image_width == 1024
def test_raster_images_ext_create(): def test_raster_images_ext_create():
ext = stix2.RasterImageExt(image_width=1024) ext = stix2.v21.RasterImageExt(image_width=1024)
assert "image_width" in str(ext) assert "image_width" in str(ext)
def test_file_example_with_WindowsPEBinaryExt(): def test_file_example_with_WindowsPEBinaryExt():
f = stix2.File(name="qwerty.dll", f = stix2.v21.File(name="qwerty.dll",
extensions={ extensions={
"windows-pebinary-ext": { "windows-pebinary-ext": {
"pe_type": "exe", "pe_type": "exe",
"machine_hex": "014c", "machine_hex": "014c",
"number_of_sections": 4, "number_of_sections": 4,
"time_date_stamp": "2016-01-22T12:31:12Z", "time_date_stamp": "2016-01-22T12:31:12Z",
"pointer_to_symbol_table_hex": "74726144", "pointer_to_symbol_table_hex": "74726144",
"number_of_symbols": 4542568, "number_of_symbols": 4542568,
"size_of_optional_header": 224, "size_of_optional_header": 224,
"characteristics_hex": "818f", "characteristics_hex": "818f",
"optional_header": { "optional_header": {
"magic_hex": "010b", "magic_hex": "010b",
"major_linker_version": 2, "major_linker_version": 2,
"minor_linker_version": 25, "minor_linker_version": 25,
"size_of_code": 512, "size_of_code": 512,
"size_of_initialized_data": 283648, "size_of_initialized_data": 283648,
"size_of_uninitialized_data": 0, "size_of_uninitialized_data": 0,
"address_of_entry_point": 4096, "address_of_entry_point": 4096,
"base_of_code": 4096, "base_of_code": 4096,
"base_of_data": 8192, "base_of_data": 8192,
"image_base": 14548992, "image_base": 14548992,
"section_alignment": 4096, "section_alignment": 4096,
"file_alignment": 4096, "file_alignment": 4096,
"major_os_version": 1, "major_os_version": 1,
"minor_os_version": 0, "minor_os_version": 0,
"major_image_version": 0, "major_image_version": 0,
"minor_image_version": 0, "minor_image_version": 0,
"major_subsystem_version": 4, "major_subsystem_version": 4,
"minor_subsystem_version": 0, "minor_subsystem_version": 0,
"win32_version_value_hex": "00", "win32_version_value_hex": "00",
"size_of_image": 299008, "size_of_image": 299008,
"size_of_headers": 4096, "size_of_headers": 4096,
"checksum_hex": "00", "checksum_hex": "00",
"subsystem_hex": "03", "subsystem_hex": "03",
"dll_characteristics_hex": "00", "dll_characteristics_hex": "00",
"size_of_stack_reserve": 100000, "size_of_stack_reserve": 100000,
"size_of_stack_commit": 8192, "size_of_stack_commit": 8192,
"size_of_heap_reserve": 100000, "size_of_heap_reserve": 100000,
"size_of_heap_commit": 4096, "size_of_heap_commit": 4096,
"loader_flags_hex": "abdbffde", "loader_flags_hex": "abdbffde",
"number_of_rva_and_sizes": 3758087646 "number_of_rva_and_sizes": 3758087646
}, },
"sections": [ "sections": [
{ {
"name": "CODE", "name": "CODE",
"entropy": 0.061089 "entropy": 0.061089
}, },
{ {
"name": "DATA", "name": "DATA",
"entropy": 7.980693 "entropy": 7.980693
}, },
{ {
"name": "NicolasB", "name": "NicolasB",
"entropy": 0.607433 "entropy": 0.607433
}, },
{ {
"name": ".idata", "name": ".idata",
"entropy": 0.607433 "entropy": 0.607433
} }
] ]
} }
})
})
assert f.name == "qwerty.dll" assert f.name == "qwerty.dll"
assert f.extensions["windows-pebinary-ext"].sections[2].entropy == 0.607433 assert f.extensions["windows-pebinary-ext"].sections[2].entropy == 0.607433
def test_file_example_encryption_error(): def test_file_example_encryption_error():
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
stix2.File(name="qwerty.dll", stix2.v21.File(name="qwerty.dll",
is_encrypted=False, is_encrypted=False,
encryption_algorithm="AES128-CBC") encryption_algorithm="AES128-CBC")
assert excinfo.value.cls == stix2.File assert excinfo.value.cls == stix2.v21.File
assert excinfo.value.dependencies == [("is_encrypted", "encryption_algorithm")] assert excinfo.value.dependencies == [("is_encrypted", "encryption_algorithm")]
assert "property dependencies" in str(excinfo.value) assert "property dependencies" in str(excinfo.value)
assert "are not met" in str(excinfo.value) assert "are not met" in str(excinfo.value)
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
stix2.File(name="qwerty.dll", stix2.v21.File(name="qwerty.dll", encryption_algorithm="AES128-CBC")
encryption_algorithm="AES128-CBC")
def test_ip4_address_example(): def test_ip4_address_example():
ip4 = stix2.IPv4Address(_valid_refs={"4": "mac-addr", "5": "mac-addr"}, ip4 = stix2.v21.IPv4Address(_valid_refs={"4": "mac-addr", "5": "mac-addr"},
value="198.51.100.3", value="198.51.100.3",
resolves_to_refs=["4", "5"]) resolves_to_refs=["4", "5"])
assert ip4.value == "198.51.100.3" assert ip4.value == "198.51.100.3"
assert ip4.resolves_to_refs == ["4", "5"] assert ip4.resolves_to_refs == ["4", "5"]
def test_ip4_address_example_cidr(): def test_ip4_address_example_cidr():
ip4 = stix2.IPv4Address(value="198.51.100.0/24") ip4 = stix2.v21.IPv4Address(value="198.51.100.0/24")
assert ip4.value == "198.51.100.0/24" assert ip4.value == "198.51.100.0/24"
def test_ip6_address_example(): def test_ip6_address_example():
ip6 = stix2.IPv6Address(value="2001:0db8:85a3:0000:0000:8a2e:0370:7334") ip6 = stix2.v21.IPv6Address(value="2001:0db8:85a3:0000:0000:8a2e:0370:7334")
assert ip6.value == "2001:0db8:85a3:0000:0000:8a2e:0370:7334" assert ip6.value == "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
def test_mac_address_example(): def test_mac_address_example():
ip6 = stix2.MACAddress(value="d2:fb:49:24:37:18") ip6 = stix2.v21.MACAddress(value="d2:fb:49:24:37:18")
assert ip6.value == "d2:fb:49:24:37:18" assert ip6.value == "d2:fb:49:24:37:18"
def test_network_traffic_example(): def test_network_traffic_example():
nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr", "1": "ipv4-addr"}, nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr", "1": "ipv4-addr"},
protocols="tcp", protocols="tcp",
src_ref="0", src_ref="0",
dst_ref="1") dst_ref="1")
assert nt.protocols == ["tcp"] assert nt.protocols == ["tcp"]
assert nt.src_ref == "0" assert nt.src_ref == "0"
assert nt.dst_ref == "1" assert nt.dst_ref == "1"
def test_network_traffic_http_request_example(): def test_network_traffic_http_request_example():
h = stix2.HTTPRequestExt(request_method="get", h = stix2.v21.HTTPRequestExt(request_method="get",
request_value="/download.html", request_value="/download.html",
request_version="http/1.1", request_version="http/1.1",
request_header={ request_header={
"Accept-Encoding": "gzip,deflate", "Accept-Encoding": "gzip,deflate",
"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113", "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113",
"Host": "www.example.com" "Host": "www.example.com"
}) })
nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"},
protocols="tcp", protocols="tcp",
src_ref="0", src_ref="0",
extensions={'http-request-ext': h}) extensions={'http-request-ext': h})
assert nt.extensions['http-request-ext'].request_method == "get" assert nt.extensions['http-request-ext'].request_method == "get"
assert nt.extensions['http-request-ext'].request_value == "/download.html" assert nt.extensions['http-request-ext'].request_value == "/download.html"
assert nt.extensions['http-request-ext'].request_version == "http/1.1" assert nt.extensions['http-request-ext'].request_version == "http/1.1"
@ -957,25 +957,25 @@ def test_network_traffic_http_request_example():
def test_network_traffic_icmp_example(): def test_network_traffic_icmp_example():
h = stix2.ICMPExt(icmp_type_hex="08", h = stix2.v21.ICMPExt(icmp_type_hex="08",
icmp_code_hex="00") icmp_code_hex="00")
nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"},
protocols="tcp", protocols="tcp",
src_ref="0", src_ref="0",
extensions={'icmp-ext': h}) extensions={'icmp-ext': h})
assert nt.extensions['icmp-ext'].icmp_type_hex == "08" assert nt.extensions['icmp-ext'].icmp_type_hex == "08"
assert nt.extensions['icmp-ext'].icmp_code_hex == "00" assert nt.extensions['icmp-ext'].icmp_code_hex == "00"
def test_network_traffic_socket_example(): def test_network_traffic_socket_example():
h = stix2.SocketExt(is_listening=True, h = stix2.v21.SocketExt(is_listening=True,
address_family="AF_INET", address_family="AF_INET",
protocol_family="PF_INET", protocol_family="PF_INET",
socket_type="SOCK_STREAM") socket_type="SOCK_STREAM")
nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"},
protocols="tcp", protocols="tcp",
src_ref="0", src_ref="0",
extensions={'socket-ext': h}) extensions={'socket-ext': h})
assert nt.extensions['socket-ext'].is_listening assert nt.extensions['socket-ext'].is_listening
assert nt.extensions['socket-ext'].address_family == "AF_INET" assert nt.extensions['socket-ext'].address_family == "AF_INET"
assert nt.extensions['socket-ext'].protocol_family == "PF_INET" assert nt.extensions['socket-ext'].protocol_family == "PF_INET"
@ -983,27 +983,27 @@ def test_network_traffic_socket_example():
def test_network_traffic_tcp_example(): def test_network_traffic_tcp_example():
h = stix2.TCPExt(src_flags_hex="00000002") h = stix2.v21.TCPExt(src_flags_hex="00000002")
nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"},
protocols="tcp", protocols="tcp",
src_ref="0", src_ref="0",
extensions={'tcp-ext': h}) extensions={'tcp-ext': h})
assert nt.extensions['tcp-ext'].src_flags_hex == "00000002" assert nt.extensions['tcp-ext'].src_flags_hex == "00000002"
def test_mutex_example(): def test_mutex_example():
m = stix2.Mutex(name="barney") m = stix2.v21.Mutex(name="barney")
assert m.name == "barney" assert m.name == "barney"
def test_process_example(): def test_process_example():
p = stix2.Process(_valid_refs={"0": "file"}, p = stix2.v21.Process(_valid_refs={"0": "file"},
pid=1221, pid=1221,
name="gedit-bin", name="gedit-bin",
created="2016-01-20T14:11:25.55Z", created="2016-01-20T14:11:25.55Z",
arguments=["--new-window"], arguments=["--new-window"],
binary_ref="0") binary_ref="0")
assert p.name == "gedit-bin" assert p.name == "gedit-bin"
assert p.arguments == ["--new-window"] assert p.arguments == ["--new-window"]
@ -1011,40 +1011,40 @@ def test_process_example():
def test_process_example_empty_error(): def test_process_example_empty_error():
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
stix2.Process() stix2.v21.Process()
assert excinfo.value.cls == stix2.Process assert excinfo.value.cls == stix2.v21.Process
properties_of_process = list(stix2.Process._properties.keys()) properties_of_process = list(stix2.v21.Process._properties.keys())
properties_of_process.remove("type") properties_of_process.remove("type")
assert excinfo.value.properties == sorted(properties_of_process) assert excinfo.value.properties == sorted(properties_of_process)
msg = "At least one of the ({1}) properties for {0} must be populated." msg = "At least one of the ({1}) properties for {0} must be populated."
msg = msg.format(stix2.Process.__name__, msg = msg.format(stix2.v21.Process.__name__,
", ".join(sorted(properties_of_process))) ", ".join(sorted(properties_of_process)))
assert str(excinfo.value) == msg assert str(excinfo.value) == msg
def test_process_example_empty_with_extensions(): def test_process_example_empty_with_extensions():
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
stix2.Process(extensions={ stix2.v21.Process(extensions={
"windows-process-ext": {} "windows-process-ext": {}
}) })
assert excinfo.value.cls == stix2.WindowsProcessExt assert excinfo.value.cls == stix2.v21.WindowsProcessExt
properties_of_extension = list(stix2.WindowsProcessExt._properties.keys()) properties_of_extension = list(stix2.v21.WindowsProcessExt._properties.keys())
assert excinfo.value.properties == sorted(properties_of_extension) assert excinfo.value.properties == sorted(properties_of_extension)
def test_process_example_windows_process_ext(): def test_process_example_windows_process_ext():
proc = stix2.Process(pid=314, proc = stix2.v21.Process(pid=314,
name="foobar.exe", name="foobar.exe",
extensions={ extensions={
"windows-process-ext": { "windows-process-ext": {
"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"
} }
}) })
assert proc.extensions["windows-process-ext"].aslr_enabled assert proc.extensions["windows-process-ext"].aslr_enabled
assert proc.extensions["windows-process-ext"].dep_enabled assert proc.extensions["windows-process-ext"].dep_enabled
assert proc.extensions["windows-process-ext"].priority == "HIGH_PRIORITY_CLASS" assert proc.extensions["windows-process-ext"].priority == "HIGH_PRIORITY_CLASS"
@ -1053,40 +1053,40 @@ def test_process_example_windows_process_ext():
def test_process_example_windows_process_ext_empty(): def test_process_example_windows_process_ext_empty():
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
stix2.Process(pid=1221, stix2.v21.Process(pid=1221,
name="gedit-bin", name="gedit-bin",
extensions={ extensions={
"windows-process-ext": {} "windows-process-ext": {}
}) })
assert excinfo.value.cls == stix2.WindowsProcessExt assert excinfo.value.cls == stix2.v21.WindowsProcessExt
properties_of_extension = list(stix2.WindowsProcessExt._properties.keys()) properties_of_extension = list(stix2.v21.WindowsProcessExt._properties.keys())
assert excinfo.value.properties == sorted(properties_of_extension) assert excinfo.value.properties == sorted(properties_of_extension)
def test_process_example_extensions_empty(): def test_process_example_extensions_empty():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Process(extensions={}) stix2.v21.Process(extensions={})
assert excinfo.value.cls == stix2.Process assert excinfo.value.cls == stix2.v21.Process
assert excinfo.value.prop_name == 'extensions' assert excinfo.value.prop_name == 'extensions'
assert 'non-empty dictionary' in excinfo.value.reason assert 'non-empty dictionary' in excinfo.value.reason
def test_process_example_with_WindowsProcessExt_Object(): def test_process_example_with_WindowsProcessExt_Object():
p = stix2.Process(extensions={ p = stix2.v21.Process(extensions={
"windows-process-ext": stix2.WindowsProcessExt(aslr_enabled=True, "windows-process-ext": stix2.v21.WindowsProcessExt(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") # noqa owner_sid="S-1-5-21-186985262-1144665072-74031268-1309") # 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.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",
@ -1101,7 +1101,7 @@ def test_process_example_with_WindowsServiceExt():
def test_process_example_with_WindowsProcessServiceExt(): def test_process_example_with_WindowsProcessServiceExt():
p = stix2.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",
@ -1124,10 +1124,10 @@ def test_process_example_with_WindowsProcessServiceExt():
def test_software_example(): def test_software_example():
s = stix2.Software(name="Word", s = stix2.v21.Software(name="Word",
cpe="cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*", cpe="cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*",
version="2002", version="2002",
vendor="Microsoft") vendor="Microsoft")
assert s.name == "Word" assert s.name == "Word"
assert s.cpe == "cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*" assert s.cpe == "cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*"
@ -1136,24 +1136,24 @@ def test_software_example():
def test_url_example(): def test_url_example():
s = stix2.URL(value="https://example.com/research/index.html") s = stix2.v21.URL(value="https://example.com/research/index.html")
assert s.type == "url" assert s.type == "url"
assert s.value == "https://example.com/research/index.html" assert s.value == "https://example.com/research/index.html"
def test_user_account_example(): def test_user_account_example():
a = stix2.UserAccount(user_id="1001", a = stix2.v21.UserAccount(user_id="1001",
account_login="jdoe", account_login="jdoe",
account_type="unix", account_type="unix",
display_name="John Doe", display_name="John Doe",
is_service_account=False, is_service_account=False,
is_privileged=False, is_privileged=False,
can_escalate_privs=True, can_escalate_privs=True,
account_created="2016-01-20T12:31:12Z", account_created="2016-01-20T12:31:12Z",
password_last_changed="2016-01-20T14:27:43Z", password_last_changed="2016-01-20T14:27:43Z",
account_first_login="2016-01-20T14:26:07Z", account_first_login="2016-01-20T14:26:07Z",
account_last_login="2016-07-22T16:08:28Z") account_last_login="2016-07-22T16:08:28Z")
assert a.user_id == "1001" assert a.user_id == "1001"
assert a.account_login == "jdoe" assert a.account_login == "jdoe"
@ -1169,11 +1169,11 @@ def test_user_account_example():
def test_user_account_unix_account_ext_example(): def test_user_account_unix_account_ext_example():
u = stix2.UNIXAccountExt(gid=1001, u = stix2.v21.UNIXAccountExt(gid=1001,
groups=["wheel"], groups=["wheel"],
home_dir="/home/jdoe", home_dir="/home/jdoe",
shell="/bin/bash") shell="/bin/bash")
a = stix2.UserAccount(user_id="1001", a = stix2.v21.UserAccount(user_id="1001",
account_login="jdoe", account_login="jdoe",
account_type="unix", account_type="unix",
extensions={'unix-account-ext': u}) extensions={'unix-account-ext': u})
@ -1185,14 +1185,14 @@ def test_user_account_unix_account_ext_example():
def test_windows_registry_key_example(): def test_windows_registry_key_example():
with pytest.raises(ValueError): with pytest.raises(ValueError):
v = stix2.WindowsRegistryValueType(name="Foo", stix2.v21.WindowsRegistryValueType(name="Foo",
data="qwerty", data="qwerty",
data_type="string") data_type="string")
v = stix2.WindowsRegistryValueType(name="Foo", v = stix2.v21.WindowsRegistryValueType(name="Foo",
data="qwerty", data="qwerty",
data_type="REG_SZ") data_type="REG_SZ")
w = stix2.WindowsRegistryKey(key="hkey_local_machine\\system\\bar\\foo", w = stix2.v21.WindowsRegistryKey(key="hkey_local_machine\\system\\bar\\foo",
values=[v]) values=[v])
assert w.key == "hkey_local_machine\\system\\bar\\foo" assert w.key == "hkey_local_machine\\system\\bar\\foo"
assert w.values[0].name == "Foo" assert w.values[0].name == "Foo"
@ -1201,7 +1201,7 @@ def test_windows_registry_key_example():
def test_x509_certificate_example(): def test_x509_certificate_example():
x509 = stix2.X509Certificate( x509 = stix2.v21.X509Certificate(
issuer="C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com", # noqa issuer="C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com", # noqa
validity_not_before="2016-03-12T12:00:00Z", validity_not_before="2016-03-12T12:00:00Z",
validity_not_after="2016-08-21T12:00:00Z", validity_not_after="2016-08-21T12:00:00Z",
@ -1213,7 +1213,7 @@ def test_x509_certificate_example():
def test_new_version_with_related_objects(): def test_new_version_with_related_objects():
data = stix2.ObservedData( data = stix2.v21.ObservedData(
first_observed="2016-03-12T12:00:00Z", first_observed="2016-03-12T12:00:00Z",
last_observed="2016-03-12T12:00:00Z", last_observed="2016-03-12T12:00:00Z",
number_observed=1, number_observed=1,

View File

@ -41,7 +41,7 @@ EXPECTED_OPINION_REPR = "Opinion(" + " ".join(("""
def test_opinion_with_required_properties(): def test_opinion_with_required_properties():
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
opi = stix2.Opinion( opi = stix2.v21.Opinion(
type='opinion', type='opinion',
id=OPINION_ID, id=OPINION_ID,
created=now, created=now,
@ -72,9 +72,10 @@ def test_opinion_with_required_properties():
} }
]) ])
def test_parse_opinion(data): def test_parse_opinion(data):
opinion = stix2.parse(data) opinion = stix2.parse(data, version="2.1")
assert opinion.type == 'opinion' assert opinion.type == 'opinion'
assert opinion.spec_version == '2.1'
assert opinion.id == OPINION_ID assert opinion.id == OPINION_ID
assert opinion.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert opinion.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
assert opinion.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert opinion.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)

View File

@ -7,7 +7,7 @@ def test_pickling():
""" """
Ensure a pickle/unpickle cycle works okay. Ensure a pickle/unpickle cycle works okay.
""" """
identity = stix2.Identity( identity = stix2.v21.Identity(
id="identity--d66cb89d-5228-4983-958c-fa84ef75c88c", id="identity--d66cb89d-5228-4983-958c-fa84ef75c88c",
name="alice", name="alice",
description="this is a pickle test", description="this is a pickle test",

View File

@ -2,7 +2,7 @@ import pytest
from stix2 import CustomObject, EmailMIMEComponent, ExtensionsProperty, TCPExt from stix2 import CustomObject, EmailMIMEComponent, ExtensionsProperty, TCPExt
from stix2.exceptions import AtLeastOnePropertyError, DictionaryKeyError from stix2.exceptions import AtLeastOnePropertyError, DictionaryKeyError
from stix2.v20.properties import (BinaryProperty, BooleanProperty, from stix2.v21.properties import (BinaryProperty, BooleanProperty,
DictionaryProperty, EmbeddedObjectProperty, DictionaryProperty, EmbeddedObjectProperty,
EnumProperty, FloatProperty, HashesProperty, EnumProperty, FloatProperty, HashesProperty,
HexProperty, IDProperty, IntegerProperty, HexProperty, IDProperty, IntegerProperty,
@ -230,11 +230,22 @@ def test_dictionary_property_valid(d):
@pytest.mark.parametrize("d", [ @pytest.mark.parametrize("d", [
[{'a': 'something'}, "Invalid dictionary key a: (shorter than 3 characters)."], [{'a': 'something'}, "Invalid dictionary key a: (shorter than 3 characters)."],
])
def test_dictionary_no_longer_raises(d):
dict_prop = DictionaryProperty()
try:
dict_prop.clean(d[0])
except DictionaryKeyError:
pytest.fail("Unexpected DictionaryKeyError...")
@pytest.mark.parametrize("d", [
[{'a'*300: 'something'}, "Invalid dictionary key aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" [{'a'*300: 'something'}, "Invalid dictionary key aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaa: (longer than 256 characters)."], "aaaaaaaaaaaaaaaaaaaaaaa: (longer than 250 characters)."],
[{'Hey!': 'something'}, "Invalid dictionary key Hey!: (contains characters other thanlowercase a-z, " [{'Hey!': 'something'}, "Invalid dictionary key Hey!: (contains characters other thanlowercase a-z, "
"uppercase A-Z, numerals 0-9, hyphen (-), or underscore (_))."], "uppercase A-Z, numerals 0-9, hyphen (-), or underscore (_))."],
]) ])

View File

@ -23,7 +23,7 @@ EXPECTED_RELATIONSHIP = """{
def test_relationship_all_required_properties(): def test_relationship_all_required_properties():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
rel = stix2.Relationship( rel = stix2.v21.Relationship(
type='relationship', type='relationship',
id=RELATIONSHIP_ID, id=RELATIONSHIP_ID,
created=now, created=now,
@ -37,6 +37,7 @@ def test_relationship_all_required_properties():
def test_relationship_autogenerated_properties(relationship): def test_relationship_autogenerated_properties(relationship):
assert relationship.type == 'relationship' assert relationship.type == 'relationship'
assert relationship.spec_version == '2.1'
assert relationship.id == 'relationship--00000000-0000-0000-0000-000000000001' assert relationship.id == 'relationship--00000000-0000-0000-0000-000000000001'
assert relationship.created == FAKE_TIME assert relationship.created == FAKE_TIME
assert relationship.modified == FAKE_TIME assert relationship.modified == FAKE_TIME
@ -45,6 +46,7 @@ def test_relationship_autogenerated_properties(relationship):
assert relationship.target_ref == MALWARE_ID assert relationship.target_ref == MALWARE_ID
assert relationship['type'] == 'relationship' assert relationship['type'] == 'relationship'
assert relationship['spec_version'] == '2.1'
assert relationship['id'] == 'relationship--00000000-0000-0000-0000-000000000001' assert relationship['id'] == 'relationship--00000000-0000-0000-0000-000000000001'
assert relationship['created'] == FAKE_TIME assert relationship['created'] == FAKE_TIME
assert relationship['modified'] == FAKE_TIME assert relationship['modified'] == FAKE_TIME
@ -55,9 +57,9 @@ def test_relationship_autogenerated_properties(relationship):
def test_relationship_type_must_be_relationship(): def test_relationship_type_must_be_relationship():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Relationship(type='xxx', **RELATIONSHIP_KWARGS) stix2.v21.Relationship(type='xxx', **RELATIONSHIP_KWARGS)
assert excinfo.value.cls == stix2.Relationship assert excinfo.value.cls == stix2.v21.Relationship
assert excinfo.value.prop_name == "type" assert excinfo.value.prop_name == "type"
assert excinfo.value.reason == "must equal 'relationship'." assert excinfo.value.reason == "must equal 'relationship'."
assert str(excinfo.value) == "Invalid value for Relationship 'type': must equal 'relationship'." assert str(excinfo.value) == "Invalid value for Relationship 'type': must equal 'relationship'."
@ -65,9 +67,9 @@ def test_relationship_type_must_be_relationship():
def test_relationship_id_must_start_with_relationship(): def test_relationship_id_must_start_with_relationship():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Relationship(id='my-prefix--', **RELATIONSHIP_KWARGS) stix2.v21.Relationship(id='my-prefix--', **RELATIONSHIP_KWARGS)
assert excinfo.value.cls == stix2.Relationship assert excinfo.value.cls == stix2.v21.Relationship
assert excinfo.value.prop_name == "id" assert excinfo.value.prop_name == "id"
assert excinfo.value.reason == "must start with 'relationship--'." assert excinfo.value.reason == "must start with 'relationship--'."
assert str(excinfo.value) == "Invalid value for Relationship 'id': must start with 'relationship--'." assert str(excinfo.value) == "Invalid value for Relationship 'id': must start with 'relationship--'."
@ -75,27 +77,27 @@ def test_relationship_id_must_start_with_relationship():
def test_relationship_required_property_relationship_type(): def test_relationship_required_property_relationship_type():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Relationship() stix2.v21.Relationship()
assert excinfo.value.cls == stix2.Relationship assert excinfo.value.cls == stix2.v21.Relationship
assert excinfo.value.properties == ["relationship_type", "source_ref", "target_ref"] assert excinfo.value.properties == ["relationship_type", "source_ref", "target_ref"]
def test_relationship_missing_some_required_properties(): def test_relationship_missing_some_required_properties():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Relationship(relationship_type='indicates') stix2.v21.Relationship(relationship_type='indicates')
assert excinfo.value.cls == stix2.Relationship assert excinfo.value.cls == stix2.v21.Relationship
assert excinfo.value.properties == ["source_ref", "target_ref"] assert excinfo.value.properties == ["source_ref", "target_ref"]
def test_relationship_required_properties_target_ref(): def test_relationship_required_properties_target_ref():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
stix2.Relationship( stix2.v21.Relationship(
relationship_type='indicates', relationship_type='indicates',
source_ref=INDICATOR_ID source_ref=INDICATOR_ID
) )
assert excinfo.value.cls == stix2.Relationship assert excinfo.value.cls == stix2.v21.Relationship
assert excinfo.value.properties == ["target_ref"] assert excinfo.value.properties == ["target_ref"]
@ -108,15 +110,15 @@ def test_cannot_assign_to_relationship_attributes(relationship):
def test_invalid_kwarg_to_relationship(): def test_invalid_kwarg_to_relationship():
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
stix2.Relationship(my_custom_property="foo", **RELATIONSHIP_KWARGS) stix2.v21.Relationship(my_custom_property="foo", **RELATIONSHIP_KWARGS)
assert excinfo.value.cls == stix2.Relationship assert excinfo.value.cls == stix2.v21.Relationship
assert excinfo.value.properties == ['my_custom_property'] assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Relationship: (my_custom_property)." assert str(excinfo.value) == "Unexpected properties for Relationship: (my_custom_property)."
def test_create_relationship_from_objects_rather_than_ids(indicator, malware): def test_create_relationship_from_objects_rather_than_ids(indicator, malware):
rel = stix2.Relationship( rel = stix2.v21.Relationship(
relationship_type="indicates", relationship_type="indicates",
source_ref=indicator, source_ref=indicator,
target_ref=malware, target_ref=malware,
@ -129,7 +131,7 @@ def test_create_relationship_from_objects_rather_than_ids(indicator, malware):
def test_create_relationship_with_positional_args(indicator, malware): def test_create_relationship_with_positional_args(indicator, malware):
rel = stix2.Relationship(indicator, 'indicates', malware) rel = stix2.v21.Relationship(indicator, 'indicates', malware)
assert rel.relationship_type == 'indicates' assert rel.relationship_type == 'indicates'
assert rel.source_ref == 'indicator--00000000-0000-0000-0000-000000000001' assert rel.source_ref == 'indicator--00000000-0000-0000-0000-000000000001'
@ -151,9 +153,10 @@ def test_create_relationship_with_positional_args(indicator, malware):
}, },
]) ])
def test_parse_relationship(data): def test_parse_relationship(data):
rel = stix2.parse(data) rel = stix2.parse(data, version="2.1")
assert rel.type == 'relationship' assert rel.type == 'relationship'
assert rel.spec_version == '2.1'
assert rel.id == RELATIONSHIP_ID assert rel.id == RELATIONSHIP_ID
assert rel.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert rel.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
assert rel.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert rel.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)

View File

@ -29,7 +29,7 @@ EXPECTED = """{
def test_report_example(): def test_report_example():
report = stix2.Report( report = stix2.v21.Report(
id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3",
created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283",
created="2015-12-21T19:59:11.000Z", created="2015-12-21T19:59:11.000Z",
@ -49,7 +49,7 @@ def test_report_example():
def test_report_example_objects_in_object_refs(): def test_report_example_objects_in_object_refs():
report = stix2.Report( report = stix2.v21.Report(
id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3",
created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283",
created="2015-12-21T19:59:11.000Z", created="2015-12-21T19:59:11.000Z",
@ -59,7 +59,7 @@ def test_report_example_objects_in_object_refs():
published="2016-01-20T17:00:00Z", published="2016-01-20T17:00:00Z",
labels=["campaign"], labels=["campaign"],
object_refs=[ object_refs=[
stix2.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), stix2.v21.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS),
"campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c",
"relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a" "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a"
], ],
@ -70,7 +70,7 @@ def test_report_example_objects_in_object_refs():
def test_report_example_objects_in_object_refs_with_bad_id(): def test_report_example_objects_in_object_refs_with_bad_id():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Report( stix2.v21.Report(
id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3",
created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283",
created="2015-12-21T19:59:11.000Z", created="2015-12-21T19:59:11.000Z",
@ -80,13 +80,13 @@ def test_report_example_objects_in_object_refs_with_bad_id():
published="2016-01-20T17:00:00Z", published="2016-01-20T17:00:00Z",
labels=["campaign"], labels=["campaign"],
object_refs=[ object_refs=[
stix2.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), stix2.v21.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS),
"campaign-83422c77-904c-4dc1-aff5-5c38f3a2c55c", # the "bad" id, missing a "-" "campaign-83422c77-904c-4dc1-aff5-5c38f3a2c55c", # the "bad" id, missing a "-"
"relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a" "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a"
], ],
) )
assert excinfo.value.cls == stix2.Report assert excinfo.value.cls == stix2.v21.Report
assert excinfo.value.prop_name == "object_refs" assert excinfo.value.prop_name == "object_refs"
assert excinfo.value.reason == "must match <object-type>--<guid>." assert excinfo.value.reason == "must match <object-type>--<guid>."
assert str(excinfo.value) == "Invalid value for Report 'object_refs': must match <object-type>--<guid>." assert str(excinfo.value) == "Invalid value for Report 'object_refs': must match <object-type>--<guid>."
@ -115,9 +115,10 @@ def test_report_example_objects_in_object_refs_with_bad_id():
}, },
]) ])
def test_parse_report(data): def test_parse_report(data):
rept = stix2.parse(data) rept = stix2.parse(data, version="2.1")
assert rept.type == 'report' assert rept.type == 'report'
assert rept.spec_version == '2.1'
assert rept.id == REPORT_ID assert rept.id == REPORT_ID
assert rept.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) assert rept.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc)
assert rept.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) assert rept.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc)

View File

@ -35,7 +35,7 @@ BAD_SIGHTING = """{
def test_sighting_all_required_properties(): def test_sighting_all_required_properties():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
s = stix2.Sighting( s = stix2.v21.Sighting(
type='sighting', type='sighting',
id=SIGHTING_ID, id=SIGHTING_ID,
created=now, created=now,
@ -50,7 +50,7 @@ def test_sighting_bad_where_sighted_refs():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Sighting( stix2.v21.Sighting(
type='sighting', type='sighting',
id=SIGHTING_ID, id=SIGHTING_ID,
created=now, created=now,
@ -59,7 +59,7 @@ def test_sighting_bad_where_sighted_refs():
where_sighted_refs=["malware--8cc7afd6-5455-4d2b-a736-e614ee631d99"] where_sighted_refs=["malware--8cc7afd6-5455-4d2b-a736-e614ee631d99"]
) )
assert excinfo.value.cls == stix2.Sighting assert excinfo.value.cls == stix2.v21.Sighting
assert excinfo.value.prop_name == "where_sighted_refs" assert excinfo.value.prop_name == "where_sighted_refs"
assert excinfo.value.reason == "must start with 'identity'." assert excinfo.value.reason == "must start with 'identity'."
assert str(excinfo.value) == "Invalid value for Sighting 'where_sighted_refs': must start with 'identity'." assert str(excinfo.value) == "Invalid value for Sighting 'where_sighted_refs': must start with 'identity'."
@ -67,9 +67,9 @@ def test_sighting_bad_where_sighted_refs():
def test_sighting_type_must_be_sightings(): def test_sighting_type_must_be_sightings():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.Sighting(type='xxx', **SIGHTING_KWARGS) stix2.v21.Sighting(type='xxx', **SIGHTING_KWARGS)
assert excinfo.value.cls == stix2.Sighting assert excinfo.value.cls == stix2.v21.Sighting
assert excinfo.value.prop_name == "type" assert excinfo.value.prop_name == "type"
assert excinfo.value.reason == "must equal 'sighting'." assert excinfo.value.reason == "must equal 'sighting'."
assert str(excinfo.value) == "Invalid value for Sighting 'type': must equal 'sighting'." assert str(excinfo.value) == "Invalid value for Sighting 'type': must equal 'sighting'."
@ -77,15 +77,15 @@ def test_sighting_type_must_be_sightings():
def test_invalid_kwarg_to_sighting(): def test_invalid_kwarg_to_sighting():
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
stix2.Sighting(my_custom_property="foo", **SIGHTING_KWARGS) stix2.v21.Sighting(my_custom_property="foo", **SIGHTING_KWARGS)
assert excinfo.value.cls == stix2.Sighting assert excinfo.value.cls == stix2.v21.Sighting
assert excinfo.value.properties == ['my_custom_property'] assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Sighting: (my_custom_property)." assert str(excinfo.value) == "Unexpected properties for Sighting: (my_custom_property)."
def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811 def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811
rel = stix2.Sighting(sighting_of_ref=malware) rel = stix2.v21.Sighting(sighting_of_ref=malware)
assert rel.sighting_of_ref == 'malware--00000000-0000-0000-0000-000000000001' assert rel.sighting_of_ref == 'malware--00000000-0000-0000-0000-000000000001'
assert rel.id == 'sighting--00000000-0000-0000-0000-000000000003' assert rel.id == 'sighting--00000000-0000-0000-0000-000000000003'
@ -98,6 +98,7 @@ def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811
"id": "sighting--bfbc19db-ec35-4e45-beed-f8bde2a772fb", "id": "sighting--bfbc19db-ec35-4e45-beed-f8bde2a772fb",
"modified": "2016-04-06T20:06:37Z", "modified": "2016-04-06T20:06:37Z",
"sighting_of_ref": "indicator--01234567-89ab-cdef-0123-456789abcdef", "sighting_of_ref": "indicator--01234567-89ab-cdef-0123-456789abcdef",
"spec_version": "2.1",
"type": "sighting", "type": "sighting",
"where_sighted_refs": [ "where_sighted_refs": [
"identity--8cc7afd6-5455-4d2b-a736-e614ee631d99" "identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"
@ -105,9 +106,10 @@ def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811
}, },
]) ])
def test_parse_sighting(data): def test_parse_sighting(data):
sighting = stix2.parse(data) sighting = stix2.parse(data, version="2.1")
assert sighting.type == 'sighting' assert sighting.type == 'sighting'
assert sighting.spec_version == '2.1'
assert sighting.id == SIGHTING_ID assert sighting.id == SIGHTING_ID
assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)

View File

@ -23,7 +23,7 @@ EXPECTED = """{
def test_threat_actor_example(): def test_threat_actor_example():
threat_actor = stix2.ThreatActor( threat_actor = stix2.v21.ThreatActor(
id="threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:48.000Z", created="2016-04-06T20:03:48.000Z",
@ -53,9 +53,10 @@ def test_threat_actor_example():
}, },
]) ])
def test_parse_threat_actor(data): def test_parse_threat_actor(data):
actor = stix2.parse(data) actor = stix2.parse(data, version="2.1")
assert actor.type == 'threat-actor' assert actor.type == 'threat-actor'
assert actor.spec_version == '2.1'
assert actor.id == THREAT_ACTOR_ID assert actor.id == THREAT_ACTOR_ID
assert actor.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert actor.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)
assert actor.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert actor.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)

View File

@ -36,7 +36,7 @@ EXPECTED_WITH_REVOKED = """{
def test_tool_example(): def test_tool_example():
tool = stix2.Tool( tool = stix2.v21.Tool(
id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:48.000Z", created="2016-04-06T20:03:48.000Z",
@ -64,9 +64,10 @@ def test_tool_example():
}, },
]) ])
def test_parse_tool(data): def test_parse_tool(data):
tool = stix2.parse(data) tool = stix2.parse(data, version="2.1")
assert tool.type == 'tool' assert tool.type == 'tool'
assert tool.spec_version == '2.1'
assert tool.id == TOOL_ID assert tool.id == TOOL_ID
assert tool.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert tool.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)
assert tool.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert tool.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc)
@ -76,13 +77,13 @@ def test_parse_tool(data):
def test_tool_no_workbench_wrappers(): def test_tool_no_workbench_wrappers():
tool = stix2.Tool(name='VNC', labels=['remote-access']) tool = stix2.v21.Tool(name='VNC', labels=['remote-access'])
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
tool.created_by() tool.created_by()
def test_tool_serialize_with_defaults(): def test_tool_serialize_with_defaults():
tool = stix2.Tool( tool = stix2.v21.Tool(
id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T20:03:48.000Z", created="2016-04-06T20:03:48.000Z",

View File

@ -105,7 +105,7 @@ def test_deduplicate(stix_objs1):
@pytest.mark.parametrize('object, tuple_to_find, expected_index', [ @pytest.mark.parametrize('object, tuple_to_find, expected_index', [
(stix2.ObservedData( (stix2.v21.ObservedData(
id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
created="2016-04-06T19:58:16.000Z", created="2016-04-06T19:58:16.000Z",
@ -158,6 +158,7 @@ def test_deduplicate(stix_objs1):
}, ('key', {'key_one': 'value', 'key_two': 'value'}), 0), }, ('key', {'key_one': 'value', 'key_two': 'value'}), 0),
({ ({
"type": "language-content", "type": "language-content",
"spec_version": "2.1",
"id": "language-content--b86bd89f-98bb-4fa9-8cb2-9ad421da981d", "id": "language-content--b86bd89f-98bb-4fa9-8cb2-9ad421da981d",
"created": "2017-02-08T21:31:22.007Z", "created": "2017-02-08T21:31:22.007Z",
"modified": "2017-02-08T21:31:22.007Z", "modified": "2017-02-08T21:31:22.007Z",

View File

@ -6,11 +6,12 @@ from .constants import CAMPAIGN_MORE_KWARGS
def test_making_new_version(): def test_making_new_version():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
campaign_v2 = campaign_v1.new_version(name="fred") campaign_v2 = campaign_v1.new_version(name="fred")
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.created_by_ref == campaign_v2.created_by_ref assert campaign_v1.created_by_ref == campaign_v2.created_by_ref
assert campaign_v1.created == campaign_v2.created assert campaign_v1.created == campaign_v2.created
assert campaign_v1.name != campaign_v2.name assert campaign_v1.name != campaign_v2.name
@ -20,11 +21,12 @@ def test_making_new_version():
def test_making_new_version_with_unset(): def test_making_new_version_with_unset():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
campaign_v2 = campaign_v1.new_version(description=None) campaign_v2 = campaign_v1.new_version(description=None)
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.created_by_ref == campaign_v2.created_by_ref assert campaign_v1.created_by_ref == campaign_v2.created_by_ref
assert campaign_v1.created == campaign_v2.created assert campaign_v1.created == campaign_v2.created
assert campaign_v1.name == campaign_v2.name assert campaign_v1.name == campaign_v2.name
@ -34,7 +36,7 @@ def test_making_new_version_with_unset():
def test_making_new_version_with_embedded_object(): def test_making_new_version_with_embedded_object():
campaign_v1 = stix2.Campaign( campaign_v1 = stix2.v21.Campaign(
external_references=[{ external_references=[{
"source_name": "capec", "source_name": "capec",
"external_id": "CAPEC-163" "external_id": "CAPEC-163"
@ -48,6 +50,7 @@ def test_making_new_version_with_embedded_object():
}]) }])
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.created_by_ref == campaign_v2.created_by_ref assert campaign_v1.created_by_ref == campaign_v2.created_by_ref
assert campaign_v1.created == campaign_v2.created assert campaign_v1.created == campaign_v2.created
assert campaign_v1.name == campaign_v2.name assert campaign_v1.name == campaign_v2.name
@ -57,11 +60,12 @@ def test_making_new_version_with_embedded_object():
def test_revoke(): def test_revoke():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
campaign_v2 = campaign_v1.revoke() campaign_v2 = campaign_v1.revoke()
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.created_by_ref == campaign_v2.created_by_ref assert campaign_v1.created_by_ref == campaign_v2.created_by_ref
assert campaign_v1.created == campaign_v2.created assert campaign_v1.created == campaign_v2.created
assert campaign_v1.name == campaign_v2.name assert campaign_v1.name == campaign_v2.name
@ -72,7 +76,7 @@ def test_revoke():
def test_versioning_error_invalid_property(): def test_versioning_error_invalid_property():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
with pytest.raises(stix2.exceptions.UnmodifiablePropertyError) as excinfo: with pytest.raises(stix2.exceptions.UnmodifiablePropertyError) as excinfo:
campaign_v1.new_version(type="threat-actor") campaign_v1.new_version(type="threat-actor")
@ -81,19 +85,19 @@ def test_versioning_error_invalid_property():
def test_versioning_error_bad_modified_value(): def test_versioning_error_bad_modified_value():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
campaign_v1.new_version(modified="2015-04-06T20:03:00.000Z") campaign_v1.new_version(modified="2015-04-06T20:03:00.000Z")
assert excinfo.value.cls == stix2.Campaign assert excinfo.value.cls == stix2.v21.Campaign
assert excinfo.value.prop_name == "modified" assert excinfo.value.prop_name == "modified"
assert excinfo.value.reason == "The new modified datetime cannot be before than or equal to the current modified datetime." \ assert excinfo.value.reason == ("The new modified datetime cannot be before than or equal to the current modified datetime."
"It cannot be equal, as according to STIX 2 specification, objects that are different " \ "It cannot be equal, as according to STIX 2 specification, objects that are different "
"but have the same id and modified timestamp do not have defined consumer behavior." "but have the same id and modified timestamp do not have defined consumer behavior.")
msg = "Invalid value for {0} '{1}': {2}" msg = "Invalid value for {0} '{1}': {2}"
msg = msg.format(stix2.Campaign.__name__, "modified", msg = msg.format(stix2.v21.Campaign.__name__, "modified",
"The new modified datetime cannot be before than or equal to the current modified datetime." "The new modified datetime cannot be before than or equal to the current modified datetime."
"It cannot be equal, as according to STIX 2 specification, objects that are different " "It cannot be equal, as according to STIX 2 specification, objects that are different "
"but have the same id and modified timestamp do not have defined consumer behavior.") "but have the same id and modified timestamp do not have defined consumer behavior.")
@ -101,21 +105,21 @@ def test_versioning_error_bad_modified_value():
def test_versioning_error_usetting_required_property(): def test_versioning_error_usetting_required_property():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
campaign_v1.new_version(name=None) campaign_v1.new_version(name=None)
assert excinfo.value.cls == stix2.Campaign assert excinfo.value.cls == stix2.v21.Campaign
assert excinfo.value.properties == ["name"] assert excinfo.value.properties == ["name"]
msg = "No values for required properties for {0}: ({1})." msg = "No values for required properties for {0}: ({1})."
msg = msg.format(stix2.Campaign.__name__, "name") msg = msg.format(stix2.v21.Campaign.__name__, "name")
assert str(excinfo.value) == msg assert str(excinfo.value) == msg
def test_versioning_error_new_version_of_revoked(): def test_versioning_error_new_version_of_revoked():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
campaign_v2 = campaign_v1.revoke() campaign_v2 = campaign_v1.revoke()
with pytest.raises(stix2.exceptions.RevokeError) as excinfo: with pytest.raises(stix2.exceptions.RevokeError) as excinfo:
@ -127,7 +131,7 @@ def test_versioning_error_new_version_of_revoked():
def test_versioning_error_revoke_of_revoked(): def test_versioning_error_revoke_of_revoked():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
campaign_v2 = campaign_v1.revoke() campaign_v2 = campaign_v1.revoke()
with pytest.raises(stix2.exceptions.RevokeError) as excinfo: with pytest.raises(stix2.exceptions.RevokeError) as excinfo:
@ -143,6 +147,7 @@ def test_making_new_version_dict():
campaign_v2 = stix2.utils.new_version(CAMPAIGN_MORE_KWARGS, name="fred") campaign_v2 = stix2.utils.new_version(CAMPAIGN_MORE_KWARGS, name="fred")
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['created_by_ref'] == campaign_v2['created_by_ref'] assert campaign_v1['created_by_ref'] == campaign_v2['created_by_ref']
assert campaign_v1['created'] == campaign_v2['created'] assert campaign_v1['created'] == campaign_v2['created']
assert campaign_v1['name'] != campaign_v2['name'] assert campaign_v1['name'] != campaign_v2['name']
@ -187,6 +192,7 @@ def test_revoke_dict():
campaign_v2 = stix2.utils.revoke(campaign_v1) campaign_v2 = stix2.utils.revoke(campaign_v1)
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['created_by_ref'] == campaign_v2['created_by_ref'] assert campaign_v1['created_by_ref'] == campaign_v2['created_by_ref']
assert campaign_v1['created'] == campaign_v2['created'] assert campaign_v1['created'] == campaign_v2['created']
assert campaign_v1['name'] == campaign_v2['name'] assert campaign_v1['name'] == campaign_v2['name']
@ -229,9 +235,9 @@ def test_remove_custom_stix_property():
def test_remove_custom_stix_object(): def test_remove_custom_stix_object():
@stix2.CustomObject("x-animal", [ @stix2.v21.CustomObject("x-animal", [
("species", stix2.properties.StringProperty(required=True)), ("species", stix2.v21.properties.StringProperty(required=True)),
("animal_class", stix2.properties.StringProperty()), ("animal_class", stix2.v21.properties.StringProperty()),
]) ])
class Animal(object): class Animal(object):
pass pass
@ -244,7 +250,7 @@ def test_remove_custom_stix_object():
def test_remove_custom_stix_no_custom(): def test_remove_custom_stix_no_custom():
campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS)
campaign_v2 = stix2.utils.remove_custom_stix(campaign_v1) campaign_v2 = stix2.utils.remove_custom_stix(campaign_v1)
assert len(campaign_v1.keys()) == len(campaign_v2.keys()) assert len(campaign_v1.keys()) == len(campaign_v2.keys())

View File

@ -24,7 +24,7 @@ EXPECTED = """{
def test_vulnerability_example(): def test_vulnerability_example():
vulnerability = stix2.Vulnerability( vulnerability = stix2.v21.Vulnerability(
id="vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", id="vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061",
created="2016-05-12T08:17:27.000Z", created="2016-05-12T08:17:27.000Z",
modified="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z",
@ -56,9 +56,10 @@ def test_vulnerability_example():
}, },
]) ])
def test_parse_vulnerability(data): def test_parse_vulnerability(data):
vuln = stix2.parse(data) vuln = stix2.parse(data, version="2.1")
assert vuln.type == 'vulnerability' assert vuln.type == 'vulnerability'
assert vuln.spec_version == '2.1'
assert vuln.id == VULNERABILITY_ID assert vuln.id == VULNERABILITY_ID
assert vuln.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert vuln.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
assert vuln.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert vuln.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)