Repository: oasis-open/cti-stix-validator
Pull request #203 (2022-11-22 18:40:40)

update maintainers list as agreed in the TC


Patch:
diff --git a/README.rst b/README.rst
index bdd2fb2..fe1dfbf 100644
--- a/README.rst
+++ b/README.rst
@@ -141,9 +141,10 @@ repositories/maintainers-guide#additionalMaintainers>`_.
 
 **Current Maintainers of this TC Open Repository**
 
-.. Initial Maintainers: Greg Back & Ivan Kirillov
+.. Initial Maintainers: Greg Back & Ivan Kirillov & Chris Lenk
 
-*  `Chris Lenk <mailto:clenk@mitre.org>`_; GitHub ID: `https://github.com/clenk <https://github.com/clenk>`_; WWW: `MITRE <https://www.mitre.org>`__
+* `Emily Ratliff <mailto:emily.ratliff@ibm.com>`__; GitHub ID: `https://github.com/ejratl <https://github.com/ejratl>`_; WWW: `IBM <http://www.ibm.com/>`__
+* `Duncan Sparrell <mailto:duncan@sfractal.com>`__; GitHub ID: `https://github.com/sparrell <https://github.com/sparrell>`_; WWW: `sFractal <http://sfractal.com/>`__
 *  `Jason Keirstead <mailto:Jason.Keirstead@ca.ibm.com>`__; GitHub ID: `https://github.com/JasonKeirstead <https://github.com/JasonKeirstead>`_; WWW: `IBM <http://www.ibm.com/>`__
 
 .. _aboutOpenRepos:
diff --git a/stix2validator/validator.py b/stix2validator/validator.py
index 4840702..6bc533b 100644
--- a/stix2validator/validator.py
+++ b/stix2validator/validator.py
@@ -569,11 +569,11 @@ def load_validator(schema_path, schema):
     return validator
 
 
-def find_schema(schema_dir, name):
-    """Search the `schema_dir` directory for a schema called `name`.json.
+def find_schema(schema_dir, obj_type):
+    """Search the `schema_dir` directory for a schema called `obj_type`.json.
     Return the file path of the first match it finds.
     """
-    schema_filename = name + '.json'
+    schema_filename = obj_type + '.json'
 
     for root, dirnames, filenames in os.walk(schema_dir):
         if "examples" in root:
@@ -602,11 +602,11 @@ def load_schema(schema_path):
     return schema
 
 
-def _get_error_generator(name, obj, schema_dir=None, version=DEFAULT_VER, default='core'):
+def _get_error_generator(type, obj, schema_dir=None, version=DEFAULT_VER, default='core'):
     """Get a generator for validating against the schema for the given object type.
 
     Args:
-        name (str): The object type or extension id to find the schema for.
+        type (str): The object type to find the schema for.
         obj: The object to be validated.
         schema_dir (str): The path in which to search for schemas.
         version (str): The version of the STIX specification to validate
@@ -628,7 +628,7 @@ def _get_error_generator(name, obj, schema_dir=None, version=DEFAULT_VER, defaul
                                      + version + '/schemas/')
 
     try:
-        schema_path = find_schema(schema_dir, name)
+        schema_path = find_schema(schema_dir, type)
         schema = load_schema(schema_path)
     except (KeyError, TypeError):
         # Assume a custom object with no schema
@@ -643,7 +643,6 @@ def _get_error_generator(name, obj, schema_dir=None, version=DEFAULT_VER, defaul
                 raise SchemaInvalidError("Cannot locate a schema for the object's "
                                          "type, nor the base schema ({}.json).".format(default))
 
-    type = obj['type']
     if type == 'observed-data' and schema_dir is None:
         # Validate against schemas for specific observed data object types later.
         # If schema_dir is not None the schema is custom and won't need to be modified.
@@ -772,20 +771,12 @@ def _schema_validate(obj, options, bundle_version=None):
         if interop_errors:
             error_gens.append((interop_errors, error_prefix))
 
-    # Get validators for any user-supplied schema
+    # Get validator for any user-supplied schema
     if options.schema_dir:
-        # schemas named by object type
         custom_sdo_errors = _get_error_generator(obj['type'], obj, options.schema_dir, version, default=core_schema)
         if custom_sdo_errors:
             error_gens.append((custom_sdo_errors, error_prefix))
 
-        # schemas for extensions
-        extension_ids = obj.get('extensions', dict()).keys()
-        for ext in extension_ids:
-            extension_errors = _get_error_generator(ext, obj, options.schema_dir, version, default=core_schema)
-            if extension_errors:
-                error_gens.append((extension_errors, error_prefix))
-
     # Validate each cyber observable object separately
     if obj['type'] == 'observed-data' and 'objects' in obj:
         # Check if observed data property is in dictionary format
@@ -868,8 +859,8 @@ def validate_instance(instance, options=None):
         A dictionary of validation results
 
     """
-    if not _is_stix_obj(instance):
-        raise ValidationError("Input must be an object with 'id' and 'type' properties.")
+    if 'type' not in instance:
+        raise ValidationError("Input must be an object with a 'type' property.")
 
     if not options:
         options = ValidationOptions()


Test patch:
diff --git a/stix2validator/test/v20/bundle_tests.py b/stix2validator/test/v20/bundle_tests.py
index 20ce013..c7cc25f 100644
--- a/stix2validator/test/v20/bundle_tests.py
+++ b/stix2validator/test/v20/bundle_tests.py
@@ -3,8 +3,6 @@ import json
 
 import pytest
 
-from stix2validator import validate_instance
-
 from . import ValidatorTest
 from ... import ValidationError
 
@@ -68,27 +66,3 @@ class BundleTestCases(ValidatorTest):
         del bundle['objects'][0]['type']
         with pytest.raises(ValidationError):
             self.assertFalseWithOptions(bundle)
-
-    def test_bundle_sdo_missing_id(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['objects'][0]['id']
-        self.assertFalseWithOptions(bundle)
-
-    def test_bundle_missing_id(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['id']
-        with pytest.raises(ValidationError):
-            self.assertFalseWithOptions(bundle)
-
-    def test_bundle_sdo_missing_id_with_no_options(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['objects'][0]['id']
-
-        results = validate_instance(bundle)
-        assert not results.is_valid
-
-    def test_bundle_missing_id_with_no_options(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['id']
-        with pytest.raises(ValidationError):
-            validate_instance(bundle)
diff --git a/stix2validator/test/v20/custom_obj_tests.py b/stix2validator/test/v20/custom_obj_tests.py
index f297fad..e2a17fa 100644
--- a/stix2validator/test/v20/custom_obj_tests.py
+++ b/stix2validator/test/v20/custom_obj_tests.py
@@ -1,8 +1,6 @@
 import copy
 import json
 
-import pytest
-
 from . import ValidatorTest
 from ... import ValidationError, validate_parsed_json, validate_string
 
@@ -33,8 +31,8 @@ class CustomObjectTestCases(ValidatorTest):
     def test_no_id(self):
         custom_obj = copy.deepcopy(self.valid_custom_object)
         del custom_obj['id']
-        with pytest.raises(ValidationError):
-            validate_parsed_json(custom_obj, self.options)
+        results = validate_parsed_json(custom_obj, self.options)
+        self.assertEqual(results.is_valid, False)
 
     def test_no_created(self):
         custom_obj = copy.deepcopy(self.valid_custom_object)
diff --git a/stix2validator/test/v21/bundle_tests.py b/stix2validator/test/v21/bundle_tests.py
index 0918bc4..072fe4c 100644
--- a/stix2validator/test/v21/bundle_tests.py
+++ b/stix2validator/test/v21/bundle_tests.py
@@ -3,8 +3,6 @@ import json
 
 import pytest
 
-from stix2validator import validate_instance
-
 from . import ValidatorTest
 from ... import ValidationError
 
@@ -75,27 +73,3 @@ class BundleTestCases(ValidatorTest):
         del bundle['objects'][0]['type']
         with pytest.raises(ValidationError):
             self.assertFalseWithOptions(bundle)
-
-    def test_bundle_sdo_missing_id(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['objects'][0]['id']
-        self.assertFalseWithOptions(bundle)
-
-    def test_bundle_missing_id(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['id']
-        with pytest.raises(ValidationError):
-            self.assertFalseWithOptions(bundle)
-
-    def test_bundle_sdo_missing_id_with_no_options(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['objects'][0]['id']
-
-        results = validate_instance(bundle)
-        assert not results.is_valid
-
-    def test_bundle_missing_id_with_no_options(self):
-        bundle = copy.deepcopy(self.valid_bundle)
-        del bundle['id']
-        with pytest.raises(ValidationError):
-            validate_instance(bundle)
diff --git a/stix2validator/test/v21/custom_obj_tests.py b/stix2validator/test/v21/custom_obj_tests.py
index 297ebf8..51660f1 100644
--- a/stix2validator/test/v21/custom_obj_tests.py
+++ b/stix2validator/test/v21/custom_obj_tests.py
@@ -1,8 +1,6 @@
 import copy
 import json
 
-import pytest
-
 from . import ValidatorTest
 from ... import ValidationError, validate_parsed_json, validate_string
 
@@ -39,8 +37,8 @@ class CustomObjectTestCases(ValidatorTest):
     def test_no_id(self):
         custom_obj = copy.deepcopy(self.valid_custom_object)
         del custom_obj['id']
-        with pytest.raises(ValidationError):
-            validate_parsed_json(custom_obj, self.options)
+        results = validate_parsed_json(custom_obj, self.options)
+        self.assertEqual(results.is_valid, False)
 
     def test_no_created(self):
         custom_obj = copy.deepcopy(self.valid_custom_object)
diff --git a/stix2validator/test/v21/indicator_tests.py b/stix2validator/test/v21/indicator_tests.py
index d6ad046..36205d4 100644
--- a/stix2validator/test/v21/indicator_tests.py
+++ b/stix2validator/test/v21/indicator_tests.py
@@ -204,28 +204,14 @@ class IndicatorTestCases(ValidatorTest):
         indicator['pattern'] = "[windows-registry-key:key LIKE 'HKEY_LOCAL_MACHINE\\\\Foo\\\\Bar%']"
         self.assertTrueWithOptions(indicator)
 
-    def test_additional_schema(self):
+    def test_additional_schemas(self):
         indicator = copy.deepcopy(self.valid_indicator)
         self.assertFalseWithOptions(indicator, schema_dir=self.custom_schemas)
 
         indicator['name'] = "Foobar"
         self.assertTrueWithOptions(indicator, schema_dir=self.custom_schemas)
 
-    def test_additional_schema_extension(self):
-        indicator = copy.deepcopy(self.valid_indicator)
-        indicator['name'] = "Foobar"
-        indicator['extensions'] = {'extension-definition--993ce403-6fdd-4efa-8279-31cf2d91b1c8': {
-            "extension_type": "toplevel-property-extension",
-        }}
-        self.assertFalseWithOptions(indicator, schema_dir=self.custom_schemas)
-
-        indicator['grade'] = "a"
-        self.assertFalseWithOptions(indicator, schema_dir=self.custom_schemas)
-
-        indicator['grade'] = "A"
-        self.assertTrueWithOptions(indicator, schema_dir=self.custom_schemas)
-
-    def test_additional_schema_custom_type(self):
+    def test_additional_schemas_custom_type(self):
         # no schema exists for this type
         new_obj = {
             "type": "x-type",
@@ -254,7 +240,7 @@ class IndicatorTestCases(ValidatorTest):
         new_obj['property2'] = 10
         self.assertTrueWithOptions(new_obj, schema_dir=self.custom_schemas)
 
-    def test_additional_schema_custom_type_invalid_schema(self):
+    def test_additional_schemas_custom_type_invalid_schema(self):
         self.assertFalseWithOptions(ADDTNL_INVALID_SCHEMA, schema_dir=self.custom_schemas)
 
     def test_validate_parsed_json_list_additional_invalid_schema(self):
diff --git a/stix2validator/test/v21/test_schemas/extension-definition--993ce403-6fdd-4efa-8279-31cf2d91b1c8.json b/stix2validator/test/v21/test_schemas/extension-definition--993ce403-6fdd-4efa-8279-31cf2d91b1c8.json
deleted file mode 100644
index 8f2ea9e..0000000
--- a/stix2validator/test/v21/test_schemas/extension-definition--993ce403-6fdd-4efa-8279-31cf2d91b1c8.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    "properties": {
-        "grade": {
-            "type": "string",
-            "pattern": "^[ABCDF]$"
-        },
-        "extensions": {
-            "patternProperties": {
-                "^extension-definition--993ce403-6fdd-4efa-8279-31cf2d91b1c8$": {
-                    "type": "object",
-                    "properties": {
-                        "extension_type": {
-                           "type": "string",
-                            "enum": ["toplevel-property-extension"]
-                        }
-                    },
-                    "required": ["extension_type"]
-                }
-            }
-        }
-    },
-    "required": [
-        "grade",
-        "extensions"
-    ]
-}