Skip to content

Commit 4dc4430

Browse files
author
Bryan Worrell
committed
Merged typedfield-entitylist branch into typedfields branch.
2 parents acfdfa5 + f2e21ba commit 4dc4430

26 files changed

Lines changed: 553 additions & 408 deletions

stix/campaign/__init__.py

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,55 @@
1010
RelatedIncident, RelatedIndicator, RelatedPackageRefs, RelatedThreatActor,
1111
RelatedTTP)
1212
from stix.common import vocabs
13+
from stix.common.vocabs import VocabField
1314
import stix.bindings.campaign as campaign_binding
1415
from stix.common.structured_text import StructuredTextList
1516
from stix.common.information_source import InformationSource
1617

18+
1719
class AssociatedCampaigns(GenericRelationshipList):
1820
_namespace = "http://stix.mitre.org/Campaign-1"
1921
_binding = campaign_binding
2022
_binding_class = campaign_binding.AssociatedCampaignsType
21-
_binding_var = "Associated_Campaign"
22-
_contained_type = RelatedCampaign
23-
_inner_name = "campaigns"
23+
24+
campaign = fields.TypedField("Associated_Campaign", RelatedCampaign, multiple=True, key_name="campaigns")
25+
26+
@classmethod
27+
def _dict_as_list(cls):
28+
return False
29+
2430

2531
class Attribution(GenericRelationshipList):
2632
_namespace = "http://stix.mitre.org/Campaign-1"
2733
_binding = campaign_binding
2834
_binding_class = campaign_binding.AttributionType
29-
_binding_var = "Attributed_Threat_Actor"
30-
_contained_type = RelatedThreatActor
31-
_inner_name = "threat_actors"
35+
36+
threat_actor = fields.TypedField("Attributed_Threat_Actor", RelatedThreatActor, multiple=True, key_name="threat_actors")
37+
38+
@classmethod
39+
def _dict_as_list(cls):
40+
return False
3241

3342

3443
class RelatedIncidents(GenericRelationshipList):
3544
_namespace = "http://stix.mitre.org/Campaign-1"
3645
_binding = campaign_binding
3746
_binding_class = campaign_binding.RelatedIncidentsType
38-
_binding_var = "Related_Incident"
39-
_contained_type = RelatedIncident
40-
_inner_name = "incidents"
47+
48+
incident = fields.TypedField("Related_Incident", RelatedIncident, multiple=True, key_name="incidents")
49+
50+
@classmethod
51+
def _dict_as_list(cls):
52+
return False
4153

4254

4355
class RelatedIndicators(GenericRelationshipList):
4456
_namespace = "http://stix.mitre.org/Campaign-1"
4557
_binding = campaign_binding
4658
_binding_class = campaign_binding.RelatedIndicatorsType
47-
_binding_var = "Related_Indicator"
48-
_contained_type = RelatedIndicator
49-
_inner_name = "indicators"
59+
60+
indicator = fields.TypedField("Related_Indicator", RelatedIndicator, multiple=True, key_name="indicators")
61+
5062

5163
def _is_valid(self, value):
5264
deprecated.warn(value)
@@ -57,18 +69,24 @@ class RelatedTTPs(GenericRelationshipList):
5769
_namespace = "http://stix.mitre.org/Campaign-1"
5870
_binding = campaign_binding
5971
_binding_class = campaign_binding.RelatedTTPsType
60-
_binding_var = "Related_TTP"
61-
_contained_type = RelatedTTP
62-
_inner_name = "ttps"
72+
73+
ttp = fields.TypedField("Related_TTP", RelatedTTP, multiple=True, key_name="ttps")
74+
75+
@classmethod
76+
def _dict_as_list(cls):
77+
return False
6378

6479

6580
class Names(stix.EntityList):
6681
_namespace = "http://stix.mitre.org/Campaign-1"
6782
_binding = campaign_binding
6883
_binding_class = campaign_binding.NamesType
69-
_binding_var = "Name"
70-
_contained_type = VocabString
71-
_inner_name = "names"
84+
85+
name = VocabField("Name", multiple=True, key_name="names")
86+
87+
@classmethod
88+
def _dict_as_list(cls):
89+
return False
7290

7391

7492
class Campaign(stix.BaseCoreComponent):

stix/coa/__init__.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,35 @@ class RelatedCOAs(GenericRelationshipList):
3232
_inner_name = "coas"
3333

3434

35+
class PotentialCOAs(GenericRelationshipList):
36+
"""
37+
A list of ``Potential_COA`` objects, defaults to empty array
38+
"""
39+
_namespace = "http://stix.mitre.org/ExploitTarget-1"
40+
_binding = exploit_target_binding
41+
_binding_class = exploit_target_binding.PotentialCOAsType
42+
43+
potential_coa = fields.TypedField("Potential_COA", RelatedCOA, multiple=True, key_name="coas")
44+
45+
def __init__(self, coas=None, scope=None):
46+
super(PotentialCOAs, self).__init__(scope, coas)
47+
48+
49+
class RelatedExploitTargets(GenericRelationshipList):
50+
"""
51+
A list of ``RelatedExploitTargets`` objects, defaults to empty array
52+
"""
53+
_namespace = "http://stix.mitre.org/ExploitTarget-1"
54+
_binding = exploit_target_binding
55+
_binding_class = exploit_target_binding.RelatedExploitTargetsType
56+
57+
related_exploit_target = fields.TypedField("Related_Exploit_Target", RelatedExploitTarget, multiple=True, key_name="related_exploit_targets")
58+
59+
def __init__(self, related_exploit_targets=None, scope=None):
60+
super(RelatedExploitTargets, self).__init__(scope, related_exploit_targets)
61+
62+
63+
3564
class CourseOfAction(stix.BaseCoreComponent):
3665
"""Implementation of the STIX Course of Action.
3766

stix/common/identity.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@ class RelatedIdentities(stix.EntityList):
4646
_namespace = 'http://stix.mitre.org/common-1'
4747
_binding = common_binding
4848
_binding_class = common_binding.RelatedIdentitiesType
49-
_binding_var = "Related_Identity"
50-
_contained_type = RelatedIdentity
51-
_inner_name = "identities"
49+
50+
related_identity = fields.TypedField("Related_Identity", RelatedIdentity, multiple=True, key_name="identities")
51+
52+
@classmethod
53+
def _dict_as_list(cls):
54+
return False
5255

5356

5457
# Backwards compatibility

stix/common/information_source.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ class ContributingSources(stix.EntityList):
8989
_namespace = "http://stix.mitre.org/common-1"
9090
_binding = stix_common_binding
9191
_binding_class = stix_common_binding.ContributingSourcesType
92-
_binding_var = "Source"
93-
_contained_type = InformationSource
94-
_inner_name = "sources"
9592

93+
source = fields.TypedField("Source", InformationSource, multiple=True, key_name="sources")
94+
95+
@classmethod
96+
def _dict_as_list(cls):
97+
return False

stix/common/kill_chains/__init__.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# See LICENSE.txt for complete terms.
33

44
from mixbox import fields
5+
from mixbox import typedlist
56

67
# internal
78
import stix
@@ -48,9 +49,12 @@ class KillChains(stix.EntityList):
4849
_binding = common_binding
4950
_namespace = 'http://stix.mitre.org/common-1'
5051
_binding_class = _binding.KillChainsType
51-
_contained_type = KillChain
52-
_binding_var = "Kill_Chain"
53-
_inner_name = "kill_chains"
52+
53+
kill_chain = fields.TypedField("Kill_Chain", KillChain, multiple=True, key_name="kill_chains")
54+
55+
@classmethod
56+
def _dict_as_list(cls):
57+
return False
5458

5559

5660
class KillChainPhase(stix.Entity):
@@ -82,6 +86,7 @@ def __ne__(self, other):
8286
return not self.__eq__(other)
8387

8488
def __hash__(self):
89+
# TODO (bworrell): Is all the tuple(sorted(...))) needed?
8590
return hash(tuple(sorted(self.to_dict().items())))
8691

8792

@@ -99,24 +104,38 @@ def __init__(self, phase_id=None, name=None, ordinality=None, kill_chain_id=None
99104
self.kill_chain_name = kill_chain_name
100105

101106

102-
class KillChainPhasesReference(stix.EntityList):
103-
_binding = common_binding
104-
_namespace = 'http://stix.mitre.org/common-1'
105-
_binding_class = _binding.KillChainPhasesReferenceType
106-
_contained_type = KillChainPhaseReference
107-
_binding_var = "Kill_Chain_Phase"
108-
_inner_name = "kill_chain_phases"
107+
class _KillChainPhaseReferenceList(typedlist.TypedList):
108+
def __init__(self, *args):
109+
super(_KillChainPhaseReferenceList, self).__init__(type=KillChainPhaseReference, *args)
109110

110111
def _fix_value(self, value):
111112
if not isinstance(value, KillChainPhase):
112-
return super(KillChainPhasesReference, self)._fix_value(value)
113+
return super(_KillChainPhaseReferenceList, self)._fix_value(value)
113114

114115
if value.phase_id:
115116
return KillChainPhaseReference(phase_id=value.phase_id)
116117

117118
raise ValueError("KillChainPhase must have a phase_id.")
118119

119120

121+
class KillChainPhasesReference(stix.EntityList):
122+
_binding = common_binding
123+
_namespace = 'http://stix.mitre.org/common-1'
124+
_binding_class = _binding.KillChainPhasesReferenceType
125+
126+
kill_chain_phase = fields.TypedField(
127+
name="Kill_Chain_Phase",
128+
type_=KillChainPhaseReference,
129+
multiple=True,
130+
listfunc=_KillChainPhaseReferenceList,
131+
key_name="kill_chain_phases"
132+
)
133+
134+
@classmethod
135+
def _dict_as_list(cls):
136+
return False
137+
138+
120139
# NOT AN ACTUAL STIX TYPE!
121140
class _KillChainPhases(stix.TypedList):
122141
_contained_type = KillChainPhase

stix/common/names.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
22
# See LICENSE.txt for complete terms.
33

4+
# external
5+
from mixbox import fields
6+
47
# internal
58
import stix
69
import stix.bindings.stix_common as common_binding
710

811
# relative
9-
from .vocabs import VocabString, VocabFactory
12+
from .vocabs import VocabField
1013

1114

1215
class Names(stix.EntityList):
1316
_namespace = 'http://stix.mitre.org/common-1'
1417
_binding = common_binding
1518
_binding_class = _binding.NamesType
16-
_contained_type = VocabString
17-
_entity_factory = VocabFactory
18-
_binding_var = 'Name'
19+
20+
name = VocabField("Name", multiple=True)

0 commit comments

Comments
 (0)