77 from ..core .metadata import Metadata
88 from ..core .versions import Versions
99 from ..core .exceptions import UNSETVALUE , typeChecker , BadInput , handler , \
10- categoryChecker , UnknownLayerProperty
10+ categoryChecker , UnknownLayerProperty , loadChecker , MissingParameters
1111except ValueError :
1212 from core .filter import Filter
1313 from core .layout import Layout
1717 from core .metadata import Metadata
1818 from core .versions import Versions
1919 from core .exceptions import UNSETVALUE , typeChecker , BadInput , handler , \
20- categoryChecker , UnknownLayerProperty
20+ categoryChecker , UnknownLayerProperty , loadChecker , MissingParameters
2121
2222class _LayerObj :
23- def __init__ (self , versions , name , domain ):
23+ def __init__ (self , name , domain ):
2424 """
2525 Initialization - Creates a layer object
2626
27- :param version: The corresponding att&ck layer version
2827 :param name: The name for this layer
29- :param domain: The domain for this layer (mitre- enterprise
30- or mitre- mobile)
28+ :param domain: The domain for this layer (enterprise-attack
29+ or mobile-attack )
3130 """
32- self .versions = versions
31+ self .__versions = UNSETVALUE
3332 self .name = name
3433 self .__description = UNSETVALUE
3534 self .domain = domain
@@ -48,28 +47,35 @@ def __init__(self, versions, name, domain):
4847
4948 @property
5049 def version (self ):
51- return self .__versions .layer
50+ if self .__versions != UNSETVALUE :
51+ return self .__versions .layer
5252
5353 @version .setter
5454 def version (self , version ):
5555 typeChecker (type (self ).__name__ , version , str , "version" )
5656 categoryChecker (type (self ).__name__ , version , ["3.0" , "4.0" ], "version" )
57+ if self .__versions is UNSETVALUE :
58+ self .__versions = Versions ()
5759 self .__versions .layer = version
5860
5961 @property
6062 def versions (self ):
61- return self .__versions
63+ if self .__versions != UNSETVALUE :
64+ return self .__versions
6265
6366 @versions .setter
6467 def versions (self , versions ):
6568 typeChecker (type (self ).__name__ , versions , dict , "version" )
66- attack = None
67- nav = None
69+ attack = UNSETVALUE
6870 if 'attack' in versions :
6971 attack = versions ['attack' ]
70- if 'navigator' in versions :
71- nav = versions ['navigator' ]
72- self .__versions = Versions (versions ['layer' ], attack , nav )
72+ try :
73+ loadChecker (type (self ).__name__ , versions , ['layer' , 'navigator' ], "versions" )
74+ self .__versions = Versions (versions ['layer' ], attack , versions ['navigator' ])
75+ except MissingParameters as e :
76+ handler (type (self ).__name__ , 'versions {} is missing parameters: '
77+ '{}. Skipping.'
78+ .format (versions , e ))
7379
7480 @property
7581 def name (self ):
@@ -112,20 +118,16 @@ def filters(self):
112118
113119 @filters .setter
114120 def filters (self , filters ):
115- if self .version == "4.0" :
116- temp = Filterv4 (self .domain )
117- else :
118- temp = Filter (self .domain )
121+ temp = Filterv4 (self .domain )
119122 try :
120- if self . version != "4.0" :
121- temp . stages = filters [ 'stages' ]
123+ loadChecker ( type ( self ). __name__ , filters , [ 'platforms' ], "filters" )
124+ # force upgrade to v4
122125 temp .platforms = filters ['platforms' ]
123126 self .__filters = temp
124- except KeyError as e :
125- handler (type (self ).__name__ , "Unable to properly extract "
126- "information from filter: {}."
127- .format (e ))
128- raise BadInput
127+ except MissingParameters as e :
128+ handler (type (self ).__name__ , 'Filters {} is missing parameters: '
129+ '{}. Skipping.'
130+ .format (filters , e ))
129131
130132 @property
131133 def sorting (self ):
@@ -173,17 +175,17 @@ def techniques(self):
173175 def techniques (self , techniques ):
174176 typeChecker (type (self ).__name__ , techniques , list , "techniques" )
175177 self .__techniques = []
176- entry = ""
177- try :
178- for entry in techniques :
178+
179+ for entry in techniques :
180+ try :
181+ loadChecker (type (self ).__name__ , entry , ['techniqueID' ], "technique" )
179182 temp = Technique (entry ['techniqueID' ])
180183 temp ._loader (entry )
181184 self .__techniques .append (temp )
182- except KeyError as e :
183- handler (type (self ).__name__ , "Unable to properly extract "
184- "information from technique {}: {}."
185- .format (entry , e ))
186- raise BadInput
185+ except MissingParameters as e :
186+ handler (type (self ).__name__ , 'Technique {} is missing parameters: '
187+ '{}. Skipping.'
188+ .format (entry , e ))
187189
188190 @property
189191 def gradient (self ):
@@ -193,12 +195,12 @@ def gradient(self):
193195 @gradient .setter
194196 def gradient (self , gradient ):
195197 try :
196- self . __gradient = Gradient ( gradient ['colors' ],
197- gradient ['minValue' ],
198- gradient [ 'maxValue' ])
199- except KeyError as e :
200- handler ( type ( self ). __name__ , 'Gradient is missing parameters: {}. '
201- 'Unable to load.' . format (e ))
198+ loadChecker ( type ( self ). __name__ , gradient , ['colors' , 'minValue' , 'maxValue' ], "gradient" )
199+ self . __gradient = Gradient ( gradient [ 'colors' ], gradient ['minValue' ], gradient [ 'maxValue' ])
200+ except MissingParameters as e :
201+ handler ( type ( self ). __name__ , 'Gradient {} is missing parameters: '
202+ ' {}. Skipping. '
203+ . format (gradient , e ))
202204
203205 @property
204206 def legendItems (self ):
@@ -209,15 +211,15 @@ def legendItems(self):
209211 def legendItems (self , legendItems ):
210212 typeChecker (type (self ).__name__ , legendItems , list , "legendItems" )
211213 self .__legendItems = []
212- entry = ""
213- try :
214- for entry in legendItems :
214+ for entry in legendItems :
215+ try :
216+ loadChecker ( type ( self ). __name__ , entry , [ 'label' , 'color' ], "legendItem" )
215217 temp = LegendItem (entry ['label' ], entry ['color' ])
216218 self .__legendItems .append (temp )
217- except KeyError as e :
218- handler (type (self ).__name__ , 'LegendItem {} is missing parameters:'
219- ' {}. Unable to load .'
220- .format (entry , e ))
219+ except MissingParameters as e :
220+ handler (type (self ).__name__ , 'Legend Item {} is missing parameters: '
221+ ' {}. Skipping .'
222+ .format (entry , e ))
221223
222224 @property
223225 def showTacticRowBackground (self ):
@@ -272,13 +274,13 @@ def metadata(self):
272274 def metadata (self , metadata ):
273275 typeChecker (type (self ).__name__ , metadata , list , "metadata" )
274276 self .__metadata = []
275- entry = ""
276- try :
277- for entry in metadata :
277+ for entry in metadata :
278+ try :
279+ loadChecker ( type ( self ). __name__ , entry , [ 'name' , 'value' ], " metadata" )
278280 self .__metadata .append (Metadata (entry ['name' ], entry ['value' ]))
279- except KeyError as e :
280- handler (type (self ).__name__ , 'Metadata {} is missing parameters: '
281- '{}. Unable to load .'
281+ except MissingParameters as e :
282+ handler (type (self ).__name__ , 'Metadata {} is missing parameters: '
283+ '{}. Skipping .'
282284 .format (entry , e ))
283285
284286 def _enumerate (self ):
@@ -321,10 +323,12 @@ def get_dict(self):
321323 Converts the currently loaded layer into a dict
322324 :returns: A dict representation of the current layer object
323325 """
324- temp = dict (name = self .name , versions = self . versions . get_dict (), domain = self .domain )
326+ temp = dict (name = self .name , domain = self .domain )
325327
326328 if self .description :
327329 temp ['description' ] = self .description
330+ if self .versions :
331+ temp ['versions' ] = self .versions .get_dict ()
328332 if self .filters :
329333 temp ['filters' ] = self .filters .get_dict ()
330334 if self .sorting :
@@ -364,6 +368,13 @@ def _linker(self, field, data):
364368 """
365369 if field == 'description' :
366370 self .description = data
371+ elif field .startswith ('version' ):
372+ if not field .endswith ('s' ):
373+ # force upgrade
374+ ver_obj = dict (layer = "4.0" , navigator = "4.0" )
375+ self .versions = ver_obj
376+ else :
377+ self .versions = data
367378 elif field == 'filters' :
368379 self .filters = data
369380 elif field == 'sorting' :
0 commit comments