def check_label(label): if not label: err = "Found empty type label in Instance Mapping worksheet" raise errors.ProfileParseError(err) if label not in instance_map: return err = ("Found duplicate type label in Instance Mapping worksheet: " "'{label}'") raise errors.ProfileParseError(err.format(label=label))
def _parse_profile(self, profile_fn): """Converts the supplied STIX profile into a Schematron representation. The Schematron schema is returned as a etree._Element instance. Args: workbook: The profile Excel workbook. Returns: A Schematron ``etree._Element`` instance. Raises: .ProfileParseError: If `profile_fn` does not point to a valid STIX profile or an error occurs while parsing the STIX profile. """ workbook = self._open_workbook(profile_fn) ws = workbook.sheet_by_name try: namespaces = self._parse_namespace_worksheet(ws("Namespaces")) instance_mapping = self._parse_instance_mapping_worksheet( worksheet=ws("Instance Mapping"), nsmap=namespaces) rules = self._parse_workbook_rules(workbook, instance_mapping) profile = Profile(namespaces) profile.extend(rules) return profile except xlrd.XLRDError as ex: err = "Error occurred while parsing STIX Profile: %s" % str(ex) raise errors.ProfileParseError(err) finally: self._unload_workbook(workbook)
def check_namespace(ns, alias): if ns and alias: return err = ("Missing namespace or alias: unable to parse Namespaces " "worksheet") raise errors.ProfileParseError(err)
def _validate(self): if not self.is_attr: return err = ("Implementation rules cannot be applied to attribute fields: " "{0}".format(self.path)) raise errors.ProfileParseError(err)
def _parse_worksheet_rules(self, worksheet, instance_map): """Parses the rules from the profile sheet `workheet`. Args: worksheet: A profile worksheet containing rules. instance_map: A dictionary representation of the ``Instance Mapping`` worksheet. Returns: A list of ``_BaseProfileRule`` implementations for the rules defined in the `worksheet`. Raises: .ProfileParseError: If a rule context label has no associated entry in `instance_map`. """ value = functools.partial(self._get_value, worksheet) is_empty_row = functools.partial(self._is_empty_row, worksheet) def check_label(label): if label not in instance_map: err = ("Worksheet '{0}' context label '{1}' has no Instance " "Mapping entry.") raise errors.ProfileParseError( err.format(worksheet.name, label)) all_rules = [] for i in range(1, worksheet.nrows): if is_empty_row(i): continue if not value(i, COL_OCCURRENCE): ctx_label = value(i, COL_FIELD_NAME) check_label(ctx_label) continue field = value(i, COL_FIELD_NAME) occurrence = value(i, COL_OCCURRENCE).lower() types = value(i, COL_XSI_TYPES) values = value(i, COL_ALLOWED_VALUES) if occurrence not in ALLOWED_OCCURRENCES: err = "Found unknown occurrence '{0}' in worksheet '{1}'." raise errors.ProfileParseError( err.format(occurrence, worksheet.name)) rules = self._build_rules(info=instance_map[ctx_label], field=field, occurrence=occurrence, types=types, values=values) all_rules.extend(rules) return all_rules
def _open_workbook(self, filename): """Returns xlrd.open_workbook(filename) or raises an Exception if the filename extension is not .xlsx or the open_workbook() call fails. """ if not filename.lower().endswith(".xlsx"): err = "Profile must have .XLSX extension. Filename provided: '{fn}'" raise errors.ProfileParseError(err.format(fn=filename)) if not os.path.exists(filename): err = "The profile document '{fn}' does not exist" raise errors.ProfileParseError(err.format(fn=filename)) try: return xlrd.open_workbook(filename) except: err = ( "Error occurred while opening '{fn}'. File may be an invalid " "or corrupted XSLX document.") raise errors.ProfileParseError(err.format(fn=filename))
def validate(self): """Checks that this is a valid InstanceMapping instance. Raises: errors.ProfileParseError: If ``namespace`` is ``None`` or any of the selector values are empty. """ if not self.label: err = "Missing type label in Instance Mapping" raise errors.ProfileParseError(err) if not self.namespace: err = "Missing namespace for '{label}'' in Instance Mapping worksheet" raise errors.ProfileParseError(err.format(label=self.label)) if not (self.selectors and all(self.selectors)): err = ( "Empty selector for '{label}' in Instance Mapping worksheet. " "Look for extra commas in field.") raise errors.ProfileParseError(err.format(label=self.label))
def namespace(self, value): """Sets the namespace and ns_alias properties. Raises: .ProfileParseError: if `value` is not found in the internal namespace dictionary. """ if not value: self._namespace = None self._ns_alias = None elif value in self._nsmap: self._namespace = value self._ns_alias = self._nsmap[value] else: err = "Unable to map namespace '{ns}' to namespace alias" raise errors.ProfileParseError(err.format(ns=value))
def _get_value(self, worksheet, row, col): """Returns the worksheet cell value found at (row,col).""" if not worksheet: raise errors.ProfileParseError("worksheet value was NoneType") return str(worksheet.cell_value(row, col))
def check_label(label): if label not in instance_map: err = ("Worksheet '{0}' context label '{1}' has no Instance " "Mapping entry.") raise errors.ProfileParseError( err.format(worksheet.name, label))