From 05ccffc5bd2c350b1db3eb726b02b77d9aa0bb08 Mon Sep 17 00:00:00 2001 From: clenk Date: Tue, 18 Apr 2017 09:21:38 -0400 Subject: [PATCH] Use correct Property classes for all STIX objects --- stix2/sdo.py | 118 ++++++++++++++++++----------------- stix2/sro.py | 16 ++--- stix2/test/test_indicator.py | 4 +- stix2/test/test_report.py | 8 +-- 4 files changed, 76 insertions(+), 70 deletions(-) diff --git a/stix2/sdo.py b/stix2/sdo.py index f7c9ad6..77db8dc 100644 --- a/stix2/sdo.py +++ b/stix2/sdo.py @@ -3,7 +3,8 @@ from .base import _STIXBase from .common import COMMON_PROPERTIES, KillChainPhase from .properties import (Property, ListProperty, StringProperty, TypeProperty, - IDProperty, ReferenceProperty) + IDProperty, TimestampProperty, ReferenceProperty, + IntegerProperty) from .utils import NOW @@ -14,9 +15,9 @@ class AttackPattern(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'name': Property(required=True), - 'description': Property(), - 'kill_chain_phases': Property(), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'kill_chain_phases': ListProperty(KillChainPhase), }) @@ -27,12 +28,12 @@ class Campaign(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'name': Property(required=True), - 'description': Property(), - 'aliases': Property(), - 'first_seen': Property(), - 'last_seen': Property(), - 'objective': Property(), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'aliases': ListProperty(StringProperty), + 'first_seen': TimestampProperty(), + 'last_seen': TimestampProperty(), + 'objective': StringProperty(), }) @@ -43,8 +44,8 @@ class CourseOfAction(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'name': Property(required=True), - 'description': Property(), + 'name': StringProperty(required=True), + 'description': StringProperty(), }) @@ -55,11 +56,12 @@ class Identity(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'name': Property(required=True), - 'description': Property(), - 'identity_class': Property(required=True), - 'sectors': Property(), - 'contact_information': Property(), + 'labels': ListProperty(StringProperty), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'identity_class': StringProperty(required=True), + 'sectors': ListProperty(StringProperty), + 'contact_information': StringProperty(), }) @@ -70,13 +72,13 @@ class Indicator(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'labels': Property(required=True), - 'name': Property(), - 'description': Property(), - 'pattern': Property(required=True), - 'valid_from': Property(default=lambda: NOW), - 'valid_until': Property(), - 'kill_chain_phases': Property(), + 'labels': ListProperty(StringProperty, required=True), + 'name': StringProperty(), + 'description': StringProperty(), + 'pattern': StringProperty(required=True), + 'valid_from': TimestampProperty(default=lambda: NOW), + 'valid_until': TimestampProperty(), + 'kill_chain_phases': ListProperty(KillChainPhase), }) @@ -87,15 +89,15 @@ class IntrusionSet(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'name': Property(required=True), - 'description': Property(), - 'aliases': Property(), - 'first_seen': Property(), - 'last_seen ': Property(), - 'goals': Property(), - 'resource_level': Property(), - 'primary_motivation': Property(), - 'secondary_motivations': Property(), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'aliases': ListProperty(StringProperty), + 'first_seen': TimestampProperty(), + 'last_seen ': TimestampProperty(), + 'goals': ListProperty(StringProperty), + 'resource_level': StringProperty(), + 'primary_motivation': StringProperty(), + 'secondary_motivations': ListProperty(StringProperty), }) @@ -120,9 +122,9 @@ class ObservedData(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'first_observed': Property(), - 'last_observed': Property(), - 'number_observed': Property(), + 'first_observed': TimestampProperty(required=True), + 'last_observed': TimestampProperty(required=True), + 'number_observed': IntegerProperty(required=True), 'objects': Property(), }) @@ -134,10 +136,10 @@ class Report(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'labels': Property(required=True), - 'name': Property(required=True), - 'description': Property(), - 'published': Property(), + 'labels': ListProperty(StringProperty, required=True), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'published': TimestampProperty(), 'object_refs': ListProperty(ReferenceProperty), }) @@ -149,17 +151,17 @@ class ThreatActor(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'labels': Property(required=True), - 'name': Property(required=True), - 'description': Property(), - 'aliases': Property(), - 'roles': Property(), - 'goals': Property(), - 'sophistication': Property(), - 'resource_level': Property(), - 'primary_motivation': Property(), - 'secondary_motivations': Property(), - 'personal_motivations': Property(), + 'labels': ListProperty(StringProperty, required=True), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'aliases': ListProperty(StringProperty), + 'roles': ListProperty(StringProperty), + 'goals': ListProperty(StringProperty), + 'sophistication': StringProperty(), + 'resource_level': StringProperty(), + 'primary_motivation': StringProperty(), + 'secondary_motivations': ListProperty(StringProperty), + 'personal_motivations': ListProperty(StringProperty), }) @@ -170,11 +172,11 @@ class Tool(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'labels': Property(required=True), - 'name': Property(required=True), - 'description': Property(), - 'kill_chain_phases': Property(), - 'tool_version': Property(), + 'labels': ListProperty(StringProperty, required=True), + 'name': StringProperty(required=True), + 'description': StringProperty(), + 'kill_chain_phases': ListProperty(KillChainPhase), + 'tool_version': StringProperty(), }) @@ -185,6 +187,6 @@ class Vulnerability(_STIXBase): _properties.update({ 'type': TypeProperty(_type), 'id': IDProperty(_type), - 'name': Property(required=True), - 'description': Property(), + 'name': StringProperty(required=True), + 'description': StringProperty(), }) diff --git a/stix2/sro.py b/stix2/sro.py index 2537567..30feef9 100644 --- a/stix2/sro.py +++ b/stix2/sro.py @@ -2,7 +2,9 @@ from .base import _STIXBase from .common import COMMON_PROPERTIES -from .properties import IDProperty, TypeProperty, ReferenceProperty, ListProperty, Property +from .properties import (ListProperty, StringProperty, TypeProperty, + IDProperty, TimestampProperty, ReferenceProperty, + IntegerProperty) class Relationship(_STIXBase): @@ -12,8 +14,8 @@ class Relationship(_STIXBase): _properties.update({ 'id': IDProperty(_type), 'type': TypeProperty(_type), - 'relationship_type': Property(required=True), - 'description': Property(), + 'relationship_type': StringProperty(required=True), + 'description': StringProperty(), 'source_ref': ReferenceProperty(required=True), 'target_ref': ReferenceProperty(required=True), }) @@ -41,13 +43,13 @@ class Sighting(_STIXBase): _properties.update({ 'id': IDProperty(_type), 'type': TypeProperty(_type), - 'first_seen': Property(), - 'last_seen': Property(), - 'count': Property(), + 'first_seen': TimestampProperty(), + 'last_seen': TimestampProperty(), + 'count': IntegerProperty(), 'sighting_of_ref': ReferenceProperty(required=True), 'observed_data_refs': ListProperty(ReferenceProperty(type="observed-data")), 'where_sighted_refs': ListProperty(ReferenceProperty(type="identity")), - 'summary': Property(), + 'summary': StringProperty(), }) # Explicitly define the first kwargs to make readable Sighting declarations. diff --git a/stix2/test/test_indicator.py b/stix2/test/test_indicator.py index d5fd3f4..421f681 100644 --- a/stix2/test/test_indicator.py +++ b/stix2/test/test_indicator.py @@ -2,6 +2,7 @@ import datetime as dt import pytest import pytz +import re import stix2 @@ -45,7 +46,8 @@ def test_indicator_with_all_required_fields(): ) assert str(ind) == EXPECTED_INDICATOR - assert repr(ind) == EXPECTED_INDICATOR_REPR + rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(ind)) + assert rep == EXPECTED_INDICATOR_REPR def test_indicator_autogenerated_fields(indicator): diff --git a/stix2/test/test_report.py b/stix2/test/test_report.py index 7cfcae9..2346658 100644 --- a/stix2/test/test_report.py +++ b/stix2/test/test_report.py @@ -17,7 +17,7 @@ EXPECTED = """{ "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a" ], - "published": "2016-01-201T17:00:00Z", + "published": "2016-01-20T17:00:00Z", "type": "report" }""" @@ -30,7 +30,7 @@ def test_report_example(): modified="2015-12-21T19:59:11Z", name="The Black Vine Cyberespionage Group", description="A simple report with an indicator and campaign", - published="2016-01-201T17:00:00Z", + published="2016-01-20T17:00:00Z", labels=["campaign"], object_refs=[ "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", @@ -50,7 +50,7 @@ def test_report_example_objects_in_object_refs(): modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", description="A simple report with an indicator and campaign", - published="2016-01-201T17:00:00Z", + published="2016-01-20T17:00:00Z", labels=["campaign"], object_refs=[ stix2.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), @@ -71,7 +71,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", description="A simple report with an indicator and campaign", - published="2016-01-201T17:00:00Z", + published="2016-01-20T17:00:00Z", labels=["campaign"], object_refs=[ stix2.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS),