def _get_class_instances(self, module_str, module): """Returns a tuple with objects that could be instantiated without arguments. Args: module: A ModuleType object. It can be either in the lowest or highest level module. Returns: A tuple with `mixbox.Entity` objects from the given module. """ result = () for klass_ in itervalues(vars(module)): try: if inspect.isclass(klass_) and issubclass( klass_, entities.Entity): result += (klass_(), ) elif inspect.ismodule(klass_) and ( module_str in module_name(klass_) and module_str != module_name(klass_)): result += self._get_class_instances(module_str, klass_) except: msg = "{0} could not be instantiated without args." LOG.debug(msg.format(klass_)) continue return result
def _set_vocab(self, klass=None, **kwargs): """Sets a controlled vocabulary property value. * If the input value is ``None``, the property is set to ``None``. * If the input value is an instance of ``VocabString``, the property is set to the input value. * If the input value is not an instance of ``VocabString``, an attempt will be made to cast the input to an instance of `klass`. If `klass` is ``None``, ``VocabString`` will be used. Args: klass: The VocabString impl to cast the input value to. If ``None`` ``VocabString`` will be assumed. **kwargs: The field name, value pair. The field name is the key and the field value is the value. """ from stix.common import VocabString klass = klass or VocabString item = next(itervalues(kwargs)) if isinstance(item, VocabString): self._set_var(VocabString, **kwargs) else: self._set_var(klass, **kwargs)
def status_code(results): """Determines the exit status code to be returned from this script by inspecting the results returned from validating file(s). Status codes are binary OR'd together, so exit codes can communicate multiple error conditions. """ status = codes.EXIT_SUCCESS for result in itervalues(results): schema = result.schema_results best_practice = result.best_practice_results profile = result.profile_results fatal = result.fatal if schema and not schema.is_valid: status |= codes.EXIT_SCHEMA_INVALID if best_practice and not best_practice.is_valid: status |= codes.EXIT_BEST_PRACTICE_INVALID if profile and not profile.is_valid: status |= codes.EXIT_PROFILE_INVALID if fatal: status |= codes.EXIT_VALIDATION_ERROR return status
def _check_1_2_duplicate_ids(self, root, namespaces, version): # noqa """STIX 1.2 dropped the schematic enforcement of id uniqueness to support versioning of components. This checks for duplicate (id, timestamp) pairs. """ results = BestPracticeWarningCollection('Duplicate IDs') nlist = namespaces.values() # Find all nodes with IDs in the STIX/CybOX namespace nodes = root.xpath("//*[@id]") filtered = [x for x in nodes if utils.namespace(x) in nlist] # Build a mapping of IDs to nodes idnodes = collections.defaultdict(list) for node in filtered: idnodes[node.attrib.get('id')].append(node) # Find all nodes that have duplicate IDs dups = [x for x in itervalues(idnodes) if len(x) > 1] # Build warnings for all nodes that have conflicting id/timestamp pairs. for nodeset in dups: warns = self._get_id_timestamp_conflicts(nodeset) results.extend(warns) return results
def instanceof(cls): """Return all cached objects that are instances of the input `cls`.""" instances = [] for cached in six.itervalues(_CACHE): objects = list(cached) # Temporarily create strong refs instances.extend(x for x in objects if isinstance(x, cls)) return instances
def _get_schemalocs(node): schemalocs = {} for ns in itervalues(node.nsmap): if ns not in self._schemalocs: continue schemalocs[ns] = self._schemalocs[ns] return schemalocs
def get_uri_schemaloc_map(self): """Constructs and returns a map from namespace URI to schema location URI. Namespaces without schema locations are excluded.""" mapping = {} for ni in six.itervalues(self.__ns_uri_map): if ni.schema_location: mapping[ni.uri] = ni.schema_location return mapping
def _check_1_0_duplicate_ids(self, root, namespaces, version): # noqa """Checks for duplicate ids in the document. """ id_nodes = collections.defaultdict(list) for node in root.xpath("//*[@id]"): id_nodes[node.attrib['id']].append(node) results = BestPracticeWarningCollection('Duplicate IDs') for nodes in itervalues(id_nodes): if len(nodes) > 1: results.extend(BestPracticeWarning(node=x) for x in nodes) return results
def __new__(metacls, name, bases, dict_): obj = type.__new__(metacls, name, bases, dict_) # Initialize a mapping of STIX versions to applicable rule funcs. ruledict = collections.defaultdict(list) # Find all @rule marked functions in the class dict_ rulefuncs = (x for x in itervalues(dict_) if hasattr(x, 'is_rule')) # Build the rule function dict. for rule in rulefuncs: ruledict[(rule.min_version, rule.max_version)].append(rule) # noqa # Attach the rule dictionary to the object instance. obj._rules = ruledict # noqa return obj
def get_prefix_uri_map(self): """Constructs and returns a map from to prefix to namespace URI, representing all namespaces in this set. The prefix chosen for each namespace is its preferred prefix if it's not None. If the preferred prefix is None, one is chosen from the set of registered prefixes. In the latter situation, if no prefixes are registered, an exception is raised. """ mapping = {} for ni in six.itervalues(self.__ns_uri_map): if ni.preferred_prefix: mapping[ni.preferred_prefix] = ni.uri elif len(ni.prefixes) > 0: prefix = next(iter(ni.prefixes)) mapping[prefix] = ni.uri else: raise NoPrefixesError(ni.uri) return mapping
def _finalize_schemalocs(self, schemaloc_dict=None): # If schemaloc_dict was passed in, make a copy so we don't mistakenly # modify the original. if schemaloc_dict: schemaloc_dict = dict(iteritems(schemaloc_dict)) else: schemaloc_dict = {} # Get our id namespace id_ns = idgen.get_id_namespace() # Build our schemalocation dictionary! # # Initialize it from values found in the parsed, input schemalocations # (if there are any) and the schemaloc_dict parameter values (if there # are any). # # If there is a schemalocation found in both the parsed schemalocs and # the schema_loc dict, use the schemaloc_dict value. for ns, loc in iteritems(self._input_schemalocs): if ns in schemaloc_dict: continue schemaloc_dict[ns] = loc # Iterate over the finalized namespaces for a document and attempt # to map them to schemalocations. Warn if the namespace should have a # schemalocation and we can't find it anywhere. nsset = set(itervalues(self.finalized_namespaces)) for ns in nsset: if ns in DEFAULT_STIX_SCHEMALOCATIONS: schemaloc_dict[ns] = DEFAULT_STIX_SCHEMALOCATIONS[ns] elif ns in schemaloc_dict: continue elif (ns == id_ns) or (ns in XML_NAMESPACES): continue else: error = "Unable to map namespace '{0}' to schemaLocation" warnings.warn(error.format(ns)) return schemaloc_dict
def get_uri_prefix_map(self): """Constructs and returns a map from namespace URI to prefix, representing all namespaces in this set. The prefix chosen for each namespace is its preferred prefix if it's not None. If the preferred prefix is None, one is chosen from the set of registered prefixes. In the latter situation, if no prefixes are registered, an exception is raised. """ mapping = {} for ni in six.itervalues(self.__ns_uri_map): if ni.preferred_prefix: mapping[ni.uri] = ni.preferred_prefix elif len(ni.prefixes) > 0: mapping[ni.uri] = next(iter(ni.prefixes)) else: # The reason I don't let any namespace map to None here is that # I don't think generateDS supports it. It requires prefixes # for all namespaces. raise NoPrefixesError(ni.uri) return mapping
def _get_include_root(self, ns, list_schemas): """Attempts to determine the "root" schema for a targetNamespace. This builds a graph of ``xs:include`` directive sources and targets and attempts to find a common base for all includes. Note: If no schemas in `list_schemas` ``xs:include`` another schema, then ``list_schemas[0]`` is returned. This occurs when duplicate schemas (or different versions of the same schema that define the same namespace) were encountered in the initialization schema directory. Args: ns: The target namespace list_schemas: A list of schemas which exist or define the target namespace. Returns: A path to the root schema for the input `ns`. """ graph = self._build_include_graph(list_schemas) if all(not(x) for x in itervalues(graph)): return list_schemas[0] for fp in graph: has_ancestors = self._is_included(graph, fp) has_children = len(graph[fp]) > 0 if has_children and not has_ancestors: return fp msg = "Unable to determine base schema for %s" % ns raise errors.XMLSchemaIncludeError(msg)
def __str__(self): """for debugging""" return "\n\n".join(str(v) for v in six.itervalues(self.__ns_uri_map))
def count(): """Return the number of objects currently in the mixbox cache.""" return sum(len(items) for items in six.itervalues(_CACHE))
def _is_included(self, graph, fp): """Returns ``True`` if the schema at `fp` was included by any other schemas in `graph`. """ return any(fp in includes for includes in itervalues(graph))
def count(): """Returns the number of objects currently in the mixbox cache. """ return sum(len(items) for items in six.itervalues(_CACHE))