diff --git a/tests/utils/custom.json b/tests/utils/custom.json index 88134caa78..1febe8c54a 100644 --- a/tests/utils/custom.json +++ b/tests/utils/custom.json @@ -40,6 +40,24 @@ "evaluate": true } } + }, + { + "id": "JSON_P12", + "title": "JSON Custom profile", + "rules": { + "R3": { + "evaluate": true + } + } + }, + { + "title": "JSON Custom profile with no given id", + "base_profile_id": "P1", + "rules": { + "R3": { + "evaluate": true + } + } } ] } diff --git a/tests/utils/custom_no_ids.json b/tests/utils/custom_no_ids.json new file mode 100644 index 0000000000..979478c73e --- /dev/null +++ b/tests/utils/custom_no_ids.json @@ -0,0 +1,12 @@ +{ + "profiles": [ + { + "title": "JSON Tailored Profile P11", + "rules": { + "R3": { + "evaluate": true + } + } + } + ] +} diff --git a/tests/utils/test_autotailor.py b/tests/utils/test_autotailor.py index f00bcf7498..68e17634b1 100644 --- a/tests/utils/test_autotailor.py +++ b/tests/utils/test_autotailor.py @@ -1,4 +1,8 @@ import importlib +import json +import os.path +import pathlib + import pytest NS = "http://checklists.nist.gov/xccdf/1.2" @@ -94,3 +98,12 @@ def test_refine_rule(): "'high'.") assert p.rule_refinements(fav, "severity") == "high" assert p.rule_refinements(fav, "role") == "full" + +def test_no_id(): + p = autotailor.Profile() + profile_dict = None + file_path = pathlib.Path(__file__).parent.joinpath("custom_no_ids.json") + with open(file_path) as fp: + profile_dict = json.load(fp) + with pytest.raises(ValueError): + p.import_json_tailoring_profile(profile_dict) diff --git a/utils/autotailor b/utils/autotailor index 3c3e994eaa..9d0754f4f2 100755 --- a/utils/autotailor +++ b/utils/autotailor @@ -29,6 +29,7 @@ import json NS = "http://checklists.nist.gov/xccdf/1.2" +NS_PREFIX = "xccdf-1.2" DEFAULT_PROFILE_SUFFIX = "_customized" DEFAULT_REVERSE_DNS = "org.ssgproject.content" ROLES = ["full", "unscored", "unchecked"] @@ -267,7 +268,8 @@ class Profile: def to_xml(self, root): profile = ET.SubElement(root, "{%s}Profile" % NS) profile.set("id", self._full_profile_id(self.profile_id)) - profile.set("extends", self._full_profile_id(self.extends)) + if self.extends: + profile.set("extends", self._full_profile_id(self.extends)) # Title has to be there due to the schema definition. title = ET.SubElement(profile, "{%s}title" % NS) @@ -284,9 +286,10 @@ class Profile: self.value_refinements_to_xml(profile) def import_json_tailoring_profile(self, profile_dict): - self.extends = profile_dict["base_profile_id"] - - self.profile_id = profile_dict.get("id", self.profile_id) + if not profile_dict.get("base_profile_id") and not profile_dict.get("id"): + raise ValueError("You must define a base_profile_id or an id") + self.extends = profile_dict.get("base_profile_id") + self.profile_id = profile_dict.get("id") self.profile_title = profile_dict.get("title", self.profile_title) self._import_groups_from_tailoring(profile_dict) @@ -440,6 +443,8 @@ if __name__ == "__main__": parser = get_parser() args = parser.parse_args() + ET.register_namespace(NS_PREFIX, NS) + if not args.profile and not args.json_tailoring: parser.error("one of the following arguments has to be provided: " "BASE_PROFILE_ID or --json-tailoring JSON_TAILORING_FILENAME")