def _generatenetwork(tree, network=None): if isinstance(tree, list): return [ _generatenetwork(item, network=network) for item in tree ] elif isinstance(tree, dict): return { k: _generatenetwork(v, network=network) for k, v in tree.items() } else: _dict = self.convert(tree) nodename = tree.__context__['class'] nodedict = _dict network.add_node(nodename, nodedict) if self.autolink: # if autolink is false, only explicit links will be set network.add_edge(tree.__context__['parent'].name, nodename) #TODO what if parent doesn't exist? #TODO add link properties to parent link _linkattribdict = {} for attrib in self.linkproperties: _attrib = getattr(tree, attrib, None) if _attrib is not None: if hasattr(_attrib, '__iter__'): if len(_attrib) > 1: raise ValueError( '%s in %s (%s) has multiple values and cannot ' 'be used for link properties' % (attrib, tree.__context__['class'], striptoclassname(type(tree)))) if hasattr(_attrib[0], '__convert__'): #handles coretypes _val = _attrib[0].__convert__(_attrib[0]) else: _val = _attrib[0] else: _val = _attrib _linkattribdict[attrib] = _val """ for k in _linkattribdict.keys(): if k in _dict: del(_dict[k]) """ if self.linkattribute is not None: _link = getattr(tree, self.linkattribute, None) else: _link = None if _link is not None: for link in _link: _obj = getObjectByUri('%s' % link) network.add_edge(nodename, _obj.__context__['class'], attr_dict=_linkattribdict) return _dict
def getname(obj, name): _val = None if hasattr(obj, name): _val = getattr(obj, name, None) if _val is None: return _val # handling for values from a method if isinstance(_val, str): return _val # handling for values in an Attribute # TODO integrate logic for value native string and strings in Attributes try: if _val.isdynamic: #TODO make this work for non-attributes, non-dynamics (use .issingleton? - what about a concat mode?) raise ValueError( 'Slice plugin cannot process %s because it contains a dynamic class' % name) except AttributeError: raise TypeError('Expected an attribute but got a %s' % type(_val)) if _val.issingleton(): _ret = '%s' % _val[0].raw() else: raise ValueError( 'Slice method plugin specified in user defined class %s ' 'only works on singleton attributes' % striptoclassname(type(self.targetobject))) return _ret
def getname(obj, name): _val = None if hasattr(obj, name): _val = getattr(obj, name, None) if _val is None: return _val # handling for values from a method if isinstance(_val, str): return _val try: if _val.isdynamic: raise ValueError('Cvssv2 plugin cannot process %s because it contains a dynamic class' % name) except AttributeError: raise TypeError('Expected an attribute but got a %s' % type(_val)) if _val.issingleton(): _ret = '%s' % _val[0].raw() else: raise ValueError('Cvssv2 method plugin specified in user defined class %s ' 'only works on singleton attributes' % striptoclassname(type(self.targetobject))) return _ret
def slicer(stringvalue, start=None, end=None): if not isinstance(stringvalue, str): raise ValueError('Slice plugin only works on string ' 'or string like attributes but got ' 'a %s instead' % striptoclassname(type(self.targetobject))) if start is None and end is None: raise ValueError( 'Slice plugin expects at least one of either a start and stop value' ) if isinstance(start, int) or start is None: pass else: raise ValueError( 'Slice plugin start value must be empty or an number but it got %s' % start) if isinstance(end, int) or end is None: pass else: raise ValueError( 'Slice plugin finish value must be empty or an number but it got %s' % end) if start is None: _ret = stringvalue[:end] elif end is None: _ret = stringvalue[start:] else: _ret = stringvalue[start:end] return _ret
def sub(matchlist, node, result, numbering=True): #returns results via list reference if isinstance(node, StructureFactory.Container): _class = 'container' else: _class = striptoclassname(node.__objectmatch__()) if _class == matchlist[0] and len(matchlist) == 1: if numbering: result.append('({0}) {1}'.format( len(result) + 1, node.fileobject.path)) else: result.append(node.fileobject.path) elif _class == matchlist[0] and len(matchlist) > 1 and len( node.children) > 0: for child in node.children: sub(matchlist[1:], child, result)
def __getattribute__(self, name): """ an "anonymous" function that will be included into the dynamically generated class to made dynamically generated properties exist. :param self: object instance :param name: name of object attribute after the dot notation :return: list """ try: listslots = object.__getattribute__(self, '__list_slots__') return listslots[name] except Exception: pass try: #self.__method_results__[name] methodresults = object.__getattribute__(self, '__method_results__') return methodresults[name] except Exception: pass try: methodlist = object.__getattribute__(self, '__methods__') methodresults = object.__getattribute__(self, '__method_results__') methoddeferred = object.__getattribute__(self, '__method_deferred__') if name in methodlist and methoddeferred: #assume it's not in method_results because that would have returned #attempt to compute because it was deferred before self.loadmethod(name, methodlist[name], force=True) if name in methodresults: return methodresults[name] else: raise SyntaxError( 'In %s a method called %s is being consumed before it is initialized. ' 'Make sure you declare your methods in order.' % (striptoclassname(type(self)), name)) except NotComputed: print('could not compute') except AttributeError: pass return super(DynamicType, self).__getattribute__(name)
def __init__(self, obj, config=None): _config = {FILEONLY: False} if config is not None: _configlist = [c.strip().lower() for c in config.split('=')] if len(_configlist) == 2 and _configlist[0] == FILEONLY: _config[FILEONLY] = strtobool(_configlist[1]) else: raise ValueError( 'Artefact method plugin (used in user defined class %s) accepts a single argument of either ' '"fileonly = True" or "fileonly = False". By default fileonly mode is False ' 'and does not need to be specified' % striptoclassname(type(obj))) super(Artefacts, self).__init__(obj, config=_config) self.computable = True
def __classoutputscheme__(self): return formatternamespace()[striptoclassname(self.__class__)]
def displayname(cls): return cls.metas()['displayname'] if 'displayname' in cls.metas( ) else '%s' % striptoclassname(cls)
def loads(self, loadstring, softload=False, context=None): # TODO make use of context in error reporting """ Method to read in a correctly structured string and load it into the object attributes :param loadstring: :return: True if data loaded """ def parseLoadstring(loadstring): attributeStartMarker = p.LineStart() + p.Literal('@') attributeStopMarker = p.Literal(':') exp = attributeStartMarker.suppress() + p.Word( p.alphanums + '_') + attributeStopMarker.suppress() # ret = {} ret = defaultdict(list) for index, line in enumerate(loadstring.splitlines()): # print(line) # TODO switch from scanString to full parsing result = list(exp.scanString(line)) if len(result) > 0: # TODO this is kludgy attribname = result[0][0][0] matchstart = result[0][1] matchend = result[0][2] + 1 if matchstart == 0: # print('matched on line %s' % index) # print('%s: %s' % (attribname, line[matchend:])) ret[attribname].append(line[matchend:]) else: raise Exception('attrib not at the start of the line') else: # print('no match on line %s' % index) # last = len(ret) - 1 ret[attribname][-1:] = [ ret[attribname][-1:][0] + "" + line.strip() ] return ret def convertandload(_self, attrname, attrval): cfunc = _self.__list_slots__[attrname].__convert__ attrfunc = _self.__list_slots__[attrname].attrtype return [attrfunc(cfunc(s.strip())) for s in attrval] self.__context__ = context ret = parseLoadstring(loadstring) attriblist = [k for k in ret.keys()] # check if all attribs required by class definition are in the data file for prop in self.__dynamic_properties__: # TODO don't raise for non-mandatory attribs if prop not in attriblist: if prop in self.__mandatory_properties__ and softload is False: raise AttributeError( 'attribute %s required by %s class definition file but not found in %s' % (prop, striptoclassname( self.__class__), self.__context__['file'])) if prop in self.__mandatory_properties__ and softload is True: self.__missing_mandatory_properties__.append(prop) if prop not in self.__mandatory_properties__: self.__missing_optional_properties__.append(prop) # reverse check of above and to ensure only attributes required by class file are present in data file for attrname, attrval in ret.items(): if attrname not in self.__dynamic_properties__: raise AttributeError( 'attribute "%s" found in load string from %s ' 'but not in %s class definition file' % (attrname, self.__context__['file'], striptoclassname(self.__class__))) else: # TODO load into object attribs # TODO pass in args (also refactor load so dict args are correct) try: self.__list_slots__[attrname].__load__( convertandload(self, attrname, attrval)) except Exception as err: raise TypeError( 'got an error when trying to load data for %s from %s: %s' % (striptoclassname( self.__class__), self.__context__['file'], err)) for k, v in self.__methods__.items(): self.loadmethod(k, v) registerObject(self.__context__['file'], self) #TODO make this true if the process completes correctly instead of true if results are returned return True if len(ret) > 0 else False
def compute(self): def getname(obj, name): _val = None if hasattr(obj, name): _val = getattr(obj, name, None) if _val is None: return _val # handling for values from a method if isinstance(_val, str): return _val try: if _val.isdynamic: raise ValueError('Cvssv2 plugin cannot process %s because it contains a dynamic class' % name) except AttributeError: raise TypeError('Expected an attribute but got a %s' % type(_val)) if _val.issingleton(): _ret = '%s' % _val[0].raw() else: raise ValueError('Cvssv2 method plugin specified in user defined class %s ' 'only works on singleton attributes' % striptoclassname(type(self.targetobject))) return _ret attrid = (p.Literal('@') | p.Literal('!')).suppress() + p.Word(p.alphanums) attrexpr = attrid.setResultsName('attribute') parseresult = attrexpr.parseString(self.config) _attrname = parseresult.get('attribute', None)[0] if _attrname is None: raise ValueError('The configuration string provided to the Cvssv2 method ' 'plugin in user defined class %s does not contain an ' 'identifiable attribute. Please provide a configuration ' 'string in the form of \'@attribute[#:#]\'' % striptoclassname(type(self.targetobject))) self.vector = getname(self.targetobject, _attrname) if isinstance(self.vector, str): self.computable = True if self.computable: try: _score = calculate_vector(self.vector, cvss2) _index = len([c for c in _score if c is not None]) - 1 self.__result__ = _score[_index] #self.__result__ = ', '.join(str(i) for i in _score) except Exception as err: raise Exception('When the Cvssv2 method plugin used in ' 'the %s class attempted to process the provided ' 'vector string from %s in %s, the following ' 'error occured: %s' % ( striptoclassname(type(self.targetobject)), _attrname, self.targetobject.__context__['file'], err ))
def compute(self): def slicer(stringvalue, start=None, end=None): if not isinstance(stringvalue, str): raise ValueError('Slice plugin only works on string ' 'or string like attributes but got ' 'a %s instead' % striptoclassname(type(self.targetobject))) if start is None and end is None: raise ValueError( 'Slice plugin expects at least one of either a start and stop value' ) if isinstance(start, int) or start is None: pass else: raise ValueError( 'Slice plugin start value must be empty or an number but it got %s' % start) if isinstance(end, int) or end is None: pass else: raise ValueError( 'Slice plugin finish value must be empty or an number but it got %s' % end) if start is None: _ret = stringvalue[:end] elif end is None: _ret = stringvalue[start:] else: _ret = stringvalue[start:end] return _ret def getname(obj, name): _val = None if hasattr(obj, name): _val = getattr(obj, name, None) if _val is None: return _val # handling for values from a method if isinstance(_val, str): return _val # handling for values in an Attribute # TODO integrate logic for value native string and strings in Attributes try: if _val.isdynamic: #TODO make this work for non-attributes, non-dynamics (use .issingleton? - what about a concat mode?) raise ValueError( 'Slice plugin cannot process %s because it contains a dynamic class' % name) except AttributeError: raise TypeError('Expected an attribute but got a %s' % type(_val)) if _val.issingleton(): _ret = '%s' % _val[0].raw() else: raise ValueError( 'Slice method plugin specified in user defined class %s ' 'only works on singleton attributes' % striptoclassname(type(self.targetobject))) return _ret attrexpr = (p.Literal('@') | p.Literal('!')).suppress() + p.Word( p.alphanums) slicestartexpr = p.Literal('[').suppress() + p.Optional(p.Word(p.nums)) sliceendexpr = p.Optional(p.Word(p.nums)) + p.Literal(']').suppress() sliceexpr = attrexpr.setResultsName('attribute') + \ slicestartexpr.setResultsName('start') + \ p.Suppress(p.Literal(':')) + \ sliceendexpr.setResultsName('end') parseresult = sliceexpr.parseString(self.config) _attrname = parseresult.get('attribute', None)[0] _slicestart = parseresult.get('start', None) _sliceend = parseresult.get('end', None) if isinstance(_slicestart, p.ParseResults) and len(_slicestart) > 0: self.slicestart = int( _slicestart[0]) if len(_slicestart[0]) > 0 else None if isinstance(_sliceend, p.ParseResults) and len(_sliceend) > 0: self.sliceend = int( _sliceend[0]) if len(_sliceend[0]) > 0 else None if _attrname is None: raise ValueError( 'The configuration string provided to the Slice method ' 'plugin in user defined class %s does not contain an ' 'identifiable attribute. Please provide a configuration ' 'string in the form of \'@attribute[#:#]\'' % striptoclassname(type(self.targetobject))) self.stringvalue = getname(self.targetobject, _attrname) if isinstance(self.stringvalue, str): self.computable = True if self.computable: self.__result__ = slicer(self.stringvalue, start=self.slicestart, end=self.sliceend)