From 04680d8a3d0375ad108bdbe82a99de2a33b1af77 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Tue, 3 Jul 2018 09:40:51 -0400 Subject: [PATCH] First pass at making sure everything uses v21 classes and representations --- stix2/test/v21/conftest.py | 16 +- ...-0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22.json | 4 +- ...-0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b.json | 4 +- ...-774a3188-6ba9-4dc4-879d-d54ee48a5ce9.json | 4 +- ...-7e150503-88e7-4861-866b-ff1ac82c4475.json | 4 +- ...-ae676644-d2d2-41b7-af7e-9bed1b55898c.json | 4 +- ...-b3d682b6-98f2-4fb0-aa3b-b4df007ca70a.json | 4 +- ...-95ddb356-7ba0-4bd9-a889-247262b8946f.json | 2 +- ...-d9727aee-48b8-4fdb-89e2-4c49746ba4dd.json | 1 + ...-c78cb6e5-0c4b-4611-8297-d1b8b55e40b5.json | 2 +- ...-a653431d-6a5e-4600-8ad3-609b5af57064.json | 2 +- ...-f3bdec95-3d62-42d9-a840-29630f6cdc1a.json | 2 +- ...-6b616fc1-1505-48e3-8b2c-0d19337bff38.json | 2 +- ...-92ec0cbd-2c30-44a2-b270-73f4ec949841.json | 2 +- ...-96b08451-b27a-4ff6-893f-790e26393a8e.json | 4 +- ...-b42378e0-f147-496f-992a-26a49705395b.json | 4 +- ...-fa42a846-8d90-4e51-bc29-71d5b4802168.json | 2 +- ...-0d4a7788-7f3b-4df8-a498-31a38003c883.json | 2 +- ...-0e55ee98-0c6d-43d4-b424-b18a0036b227.json | 4 +- ...-1e91cd45-a725-4965-abe3-700694374432.json | 4 +- ...-3a3084f9-0302-4fd5-9b8a-e0db10f5345e.json | 4 +- ...-3a3ed0b2-0c38-441f-ac40-53b873e545d1.json | 4 +- ...-592d0c31-e61f-495e-a60e-70d7be59a719.json | 4 +- ...-70dc6b5c-c524-429e-a6ab-0dd40f0482c1.json | 4 +- ...-8797579b-e3be-4209-a71b-255a4d08243d.json | 4 +- ...-03342581-f790-4f03-ba41-e82e67392e23.json | 4 +- ...-242f3da3-4425-4d11-8f5c-b842886da966.json | 4 +- stix2/test/v21/test_attack_pattern.py | 8 +- stix2/test/v21/test_bundle.py | 31 +- stix2/test/v21/test_campaign.py | 5 +- stix2/test/v21/test_course_of_action.py | 5 +- stix2/test/v21/test_custom.py | 70 +- stix2/test/v21/test_datastore.py | 2 +- stix2/test/v21/test_datastore_filesystem.py | 106 ++-- stix2/test/v21/test_datastore_filters.py | 5 + stix2/test/v21/test_datastore_memory.py | 1 - stix2/test/v21/test_datastore_taxii.py | 100 +-- stix2/test/v21/test_environment.py | 91 +-- stix2/test/v21/test_external_reference.py | 16 +- stix2/test/v21/test_granular_markings.py | 3 +- stix2/test/v21/test_identity.py | 9 +- stix2/test/v21/test_indicator.py | 45 +- stix2/test/v21/test_intrusion_set.py | 3 +- stix2/test/v21/test_kill_chain_phases.py | 16 +- stix2/test/v21/test_language_content.py | 4 +- stix2/test/v21/test_location.py | 5 +- stix2/test/v21/test_malware.py | 31 +- stix2/test/v21/test_markings.py | 35 +- stix2/test/v21/test_note.py | 5 +- stix2/test/v21/test_object_markings.py | 1 - stix2/test/v21/test_observed_data.py | 600 +++++++++--------- stix2/test/v21/test_opinion.py | 5 +- stix2/test/v21/test_pickle.py | 2 +- stix2/test/v21/test_properties.py | 15 +- stix2/test/v21/test_relationship.py | 35 +- stix2/test/v21/test_report.py | 15 +- stix2/test/v21/test_sighting.py | 20 +- stix2/test/v21/test_threat_actor.py | 5 +- stix2/test/v21/test_tool.py | 9 +- stix2/test/v21/test_utils.py | 3 +- stix2/test/v21/test_versioning.py | 46 +- stix2/test/v21/test_vulnerability.py | 5 +- 62 files changed, 759 insertions(+), 699 deletions(-) diff --git a/stix2/test/v21/conftest.py b/stix2/test/v21/conftest.py index c73eafb..2c7f641 100644 --- a/stix2/test/v21/conftest.py +++ b/stix2/test/v21/conftest.py @@ -35,17 +35,17 @@ def uuid4(monkeypatch): @pytest.fixture def indicator(uuid4, clock): - return stix2.Indicator(**INDICATOR_KWARGS) + return stix2.v21.Indicator(**INDICATOR_KWARGS) @pytest.fixture def malware(uuid4, clock): - return stix2.Malware(**MALWARE_KWARGS) + return stix2.v21.Malware(**MALWARE_KWARGS) @pytest.fixture def relationship(uuid4, clock): - return stix2.Relationship(**RELATIONSHIP_KWARGS) + return stix2.v21.Relationship(**RELATIONSHIP_KWARGS) @pytest.fixture @@ -59,6 +59,7 @@ def stix_objs1(): "modified": "2017-01-27T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -71,6 +72,7 @@ def stix_objs1(): "modified": "2017-01-27T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -83,6 +85,7 @@ def stix_objs1(): "modified": "2017-01-27T13:49:53.936Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -95,6 +98,7 @@ def stix_objs1(): "modified": "2017-01-27T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -107,6 +111,7 @@ def stix_objs1(): "modified": "2017-01-27T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -124,6 +129,7 @@ def stix_objs2(): "modified": "2017-01-31T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -136,6 +142,7 @@ def stix_objs2(): "modified": "2017-01-27T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -148,6 +155,7 @@ def stix_objs2(): "modified": "2017-01-27T13:49:53.935Z", "name": "Malicious site hosting downloader", "pattern": "[url:value = 'http://x4z9arb.cn/4712']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2017-01-27T13:49:53.935382Z" } @@ -156,4 +164,4 @@ def stix_objs2(): @pytest.fixture 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] diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22.json index 47dd5f8..e0d9217 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22.json @@ -34,9 +34,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "attack-pattern" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b.json index 13f900f..3b60fca 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b.json @@ -29,9 +29,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "attack-pattern" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9.json index db57e2c..4d35f27 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9.json @@ -24,9 +24,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "attack-pattern" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475.json index d48092d..9452cee 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475.json @@ -24,9 +24,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "attack-pattern" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c.json index 031419e..eafbb58 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c.json @@ -24,9 +24,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "attack-pattern" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a.json index 67c380c..4cd79c5 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a.json @@ -24,9 +24,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "attack-pattern" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f.json b/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f.json index bf14aa7..ed11040 100644 --- a/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f.json +++ b/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f.json @@ -8,9 +8,9 @@ "id": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f", "modified": "2017-05-31T21:30:26.495974Z", "name": "Rootkit Mitigation", + "spec_version": "2.1", "type": "course-of-action" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd.json b/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd.json index cb9cfe2..f437cf1 100644 --- a/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd.json +++ b/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd.json @@ -5,5 +5,6 @@ "id": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd", "modified": "2017-05-31T21:30:41.022744Z", "name": "Data from Network Shared Drive Mitigation", + "spec_version": "2.1", "type": "course-of-action" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5.json b/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5.json index 77d4464..a1582f6 100644 --- a/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5.json +++ b/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5.json @@ -7,9 +7,9 @@ "identity_class": "organization", "modified": "2017-06-01T00:00:00Z", "name": "The MITRE Corporation", + "spec_version": "2.1", "type": "identity" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064.json b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064.json index 10ef3a5..017edc6 100644 --- a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064.json +++ b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064.json @@ -46,9 +46,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "intrusion-set" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a.json b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a.json index 84b75b1..187899f 100644 --- a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a.json +++ b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a.json @@ -36,9 +36,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "intrusion-set" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38.json b/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38.json index 19354c5..751dda3 100644 --- a/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38.json +++ b/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38.json @@ -26,10 +26,10 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "malware", "is_family": false } ], - "spec_version": "2.1", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841.json b/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841.json index 99cdc50..54a368d 100644 --- a/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841.json +++ b/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841.json @@ -26,10 +26,10 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "malware", "is_family": false } ], - "spec_version": "2.1", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e.json b/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e.json index 98d89b9..2ad7129 100644 --- a/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e.json +++ b/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e.json @@ -26,10 +26,10 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "malware", "is_family": false } ], - "spec_version": "2.1", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b.json b/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b.json index dfbe54c..34c4f1e 100644 --- a/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b.json +++ b/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b.json @@ -26,10 +26,10 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "malware", "is_family": false } ], - "spec_version": "2.1", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/marking-definition/marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168.json b/stix2/test/v21/stix2_data/marking-definition/marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168.json index bcae183..1e06164 100644 --- a/stix2/test/v21/stix2_data/marking-definition/marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168.json +++ b/stix2/test/v21/stix2_data/marking-definition/marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168.json @@ -8,9 +8,9 @@ }, "definition_type": "statement", "id": "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168", + "spec_version": "2.1", "type": "marking-definition" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883.json b/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883.json index ac59925..c25ae30 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883.json @@ -11,10 +11,10 @@ ], "relationship_type": "uses", "source_ref": "attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a", + "spec_version": "2.1", "target_ref": "malware--92ec0cbd-2c30-44a2-b270-73f4ec949841", "type": "relationship" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227.json b/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227.json index ee97edf..25e099f 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227.json @@ -11,10 +11,10 @@ ], "relationship_type": "uses", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432.json b/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432.json index ff0d8cc..5111b03 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432.json @@ -11,10 +11,10 @@ ], "relationship_type": "mitigates", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e.json b/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e.json index 36d1482..9d6befe 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e.json @@ -11,10 +11,10 @@ ], "relationship_type": "uses", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1.json b/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1.json index 888cc3b..4a140e5 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1.json @@ -11,10 +11,10 @@ ], "relationship_type": "uses", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719.json b/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719.json index d9078d1..1ad1c12 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719.json @@ -11,10 +11,10 @@ ], "relationship_type": "mitigates", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1.json b/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1.json index ef1c4b2..faa796b 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1.json @@ -11,10 +11,10 @@ ], "relationship_type": "uses", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d.json b/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d.json index 1f20179..8a95962 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d.json @@ -11,10 +11,10 @@ ], "relationship_type": "uses", "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" } ], - "spec_version": "2.0", "type": "bundle" } \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23.json b/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23.json index 9d47880..3385119 100644 --- a/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23.json +++ b/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23.json @@ -31,9 +31,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "tool" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966.json b/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966.json index 281888e..9d9a06e 100644 --- a/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966.json +++ b/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966.json @@ -26,9 +26,9 @@ "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], + "spec_version": "2.1", "type": "tool" } ], - "spec_version": "2.0", "type": "bundle" -} +} \ No newline at end of file diff --git a/stix2/test/v21/test_attack_pattern.py b/stix2/test/v21/test_attack_pattern.py index 62c2d81..cb73767 100644 --- a/stix2/test/v21/test_attack_pattern.py +++ b/stix2/test/v21/test_attack_pattern.py @@ -25,7 +25,7 @@ EXPECTED = """{ def test_attack_pattern_example(): - ap = stix2.AttackPattern( + ap = stix2.v21.AttackPattern( id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", @@ -44,6 +44,7 @@ def test_attack_pattern_example(): EXPECTED, { "type": "attack-pattern", + "spec_version": "2.1", "id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", "created": "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): - ap = stix2.parse(data) + ap = stix2.parse(data, version="2.1") assert ap.type == 'attack-pattern' + assert ap.spec_version == '2.1' assert ap.id == ATTACK_PATTERN_ID 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) @@ -72,7 +74,7 @@ def test_parse_attack_pattern(data): def test_attack_pattern_invalid_labels(): with pytest.raises(stix2.exceptions.InvalidValueError): - stix2.AttackPattern( + stix2.v21.AttackPattern( id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", created="2016-05-12T08:17:27Z", modified="2016-05-12T08:17:27Z", diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py index 7694389..4abb9c7 100644 --- a/stix2/test/v21/test_bundle.py +++ b/stix2/test/v21/test_bundle.py @@ -88,7 +88,7 @@ EXPECTED_BUNDLE_DICT = { def test_empty_bundle(): - bundle = stix2.Bundle() + bundle = stix2.v21.Bundle() assert bundle.type == "bundle" assert bundle.id.startswith("bundle--") @@ -98,7 +98,7 @@ def test_empty_bundle(): def test_bundle_with_wrong_type(): 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.prop_name == "type" @@ -108,7 +108,7 @@ def test_bundle_with_wrong_type(): def test_bundle_id_must_start_with_bundle(): 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.prop_name == "id" @@ -117,59 +117,59 @@ def test_bundle_id_must_start_with_bundle(): 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 bundle.serialize(pretty=True) == EXPECTED_BUNDLE 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 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 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 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 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 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 def test_create_bundle_invalid(indicator, malware, relationship): 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" 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" 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' @@ -188,6 +188,7 @@ def test_parse_bundle(version): def test_parse_unknown_type(): unknown = { "type": "other", + "spec_version": "2.1", "id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", "created": "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: - 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." def test_stix_object_property(): 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 diff --git a/stix2/test/v21/test_campaign.py b/stix2/test/v21/test_campaign.py index 334863c..32b6c1f 100644 --- a/stix2/test/v21/test_campaign.py +++ b/stix2/test/v21/test_campaign.py @@ -20,7 +20,7 @@ EXPECTED = """{ def test_campaign_example(): - campaign = stix2.Campaign( + campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:00Z", @@ -46,9 +46,10 @@ def test_campaign_example(): }, ]) def test_parse_campaign(data): - cmpn = stix2.parse(data) + cmpn = stix2.parse(data, version="2.1") assert cmpn.type == 'campaign' + assert cmpn.spec_version == '2.1' assert cmpn.id == CAMPAIGN_ID 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) diff --git a/stix2/test/v21/test_course_of_action.py b/stix2/test/v21/test_course_of_action.py index 847e47c..e59273a 100644 --- a/stix2/test/v21/test_course_of_action.py +++ b/stix2/test/v21/test_course_of_action.py @@ -20,7 +20,7 @@ EXPECTED = """{ def test_course_of_action_example(): - coa = stix2.CourseOfAction( + coa = stix2.v21.CourseOfAction( id="course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", @@ -46,9 +46,10 @@ def test_course_of_action_example(): }, ]) 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.spec_version == '2.1' assert coa.id == COURSE_OF_ACTION_ID 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) diff --git a/stix2/test/v21/test_custom.py b/stix2/test/v21/test_custom.py index df3edbc..c94ae2e 100644 --- a/stix2/test/v21/test_custom.py +++ b/stix2/test/v21/test_custom.py @@ -6,7 +6,7 @@ import stix2.v21.sdo from .constants import FAKE_TIME, MARKING_DEFINITION_ID -IDENTITY_CUSTOM_PROP = stix2.Identity( +IDENTITY_CUSTOM_PROP = stix2.v21.Identity( name="John Smith", identity_class="individual", x_foo="bar", @@ -16,7 +16,7 @@ IDENTITY_CUSTOM_PROP = stix2.Identity( def test_identity_custom_property(): with pytest.raises(ValueError) as excinfo: - stix2.Identity( + stix2.v21.Identity( id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", created="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" with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: - stix2.Identity( + stix2.v21.Identity( id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", created="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) - identity = stix2.Identity( + identity = stix2.v21.Identity( id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", created="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(): with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: - stix2.Identity( + stix2.v21.Identity( id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", @@ -63,13 +63,13 @@ def test_identity_custom_property_invalid(): identity_class="individual", x_foo="bar", ) - assert excinfo.value.cls == stix2.Identity + assert excinfo.value.cls == stix2.v21.Identity assert excinfo.value.properties == ['x_foo'] assert "Unexpected properties for" in str(excinfo.value) def test_identity_custom_property_allowed(): - identity = stix2.Identity( + identity = stix2.v21.Identity( id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", created="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", [ """{ "type": "identity", + "spec_version": "2.1", "id": "identity--311b2d2d-f010-5473-83ec-1edf84858f4c", "created": "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): with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: - identity = stix2.parse(data) - assert excinfo.value.cls == stix2.v21.sdo.Identity + stix2.parse(data, version="2.1") + assert excinfo.value.cls == stix2.v21.Identity assert excinfo.value.properties == ['foo'] 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" 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 '"x_foo": "bar"' in str(bundle) def test_custom_properties_object_in_bundled_object(): - obj = stix2.Identity( + obj = stix2.v21.Identity( name="John Smith", identity_class="individual", custom_properties={ "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 '"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(): custom_identity = { 'type': 'identity', + 'spec_version': '2.1', 'id': 'identity--311b2d2d-f010-5473-83ec-1edf84858f4c', 'created': '2015-12-21T19:59:11Z', 'name': 'John Smith', @@ -134,9 +136,9 @@ def test_custom_property_dict_in_bundled_object(): 'x_foo': 'bar', } 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 '"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(): custom_identity = { 'type': 'identity', + 'spec_version': '2.1', 'id': 'identity--311b2d2d-f010-5473-83ec-1edf84858f4c', 'created': '2015-12-21T19:59:11Z', 'name': 'John Smith', @@ -152,19 +155,19 @@ def test_custom_properties_dict_in_bundled_object(): 'x_foo': 'bar', }, } - bundle = stix2.Bundle(custom_identity) + bundle = stix2.v21.Bundle(custom_identity) assert bundle.objects[0].x_foo == "bar" assert '"x_foo": "bar"' in str(bundle) def test_custom_property_in_observed_data(): - artifact = stix2.File( + artifact = stix2.v21.File( allow_custom=True, name='test', x_foo='bar' ) - observed_data = stix2.ObservedData( + observed_data = stix2.v21.ObservedData( allow_custom=True, first_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(): - ntfs = stix2.NTFSExt( + ntfs = stix2.v21.NTFSExt( allow_custom=True, sid=1, x_foo='bar', ) - artifact = stix2.File( + artifact = stix2.v21.File( name='test', extensions={'ntfs-ext': ntfs}, ) - observed_data = stix2.ObservedData( + observed_data = stix2.v21.ObservedData( allow_custom=True, first_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(): with pytest.raises(stix2.exceptions.ExtraPropertiesError): - artifact = stix2.File( + stix2.v21.File( name='test', extensions={ 'ntfs-ext': { @@ -210,7 +213,7 @@ def test_custom_property_dict_in_observable_extension(): }, ) - artifact = stix2.File( + artifact = stix2.v21.File( allow_custom=True, name='test', 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, first_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(): - marking_obj = stix2.MarkingDefinition( + marking_obj = stix2.v21.MarkingDefinition( id=MARKING_DEFINITION_ID, 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, definition_type="statement", - definition=stix2.StatementMarking(statement="Another one") + definition=stix2.v21.StatementMarking(statement="Another one") ) # 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(): @stix2.CustomMarking('x-new-obj', [ - ('property1', stix2.properties.StringProperty(required=True)), + ('property1', stix2.v21.properties.StringProperty(required=True)), ]) class NewObj(): pass @@ -272,7 +275,7 @@ def test_custom_marking_no_init_1(): def test_custom_marking_no_init_2(): @stix2.CustomMarking('x-new-obj2', [ - ('property1', stix2.properties.StringProperty(required=True)), + ('property1', stix2.v21.properties.StringProperty(required=True)), ]) class NewObj2(object): pass @@ -282,8 +285,8 @@ def test_custom_marking_no_init_2(): @stix2.sdo.CustomObject('x-new-type', [ - ('property1', stix2.properties.StringProperty(required=True)), - ('property2', stix2.properties.IntegerProperty()), + ('property1', stix2.v21.properties.StringProperty(required=True)), + ('property2', stix2.v21.properties.IntegerProperty()), ]) class NewType(object): def __init__(self, property2=None, **kwargs): @@ -867,6 +870,7 @@ def test_extension_property_location(): @pytest.mark.parametrize("data", [ """{ "type": "x-example", + "spec_version": "2.1", "id": "x-example--336d8a9f-91f1-46c5-b142-6441bb9f8b8d", "created": "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): @stix2.sdo.CustomObject('x-example', [ - ('dictionary', stix2.properties.DictionaryProperty()), + ('dictionary', stix2.v21.properties.DictionaryProperty()), ]) class Example(object): def __init__(self, **kwargs): diff --git a/stix2/test/v21/test_datastore.py b/stix2/test/v21/test_datastore.py index 323365a..0744438 100644 --- a/stix2/test/v21/test_datastore.py +++ b/stix2/test/v21/test_datastore.py @@ -3,7 +3,7 @@ import pytest from stix2.datastore import (CompositeDataSource, DataSink, DataSource, DataStoreMixin) 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(): diff --git a/stix2/test/v21/test_datastore_filesystem.py b/stix2/test/v21/test_datastore_filesystem.py index 49cbcc1..268fdb6 100644 --- a/stix2/test/v21/test_datastore_filesystem.py +++ b/stix2/test/v21/test_datastore_filesystem.py @@ -4,13 +4,12 @@ import shutil import pytest -from stix2 import (Bundle, Campaign, CustomObject, FileSystemSink, - FileSystemSource, FileSystemStore, Filter, Identity, - Indicator, Malware, Relationship, properties) -from stix2.test.constants import (CAMPAIGN_ID, CAMPAIGN_KWARGS, IDENTITY_ID, - IDENTITY_KWARGS, INDICATOR_ID, - INDICATOR_KWARGS, MALWARE_ID, MALWARE_KWARGS, - RELATIONSHIP_IDS) +import stix2 +from stix2.test.v21.constants import (CAMPAIGN_ID, CAMPAIGN_KWARGS, + IDENTITY_ID, IDENTITY_KWARGS, + INDICATOR_ID, INDICATOR_KWARGS, + MALWARE_ID, MALWARE_KWARGS, + RELATIONSHIP_IDS) 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 def fs_store(): # create - yield FileSystemStore(FS_PATH) + yield stix2.FileSystemStore(FS_PATH) # remove campaign dir shutil.rmtree(os.path.join(FS_PATH, "campaign"), True) @@ -27,7 +26,7 @@ def fs_store(): @pytest.fixture def fs_source(): # create - fs = FileSystemSource(FS_PATH) + fs = stix2.FileSystemSource(FS_PATH) assert fs.stix_dir == FS_PATH yield fs @@ -38,7 +37,7 @@ def fs_source(): @pytest.fixture def fs_sink(): # create - fs = FileSystemSink(FS_PATH) + fs = stix2.FileSystemSink(FS_PATH) assert fs.stix_dir == FS_PATH yield fs @@ -83,15 +82,15 @@ def bad_stix_files(): @pytest.fixture(scope='module') def rel_fs_store(): - cam = Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) - idy = Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) - ind = Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) - mal = Malware(id=MALWARE_ID, **MALWARE_KWARGS) - rel1 = Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) - rel2 = Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) - rel3 = Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) + cam = stix2.v21.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) + idy = stix2.v21.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) + ind = stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) + mal = stix2.v21.Malware(id=MALWARE_ID, **MALWARE_KWARGS) + rel1 = stix2.v21.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) + rel2 = stix2.v21.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) + rel3 = stix2.v21.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3] - fs = FileSystemStore(FS_PATH) + fs = stix2.FileSystemStore(FS_PATH) for o in stix_objs: fs.add(o) yield fs @@ -102,13 +101,13 @@ def rel_fs_store(): def test_filesystem_source_nonexistent_folder(): with pytest.raises(ValueError) as excinfo: - FileSystemSource('nonexistent-folder') + stix2.FileSystemSource('nonexistent-folder') assert "for STIX data does not exist" in str(excinfo) def test_filesystem_sink_nonexistent_folder(): with pytest.raises(ValueError) as excinfo: - FileSystemSink('nonexistent-folder') + stix2.FileSystemSink('nonexistent-folder') 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): # 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 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): # 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 "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] @@ -176,9 +175,9 @@ def test_filesytem_source_query_multiple(fs_source): def test_filesystem_sink_add_python_stix_object(fs_sink, fs_source): # add python stix object - camp1 = Campaign(name="Hannibal", - objective="Targeting Italian and Spanish Diplomat internet accounts", - aliases=["War Elephant"]) + camp1 = stix2.v21.Campaign(name="Hannibal", + objective="Targeting Italian and Spanish Diplomat internet accounts", + aliases=["War Elephant"]) 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): # add json-encoded stix bundle 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"}]}' 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): # add list of objects - camp6 = Campaign(name="Comanche", - objective="US Midwest manufacturing firms, oil refineries, and businesses", - aliases=["Horse Warrior"]) + camp6 = stix2.v21.Campaign(name="Comanche", + objective="US Midwest manufacturing firms, oil refineries, and businesses", + aliases=["Horse Warrior"]) camp7 = { "name": "Napolean", "type": "campaign", + "spec_version": "2.1", "objective": "Central and Eastern Europe military commands and departments", "aliases": ["The Frenchmen"], "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): # query() - tools = fs_store.query([Filter("labels", "in", "tool")]) + tools = fs_store.query([stix2.Filter("labels", "in", "tool")]) assert len(tools) == 2 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] 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) assert len(tools) == 2 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): - fs_store.source.filters.add(Filter("labels", "in", "tool")) - tools = fs_store.query(Filter("id", "=", "tool--242f3da3-4425-4d11-8f5c-b842886da966")) + fs_store.source.filters.add(stix2.Filter("labels", "in", "tool")) + tools = fs_store.query(stix2.Filter("id", "=", "tool--242f3da3-4425-4d11-8f5c-b842886da966")) assert len(tools) == 1 assert tools[0].id == "tool--242f3da3-4425-4d11-8f5c-b842886da966" 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 def test_filesystem_store_add(fs_store): # add() - camp1 = Campaign(name="Great Heathen Army", - objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England", - aliases=["Ragnar"]) + camp1 = stix2.v21.Campaign(name="Great Heathen Army", + objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England", + aliases=["Ragnar"]) fs_store.add(camp1) 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(): - fs_store = FileSystemStore(FS_PATH, bundlify=True) + fs_store = stix2.FileSystemStore(FS_PATH, bundlify=True) - camp1 = Campaign(name="Great Heathen Army", - objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England", - aliases=["Ragnar"]) + camp1 = stix2.v21.Campaign(name="Great Heathen Army", + objective="Targeting the government of United Kingdom and insitutions affiliated with the Church Of England", + aliases=["Ragnar"]) fs_store.add(camp1) 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): - bundle = Bundle() + bundle = stix2.v21.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): - camp = Campaign(name="Scipio Africanus", - objective="Defeat the Carthaginians", - x_empire="Roman", - allow_custom=True) + camp = stix2.v21.Campaign(name="Scipio Africanus", + objective="Defeat the Carthaginians", + x_empire="Roman", + allow_custom=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): - camp = Campaign(name="Scipio Africanus", - objective="Defeat the Carthaginians", - x_empire="Roman", - allow_custom=True) + camp = stix2.v21.Campaign(name="Scipio Africanus", + objective="Defeat the Carthaginians", + x_empire="Roman", + allow_custom=True) - bundle = Bundle(camp, allow_custom=True) + bundle = stix2.v21.Bundle(camp, allow_custom=True) fs_store.add(bundle) 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): - @CustomObject('x-new-obj', [ - ('property1', properties.StringProperty(required=True)), + @stix2.CustomObject('x-new-obj', [ + ('property1', stix2.v21.properties.StringProperty(required=True)), ]) class NewObj(): pass diff --git a/stix2/test/v21/test_datastore_filters.py b/stix2/test/v21/test_datastore_filters.py index 8ed82f3..a51a4d7 100644 --- a/stix2/test/v21/test_datastore_filters.py +++ b/stix2/test/v21/test_datastore_filters.py @@ -27,6 +27,7 @@ stix_objs = [ "modified": "2014-05-08T09:00:00.000Z", "name": "File hash for Poison Ivy variant", "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']", + "spec_version": "2.1", "type": "indicator", "valid_from": "2014-05-08T09:00:00.000000Z" }, @@ -48,11 +49,13 @@ stix_objs = [ "relationship_type": "indicates", "revoked": True, "source_ref": "indicator--a932fcc6-e032-176c-126f-cb970a5a1ade", + "spec_version": "2.1", "target_ref": "malware--fdd60b30-b67c-11e3-b0b9-f01faf20d111", "type": "relationship" }, { "id": "vulnerability--ee916c28-c7a4-4d0d-ad56-a8d357f89fef", + "spec_version": "2.1", "created": "2016-02-14T00:00:00.000Z", "created_by_ref": "identity--00000000-0000-0000-0000-b8e91df99dc9", "modified": "2016-02-14T00:00:00.000Z", @@ -69,6 +72,7 @@ stix_objs = [ }, { "type": "observed-data", + "spec_version": "2.1", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created": "2016-04-06T19:58:16.000Z", @@ -422,6 +426,7 @@ def test_filters7(stix_objs2, real_stix_objs2): # Test filtering on embedded property obsvd_data_obj = { "type": "observed-data", + "spec_version": "2.1", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created": "2016-04-06T19:58:16.000Z", diff --git a/stix2/test/v21/test_datastore_memory.py b/stix2/test/v21/test_datastore_memory.py index 7a5bf10..cdcfa21 100644 --- a/stix2/test/v21/test_datastore_memory.py +++ b/stix2/test/v21/test_datastore_memory.py @@ -28,7 +28,6 @@ def test_add_remove_composite_datasource(): def test_composite_datasource_operations(stix_objs1, stix_objs2): BUNDLE1 = dict(id="bundle--%s" % make_id(), objects=stix_objs1, - spec_version="2.0", type="bundle") cds1 = CompositeDataSource() ds1_1 = MemorySource(stix_data=BUNDLE1) diff --git a/stix2/test/v21/test_datastore_taxii.py b/stix2/test/v21/test_datastore_taxii.py index 8cc5033..13a389e 100644 --- a/stix2/test/v21/test_datastore_taxii.py +++ b/stix2/test/v21/test_datastore_taxii.py @@ -5,8 +5,7 @@ import pytest from requests.models import Response from taxii2client import Collection, _filter_kwargs_to_query_params -from stix2 import (Bundle, TAXIICollectionSink, TAXIICollectionSource, - TAXIICollectionStore, ThreatActor) +import stix2 from stix2.datastore import DataSourceError from stix2.datastore.filters import Filter @@ -39,7 +38,7 @@ class MockTAXIICollectionEndpoint(Collection): [] ) if objs: - return Bundle(objects=objs) + return stix2.v21.Bundle(objects=objs) else: resp = Response() resp.status_code = 404 @@ -59,7 +58,7 @@ class MockTAXIICollectionEndpoint(Collection): [] ) if objs: - return Bundle(objects=objs) + return stix2.v21.Bundle(objects=objs) else: resp = Response() resp.status_code = 404 @@ -101,65 +100,65 @@ def collection_no_rw_access(stix_objs1): def test_ds_taxii(collection): - ds = TAXIICollectionSource(collection) + ds = stix2.TAXIICollectionSource(collection) assert ds.collection is not None def test_add_stix2_object(collection): - tc_sink = TAXIICollectionSink(collection) + tc_sink = stix2.TAXIICollectionSink(collection) # create new STIX threat-actor - ta = ThreatActor(name="Teddy Bear", - labels=["nation-state"], - sophistication="innovator", - resource_level="government", - goals=[ - "compromising environment NGOs", - "water-hole attacks geared towards energy sector", - ]) + ta = stix2.v21.ThreatActor(name="Teddy Bear", + labels=["nation-state"], + sophistication="innovator", + resource_level="government", + goals=[ + "compromising environment NGOs", + "water-hole attacks geared towards energy sector", + ]) tc_sink.add(ta) 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 - ta = ThreatActor(name="Teddy Bear", - labels=["nation-state"], - sophistication="innovator", - resource_level="government", - goals=[ - "compromising environment NGOs", - "water-hole attacks geared towards energy sector", - ], - foo="bar", - allow_custom=True) + ta = stix2.v21.ThreatActor(name="Teddy Bear", + labels=["nation-state"], + sophistication="innovator", + resource_level="government", + goals=[ + "compromising environment NGOs", + "water-hole attacks geared towards energy sector", + ], + foo="bar", + allow_custom=True) tc_sink.add(ta) def test_add_list_object(collection, indicator): - tc_sink = TAXIICollectionSink(collection) + tc_sink = stix2.TAXIICollectionSink(collection) # create new STIX threat-actor - ta = ThreatActor(name="Teddy Bear", - labels=["nation-state"], - sophistication="innovator", - resource_level="government", - goals=[ - "compromising environment NGOs", - "water-hole attacks geared towards energy sector", - ]) + ta = stix2.v21.ThreatActor(name="Teddy Bear", + labels=["nation-state"], + sophistication="innovator", + resource_level="government", + goals=[ + "compromising environment NGOs", + "water-hole attacks geared towards energy sector", + ]) tc_sink.add([ta, indicator]) def test_add_stix2_bundle_object(collection): - tc_sink = TAXIICollectionSink(collection) + tc_sink = stix2.TAXIICollectionSink(collection) # create new STIX threat-actor - ta = ThreatActor(name="Teddy Bear", + ta = stix2.v21.ThreatActor(name="Teddy Bear", labels=["nation-state"], sophistication="innovator", resource_level="government", @@ -168,15 +167,16 @@ def test_add_stix2_bundle_object(collection): "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): - tc_sink = TAXIICollectionSink(collection) + tc_sink = stix2.TAXIICollectionSink(collection) # create new STIX threat-actor ta = """{ "type": "threat-actor", + "spec_version": "2.1", "id": "threat-actor--eddff64f-feb1-4469-b07c-499a73c96415", "created": "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): - tc_sink = TAXIICollectionSink(collection) + tc_sink = stix2.TAXIICollectionSink(collection) ta = { "type": "threat-actor", + "spec_version": "2.1", "id": "threat-actor--eddff64f-feb1-4469-b07c-499a73c96415", "created": "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): - tc_sink = TAXIICollectionSink(collection) + tc_sink = stix2.TAXIICollectionSink(collection) ta = { "type": "bundle", @@ -227,6 +228,7 @@ def test_add_dict_bundle_object(collection): "objects": [ { "type": "threat-actor", + "spec_version": "2.1", "id": "threat-actor--dc5a2f41-f76e-425a-81fe-33afc7aabd75", "created": "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): - tc_sink = TAXIICollectionSource(collection) + tc_sink = stix2.TAXIICollectionSource(collection) objects = tc_sink.get("indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f") @@ -271,7 +273,7 @@ def test_parse_taxii_filters(collection): Filter("version", "=", "first") ] - ds = TAXIICollectionSource(collection) + ds = stix2.TAXIICollectionSource(collection) taxii_filters = ds._parse_taxii_filters(query) @@ -279,7 +281,7 @@ def test_parse_taxii_filters(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 valid_filters = [ @@ -315,7 +317,7 @@ def test_add_get_remove_filter(collection): def test_get_all_versions(collection): - ds = TAXIICollectionStore(collection) + ds = stix2.TAXIICollectionStore(collection) indicators = ds.all_versions('indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f') # 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""" 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) @@ -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""" 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) @@ -357,7 +359,7 @@ def test_get_404(): resp.status_code = 404 resp.raise_for_status() - ds = TAXIICollectionSource(TAXIICollection404()) + ds = stix2.TAXIICollectionSource(TAXIICollection404()) # this will raise 404 from mock TAXII Client but TAXIICollectionStore # 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 response code from the taxii2client should be returned as an exception""" - ds = TAXIICollectionStore(collection) + ds = stix2.TAXIICollectionStore(collection) with pytest.raises(DataSourceError) as excinfo: ds.all_versions("indicator--1") @@ -381,7 +383,7 @@ def test_query_404(collection): """ a TAXIICollectionSource.query() call that recieves an HTTP 404 response code from the taxii2client should be returned as an exception""" - ds = TAXIICollectionStore(collection) + ds = stix2.TAXIICollectionStore(collection) query = [Filter("type", "=", "malware")] with pytest.raises(DataSourceError) as excinfo: diff --git a/stix2/test/v21/test_environment.py b/stix2/test/v21/test_environment.py index a5166b7..2aa63f6 100644 --- a/stix2/test/v21/test_environment.py +++ b/stix2/test/v21/test_environment.py @@ -9,92 +9,92 @@ from .constants import (CAMPAIGN_ID, CAMPAIGN_KWARGS, FAKE_TIME, IDENTITY_ID, @pytest.fixture def ds(): - cam = stix2.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) - idy = stix2.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) - ind = stix2.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) - mal = stix2.Malware(id=MALWARE_ID, **MALWARE_KWARGS) - rel1 = stix2.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) - rel2 = stix2.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) - rel3 = stix2.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) + cam = stix2.v21.Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS) + idy = stix2.v21.Identity(id=IDENTITY_ID, **IDENTITY_KWARGS) + ind = stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS) + mal = stix2.v21.Malware(id=MALWARE_ID, **MALWARE_KWARGS) + rel1 = stix2.v21.Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0]) + rel2 = stix2.v21.Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1]) + rel3 = stix2.v21.Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2]) stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3] yield stix2.MemoryStore(stix_objs) def test_object_factory_created_by_ref_str(): 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 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) - ind = factory.create(stix2.Indicator, **INDICATOR_KWARGS) + ind = factory.create(stix2.v21.Indicator, **INDICATOR_KWARGS) assert ind.created_by_ref == IDENTITY_ID def test_object_factory_override_default(): factory = stix2.ObjectFactory(created_by_ref=IDENTITY_ID) 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 def test_object_factory_created(): 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.modified == FAKE_TIME def test_object_factory_external_reference(): - ext_ref = stix2.ExternalReference(source_name="ACME Threat Intel", - description="Threat report") + ext_ref = stix2.v21.ExternalReference(source_name="ACME Threat Intel", + description="Threat report") 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].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 def test_object_factory_obj_markings(): - stmt_marking = stix2.StatementMarking("Copyright 2016, Example Corp") - mark_def = stix2.MarkingDefinition(definition_type="statement", - definition=stmt_marking) + stmt_marking = stix2.v21.StatementMarking("Copyright 2016, Example Corp") + mark_def = stix2.v21.MarkingDefinition(definition_type="statement", + definition=stmt_marking) 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 stix2.TLP_AMBER.id in ind.object_marking_refs 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 def test_object_factory_list_append(): - ext_ref = stix2.ExternalReference(source_name="ACME Threat Intel", - description="Threat report from ACME") - ext_ref2 = stix2.ExternalReference(source_name="Yet Another Threat Report", - description="Threat report from YATR") - ext_ref3 = stix2.ExternalReference(source_name="Threat Report #3", - description="One more threat report") + ext_ref = stix2.v21.ExternalReference(source_name="ACME Threat Intel", + description="Threat report from ACME") + ext_ref2 = stix2.v21.ExternalReference(source_name="Yet Another Threat Report", + description="Threat report from YATR") + ext_ref3 = stix2.v21.ExternalReference(source_name="Threat Report #3", + description="One more threat report") 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" - 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" def test_object_factory_list_replace(): - ext_ref = stix2.ExternalReference(source_name="ACME Threat Intel", - description="Threat report from ACME") - ext_ref2 = stix2.ExternalReference(source_name="Yet Another Threat Report", - description="Threat report from YATR") + ext_ref = stix2.v21.ExternalReference(source_name="ACME Threat Intel", + description="Threat report from ACME") + ext_ref2 = stix2.v21.ExternalReference(source_name="Yet Another Threat Report", + description="Threat report from YATR") 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 ind.external_references[0].source_name == "Yet Another Threat Report" @@ -104,7 +104,7 @@ def test_environment_functions(): stix2.MemoryStore()) # 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 # Add objects to datastore @@ -133,7 +133,7 @@ def test_environment_functions(): 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])) assert env.get(INDICATOR_ID).labels[0] == 'malicious-activity' @@ -149,7 +149,7 @@ def test_environment_no_datastore(): env = stix2.Environment(factory=stix2.ObjectFactory()) 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) with pytest.raises(AttributeError) as excinfo: @@ -182,7 +182,7 @@ def test_environment_add_filters(): def test_environment_datastore_and_no_object_factory(): # Uses a default object factory 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 @@ -203,6 +203,7 @@ def test_parse_malware(): mal = env.parse(data) assert mal.type == 'malware' + assert mal.spec_version == '2.1' assert mal.id == MALWARE_ID assert mal.created == FAKE_TIME assert mal.modified == FAKE_TIME @@ -211,40 +212,40 @@ def test_parse_malware(): def test_creator_of(): - identity = stix2.Identity(**IDENTITY_KWARGS) + identity = stix2.v21.Identity(**IDENTITY_KWARGS) factory = stix2.ObjectFactory(created_by_ref=identity.id) env = stix2.Environment(store=stix2.MemoryStore(), factory=factory) env.add(identity) - ind = env.create(stix2.Indicator, **INDICATOR_KWARGS) + ind = env.create(stix2.v21.Indicator, **INDICATOR_KWARGS) creator = env.creator_of(ind) assert creator is identity 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) 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: env.creator_of(ind) assert 'Environment has no data source' in str(excinfo.value) 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) 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) assert creator is None def test_creator_of_no_created_by_ref(): 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) assert creator is None diff --git a/stix2/test/v21/test_external_reference.py b/stix2/test/v21/test_external_reference.py index 9b90998..27929c2 100644 --- a/stix2/test/v21/test_external_reference.py +++ b/stix2/test/v21/test_external_reference.py @@ -17,7 +17,7 @@ VERIS = """{ def test_external_reference_veris(): - ref = stix2.ExternalReference( + ref = stix2.v21.ExternalReference( source_name="veris", external_id="0001AA7F-C601-424A-B2B8-BE6C9F5164E7", hashes={ @@ -36,7 +36,7 @@ CAPEC = """{ def test_external_reference_capec(): - ref = stix2.ExternalReference( + ref = stix2.v21.ExternalReference( source_name="capec", external_id="CAPEC-550", ) @@ -53,7 +53,7 @@ CAPEC_URL = """{ def test_external_reference_capec_url(): - ref = stix2.ExternalReference( + ref = stix2.v21.ExternalReference( source_name="capec", external_id="CAPEC-550", url="http://capec.mitre.org/data/definitions/550.html", @@ -70,7 +70,7 @@ THREAT_REPORT = """{ def test_external_reference_threat_report(): - ref = stix2.ExternalReference( + ref = stix2.v21.ExternalReference( source_name="ACME Threat Intel", description="Threat report", url="http://www.example.com/threat-report.pdf", @@ -87,7 +87,7 @@ BUGZILLA = """{ def test_external_reference_bugzilla(): - ref = stix2.ExternalReference( + ref = stix2.v21.ExternalReference( source_name="ACME Bugzilla", external_id="1370", url="https://www.example.com/bugs/1370", @@ -103,7 +103,7 @@ OFFLINE = """{ def test_external_reference_offline(): - ref = stix2.ExternalReference( + ref = stix2.v21.ExternalReference( source_name="ACME Threat Intel", description="Threat report", ) @@ -116,7 +116,7 @@ def test_external_reference_offline(): def test_external_reference_source_required(): 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"] diff --git a/stix2/test/v21/test_granular_markings.py b/stix2/test/v21/test_granular_markings.py index 9e024a1..89947a1 100644 --- a/stix2/test/v21/test_granular_markings.py +++ b/stix2/test/v21/test_granular_markings.py @@ -1,4 +1,3 @@ - import pytest 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): """Test clearing markings for a selector that has no associated markings.""" with pytest.raises(MarkingNotFoundError): - data = markings.clear_markings(data, ["labels"]) + markings.clear_markings(data, ["labels"]) diff --git a/stix2/test/v21/test_identity.py b/stix2/test/v21/test_identity.py index 280dc19..13225e4 100644 --- a/stix2/test/v21/test_identity.py +++ b/stix2/test/v21/test_identity.py @@ -19,7 +19,7 @@ EXPECTED = """{ def test_identity_example(): - identity = stix2.Identity( + identity = stix2.v21.Identity( id="identity--311b2d2d-f010-5473-83ec-1edf84858f4c", created="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): - identity = stix2.parse(data) + identity = stix2.parse(data, version="2.1") assert identity.type == 'identity' + assert identity.spec_version == '2.1' assert identity.id == IDENTITY_ID 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) @@ -61,11 +62,11 @@ def test_parse_no_type(): "modified": "2015-12-21T19:59:11.000Z", "name": "John Smith", "identity_class": "individual" - }""") + }""", version="2.1") def test_identity_with_custom(): - identity = stix2.Identity( + identity = stix2.v21.Identity( name="John Smith", identity_class="individual", custom_properties={'x_foo': 'bar'} diff --git a/stix2/test/v21/test_indicator.py b/stix2/test/v21/test_indicator.py index 2864ef3..71685cd 100644 --- a/stix2/test/v21/test_indicator.py +++ b/stix2/test/v21/test_indicator.py @@ -37,7 +37,7 @@ def test_indicator_with_all_required_properties(): now = dt.datetime(2017, 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", id=INDICATOR_ID, created=now, @@ -55,6 +55,7 @@ def test_indicator_with_all_required_properties(): def test_indicator_autogenerated_properties(indicator): assert indicator.type == 'indicator' + assert indicator.spec_version == '2.1' assert indicator.id == 'indicator--00000000-0000-0000-0000-000000000001' assert indicator.created == 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['type'] == 'indicator' + assert indicator['spec_version'] == '2.1' assert indicator['id'] == 'indicator--00000000-0000-0000-0000-000000000001' assert indicator['created'] == FAKE_TIME assert indicator['modified'] == FAKE_TIME @@ -73,9 +75,9 @@ def test_indicator_autogenerated_properties(indicator): def test_indicator_type_must_be_indicator(): 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.reason == "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(): 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.reason == "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(): 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 str(excinfo.value) == "No values for required properties for Indicator: (labels, pattern)." def test_indicator_required_property_pattern(): 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"] def test_indicator_created_ref_invalid_format(): 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.reason == "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(): 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.reason == "must be a boolean value." @@ -136,16 +138,16 @@ def test_cannot_assign_to_indicator_attributes(indicator): def test_invalid_kwarg_to_indicator(): 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 str(excinfo.value) == "Unexpected properties for Indicator: (my_custom_property)." def test_created_modified_time_are_identical_by_default(): """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 @@ -165,9 +167,10 @@ def test_created_modified_time_are_identical_by_default(): }, ]) def test_parse_indicator(data): - idctr = stix2.parse(data) + idctr = stix2.parse(data, version="2.1") assert idctr.type == 'indicator' + assert idctr.spec_version == '2.1' assert idctr.id == INDICATOR_ID 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) @@ -178,19 +181,19 @@ def test_parse_indicator(data): def test_invalid_indicator_pattern(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.Indicator( + stix2.v21.Indicator( labels=['malicious-activity'], 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 'input is missing square brackets' in excinfo.value.reason with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.Indicator( + stix2.v21.Indicator( labels=['malicious-activity'], 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 'mismatched input' in excinfo.value.reason diff --git a/stix2/test/v21/test_intrusion_set.py b/stix2/test/v21/test_intrusion_set.py index 1657da0..cc650ad 100644 --- a/stix2/test/v21/test_intrusion_set.py +++ b/stix2/test/v21/test_intrusion_set.py @@ -28,7 +28,7 @@ EXPECTED = """{ def test_intrusion_set_example(): - intrusion_set = stix2.IntrusionSet( + intrusion_set = stix2.v21.IntrusionSet( id="intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", @@ -67,6 +67,7 @@ def test_parse_intrusion_set(data): intset = stix2.parse(data) assert intset.type == "intrusion-set" + assert intset.spec_version == '2.1' assert intset.id == INTRUSION_SET_ID 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) diff --git a/stix2/test/v21/test_kill_chain_phases.py b/stix2/test/v21/test_kill_chain_phases.py index 220c714..0acc538 100644 --- a/stix2/test/v21/test_kill_chain_phases.py +++ b/stix2/test/v21/test_kill_chain_phases.py @@ -11,7 +11,7 @@ LMCO_RECON = """{ def test_lockheed_martin_cyber_kill_chain(): - recon = stix2.KillChainPhase( + recon = stix2.v21.KillChainPhase( kill_chain_name="lockheed-martin-cyber-kill-chain", phase_name="reconnaissance", ) @@ -26,7 +26,7 @@ FOO_PRE_ATTACK = """{ def test_kill_chain_example(): - preattack = stix2.KillChainPhase( + preattack = stix2.v21.KillChainPhase( kill_chain_name="foo", phase_name="pre-attack", ) @@ -37,25 +37,25 @@ def test_kill_chain_example(): def test_kill_chain_required_properties(): 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"] def test_kill_chain_required_property_chain_name(): 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"] def test_kill_chain_required_property_phase_name(): 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"] diff --git a/stix2/test/v21/test_language_content.py b/stix2/test/v21/test_language_content.py index f38a16b..093b8e4 100644 --- a/stix2/test/v21/test_language_content.py +++ b/stix2/test/v21/test_language_content.py @@ -45,7 +45,7 @@ TEST_LANGUAGE_CONTENT = u"""{ def test_language_content_campaign(): now = dt.datetime(2017, 2, 8, 21, 31, 22, microsecond=7000, tzinfo=pytz.utc) - lc = stix2.LanguageContent( + lc = stix2.v21.LanguageContent( type='language-content', id=LANGUAGE_CONTENT_ID, 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 json.dumps(). https://docs.python.org/3/library/json.html#json.dumps diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 5a05753..0fa61f6 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -49,7 +49,7 @@ EXPECTED_LOCATION_2_REPR = "Location(" + " ".join(""" def test_location_with_some_required_properties(): now = dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) - loc = stix2.Location( + loc = stix2.v21.Location( type="location", id=LOCATION_ID, created=now, @@ -75,9 +75,10 @@ def test_location_with_some_required_properties(): } ]) def test_parse_location(data): - location = stix2.parse(data) + location = stix2.parse(data, version="2.1") assert location.type == 'location' + assert location.spec_version == '2.1' assert location.id == LOCATION_ID 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) diff --git a/stix2/test/v21/test_malware.py b/stix2/test/v21/test_malware.py index cf14c19..01e0da9 100644 --- a/stix2/test/v21/test_malware.py +++ b/stix2/test/v21/test_malware.py @@ -25,7 +25,7 @@ EXPECTED_MALWARE = """{ def test_malware_with_all_required_properties(): now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) - mal = stix2.Malware( + mal = stix2.v21.Malware( type="malware", id=MALWARE_ID, created=now, @@ -56,9 +56,9 @@ def test_malware_autogenerated_properties(malware): def test_malware_type_must_be_malware(): 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.reason == "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(): 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.reason == "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(): 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"] def test_malware_required_property_name(): 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"] @@ -99,9 +99,9 @@ def test_cannot_assign_to_malware_attributes(malware): def test_invalid_kwarg_to_malware(): 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 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): - mal = stix2.parse(data) + mal = stix2.parse(data, version="2.1") assert mal.type == 'malware' + assert mal.spec_version == '2.1' assert mal.id == MALWARE_ID 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) @@ -133,7 +134,7 @@ def test_parse_malware(data): def test_parse_malware_invalid_labels(): data = re.compile('\\[.+\\]', re.DOTALL).sub('1', EXPECTED_MALWARE) 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) @@ -146,7 +147,7 @@ def test_parse_malware_kill_chain_phases(): } ]""" 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].phase_name == "reconnaissance" 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) - mal = stix2.parse(data) + mal = stix2.parse(data, version="2.1") assert mal['kill_chain_phases'][0]['phase_name'] == "1" diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index 71143fb..5d4ec67 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -79,7 +79,7 @@ def test_marking_def_example_with_tlp(): 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", created="2017-01-20T00:00:00.000Z", definition_type="statement", @@ -91,7 +91,7 @@ def test_marking_def_example_with_statement_positional_argument(): def test_marking_def_example_with_kwargs_statement(): kwargs = dict(statement="Copyright 2016, Example Corp") - marking_definition = stix2.MarkingDefinition( + marking_definition = stix2.v21.MarkingDefinition( id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", created="2017-01-20T00:00:00.000Z", definition_type="statement", @@ -103,7 +103,7 @@ def test_marking_def_example_with_kwargs_statement(): def test_marking_def_invalid_type(): with pytest.raises(ValueError): - stix2.MarkingDefinition( + stix2.v21.MarkingDefinition( id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", created="2017-01-20T00:00:00.000Z", definition_type="my-definition-type", @@ -112,7 +112,7 @@ def test_marking_def_invalid_type(): def test_campaign_with_markings_example(): - campaign = stix2.Campaign( + campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:00Z", @@ -125,7 +125,7 @@ def test_campaign_with_markings_example(): def test_granular_example(): - granular_marking = stix2.GranularMarking( + granular_marking = stix2.v21.GranularMarking( marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"] ) @@ -135,19 +135,19 @@ def test_granular_example(): def test_granular_example_with_bad_selector(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.GranularMarking( + stix2.v21.GranularMarking( marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", 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.reason == "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(): - campaign = stix2.Campaign( + campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:00Z", @@ -155,7 +155,7 @@ def test_campaign_with_granular_markings_example(): name="Green Group Attacks Against Finance", description="Campaign by Green Group against a series of targets in the financial services sector.", granular_markings=[ - stix2.GranularMarking( + stix2.v21.GranularMarking( marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", selectors=["description"]) ]) @@ -175,9 +175,10 @@ def test_campaign_with_granular_markings_example(): }, ]) def test_parse_marking_definition(data): - gm = stix2.parse(data) + gm = stix2.parse(data, version="2.1") assert gm.type == 'marking-definition' + assert gm.spec_version == '2.1' assert gm.id == MARKING_DEFINITION_ID assert gm.created == dt.datetime(2017, 1, 20, 0, 0, 0, tzinfo=pytz.utc) assert gm.definition.tlp == "white" @@ -185,8 +186,8 @@ def test_parse_marking_definition(data): @stix2.common.CustomMarking('x-new-marking-type', [ - ('property1', stix2.properties.StringProperty(required=True)), - ('property2', stix2.properties.IntegerProperty()), + ('property1', stix2.v21.properties.StringProperty(required=True)), + ('property2', stix2.v21.properties.IntegerProperty()), ]) class NewMarking(object): def __init__(self, property2=None, **kwargs): @@ -197,7 +198,7 @@ class NewMarking(object): def test_registered_custom_marking(): nm = NewMarking(property1='something', property2=55) - marking_def = stix2.MarkingDefinition( + marking_def = stix2.v21.MarkingDefinition( id="marking-definition--00000000-0000-0000-0000-000000000012", created="2017-01-22T00:00:00.000Z", definition_type="x-new-marking-type", @@ -223,8 +224,8 @@ def test_not_registered_marking_raises_exception(): with pytest.raises(ValueError) as excinfo: # Used custom object on purpose to demonstrate a not-registered marking @stix2.sdo.CustomObject('x-new-marking-type2', [ - ('property1', stix2.properties.StringProperty(required=True)), - ('property2', stix2.properties.IntegerProperty()), + ('property1', stix2.v21.properties.StringProperty(required=True)), + ('property2', stix2.v21.properties.IntegerProperty()), ]) class NewObject2(object): def __init__(self, property2=None, **kwargs): @@ -232,7 +233,7 @@ def test_not_registered_marking_raises_exception(): no = NewObject2(property1='something', property2=55) - stix2.MarkingDefinition( + stix2.v21.MarkingDefinition( id="marking-definition--00000000-0000-0000-0000-000000000012", created="2017-01-22T00:00:00.000Z", definition_type="x-new-marking-type2", @@ -253,7 +254,7 @@ def test_marking_wrong_type_construction(): def test_campaign_add_markings(): - campaign = stix2.Campaign( + campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:00Z", diff --git a/stix2/test/v21/test_note.py b/stix2/test/v21/test_note.py index 8274e84..86c11ea 100644 --- a/stix2/test/v21/test_note.py +++ b/stix2/test/v21/test_note.py @@ -52,7 +52,7 @@ EXPECTED_OPINION_REPR = "Note(" + " ".join((""" def test_note_with_required_properties(): now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) - note = stix2.Note( + note = stix2.v21.Note( type='note', id=NOTE_ID, created=now, @@ -99,9 +99,10 @@ def test_note_with_required_properties(): } ]) def test_parse_note(data): - note = stix2.parse(data) + note = stix2.parse(data, version="2.1") assert note.type == 'note' + assert note.spec_version == '2.1' assert note.id == NOTE_ID 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) diff --git a/stix2/test/v21/test_object_markings.py b/stix2/test/v21/test_object_markings.py index f216355..1ed98a6 100644 --- a/stix2/test/v21/test_object_markings.py +++ b/stix2/test/v21/test_object_markings.py @@ -1,4 +1,3 @@ - import pytest from stix2 import TLP_AMBER, Malware, exceptions, markings diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 011a2d5..eee606c 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -31,7 +31,7 @@ EXPECTED = """{ def test_observed_data_example(): - observed_data = stix2.ObservedData( + observed_data = stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", @@ -77,7 +77,7 @@ EXPECTED_WITH_REF = """{ def test_observed_data_example_with_refs(): - observed_data = stix2.ObservedData( + observed_data = stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", 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(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.ObservedData( + stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", 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.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(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.ObservedData( + stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", @@ -142,14 +142,14 @@ def test_observed_data_example_with_non_dictionary(): objects="file: foo.exe", ) - assert excinfo.value.cls == stix2.ObservedData + assert excinfo.value.cls == stix2.v21.ObservedData assert excinfo.value.prop_name == "objects" assert 'must contain a dictionary' in excinfo.value.reason def test_observed_data_example_with_empty_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.ObservedData( + stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", @@ -160,7 +160,7 @@ def test_observed_data_example_with_empty_dictionary(): objects={}, ) - assert excinfo.value.cls == stix2.ObservedData + assert excinfo.value.cls == stix2.v21.ObservedData assert excinfo.value.prop_name == "objects" 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): - odata = stix2.parse(data) + odata = stix2.parse(data, version="2.1") assert odata.type == 'observed-data' + assert odata.spec_version == '2.1' assert odata.id == OBSERVED_DATA_ID 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) @@ -215,7 +216,7 @@ def test_parse_observed_data(data): ]) def test_parse_artifact_valid(data): 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" @@ -237,12 +238,12 @@ def test_parse_artifact_valid(data): def test_parse_artifact_invalid(data): odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED) with pytest.raises(ValueError): - stix2.parse(odata_str) + stix2.parse(odata_str, version="2.1") def test_artifact_example_dependency_error(): 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 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): 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"].number == 15139 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: 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")] @@ -401,7 +402,7 @@ def test_parse_email_message_not_multipart(data): ]) def test_parse_file_archive(data): 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" @@ -456,7 +457,7 @@ def test_parse_email_message_with_at_least_one_error(data): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: 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 "At least one of the" 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: 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"] @@ -535,12 +536,13 @@ EXPECTED_PROCESS_OD = """{ "binary_ref": "0" } }, + "spec_version": "2.1", "type": "observed-data" }""" def test_observed_data_with_process_example(): - observed_data = stix2.ObservedData( + observed_data = stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", @@ -578,11 +580,11 @@ def test_observed_data_with_process_example(): # creating cyber observables directly def test_artifact_example(): - art = stix2.Artifact(mime_type="image/jpeg", - url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg", - hashes={ - "MD5": "6826f9a05da08134006557758bb3afbb" - }) + art = stix2.v21.Artifact(mime_type="image/jpeg", + url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg", + hashes={ + "MD5": "6826f9a05da08134006557758bb3afbb" + }) 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.hashes["MD5"] == "6826f9a05da08134006557758bb3afbb" @@ -590,25 +592,25 @@ def test_artifact_example(): def test_artifact_mutual_exclusion_error(): with pytest.raises(stix2.exceptions.MutuallyExclusivePropertiesError) as excinfo: - stix2.Artifact(mime_type="image/jpeg", - url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg", - hashes={ - "MD5": "6826f9a05da08134006557758bb3afbb" - }, - payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==") + stix2.v21.Artifact(mime_type="image/jpeg", + url="https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg", + hashes={ + "MD5": "6826f9a05da08134006557758bb3afbb" + }, + payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==") - assert excinfo.value.cls == stix2.Artifact + assert excinfo.value.cls == stix2.v21.Artifact assert excinfo.value.properties == ["payload_bin", "url"] assert 'are mutually exclusive' in str(excinfo.value) def test_directory_example(): - dir = stix2.Directory(_valid_refs={"1": "file"}, - path='/usr/lib', - created="2015-12-21T19:00:00Z", - modified="2015-12-24T19:00:00Z", - accessed="2015-12-21T20:00:00Z", - contains_refs=["1"]) + dir = stix2.v21.Directory(_valid_refs={"1": "file"}, + path='/usr/lib', + created="2015-12-21T19:00:00Z", + modified="2015-12-24T19:00:00Z", + accessed="2015-12-21T20:00:00Z", + contains_refs=["1"]) assert dir.path == '/usr/lib' 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(): with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo: - stix2.Directory(_valid_refs=[], - path='/usr/lib', - created="2015-12-21T19:00:00Z", - modified="2015-12-24T19:00:00Z", - accessed="2015-12-21T20:00:00Z", - contains_refs=["1"]) + stix2.v21.Directory(_valid_refs=[], + path='/usr/lib', + created="2015-12-21T19:00:00Z", + modified="2015-12-24T19:00:00Z", + accessed="2015-12-21T20:00:00Z", + contains_refs=["1"]) - assert excinfo.value.cls == stix2.Directory + assert excinfo.value.cls == stix2.v21.Directory assert excinfo.value.prop_name == "contains_refs" def test_domain_name_example(): - dn = stix2.DomainName(_valid_refs={"1": 'domain-name'}, - value="example.com", - resolves_to_refs=["1"]) + dn = stix2.v21.DomainName(_valid_refs={"1": 'domain-name'}, + value="example.com", + resolves_to_refs=["1"]) assert dn.value == "example.com" assert dn.resolves_to_refs == ["1"] @@ -641,28 +643,28 @@ def test_domain_name_example(): def test_domain_name_example_invalid_ref_type(): with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo: - stix2.DomainName(_valid_refs={"1": "file"}, - value="example.com", - resolves_to_refs=["1"]) + stix2.v21.DomainName(_valid_refs={"1": "file"}, + value="example.com", + 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" def test_file_example(): - f = stix2.File(name="qwerty.dll", - hashes={ - "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a"}, - size=100, - magic_number_hex="1C", - mime_type="application/msword", - created="2016-12-21T19:00:00Z", - modified="2016-12-24T19:00:00Z", - accessed="2016-12-21T20:00:00Z", - is_encrypted=True, - encryption_algorithm="AES128-CBC", - decryption_key="fred" - ) + f = stix2.v21.File(name="qwerty.dll", + hashes={ + "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a"}, + size=100, + magic_number_hex="1C", + mime_type="application/msword", + created="2016-12-21T19:00:00Z", + modified="2016-12-24T19:00:00Z", + accessed="2016-12-21T20:00:00Z", + is_encrypted=True, + encryption_algorithm="AES128-CBC", + decryption_key="fred" + ) assert f.name == "qwerty.dll" assert f.size == 100 @@ -678,17 +680,17 @@ def test_file_example(): def test_file_example_with_NTFSExt(): - f = stix2.File(name="abc.txt", - extensions={ - "ntfs-ext": { - "alternate_data_streams": [ - { - "name": "second.stream", - "size": 25536 - } - ] - } - }) + f = stix2.v21.File(name="abc.txt", + extensions={ + "ntfs-ext": { + "alternate_data_streams": [ + { + "name": "second.stream", + "size": 25536 + } + ] + } + }) assert f.name == "abc.txt" 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(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.File(name="abc.txt", - extensions={ - "ntfs-ext": { - } - }) + stix2.v21.File(name="abc.txt", + extensions={ + "ntfs-ext": { + } + }) assert excinfo.value.cls == stix2.NTFSExt assert excinfo.value.properties == sorted(list(stix2.NTFSExt._properties.keys())) def test_file_example_with_PDFExt(): - f = stix2.File(name="qwerty.dll", - extensions={ - "pdf-ext": { - "version": "1.7", - "document_info_dict": { - "Title": "Sample document", - "Author": "Adobe Systems Incorporated", - "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", - "Producer": "Acrobat Distiller 3.01 for Power Macintosh", - "CreationDate": "20070412090123-02" - }, - "pdfid0": "DFCE52BD827ECF765649852119D", - "pdfid1": "57A1E0F9ED2AE523E313C" - } - }) + f = stix2.v21.File(name="qwerty.dll", + extensions={ + "pdf-ext": { + "version": "1.7", + "document_info_dict": { + "Title": "Sample document", + "Author": "Adobe Systems Incorporated", + "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", + "Producer": "Acrobat Distiller 3.01 for Power Macintosh", + "CreationDate": "20070412090123-02" + }, + "pdfid0": "DFCE52BD827ECF765649852119D", + "pdfid1": "57A1E0F9ED2AE523E313C" + } + }) assert f.name == "qwerty.dll" 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(): - f = stix2.File(name="qwerty.dll", - extensions={ - "pdf-ext": - stix2.PDFExt(version="1.7", - document_info_dict={ - "Title": "Sample document", - "Author": "Adobe Systems Incorporated", - "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", - "Producer": "Acrobat Distiller 3.01 for Power Macintosh", - "CreationDate": "20070412090123-02" - }, - pdfid0="DFCE52BD827ECF765649852119D", - pdfid1="57A1E0F9ED2AE523E313C") - - }) + f = stix2.v21.File(name="qwerty.dll", + extensions={ + "pdf-ext": + stix2.v21.PDFExt(version="1.7", + document_info_dict={ + "Title": "Sample document", + "Author": "Adobe Systems Incorporated", + "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", + "Producer": "Acrobat Distiller 3.01 for Power Macintosh", + "CreationDate": "20070412090123-02" + }, + pdfid0="DFCE52BD827ECF765649852119D", + pdfid1="57A1E0F9ED2AE523E313C") + }) assert f.name == "qwerty.dll" 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(): - f = stix2.File(name="qwerty.jpeg", - extensions={ - "raster-image-ext": { - "bits_per_pixel": 123, - "exif_tags": { - "Make": "Nikon", - "Model": "D7000", - "XResolution": 4928, - "YResolution": 3264 - } - } - }) + f = stix2.v21.File(name="qwerty.jpeg", + extensions={ + "raster-image-ext": { + "bits_per_pixel": 123, + "exif_tags": { + "Make": "Nikon", + "Model": "D7000", + "XResolution": 4928, + "YResolution": 3264 + } + } + }) assert f.name == "qwerty.jpeg" assert f.extensions["raster-image-ext"].bits_per_pixel == 123 assert f.extensions["raster-image-ext"].exif_tags["XResolution"] == 4928 @@ -770,6 +771,7 @@ def test_file_example_with_RasterImageExt_Object(): RASTER_IMAGE_EXT = """{ "type": "observed-data", +"spec_version": "2.1", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "created": "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(): - 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 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) def test_file_example_with_WindowsPEBinaryExt(): - f = stix2.File(name="qwerty.dll", - extensions={ - "windows-pebinary-ext": { - "pe_type": "exe", - "machine_hex": "014c", - "number_of_sections": 4, - "time_date_stamp": "2016-01-22T12:31:12Z", - "pointer_to_symbol_table_hex": "74726144", - "number_of_symbols": 4542568, - "size_of_optional_header": 224, - "characteristics_hex": "818f", - "optional_header": { - "magic_hex": "010b", - "major_linker_version": 2, - "minor_linker_version": 25, - "size_of_code": 512, - "size_of_initialized_data": 283648, - "size_of_uninitialized_data": 0, - "address_of_entry_point": 4096, - "base_of_code": 4096, - "base_of_data": 8192, - "image_base": 14548992, - "section_alignment": 4096, - "file_alignment": 4096, - "major_os_version": 1, - "minor_os_version": 0, - "major_image_version": 0, - "minor_image_version": 0, - "major_subsystem_version": 4, - "minor_subsystem_version": 0, - "win32_version_value_hex": "00", - "size_of_image": 299008, - "size_of_headers": 4096, - "checksum_hex": "00", - "subsystem_hex": "03", - "dll_characteristics_hex": "00", - "size_of_stack_reserve": 100000, - "size_of_stack_commit": 8192, - "size_of_heap_reserve": 100000, - "size_of_heap_commit": 4096, - "loader_flags_hex": "abdbffde", - "number_of_rva_and_sizes": 3758087646 - }, - "sections": [ - { - "name": "CODE", - "entropy": 0.061089 - }, - { - "name": "DATA", - "entropy": 7.980693 - }, - { - "name": "NicolasB", - "entropy": 0.607433 - }, - { - "name": ".idata", - "entropy": 0.607433 - } - ] - } - - }) + f = stix2.v21.File(name="qwerty.dll", + extensions={ + "windows-pebinary-ext": { + "pe_type": "exe", + "machine_hex": "014c", + "number_of_sections": 4, + "time_date_stamp": "2016-01-22T12:31:12Z", + "pointer_to_symbol_table_hex": "74726144", + "number_of_symbols": 4542568, + "size_of_optional_header": 224, + "characteristics_hex": "818f", + "optional_header": { + "magic_hex": "010b", + "major_linker_version": 2, + "minor_linker_version": 25, + "size_of_code": 512, + "size_of_initialized_data": 283648, + "size_of_uninitialized_data": 0, + "address_of_entry_point": 4096, + "base_of_code": 4096, + "base_of_data": 8192, + "image_base": 14548992, + "section_alignment": 4096, + "file_alignment": 4096, + "major_os_version": 1, + "minor_os_version": 0, + "major_image_version": 0, + "minor_image_version": 0, + "major_subsystem_version": 4, + "minor_subsystem_version": 0, + "win32_version_value_hex": "00", + "size_of_image": 299008, + "size_of_headers": 4096, + "checksum_hex": "00", + "subsystem_hex": "03", + "dll_characteristics_hex": "00", + "size_of_stack_reserve": 100000, + "size_of_stack_commit": 8192, + "size_of_heap_reserve": 100000, + "size_of_heap_commit": 4096, + "loader_flags_hex": "abdbffde", + "number_of_rva_and_sizes": 3758087646 + }, + "sections": [ + { + "name": "CODE", + "entropy": 0.061089 + }, + { + "name": "DATA", + "entropy": 7.980693 + }, + { + "name": "NicolasB", + "entropy": 0.607433 + }, + { + "name": ".idata", + "entropy": 0.607433 + } + ] + } + }) assert f.name == "qwerty.dll" assert f.extensions["windows-pebinary-ext"].sections[2].entropy == 0.607433 def test_file_example_encryption_error(): with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: - stix2.File(name="qwerty.dll", - is_encrypted=False, - encryption_algorithm="AES128-CBC") + stix2.v21.File(name="qwerty.dll", + is_encrypted=False, + 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 "property dependencies" in str(excinfo.value) assert "are not met" in str(excinfo.value) with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: - stix2.File(name="qwerty.dll", - encryption_algorithm="AES128-CBC") + stix2.v21.File(name="qwerty.dll", encryption_algorithm="AES128-CBC") def test_ip4_address_example(): - ip4 = stix2.IPv4Address(_valid_refs={"4": "mac-addr", "5": "mac-addr"}, - value="198.51.100.3", - resolves_to_refs=["4", "5"]) + ip4 = stix2.v21.IPv4Address(_valid_refs={"4": "mac-addr", "5": "mac-addr"}, + value="198.51.100.3", + resolves_to_refs=["4", "5"]) assert ip4.value == "198.51.100.3" assert ip4.resolves_to_refs == ["4", "5"] 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" 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" 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" def test_network_traffic_example(): - nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr", "1": "ipv4-addr"}, - protocols="tcp", - src_ref="0", - dst_ref="1") + nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr", "1": "ipv4-addr"}, + protocols="tcp", + src_ref="0", + dst_ref="1") assert nt.protocols == ["tcp"] assert nt.src_ref == "0" assert nt.dst_ref == "1" def test_network_traffic_http_request_example(): - h = stix2.HTTPRequestExt(request_method="get", - request_value="/download.html", - request_version="http/1.1", - request_header={ - "Accept-Encoding": "gzip,deflate", - "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113", - "Host": "www.example.com" - }) - nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, - protocols="tcp", - src_ref="0", - extensions={'http-request-ext': h}) + h = stix2.v21.HTTPRequestExt(request_method="get", + request_value="/download.html", + request_version="http/1.1", + request_header={ + "Accept-Encoding": "gzip,deflate", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113", + "Host": "www.example.com" + }) + nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, + protocols="tcp", + src_ref="0", + extensions={'http-request-ext': h}) 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_version == "http/1.1" @@ -957,25 +957,25 @@ def test_network_traffic_http_request_example(): def test_network_traffic_icmp_example(): - h = stix2.ICMPExt(icmp_type_hex="08", - icmp_code_hex="00") - nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, - protocols="tcp", - src_ref="0", - extensions={'icmp-ext': h}) + h = stix2.v21.ICMPExt(icmp_type_hex="08", + icmp_code_hex="00") + nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, + protocols="tcp", + src_ref="0", + extensions={'icmp-ext': h}) assert nt.extensions['icmp-ext'].icmp_type_hex == "08" assert nt.extensions['icmp-ext'].icmp_code_hex == "00" def test_network_traffic_socket_example(): - h = stix2.SocketExt(is_listening=True, - address_family="AF_INET", - protocol_family="PF_INET", - socket_type="SOCK_STREAM") - nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, - protocols="tcp", - src_ref="0", - extensions={'socket-ext': h}) + h = stix2.v21.SocketExt(is_listening=True, + address_family="AF_INET", + protocol_family="PF_INET", + socket_type="SOCK_STREAM") + nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, + protocols="tcp", + src_ref="0", + extensions={'socket-ext': h}) assert nt.extensions['socket-ext'].is_listening assert nt.extensions['socket-ext'].address_family == "AF_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(): - h = stix2.TCPExt(src_flags_hex="00000002") - nt = stix2.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, - protocols="tcp", - src_ref="0", - extensions={'tcp-ext': h}) + h = stix2.v21.TCPExt(src_flags_hex="00000002") + nt = stix2.v21.NetworkTraffic(_valid_refs={"0": "ipv4-addr"}, + protocols="tcp", + src_ref="0", + extensions={'tcp-ext': h}) assert nt.extensions['tcp-ext'].src_flags_hex == "00000002" def test_mutex_example(): - m = stix2.Mutex(name="barney") + m = stix2.v21.Mutex(name="barney") assert m.name == "barney" def test_process_example(): - p = stix2.Process(_valid_refs={"0": "file"}, - pid=1221, - name="gedit-bin", - created="2016-01-20T14:11:25.55Z", - arguments=["--new-window"], - binary_ref="0") + p = stix2.v21.Process(_valid_refs={"0": "file"}, + pid=1221, + name="gedit-bin", + created="2016-01-20T14:11:25.55Z", + arguments=["--new-window"], + binary_ref="0") assert p.name == "gedit-bin" assert p.arguments == ["--new-window"] @@ -1011,40 +1011,40 @@ def test_process_example(): def test_process_example_empty_error(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.Process() + stix2.v21.Process() - assert excinfo.value.cls == stix2.Process - properties_of_process = list(stix2.Process._properties.keys()) + assert excinfo.value.cls == stix2.v21.Process + properties_of_process = list(stix2.v21.Process._properties.keys()) properties_of_process.remove("type") assert excinfo.value.properties == sorted(properties_of_process) 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))) assert str(excinfo.value) == msg def test_process_example_empty_with_extensions(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.Process(extensions={ - "windows-process-ext": {} - }) + stix2.v21.Process(extensions={ + "windows-process-ext": {} + }) - assert excinfo.value.cls == stix2.WindowsProcessExt - properties_of_extension = list(stix2.WindowsProcessExt._properties.keys()) + assert excinfo.value.cls == stix2.v21.WindowsProcessExt + properties_of_extension = list(stix2.v21.WindowsProcessExt._properties.keys()) assert excinfo.value.properties == sorted(properties_of_extension) def test_process_example_windows_process_ext(): - proc = stix2.Process(pid=314, - name="foobar.exe", - extensions={ - "windows-process-ext": { - "aslr_enabled": True, - "dep_enabled": True, - "priority": "HIGH_PRIORITY_CLASS", - "owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309" - } - }) + proc = stix2.v21.Process(pid=314, + name="foobar.exe", + extensions={ + "windows-process-ext": { + "aslr_enabled": True, + "dep_enabled": True, + "priority": "HIGH_PRIORITY_CLASS", + "owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309" + } + }) assert proc.extensions["windows-process-ext"].aslr_enabled assert proc.extensions["windows-process-ext"].dep_enabled 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(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.Process(pid=1221, - name="gedit-bin", - extensions={ - "windows-process-ext": {} - }) + stix2.v21.Process(pid=1221, + name="gedit-bin", + extensions={ + "windows-process-ext": {} + }) - assert excinfo.value.cls == stix2.WindowsProcessExt - properties_of_extension = list(stix2.WindowsProcessExt._properties.keys()) + assert excinfo.value.cls == stix2.v21.WindowsProcessExt + properties_of_extension = list(stix2.v21.WindowsProcessExt._properties.keys()) assert excinfo.value.properties == sorted(properties_of_extension) def test_process_example_extensions_empty(): 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 'non-empty dictionary' in excinfo.value.reason def test_process_example_with_WindowsProcessExt_Object(): - p = stix2.Process(extensions={ - "windows-process-ext": stix2.WindowsProcessExt(aslr_enabled=True, - dep_enabled=True, - priority="HIGH_PRIORITY_CLASS", - owner_sid="S-1-5-21-186985262-1144665072-74031268-1309") # noqa - }) + p = stix2.v21.Process(extensions={ + "windows-process-ext": stix2.v21.WindowsProcessExt(aslr_enabled=True, + dep_enabled=True, + priority="HIGH_PRIORITY_CLASS", + 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"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309" def test_process_example_with_WindowsServiceExt(): - p = stix2.Process(extensions={ + p = stix2.v21.Process(extensions={ "windows-service-ext": { "service_name": "sirvizio", "display_name": "Sirvizio", @@ -1101,7 +1101,7 @@ def test_process_example_with_WindowsServiceExt(): def test_process_example_with_WindowsProcessServiceExt(): - p = stix2.Process(extensions={ + p = stix2.v21.Process(extensions={ "windows-service-ext": { "service_name": "sirvizio", "display_name": "Sirvizio", @@ -1124,10 +1124,10 @@ def test_process_example_with_WindowsProcessServiceExt(): def test_software_example(): - s = stix2.Software(name="Word", - cpe="cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*", - version="2002", - vendor="Microsoft") + s = stix2.v21.Software(name="Word", + cpe="cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*", + version="2002", + vendor="Microsoft") assert s.name == "Word" assert s.cpe == "cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*" @@ -1136,24 +1136,24 @@ def test_software_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.value == "https://example.com/research/index.html" def test_user_account_example(): - a = stix2.UserAccount(user_id="1001", - account_login="jdoe", - account_type="unix", - display_name="John Doe", - is_service_account=False, - is_privileged=False, - can_escalate_privs=True, - account_created="2016-01-20T12:31:12Z", - password_last_changed="2016-01-20T14:27:43Z", - account_first_login="2016-01-20T14:26:07Z", - account_last_login="2016-07-22T16:08:28Z") + a = stix2.v21.UserAccount(user_id="1001", + account_login="jdoe", + account_type="unix", + display_name="John Doe", + is_service_account=False, + is_privileged=False, + can_escalate_privs=True, + account_created="2016-01-20T12:31:12Z", + password_last_changed="2016-01-20T14:27:43Z", + account_first_login="2016-01-20T14:26:07Z", + account_last_login="2016-07-22T16:08:28Z") assert a.user_id == "1001" assert a.account_login == "jdoe" @@ -1169,11 +1169,11 @@ def test_user_account_example(): def test_user_account_unix_account_ext_example(): - u = stix2.UNIXAccountExt(gid=1001, + u = stix2.v21.UNIXAccountExt(gid=1001, groups=["wheel"], home_dir="/home/jdoe", shell="/bin/bash") - a = stix2.UserAccount(user_id="1001", + a = stix2.v21.UserAccount(user_id="1001", account_login="jdoe", account_type="unix", extensions={'unix-account-ext': u}) @@ -1185,14 +1185,14 @@ def test_user_account_unix_account_ext_example(): def test_windows_registry_key_example(): with pytest.raises(ValueError): - v = stix2.WindowsRegistryValueType(name="Foo", + stix2.v21.WindowsRegistryValueType(name="Foo", data="qwerty", data_type="string") - v = stix2.WindowsRegistryValueType(name="Foo", + v = stix2.v21.WindowsRegistryValueType(name="Foo", data="qwerty", 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]) assert w.key == "hkey_local_machine\\system\\bar\\foo" assert w.values[0].name == "Foo" @@ -1201,7 +1201,7 @@ def test_windows_registry_key_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 validity_not_before="2016-03-12T12: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(): - data = stix2.ObservedData( + data = stix2.v21.ObservedData( first_observed="2016-03-12T12:00:00Z", last_observed="2016-03-12T12:00:00Z", number_observed=1, diff --git a/stix2/test/v21/test_opinion.py b/stix2/test/v21/test_opinion.py index 3156ea7..c82e1cf 100644 --- a/stix2/test/v21/test_opinion.py +++ b/stix2/test/v21/test_opinion.py @@ -41,7 +41,7 @@ EXPECTED_OPINION_REPR = "Opinion(" + " ".join((""" def test_opinion_with_required_properties(): now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) - opi = stix2.Opinion( + opi = stix2.v21.Opinion( type='opinion', id=OPINION_ID, created=now, @@ -72,9 +72,10 @@ def test_opinion_with_required_properties(): } ]) def test_parse_opinion(data): - opinion = stix2.parse(data) + opinion = stix2.parse(data, version="2.1") assert opinion.type == 'opinion' + assert opinion.spec_version == '2.1' assert opinion.id == OPINION_ID 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) diff --git a/stix2/test/v21/test_pickle.py b/stix2/test/v21/test_pickle.py index 9e2cc9a..b573d7a 100644 --- a/stix2/test/v21/test_pickle.py +++ b/stix2/test/v21/test_pickle.py @@ -7,7 +7,7 @@ def test_pickling(): """ Ensure a pickle/unpickle cycle works okay. """ - identity = stix2.Identity( + identity = stix2.v21.Identity( id="identity--d66cb89d-5228-4983-958c-fa84ef75c88c", name="alice", description="this is a pickle test", diff --git a/stix2/test/v21/test_properties.py b/stix2/test/v21/test_properties.py index cd7723a..cfe2398 100644 --- a/stix2/test/v21/test_properties.py +++ b/stix2/test/v21/test_properties.py @@ -2,7 +2,7 @@ import pytest from stix2 import CustomObject, EmailMIMEComponent, ExtensionsProperty, TCPExt from stix2.exceptions import AtLeastOnePropertyError, DictionaryKeyError -from stix2.v20.properties import (BinaryProperty, BooleanProperty, +from stix2.v21.properties import (BinaryProperty, BooleanProperty, DictionaryProperty, EmbeddedObjectProperty, EnumProperty, FloatProperty, HashesProperty, HexProperty, IDProperty, IntegerProperty, @@ -230,11 +230,22 @@ def test_dictionary_property_valid(d): @pytest.mark.parametrize("d", [ [{'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" "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, " "uppercase A-Z, numerals 0-9, hyphen (-), or underscore (_))."], ]) diff --git a/stix2/test/v21/test_relationship.py b/stix2/test/v21/test_relationship.py index 21a2ec5..51e03ff 100644 --- a/stix2/test/v21/test_relationship.py +++ b/stix2/test/v21/test_relationship.py @@ -23,7 +23,7 @@ EXPECTED_RELATIONSHIP = """{ def test_relationship_all_required_properties(): now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) - rel = stix2.Relationship( + rel = stix2.v21.Relationship( type='relationship', id=RELATIONSHIP_ID, created=now, @@ -37,6 +37,7 @@ def test_relationship_all_required_properties(): def test_relationship_autogenerated_properties(relationship): assert relationship.type == 'relationship' + assert relationship.spec_version == '2.1' assert relationship.id == 'relationship--00000000-0000-0000-0000-000000000001' assert relationship.created == 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['type'] == 'relationship' + assert relationship['spec_version'] == '2.1' assert relationship['id'] == 'relationship--00000000-0000-0000-0000-000000000001' assert relationship['created'] == FAKE_TIME assert relationship['modified'] == FAKE_TIME @@ -55,9 +57,9 @@ def test_relationship_autogenerated_properties(relationship): def test_relationship_type_must_be_relationship(): 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.reason == "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(): 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.reason == "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(): with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: - stix2.Relationship() - assert excinfo.value.cls == stix2.Relationship + stix2.v21.Relationship() + assert excinfo.value.cls == stix2.v21.Relationship assert excinfo.value.properties == ["relationship_type", "source_ref", "target_ref"] def test_relationship_missing_some_required_properties(): 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"] def test_relationship_required_properties_target_ref(): with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo: - stix2.Relationship( + stix2.v21.Relationship( relationship_type='indicates', source_ref=INDICATOR_ID ) - assert excinfo.value.cls == stix2.Relationship + assert excinfo.value.cls == stix2.v21.Relationship assert excinfo.value.properties == ["target_ref"] @@ -108,15 +110,15 @@ def test_cannot_assign_to_relationship_attributes(relationship): def test_invalid_kwarg_to_relationship(): 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 str(excinfo.value) == "Unexpected properties for Relationship: (my_custom_property)." def test_create_relationship_from_objects_rather_than_ids(indicator, malware): - rel = stix2.Relationship( + rel = stix2.v21.Relationship( relationship_type="indicates", source_ref=indicator, 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): - rel = stix2.Relationship(indicator, 'indicates', malware) + rel = stix2.v21.Relationship(indicator, 'indicates', malware) assert rel.relationship_type == 'indicates' 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): - rel = stix2.parse(data) + rel = stix2.parse(data, version="2.1") assert rel.type == 'relationship' + assert rel.spec_version == '2.1' assert rel.id == RELATIONSHIP_ID 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) diff --git a/stix2/test/v21/test_report.py b/stix2/test/v21/test_report.py index da5a7ab..d9e2d49 100644 --- a/stix2/test/v21/test_report.py +++ b/stix2/test/v21/test_report.py @@ -29,7 +29,7 @@ EXPECTED = """{ def test_report_example(): - report = stix2.Report( + report = stix2.v21.Report( id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", @@ -49,7 +49,7 @@ def test_report_example(): def test_report_example_objects_in_object_refs(): - report = stix2.Report( + report = stix2.v21.Report( id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", 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", labels=["campaign"], 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", "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(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.Report( + stix2.v21.Report( id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", 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", labels=["campaign"], 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 "-" "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.reason == "must match --." assert str(excinfo.value) == "Invalid value for Report 'object_refs': must match --." @@ -115,9 +115,10 @@ def test_report_example_objects_in_object_refs_with_bad_id(): }, ]) def test_parse_report(data): - rept = stix2.parse(data) + rept = stix2.parse(data, version="2.1") assert rept.type == 'report' + assert rept.spec_version == '2.1' assert rept.id == REPORT_ID 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) diff --git a/stix2/test/v21/test_sighting.py b/stix2/test/v21/test_sighting.py index 209403e..baec1d9 100644 --- a/stix2/test/v21/test_sighting.py +++ b/stix2/test/v21/test_sighting.py @@ -35,7 +35,7 @@ BAD_SIGHTING = """{ def test_sighting_all_required_properties(): now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) - s = stix2.Sighting( + s = stix2.v21.Sighting( type='sighting', id=SIGHTING_ID, 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) with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.Sighting( + stix2.v21.Sighting( type='sighting', id=SIGHTING_ID, created=now, @@ -59,7 +59,7 @@ def test_sighting_bad_where_sighted_refs(): 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.reason == "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(): 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.reason == "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(): 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 str(excinfo.value) == "Unexpected properties for Sighting: (my_custom_property)." 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.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", "modified": "2016-04-06T20:06:37Z", "sighting_of_ref": "indicator--01234567-89ab-cdef-0123-456789abcdef", + "spec_version": "2.1", "type": "sighting", "where_sighted_refs": [ "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): - sighting = stix2.parse(data) + sighting = stix2.parse(data, version="2.1") assert sighting.type == 'sighting' + assert sighting.spec_version == '2.1' assert sighting.id == SIGHTING_ID 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) diff --git a/stix2/test/v21/test_threat_actor.py b/stix2/test/v21/test_threat_actor.py index c0001f0..54db522 100644 --- a/stix2/test/v21/test_threat_actor.py +++ b/stix2/test/v21/test_threat_actor.py @@ -23,7 +23,7 @@ EXPECTED = """{ def test_threat_actor_example(): - threat_actor = stix2.ThreatActor( + threat_actor = stix2.v21.ThreatActor( id="threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", @@ -53,9 +53,10 @@ def test_threat_actor_example(): }, ]) def test_parse_threat_actor(data): - actor = stix2.parse(data) + actor = stix2.parse(data, version="2.1") assert actor.type == 'threat-actor' + assert actor.spec_version == '2.1' assert actor.id == THREAT_ACTOR_ID 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) diff --git a/stix2/test/v21/test_tool.py b/stix2/test/v21/test_tool.py index 7920e3d..eaadc0b 100644 --- a/stix2/test/v21/test_tool.py +++ b/stix2/test/v21/test_tool.py @@ -36,7 +36,7 @@ EXPECTED_WITH_REVOKED = """{ def test_tool_example(): - tool = stix2.Tool( + tool = stix2.v21.Tool( id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", @@ -64,9 +64,10 @@ def test_tool_example(): }, ]) def test_parse_tool(data): - tool = stix2.parse(data) + tool = stix2.parse(data, version="2.1") assert tool.type == 'tool' + assert tool.spec_version == '2.1' assert tool.id == TOOL_ID 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) @@ -76,13 +77,13 @@ def test_parse_tool(data): 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): tool.created_by() def test_tool_serialize_with_defaults(): - tool = stix2.Tool( + tool = stix2.v21.Tool( id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", diff --git a/stix2/test/v21/test_utils.py b/stix2/test/v21/test_utils.py index 885c4d9..8b368d3 100644 --- a/stix2/test/v21/test_utils.py +++ b/stix2/test/v21/test_utils.py @@ -105,7 +105,7 @@ def test_deduplicate(stix_objs1): @pytest.mark.parametrize('object, tuple_to_find, expected_index', [ - (stix2.ObservedData( + (stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", @@ -158,6 +158,7 @@ def test_deduplicate(stix_objs1): }, ('key', {'key_one': 'value', 'key_two': 'value'}), 0), ({ "type": "language-content", + "spec_version": "2.1", "id": "language-content--b86bd89f-98bb-4fa9-8cb2-9ad421da981d", "created": "2017-02-08T21:31:22.007Z", "modified": "2017-02-08T21:31:22.007Z", diff --git a/stix2/test/v21/test_versioning.py b/stix2/test/v21/test_versioning.py index 254090d..acd34fa 100644 --- a/stix2/test/v21/test_versioning.py +++ b/stix2/test/v21/test_versioning.py @@ -6,11 +6,12 @@ from .constants import CAMPAIGN_MORE_KWARGS 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") 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 == campaign_v2.created assert campaign_v1.name != campaign_v2.name @@ -20,11 +21,12 @@ def test_making_new_version(): 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) 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 == campaign_v2.created 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(): - campaign_v1 = stix2.Campaign( + campaign_v1 = stix2.v21.Campaign( external_references=[{ "source_name": "capec", "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.spec_version == campaign_v2.spec_version assert campaign_v1.created_by_ref == campaign_v2.created_by_ref assert campaign_v1.created == campaign_v2.created assert campaign_v1.name == campaign_v2.name @@ -57,11 +60,12 @@ def test_making_new_version_with_embedded_object(): def test_revoke(): - campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) + campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v2 = campaign_v1.revoke() 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 == campaign_v2.created assert campaign_v1.name == campaign_v2.name @@ -72,7 +76,7 @@ def test_revoke(): 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: campaign_v1.new_version(type="threat-actor") @@ -81,19 +85,19 @@ def test_versioning_error_invalid_property(): 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: 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.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 " \ - "but have the same id and modified timestamp do not have defined consumer behavior." + 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 " + "but have the same id and modified timestamp do not have defined consumer behavior.") 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." "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.") @@ -101,21 +105,21 @@ def test_versioning_error_bad_modified_value(): 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: campaign_v1.new_version(name=None) - assert excinfo.value.cls == stix2.Campaign + assert excinfo.value.cls == stix2.v21.Campaign assert excinfo.value.properties == ["name"] 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 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() 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(): - campaign_v1 = stix2.Campaign(**CAMPAIGN_MORE_KWARGS) + campaign_v1 = stix2.v21.Campaign(**CAMPAIGN_MORE_KWARGS) campaign_v2 = campaign_v1.revoke() 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") 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'] == campaign_v2['created'] assert campaign_v1['name'] != campaign_v2['name'] @@ -187,6 +192,7 @@ def test_revoke_dict(): campaign_v2 = stix2.utils.revoke(campaign_v1) 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'] == campaign_v2['created'] assert campaign_v1['name'] == campaign_v2['name'] @@ -229,9 +235,9 @@ def test_remove_custom_stix_property(): def test_remove_custom_stix_object(): - @stix2.CustomObject("x-animal", [ - ("species", stix2.properties.StringProperty(required=True)), - ("animal_class", stix2.properties.StringProperty()), + @stix2.v21.CustomObject("x-animal", [ + ("species", stix2.v21.properties.StringProperty(required=True)), + ("animal_class", stix2.v21.properties.StringProperty()), ]) class Animal(object): pass @@ -244,7 +250,7 @@ def test_remove_custom_stix_object(): 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) assert len(campaign_v1.keys()) == len(campaign_v2.keys()) diff --git a/stix2/test/v21/test_vulnerability.py b/stix2/test/v21/test_vulnerability.py index daaef12..1f5b342 100644 --- a/stix2/test/v21/test_vulnerability.py +++ b/stix2/test/v21/test_vulnerability.py @@ -24,7 +24,7 @@ EXPECTED = """{ def test_vulnerability_example(): - vulnerability = stix2.Vulnerability( + vulnerability = stix2.v21.Vulnerability( id="vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", created="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): - vuln = stix2.parse(data) + vuln = stix2.parse(data, version="2.1") assert vuln.type == 'vulnerability' + assert vuln.spec_version == '2.1' assert vuln.id == VULNERABILITY_ID 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)