Esempio n. 1
0
        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))
Esempio n. 2
0
    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)
Esempio n. 3
0
        def check_namespace(ns, alias):
            if ns and alias:
                return

            err = ("Missing namespace or alias: unable to parse Namespaces "
                   "worksheet")
            raise errors.ProfileParseError(err)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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
Esempio n. 6
0
    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))
Esempio n. 7
0
    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))
Esempio n. 8
0
    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))
Esempio n. 9
0
    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))
Esempio n. 10
0
 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))