diff --git a/gvm/protocols/gmp/_gmp224.py b/gvm/protocols/gmp/_gmp224.py index 2fdf28798..dbac8a503 100644 --- a/gvm/protocols/gmp/_gmp224.py +++ b/gvm/protocols/gmp/_gmp224.py @@ -17,6 +17,7 @@ HelpFormat, PortList, PortRangeType, + ScanConfigs, SortOrder, SystemReports, TrashCan, @@ -398,3 +399,268 @@ def modify_user_setting( setting_id=setting_id, name=name, value=value ) ) + + def clone_scan_config(self, config_id: EntityID) -> T: + """Clone a scan config from an existing one + + Args: + config_id: UUID of the existing scan config + """ + return self._send_and_transform_command( + ScanConfigs.clone_scan_config(config_id) + ) + + def create_scan_config( + self, + config_id: EntityID, + name: str, + *, + comment: Optional[str] = None, + ) -> T: + """Create a new scan config + + Args: + config_id: UUID of the existing scan config + name: Name of the new scan config + comment: A comment on the config + """ + return self._send_and_transform_command( + ScanConfigs.create_scan_config(config_id, name, comment=comment) + ) + + def delete_scan_config( + self, config_id: EntityID, *, ultimate: Optional[bool] = False + ) -> T: + """Deletes an existing config + + Args: + config_id: UUID of the config to be deleted. + ultimate: Whether to remove entirely, or to the trashcan. + """ + return self._send_and_transform_command( + ScanConfigs.delete_scan_config(config_id, ultimate=ultimate) + ) + + def get_scan_configs( + self, + *, + filter_string: Optional[str] = None, + filter_id: Optional[EntityID] = None, + trash: Optional[bool] = None, + details: Optional[bool] = None, + families: Optional[bool] = None, + preferences: Optional[bool] = None, + tasks: Optional[bool] = None, + ) -> T: + """Request a list of scan configs + + Args: + filter_string: Filter term to use for the query + filter_id: UUID of an existing filter to use for the query + trash: Whether to get the trashcan scan configs instead + details: Whether to get config families, preferences, nvt selectors + and tasks. + families: Whether to include the families if no details are + requested + preferences: Whether to include the preferences if no details are + requested + tasks: Whether to get tasks using this config + """ + return self._send_and_transform_command( + ScanConfigs.get_scan_configs( + filter_string=filter_string, + filter_id=filter_id, + trash=trash, + details=details, + families=families, + preferences=preferences, + tasks=tasks, + ) + ) + + def get_scan_config( + self, config_id: EntityID, *, tasks: Optional[bool] = None + ) -> T: + """Request a single scan config + + Args: + config_id: UUID of an existing scan config + tasks: Whether to get tasks using this config + """ + return self._send_and_transform_command( + ScanConfigs.get_scan_config(config_id, tasks=tasks) + ) + + def get_scan_config_preferences( + self, + *, + nvt_oid: Optional[str] = None, + config_id: Optional[EntityID] = None, + ) -> T: + """Request a list of scan_config preferences + + When the command includes a config_id attribute, the preference element + includes the preference name, type and value, and the NVT to which the + preference applies. + If the command includes a config_id and an nvt_oid, the preferences for + the given nvt in the config will be shown. + + Args: + nvt_oid: OID of nvt + config_id: UUID of scan config of which to show preference values + """ + return self._send_and_transform_command( + ScanConfigs.get_scan_config_preferences( + nvt_oid=nvt_oid, config_id=config_id + ) + ) + + def get_scan_config_preference( + self, + name: str, + *, + nvt_oid: Optional[str] = None, + config_id: Optional[EntityID] = None, + ) -> T: + """Request a nvt preference + + Args: + name: name of a particular preference + nvt_oid: OID of nvt + config_id: UUID of scan config of which to show preference values + """ + return self._send_and_transform_command( + ScanConfigs.get_scan_config_preference( + name, nvt_oid=nvt_oid, config_id=config_id + ) + ) + + def import_scan_config(self, config: str) -> T: + """Import a scan config from XML + + Args: + config: Scan Config XML as string to import. This XML must + contain a :code:`` root element. + """ + return self._send_and_transform_command( + ScanConfigs.import_scan_config(config) + ) + + def modify_scan_config_set_nvt_preference( + self, + config_id: EntityID, + name: str, + nvt_oid: str, + *, + value: Optional[str] = None, + ) -> T: + """Modifies the nvt preferences of an existing scan config. + + Args: + config_id: UUID of scan config to modify. + name: Name for nvt preference to change. + nvt_oid: OID of the NVT associated with preference to modify + value: New value for the preference. None to delete the preference + and to use the default instead. + """ + return self._send_and_transform_command( + ScanConfigs.modify_scan_config_set_nvt_preference( + config_id, name, nvt_oid, value=value + ) + ) + + def modify_scan_config_set_name(self, config_id: EntityID, name: str) -> T: + """Modifies the name of an existing scan config + + Args: + config_id: UUID of scan config to modify. + name: New name for the config. + """ + return self._send_and_transform_command( + ScanConfigs.modify_scan_config_set_name(config_id, name) + ) + + def modify_scan_config_set_comment( + self, config_id: EntityID, *, comment: Optional[str] = None + ) -> T: + """Modifies the comment of an existing scan config + + Args: + config_id: UUID of scan config to modify. + comment: Comment to set on a config. Default is an + empty comment and the previous comment will be + removed. + """ + return self._send_and_transform_command( + ScanConfigs.modify_scan_config_set_comment( + config_id, comment=comment + ) + ) + + def modify_scan_config_set_scanner_preference( + self, + config_id: EntityID, + name: str, + *, + value: Optional[str] = None, + ) -> T: + """Modifies the scanner preferences of an existing scan config + + Args: + config_id: UUID of scan config to modify. + name: Name of the scanner preference to change + value: New value for the preference. None to delete the preference + and to use the default instead. + """ + return self._send_and_transform_command( + ScanConfigs.modify_scan_config_set_scanner_preference( + config_id, name, value=value + ) + ) + + def modify_scan_config_set_nvt_selection( + self, + config_id: EntityID, + family: str, + nvt_oids: Union[tuple[str], list[str]], + ) -> T: + """Modifies the selected nvts of an existing scan config + + The manager updates the given family in the config to include only the + given NVTs. + + Arguments: + config_id: UUID of scan config to modify. + family: Name of the NVT family to include NVTs from + nvt_oids: List of NVTs to select for the family. + """ + return self._send_and_transform_command( + ScanConfigs.modify_scan_config_set_nvt_selection( + config_id, family, nvt_oids + ) + ) + + def modify_scan_config_set_family_selection( + self, + config_id: EntityID, + families: list[tuple[str, bool, bool]], + *, + auto_add_new_families: Optional[bool] = True, + ) -> T: + """ + Selected the NVTs of a scan config at a family level. + + Args: + config_id: UUID of scan config to modify. + families: A list of tuples (str, bool, bool): + str: the name of the NVT family selected, + bool: add new NVTs to the family automatically, + bool: include all NVTs from the family + auto_add_new_families: Whether new families should be added to the + scan config automatically. Default: True. + """ + return self._send_and_transform_command( + ScanConfigs.modify_scan_config_set_family_selection( + config_id, families, auto_add_new_families=auto_add_new_families + ) + ) diff --git a/gvm/protocols/gmp/requests/__init__.py b/gvm/protocols/gmp/requests/__init__.py index 7592df0b4..904d48d51 100644 --- a/gvm/protocols/gmp/requests/__init__.py +++ b/gvm/protocols/gmp/requests/__init__.py @@ -10,6 +10,7 @@ from ._help import Help, HelpFormat from ._port_list import PortList, PortRangeType from ._resource_names import ResourceNames, ResourceType +from ._scan_configs import ScanConfigs from ._system_reports import SystemReports from ._trashcan import TrashCan from ._user_settings import UserSettings @@ -29,6 +30,7 @@ "PortRangeType", "ResourceNames", "ResourceType", + "ScanConfigs", "SortOrder", "SystemReports", "TrashCan", diff --git a/gvm/protocols/gmp/requests/_scan_configs.py b/gvm/protocols/gmp/requests/_scan_configs.py new file mode 100644 index 000000000..c74dd736e --- /dev/null +++ b/gvm/protocols/gmp/requests/_scan_configs.py @@ -0,0 +1,510 @@ +# SPDX-FileCopyrightText: 2024 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + +from typing import Optional, Union + +from gvm.errors import InvalidArgument, InvalidArgumentType, RequiredArgument +from gvm.protocols.core import Request +from gvm.utils import is_list_like, to_base64, to_bool +from gvm.xml import XmlCommand, XmlError + +from ._entity_id import EntityID + + +class ScanConfigs: + @classmethod + def clone_scan_config(cls, config_id: EntityID) -> Request: + """Clone a scan config from an existing one + + Args: + config_id: UUID of the existing scan config + """ + if not config_id: + raise RequiredArgument( + function=cls.clone_scan_config.__name__, argument="config_id" + ) + + cmd = XmlCommand("create_config") + cmd.add_element("copy", str(config_id)) + return cmd + + @classmethod + def create_scan_config( + cls, + config_id: EntityID, + name: str, + *, + comment: Optional[str] = None, + ) -> Request: + """Create a new scan config + + Args: + config_id: UUID of the existing scan config + name: Name of the new scan config + comment: A comment on the config + """ + if not name: + raise RequiredArgument( + function=cls.create_scan_config.__name__, argument="name" + ) + + if not config_id: + raise RequiredArgument( + function=cls.create_scan_config.__name__, argument="config_id" + ) + + cmd = XmlCommand("create_config") + if comment is not None: + cmd.add_element("comment", comment) + + cmd.add_element("copy", str(config_id)) + cmd.add_element("name", name) + cmd.add_element("usage_type", "scan") + + return cmd + + @classmethod + def delete_scan_config( + cls, config_id: EntityID, *, ultimate: Optional[bool] = False + ) -> Request: + """Deletes an existing config + + Args: + config_id: UUID of the config to be deleted. + ultimate: Whether to remove entirely, or to the trashcan. + """ + if not config_id: + raise RequiredArgument( + function=cls.delete_scan_config.__name__, argument="config_id" + ) + + cmd = XmlCommand("delete_config") + cmd.set_attribute("config_id", str(config_id)) + cmd.set_attribute("ultimate", to_bool(ultimate)) + + return cmd + + @staticmethod + def get_scan_configs( + *, + filter_string: Optional[str] = None, + filter_id: Optional[EntityID] = None, + trash: Optional[bool] = None, + details: Optional[bool] = None, + families: Optional[bool] = None, + preferences: Optional[bool] = None, + tasks: Optional[bool] = None, + ) -> Request: + """Request a list of scan configs + + Args: + filter_string: Filter term to use for the query + filter_id: UUID of an existing filter to use for the query + trash: Whether to get the trashcan scan configs instead + details: Whether to get config families, preferences, nvt selectors + and tasks. + families: Whether to include the families if no details are + requested + preferences: Whether to include the preferences if no details are + requested + tasks: Whether to get tasks using this config + """ + cmd = XmlCommand("get_configs") + cmd.set_attribute("usage_type", "scan") + + cmd.add_filter(filter_string, filter_id) + + if trash is not None: + cmd.set_attribute("trash", to_bool(trash)) + + if details is not None: + cmd.set_attribute("details", to_bool(details)) + + if families is not None: + cmd.set_attribute("families", to_bool(families)) + + if preferences is not None: + cmd.set_attribute("preferences", to_bool(preferences)) + + if tasks is not None: + cmd.set_attribute("tasks", to_bool(tasks)) + + return cmd + + @classmethod + def get_scan_config( + cls, config_id: EntityID, *, tasks: Optional[bool] = None + ) -> Request: + """Request a single scan config + + Args: + config_id: UUID of an existing scan config + tasks: Whether to get tasks using this config + """ + if not config_id: + raise RequiredArgument( + function=cls.get_scan_config.__name__, argument="config_id" + ) + + cmd = XmlCommand("get_configs") + cmd.set_attribute("config_id", str(config_id)) + + cmd.set_attribute("usage_type", "scan") + + if tasks is not None: + cmd.set_attribute("tasks", to_bool(tasks)) + + # for single entity always request all details + cmd.set_attribute("details", "1") + + return cmd + + @classmethod + def get_scan_config_preferences( + cls, + *, + nvt_oid: Optional[str] = None, + config_id: Optional[EntityID] = None, + ) -> Request: + """Request a list of scan_config preferences + + When the command includes a config_id attribute, the preference element + includes the preference name, type and value, and the NVT to which the + preference applies. + If the command includes a config_id and an nvt_oid, the preferences for + the given nvt in the config will be shown. + + Args: + nvt_oid: OID of nvt + config_id: UUID of scan config of which to show preference values + """ + cmd = XmlCommand("get_preferences") + + if nvt_oid: + cmd.set_attribute("nvt_oid", str(nvt_oid)) + + if config_id: + cmd.set_attribute("config_id", str(config_id)) + + return cmd + + @classmethod + def get_scan_config_preference( + cls, + name: str, + *, + nvt_oid: Optional[str] = None, + config_id: Optional[EntityID] = None, + ) -> Request: + """Request a nvt preference + + Args: + name: name of a particular preference + nvt_oid: OID of nvt + config_id: UUID of scan config of which to show preference values + """ + cmd = XmlCommand("get_preferences") + + if not name: + raise RequiredArgument( + function=cls.get_scan_config_preference.__name__, + argument="name", + ) + + cmd.set_attribute("preference", name) + + if nvt_oid: + cmd.set_attribute("nvt_oid", str(nvt_oid)) + + if config_id: + cmd.set_attribute("config_id", str(config_id)) + + return cmd + + @classmethod + def import_scan_config(cls, config: str) -> Request: + """Import a scan config from XML + + Args: + config: Scan Config XML as string to import. This XML must + contain a :code:`` root element. + """ + if not config: + raise RequiredArgument( + function=cls.import_scan_config.__name__, argument="config" + ) + + cmd = XmlCommand("create_config") + + try: + cmd.append_xml_str(config) + except XmlError as e: + raise InvalidArgument( + function=cls.import_scan_config.__name__, argument="config" + ) from e + + return cmd + + @classmethod + def modify_scan_config_set_nvt_preference( + cls, + config_id: EntityID, + name: str, + nvt_oid: str, + *, + value: Optional[str] = None, + ) -> Request: + """Modifies the nvt preferences of an existing scan config. + + Args: + config_id: UUID of scan config to modify. + name: Name for nvt preference to change. + nvt_oid: OID of the NVT associated with preference to modify + value: New value for the preference. None to delete the preference + and to use the default instead. + """ + if not config_id: + raise RequiredArgument( + function=cls.modify_scan_config_set_nvt_preference.__name__, + argument="config_id", + ) + + if not nvt_oid: + raise RequiredArgument( + function=cls.modify_scan_config_set_nvt_preference.__name__, + argument="nvt_oid", + ) + + if not name: + raise RequiredArgument( + function=cls.modify_scan_config_set_nvt_preference.__name__, + argument="name", + ) + + cmd = XmlCommand("modify_config") + cmd.set_attribute("config_id", str(config_id)) + + xml_preference = cmd.add_element("preference") + + xml_preference.add_element("nvt", attrs={"oid": str(nvt_oid)}) + xml_preference.add_element("name", name) + + if value: + xml_preference.add_element("value", to_base64(value)) + + return cmd + + @classmethod + def modify_scan_config_set_name( + cls, config_id: EntityID, name: str + ) -> Request: + """Modifies the name of an existing scan config + + Args: + config_id: UUID of scan config to modify. + name: New name for the config. + """ + if not config_id: + raise RequiredArgument( + function=cls.modify_scan_config_set_name.__name__, + argument="config_id", + ) + + if not name: + raise RequiredArgument( + function=cls.modify_scan_config_set_name.__name__, + argument="name", + ) + + cmd = XmlCommand("modify_config") + cmd.set_attribute("config_id", str(config_id)) + + cmd.add_element("name", name) + + return cmd + + @classmethod + def modify_scan_config_set_comment( + cls, config_id: EntityID, *, comment: Optional[str] = None + ) -> Request: + """Modifies the comment of an existing scan config + + Args: + config_id: UUID of scan config to modify. + comment: Comment to set on a config. Default is an + empty comment and the previous comment will be + removed. + """ + if not config_id: + raise RequiredArgument( + function=cls.modify_scan_config_set_comment.__name__, + argument="config_id argument", + ) + + cmd = XmlCommand("modify_config") + cmd.set_attribute("config_id", str(config_id)) + + if not comment: + comment = "" + + cmd.add_element("comment", comment) + + return cmd + + @classmethod + def modify_scan_config_set_scanner_preference( + cls, + config_id: EntityID, + name: str, + *, + value: Optional[str] = None, + ) -> Request: + """Modifies the scanner preferences of an existing scan config + + Args: + config_id: UUID of scan config to modify. + name: Name of the scanner preference to change + value: New value for the preference. None to delete the preference + and to use the default instead. + """ + if not config_id: + raise RequiredArgument( + function=( + cls.modify_scan_config_set_scanner_preference.__name__ + ), + argument="config_id", + ) + + if not name: + raise RequiredArgument( + function=( + cls.modify_scan_config_set_scanner_preference.__name__ + ), + argument="name argument", + ) + + cmd = XmlCommand("modify_config") + cmd.set_attribute("config_id", str(config_id)) + + xml_preference = cmd.add_element("preference") + + xml_preference.add_element("name", name) + + if value: + xml_preference.add_element("value", to_base64(value)) + + return cmd + + @classmethod + def modify_scan_config_set_nvt_selection( + cls, + config_id: EntityID, + family: str, + nvt_oids: Union[tuple[str], list[str]], + ) -> Request: + """Modifies the selected nvts of an existing scan config + + The manager updates the given family in the config to include only the + given NVTs. + + Arguments: + config_id: UUID of scan config to modify. + family: Name of the NVT family to include NVTs from + nvt_oids: List of NVTs to select for the family. + """ + if not config_id: + raise RequiredArgument( + function=cls.modify_scan_config_set_nvt_selection.__name__, + argument="config_id", + ) + + if not family: + raise RequiredArgument( + function=cls.modify_scan_config_set_nvt_selection.__name__, + argument="family argument", + ) + + if not is_list_like(nvt_oids): + raise InvalidArgumentType( + function=cls.modify_scan_config_set_nvt_selection.__name__, + argument="nvt_oids", + arg_type="list", + ) + + cmd = XmlCommand("modify_config") + cmd.set_attribute("config_id", str(config_id)) + + xmlnvtsel = cmd.add_element("nvt_selection") + xmlnvtsel.add_element("family", family) + + for nvt in nvt_oids: + xmlnvtsel.add_element("nvt", attrs={"oid": nvt}) + + return cmd + + @classmethod + def modify_scan_config_set_family_selection( + cls, + config_id: EntityID, + families: list[tuple[str, bool, bool]], + *, + auto_add_new_families: Optional[bool] = True, + ) -> Request: + """ + Selected the NVTs of a scan config at a family level. + + Args: + config_id: UUID of scan config to modify. + families: A list of tuples (str, bool, bool): + str: the name of the NVT family selected, + bool: add new NVTs to the family automatically, + bool: include all NVTs from the family + auto_add_new_families: Whether new families should be added to the + scan config automatically. Default: True. + """ + if not config_id: + raise RequiredArgument( + function=cls.modify_scan_config_set_family_selection.__name__, + argument="config_id", + ) + + if not is_list_like(families): + raise InvalidArgumentType( + function=cls.modify_scan_config_set_family_selection.__name__, + argument="families", + arg_type="list", + ) + + cmd = XmlCommand("modify_config") + cmd.set_attribute("config_id", str(config_id)) + + xml_family_selection = cmd.add_element("family_selection") + xml_family_selection.add_element( + "growing", to_bool(auto_add_new_families) + ) + + for family in families: + xml_family = xml_family_selection.add_element("family") + xml_family.add_element("name", family[0]) + + if len(family) != 3: + raise InvalidArgument( + "Family must be a tuple of 3. (str, bool, bool)" + ) + + if not isinstance(family[1], bool) or not isinstance( + family[2], bool + ): + raise InvalidArgumentType( + function=( + cls.modify_scan_config_set_family_selection.__name__ + ), + argument="families", + arg_type="[tuple(str, bool, bool)]", + ) + + xml_family.add_element("all", to_bool(family[2])) + xml_family.add_element("growing", to_bool(family[1])) + + return cmd diff --git a/tests/protocols/gmp/requests/test_scan_configs.py b/tests/protocols/gmp/requests/test_scan_configs.py new file mode 100644 index 000000000..64908b04e --- /dev/null +++ b/tests/protocols/gmp/requests/test_scan_configs.py @@ -0,0 +1,777 @@ +# SPDX-FileCopyrightText: 2024 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + +import unittest + +from gvm.errors import InvalidArgument, InvalidArgumentType, RequiredArgument +from gvm.protocols.gmp.requests import ScanConfigs + + +class ScanConfigsTestCase(unittest.TestCase): + + def test_clone_scan_config(self): + request = ScanConfigs.clone_scan_config("a1") + + self.assertEqual( + bytes(request), b"a1" + ) + + def test_clone_scan_config_missing_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.clone_scan_config("") + + with self.assertRaises(RequiredArgument): + ScanConfigs.clone_scan_config(None) + + def test_create_scan_config(self): + request = ScanConfigs.create_scan_config("a1", "foo") + + self.assertEqual( + bytes(request), + b"a1foo" + b"scan", + ) + + def test_create_scan_config_with_comment(self): + request = ScanConfigs.create_scan_config("a1", "foo", comment="comment") + + self.assertEqual( + bytes(request), + b"commenta1" + b"fooscan", + ) + + def test_create_scan_config_missing_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.create_scan_config("", "foo") + + with self.assertRaises(RequiredArgument): + ScanConfigs.create_scan_config(None, "foo") + + def test_create_scan_config_missing_name(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.create_scan_config("c1", None) + + with self.assertRaises(RequiredArgument): + ScanConfigs.create_scan_config("c1", "") + + def test_delete_scan_config(self): + request = ScanConfigs.delete_scan_config("a1") + + self.assertEqual( + bytes(request), b'' + ) + + def test_delete_scan_config_ultimate(self): + request = ScanConfigs.delete_scan_config("a1", ultimate=True) + + self.assertEqual( + bytes(request), b'' + ) + + def test_delete_scan_config_missing_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.delete_scan_config("") + + with self.assertRaises(RequiredArgument): + ScanConfigs.delete_scan_config(None) + + def test_get_scan_config_preference(self): + request = ScanConfigs.get_scan_config_preference("foo") + + self.assertEqual(bytes(request), b'') + + def test_get_scan_config_preference_missing_name(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.get_scan_config_preference("") + + with self.assertRaises(RequiredArgument): + ScanConfigs.get_scan_config_preference(None) + + def test_get_scan_config_preference_with_nvt_oid(self): + request = ScanConfigs.get_scan_config_preference("foo", nvt_oid="oid") + + self.assertEqual( + bytes(request), b'' + ) + + def test_get_scan_config_preference_with_config_id(self): + request = ScanConfigs.get_scan_config_preference("foo", config_id="c1") + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_config_preferences(self): + request = ScanConfigs.get_scan_config_preferences() + + self.assertEqual(bytes(request), b"") + + def test_get_scan_config_preferences_with_nvt_oid(self): + request = ScanConfigs.get_scan_config_preferences(nvt_oid="oid") + + self.assertEqual(bytes(request), b'') + + def test_get_scan_config_preferences_with_config_id(self): + request = ScanConfigs.get_scan_config_preferences(config_id="c1") + + self.assertEqual(bytes(request), b'') + + def test_get_scan_config(self): + request = ScanConfigs.get_scan_config("a1") + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_config_with_tasks(self): + request = ScanConfigs.get_scan_config("a1", tasks=True) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_config_without_scan_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.get_scan_config(None) + + with self.assertRaises(RequiredArgument): + ScanConfigs.get_scan_config("") + + def test_get_scan_configs(self): + request = ScanConfigs.get_scan_configs() + + self.assertEqual(bytes(request), b'') + + def test_get_scan_configs_with_filter_string(self): + request = ScanConfigs.get_scan_configs(filter_string="name=foo") + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_with_filter_id(self): + request = ScanConfigs.get_scan_configs(filter_id="f1") + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_from_trash(self): + request = ScanConfigs.get_scan_configs(trash=True) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_with_details(self): + request = ScanConfigs.get_scan_configs(details=True) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_without_details(self): + request = ScanConfigs.get_scan_configs(details=False) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_with_families(self): + request = ScanConfigs.get_scan_configs(families=True) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_without_families(self): + request = ScanConfigs.get_scan_configs(families=False) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_with_preferences(self): + request = ScanConfigs.get_scan_configs(preferences=True) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_without_preferences(self): + request = ScanConfigs.get_scan_configs(preferences=False) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_with_tasks(self): + request = ScanConfigs.get_scan_configs(tasks=True) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_get_scan_configs_without_tasks(self): + request = ScanConfigs.get_scan_configs(tasks=False) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_import_scan_config(self): + CONFIG_XML_STRING = ( + '' + '' + "Foobar" + "Foobar config" + "2018-11-09T10:48:03Z" + "2018-11-09T10:48:03Z" + "" + "" + ) + request = ScanConfigs.import_scan_config(CONFIG_XML_STRING) + + self.assertEqual( + bytes(request), + f"{CONFIG_XML_STRING}".encode( + encoding="utf-8" + ), + ) + + def test_import_missing_scan_config_xml(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.import_scan_config(None) + + with self.assertRaises(RequiredArgument): + ScanConfigs.import_scan_config("") + + def test_import_invalid_xml(self): + with self.assertRaises(InvalidArgument): + ScanConfigs.import_scan_config("abcdef") + + def test_modify_scan_config_set_comment(self): + request = ScanConfigs.modify_scan_config_set_comment("c1") + + self.assertEqual( + bytes(request), + b'', + ) + + request = ScanConfigs.modify_scan_config_set_comment( + "c1", comment="foo" + ) + + self.assertEqual( + bytes(request), + b'foo', + ) + + request = ScanConfigs.modify_scan_config_set_comment("c1", comment=None) + + self.assertEqual( + bytes(request), + b'', + ) + + def test_modify_scan_config_set_comment_missing_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_comment(config_id=None) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_comment("") + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_comment(config_id="") + + def test_modify_scan_config_set_family_selection(self): + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, True)] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"1" + b"" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, True), ("bar", True, True)] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"1" + b"" + b"" + b"bar" + b"1" + b"1" + b"" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", (("foo", True, True), ("bar", True, True)) + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"1" + b"" + b"" + b"bar" + b"1" + b"1" + b"" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, False), ("bar", False, True)] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"0" + b"1" + b"" + b"" + b"bar" + b"1" + b"0" + b"" + b"" + b"", + ) + + def test_modify_scan_config_set_family_selection_missing_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_family_selection( + None, [("foo", True, True)] + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_family_selection( + "", [("foo", True, True)] + ) + + def test_modify_scan_config_set_family_selection_invalid_families(self): + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_family_selection( + "c1", + None, + ) + + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_family_selection( + "c1", + "", + ) + + def test_modify_scan_config_set_family_selection_with_auto_add_new_families( + self, + ): + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, True)], auto_add_new_families=True + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"1" + b"" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, True)], auto_add_new_families=False + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"0" + b"" + b"foo" + b"1" + b"1" + b"" + b"" + b"", + ) + + def test_modify_scan_config_set_family_selection_with_auto_add_new_nvts( + self, + ): + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, True)] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"1" + b"" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", False, True)] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"0" + b"" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_family_selection( + "c1", + [("foo", False, True), ("bar", True, False)], + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"1" + b"" + b"foo" + b"1" + b"0" + b"" + b"" + b"bar" + b"0" + b"1" + b"" + b"" + b"", + ) + + def test_modify_scan_config_set_family_selection_with_invalid_arguments( + self, + ): + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", "False", "True")] + ) + + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", True, None)] + ) + + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo", "True", False)] + ) + + with self.assertRaises(InvalidArgument): + ScanConfigs.modify_scan_config_set_family_selection( + "c1", [("foo",)] + ) + + def test_modify_scan_config_set_name(self): + request = ScanConfigs.modify_scan_config_set_name("c1", "foo") + + self.assertEqual( + bytes(request), + b'foo', + ) + + def test_modify_scan_config_set_name_missing_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_name(None, name="name") + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_name("", name="name") + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_name(config_id="", name="name") + + def test_modify_scan_config_set_name_missing_name(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_name("c1", None) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_name("c1", "") + + def test_modify_scan_config_set_nvt_preference(self): + request = ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", nvt_oid="o1", name="foo" + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b'' + b"foo" + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", "foo", "o1" + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b'' + b"foo" + b"" + b"", + ) + + def test_modify_scan_config_set_nvt_pref_with_value(self): + request = ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", "foo", nvt_oid="o1", value="bar" + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b'' + b"foo" + b"YmFy" + b"" + b"", + ) + + def test_modify_scan_config_set_nvt_pref_missing_nvt_oid(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", "foo", nvt_oid=None, value="bar" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", "foo", nvt_oid="", value="bar" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", "foo", "", value="bar" + ) + + def test_modify_scan_config_nvt_pref_missing_name(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", name=None, nvt_oid="o1", value="bar" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", name="", nvt_oid="o1", value="bar" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference( + "c1", "", nvt_oid="o1", value="bar" + ) + + def test_modify_scan_config_set_nvt_preference_missing_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference("", "foo", "o1") + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_preference(None, "foo", "o1") + + def test_modify_scan_config_set_nvt_selection(self): + request = ScanConfigs.modify_scan_config_set_nvt_selection( + "c1", "foo", ["o1"] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"foo" + b'' + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_nvt_selection( + "c1", "foo", ["o1", "o2"] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"foo" + b'' + b'' + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_nvt_selection( + "c1", "foo", ("o1", "o2") + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"foo" + b'' + b'' + b"" + b"", + ) + + request = ScanConfigs.modify_scan_config_set_nvt_selection( + "c1", "foo", [] + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"foo" + b"" + b"", + ) + + def test_modify_scan_config_set_nvt_selection_missing_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_selection( + None, "foo", ["o1"] + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_nvt_selection("", "foo", ["o1"]) + + def test_modify_scan_config_set_nvt_selection_invalid_nvt_oids(self): + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_nvt_selection("c1", "foo", None) + + with self.assertRaises(InvalidArgumentType): + ScanConfigs.modify_scan_config_set_nvt_selection("c1", "foo", "") + + def test_modify_scan_config_set_scanner_pref(self): + request = ScanConfigs.modify_scan_config_set_scanner_preference( + "c1", "foo" + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"foo" + b"" + b"", + ) + + def test_modify_scan_config_set_scanner_pref_with_value(self): + request = ScanConfigs.modify_scan_config_set_scanner_preference( + "c1", "foo", value="bar" + ) + + self.assertEqual( + bytes(request), + b'' + b"" + b"foo" + b"YmFy" + b"" + b"", + ) + + def test_modify_scan_config_scanner_pref_missing_name(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_scanner_preference( + "c1", name=None, value="bar" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_scanner_preference( + "c1", name="", value="bar" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_scanner_preference( + "c1", "", value="bar" + ) + + def test_modify_scan_config_set_scanner_pref_missing_config_id(self): + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_scanner_preference( + None, name="foo" + ) + + with self.assertRaises(RequiredArgument): + ScanConfigs.modify_scan_config_set_scanner_preference( + "", name="foo" + )