diff --git a/connector-packager/CHANGELOG.md b/connector-packager/CHANGELOG.md index ca448602..4eebaad4 100644 --- a/connector-packager/CHANGELOG.md +++ b/connector-packager/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.1.2] - 4/9/2026 +- Add check for non-lowercase default OAuth config IDs +- Add check for duplicate OAuth config IDs +- Add check for missing default OAuth config ID if non-default IDs are defined + ## [2.1.1] - 8/29/2025 - Add checks for secure field violations diff --git a/connector-packager/connector_packager/connector_properties.py b/connector-packager/connector_packager/connector_properties.py index 64d099ac..876695ff 100644 --- a/connector-packager/connector_packager/connector_properties.py +++ b/connector-packager/connector_packager/connector_properties.py @@ -7,3 +7,4 @@ def __init__(self): self.backwards_compatibility_mode = False self.is_jdbc = False self.connection_metadata_database = True + self.oauth_config_ids = [] diff --git a/connector-packager/connector_packager/version.py b/connector-packager/connector_packager/version.py index 985e0403..2d7b19ad 100644 --- a/connector-packager/connector_packager/version.py +++ b/connector-packager/connector_packager/version.py @@ -1,2 +1,2 @@ -__version__ = '2.1.0' +__version__ = '2.1.2' __default_min_version_tableau__ = '2019.4' diff --git a/connector-packager/connector_packager/xsd_validator.py b/connector-packager/connector_packager/xsd_validator.py index 2ca41d82..7e0929cb 100644 --- a/connector-packager/connector_packager/xsd_validator.py +++ b/connector-packager/connector_packager/xsd_validator.py @@ -74,6 +74,12 @@ def validate_all_xml(files_list: List[ConnectorFile], folder_path: Path, propert warn_file_specific_rules(file_to_test, path_to_file) + # If we have oauth-configs, we need to confirm we have at least one default config + if len(properties.oauth_config_ids) > 1: + if "default" not in properties.oauth_config_ids: + xml_violations_found += 1 + xml_violations_buffer.append("Connector has embedded OAuth configs, but does not define a default config.") + if xml_violations_found <= 0: logger.debug("No XML violations found") else: @@ -175,6 +181,9 @@ def validate_file_specific_rules(file_to_test: ConnectorFile, path_to_file: Path return validate_file_specific_rules_tdr(file_to_test, path_to_file, xml_violations_buffer, properties) elif file_to_test.file_type == 'connection-dialog': return validate_file_specific_rules_tcd(file_to_test, path_to_file, xml_violations_buffer, properties) + elif file_to_test.file_type == 'oauth-config': + return validate_file_specific_rules_oauth_config(file_to_test, path_to_file, xml_violations_buffer, properties) + return True @@ -346,6 +355,43 @@ def validate_file_specific_rules_tcd(file_to_test: ConnectorFile, path_to_file: if vendor3 is not None: properties.vendor_defined_fields.append('vendor3') + return True + +def validate_file_specific_rules_oauth_config(file_to_test: ConnectorFile, path_to_file: Path, xml_violations_buffer: List[str], properties: ConnectorProperties) -> bool: + xml_tree = parse(str(path_to_file)) + root = xml_tree.getroot() + + + oauthConfigId = root.find('.//oauthConfigId') + + # No config id is equivilant to default + if oauthConfigId is None: + if "default" in properties.oauth_config_ids: + xml_violations_buffer.append("Multiple defualt OAuth configs (Note: no oauthConfigId is equivilant to default). " + + str(path_to_file)) + return False + else: + properties.oauth_config_ids.append("default") + return True + + # oauthConfigId is case sensitive, and if it's default it must be lowercase + if oauthConfigId.text.lower() == 'default': + if 'default' != oauthConfigId.text: + xml_violations_buffer.append("'default' OAuth Config must be lowercase as oauthConfigId is case sensitive. " + + str(path_to_file)) + return False + + # Check that new oauth config is unique + if oauthConfigId.text in properties.oauth_config_ids: + xml_violations_buffer.append("OAuth config ID of '" + oauthConfigId.text + "' already defined. " + + str(path_to_file)) + return False + else: + properties.oauth_config_ids.append(oauthConfigId.text) + + + + return True # Check if connector file content contains warnings needs to notify connector developer diff --git a/connector-packager/tests/test_resources/oauth_default_and_missing_ids/manifest.xml b/connector-packager/tests/test_resources/oauth_default_and_missing_ids/manifest.xml new file mode 100644 index 00000000..57c5045d --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_default_and_missing_ids/manifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/connector-packager/tests/test_resources/oauth_default_and_missing_ids/oauth-config.xml b/connector-packager/tests/test_resources/oauth_default_and_missing_ids/oauth-config.xml new file mode 100644 index 00000000..1b749bcc --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_default_and_missing_ids/oauth-config.xml @@ -0,0 +1,18 @@ + + + test_oauth + + default + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_default_and_missing_ids/oauth-config2.xml b/connector-packager/tests/test_resources/oauth_default_and_missing_ids/oauth-config2.xml new file mode 100644 index 00000000..e956418a --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_default_and_missing_ids/oauth-config2.xml @@ -0,0 +1,17 @@ + + + test_oauth + + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_default_config_id/invalid/oauth-config.xml b/connector-packager/tests/test_resources/oauth_default_config_id/invalid/oauth-config.xml new file mode 100644 index 00000000..260d5935 --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_default_config_id/invalid/oauth-config.xml @@ -0,0 +1,18 @@ + + + test_oauth + + DEFAULT + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_default_config_id/valid/oauth-config.xml b/connector-packager/tests/test_resources/oauth_default_config_id/valid/oauth-config.xml new file mode 100644 index 00000000..1b749bcc --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_default_config_id/valid/oauth-config.xml @@ -0,0 +1,18 @@ + + + test_oauth + + default + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_duplicate_config_ids/manifest.xml b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/manifest.xml new file mode 100644 index 00000000..782e8243 --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/manifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config.xml b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config.xml new file mode 100644 index 00000000..1b749bcc --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config.xml @@ -0,0 +1,18 @@ + + + test_oauth + + default + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config2.xml b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config2.xml new file mode 100644 index 00000000..5d8867be --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config2.xml @@ -0,0 +1,18 @@ + + + test_oauth + + oauthConfigid + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config3.xml b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config3.xml new file mode 100644 index 00000000..5d8867be --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_duplicate_config_ids/oauth-config3.xml @@ -0,0 +1,18 @@ + + + test_oauth + + oauthConfigid + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_no_default/manifest.xml b/connector-packager/tests/test_resources/oauth_no_default/manifest.xml new file mode 100644 index 00000000..57c5045d --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_no_default/manifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/connector-packager/tests/test_resources/oauth_no_default/oauth-config.xml b/connector-packager/tests/test_resources/oauth_no_default/oauth-config.xml new file mode 100644 index 00000000..9ff5a245 --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_no_default/oauth-config.xml @@ -0,0 +1,18 @@ + + + test_oauth + + oauthConfigId + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_resources/oauth_no_default/oauth-config2.xml b/connector-packager/tests/test_resources/oauth_no_default/oauth-config2.xml new file mode 100644 index 00000000..008deabd --- /dev/null +++ b/connector-packager/tests/test_resources/oauth_no_default/oauth-config2.xml @@ -0,0 +1,18 @@ + + + test_oauth + + oauthConfigId2 + ****** + ****** + http://localhost:55555/Callback + + /oauth2/v2.0/authorize + /oauth2/v2.0/token + + openid + email + profile + offline_access + + diff --git a/connector-packager/tests/test_xsd_validator.py b/connector-packager/tests/test_xsd_validator.py index 6fb5ad97..6677fcd7 100644 --- a/connector-packager/tests/test_xsd_validator.py +++ b/connector-packager/tests/test_xsd_validator.py @@ -10,7 +10,8 @@ TEST_FOLDER = Path("tests/test_resources") -dummy_properties = ConnectorProperties() +def get_dummy_properties(): + return ConnectorProperties() class TestXSDValidator(unittest.TestCase): @@ -27,14 +28,14 @@ def test_validate_all_xml(self): ConnectorFile("connectionResolver.tdr", "connection-resolver"), ConnectorFile("resources-en_US.xml", "resource")] - self.assertTrue(validate_all_xml(files_list, test_folder, dummy_properties), "Valid connector not marked as valid") + self.assertTrue(validate_all_xml(files_list, test_folder, get_dummy_properties()), "Valid connector not marked as valid") print("\nTest broken xml. Throws a XML validation error.") test_folder = TEST_FOLDER / Path("broken_xml") files_list = [ConnectorFile("manifest.xml", "manifest")] - self.assertFalse(validate_all_xml(files_list, test_folder, dummy_properties), "Invalid connector was marked as valid") + self.assertFalse(validate_all_xml(files_list, test_folder, get_dummy_properties()), "Invalid connector was marked as valid") def test_validate_single_file(self): @@ -42,25 +43,25 @@ def test_validate_single_file(self): file_to_test = ConnectorFile("manifest.xml", "manifest") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") test_file = TEST_FOLDER / Path("big_manifest/manifest.xml") - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Big XML file marked as valid") print("\nTest broken xml. Throws XML validation error.") test_file = TEST_FOLDER / Path("broken_xml/manifest.xml") - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML file that doesn't follow schema marked as valid") print("\nTest malformed xml. Throws XML validation error.") test_file = TEST_FOLDER / Path("broken_xml/connectionResolver.tdr") file_to_test = ConnectorFile("connectionResolver.tdr", "connection-resolver") - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Malformed XML file marked as valid") logging.debug("test_validate_single_file xml violations:") @@ -73,12 +74,12 @@ def test_validate_vendor_prefix(self): file_to_test = ConnectorFile("connectionFields.xml", "connection-fields") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") print("\nTest malformed xml. Throws XML validation error.") test_file = TEST_FOLDER / "broken_xml/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML file with invalid name values marked as valid") logging.debug("test_validate_vendor_prefix xml violations:") @@ -91,12 +92,12 @@ def test_validate_required_advanced_field_has_default_value(self): file_to_test = ConnectorFile("connectionFields.xml", "connection-fields") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") print("\nTest missing default-value for non-optional advanced field. Throws XML validation error.") test_file = TEST_FOLDER / "advanced_required_missing_default/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML file containing required field in 'advanced' category with no default value marked as valid") logging.debug("test_validate_required_advanced_field_has_default_value xml violations:") @@ -109,12 +110,12 @@ def test_validate_duplicate_fields_absent(self): file_to_test = ConnectorFile("connectionFields.xml", "connection-fields") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") print("\nTest duplicate fields not allowed. Throws XML validation error.") test_file = TEST_FOLDER / "duplicate_fields/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "A field with the field name = server already exists. Cannot have multiple fields with the same name.") logging.debug("test_validate_duplicate_fields_absent xml violations:") @@ -126,14 +127,14 @@ def test_validate_instanceurl(self): file_to_test = ConnectorFile("connectionFields.xml", "connection-fields") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") test_file = TEST_FOLDER / "instanceurl/connectionFields.xml" file_to_test = ConnectorFile("connectionFields.xml", "connection-fields") xml_violations_buffer = [] - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "An instanceurl field must be conditional to authentication field with value=oauth") # instanceURL should not be required in required-attributes since it's automatically added @@ -155,21 +156,21 @@ def test_validate_oauth_config_id(self): file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") test_file = TEST_FOLDER / "oauth_connector/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "oauthConfig should be able to have no oauthConfigId field") test_file = TEST_FOLDER / "oauth_config_id/invalid/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "There can only be one oauthConfigId field") def test_warn_defaultSQLDialect_as_base(self): @@ -237,48 +238,48 @@ def test_validate_connection_field_name(self): file_to_test = ConnectorFile("connectionFields.xml", "connection-fields") print("Test connectionFields is validated by XSD when field name is vaild ") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation passed for connectionFields.xml") print("Test connectionFields is invalidated by XSD when field name" "contains special character other than - or _") test_file = TEST_FOLDER / "field_name_validation/invalid/special_character/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by XSD when field name starts with a number") test_file = TEST_FOLDER / "field_name_validation/invalid/starting_number/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by XSD when field name starts with a space") test_file = TEST_FOLDER / "field_name_validation/invalid/starting_space/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by XSD when field name has space in between") test_file = TEST_FOLDER / "field_name_validation/invalid/space_in_between/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by XSD when field name ends with a space") test_file = TEST_FOLDER / "field_name_validation/invalid/ending_space/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by non-password field marked secure") test_file = TEST_FOLDER / "field_name_validation/invalid/non_password_secure_field/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by non-secure field containing prohibited word") test_file = TEST_FOLDER / "field_name_validation/invalid/prohibited_word/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") print("Test connectionFields is invalidated by non-secure field containing prohibited word in label") test_file = TEST_FOLDER / "field_name_validation/invalid/prohibited_word_label/connectionFields.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "XML Validation failed for connectionFields.xml") logging.debug("test_validate_connetion_field_name xml violations:") @@ -334,12 +335,12 @@ def test_validate_company_name_length(self): print("Test that company name with length less than 1 is invalidated") test_file = TEST_FOLDER / "company_name_length_validation/min/manifest.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Empty company name marked as valid") print("Test that company name with length greater than 24 is invalidated") test_file = TEST_FOLDER / "company_name_length_validation/max/manifest.xml" - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Company name with length greater than 24 marked as valid") def test_validate_jdbc_properties_builder(self): @@ -410,12 +411,12 @@ def test_validate_multiple_oauth_config(self): print("Test that 2 oauth-config fields are validated") test_file = TEST_FOLDER / "multiple_oauth_config/test_manifest_files/manifest_2_config.xml" - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "2 OAuth Config Fields are marked as invalid") print("Test that 3 oauth-config fields are validated") test_file = TEST_FOLDER / "multiple_oauth_config/test_manifest_files/manifest_2_config.xml" - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "3 OAuth Config Fields are marked as invalid") def test_validate_default_instance_url(self): @@ -423,21 +424,21 @@ def test_validate_default_instance_url(self): file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") test_file = TEST_FOLDER / "oauth_connector/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "oauthConfig should be able to have no defaultInstanceUrl field") test_file = TEST_FOLDER / "oauth_default_instance_url/invalid/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "The defaultInstanceUrl must be located after authUri and tokenUri.") def test_validate_instance_url_suffix(self): @@ -445,21 +446,21 @@ def test_validate_instance_url_suffix(self): file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") test_file = TEST_FOLDER / "oauth_connector/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "oauthConfig should be able to have no instanceUrlSuffix field") test_file = TEST_FOLDER / "oauth_instance_url_suffix/invalid/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "The instanceUrlSuffix must be located after authUri and tokenUri.") def test_validate_config_label(self): @@ -467,19 +468,65 @@ def test_validate_config_label(self): file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "Valid XML file not marked as valid") test_file = TEST_FOLDER / "oauth_connector/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "oauthConfig should be able to have no configLabel field") test_file = TEST_FOLDER / "oauth_config_label/invalid/oauth-config.xml" file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") xml_violations_buffer = [] - self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties), + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), "The configLabel field must be located after authUri and tokenUri.") + + def test_validate_oauth_default_config_id(self): + test_file = TEST_FOLDER / "oauth_default_config_id/valid/oauth-config.xml" + file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") + xml_violations_buffer = [] + + self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), + "Lowercase default should be accepted") + + test_file = TEST_FOLDER / "oauth_default_config_id/invalid/oauth-config.xml" + file_to_test = ConnectorFile("oauth-config.xml", "oauth-config") + xml_violations_buffer = [] + + self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, get_dummy_properties()), + "Uppercase default should be rejected") + + def test_validate_oauth_duplicatet_config_id(self): + test_folder = TEST_FOLDER / Path("oauth_duplicate_config_ids") + + files_list = [ + ConnectorFile("manifest.xml", "manifest"), + ConnectorFile("oauth-config.xml", "oauth-config"), + ConnectorFile("oauth-config2.xml", "oauth-config"), + ConnectorFile("oauth-config3.xml", "oauth-config")] + + self.assertFalse(validate_all_xml(files_list, test_folder, get_dummy_properties()), "Connector with duplicate config ids marked as valid") + + def test_validate_oauth_default_and_missing_ids(self): + test_folder = TEST_FOLDER / Path("oauth_default_and_missing_ids") + + files_list = [ + ConnectorFile("manifest.xml", "manifest"), + ConnectorFile("oauth-config.xml", "oauth-config"), + ConnectorFile("oauth-config2.xml", "oauth-config")] + + self.assertFalse(validate_all_xml(files_list, test_folder, get_dummy_properties()), "Connector with default and missing config ids marked as valid") + + def test_validate_oauth_no_default(self): + test_folder = TEST_FOLDER / Path("oauth_no_default") + + files_list = [ + ConnectorFile("manifest.xml", "manifest"), + ConnectorFile("oauth-config.xml", "oauth-config"), + ConnectorFile("oauth-config2.xml", "oauth-config")] + + self.assertFalse(validate_all_xml(files_list, test_folder, get_dummy_properties()), "Connector with default and missing config ids marked as valid")