Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions connector-packager/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
2 changes: 1 addition & 1 deletion connector-packager/connector_packager/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = '2.1.0'
__version__ = '2.1.2'
__default_min_version_tableau__ = '2019.4'
46 changes: 46 additions & 0 deletions connector-packager/connector_packager/xsd_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version='1.0' encoding='utf-8' ?>

<connector-plugin class='test_oauth' superclass='jdbc' plugin-version='0.0.1' name='test' version='18.1'>
<vendor-information>
<company name="Connector SDK"/>
<support-link url = "https://example.com"/>
</vendor-information>
<connection-customization class="test_oauth" enabled="true" version="10.0">
<vendor name="vendor"/>
<driver name="driver"/>
<customizations>
<customization name="CAP_SELECT_INTO" value="yes"/>
<customization name="CAP_SELECT_TOP_INTO" value="yes"/>
<customization name="CAP_CREATE_TEMP_TABLES" value="no"/>
<customization name="CAP_QUERY_BOOLEXPR_TO_INTEXPR" value="no"/>
<customization name="CAP_QUERY_GROUP_BY_BOOL" value="yes"/>
<customization name="CAP_QUERY_GROUP_BY_DEGREE" value="yes"/>
<customization name="CAP_QUERY_SORT_BY" value="yes"/>
<customization name="CAP_QUERY_SUBQUERIES" value="yes"/>
<customization name="CAP_QUERY_TOP_N" value="yes"/>
<customization name="CAP_QUERY_TOP_SAMPLE" value="yes"/>
<customization name="CAP_QUERY_TOP_SAMPLE_PERCENT" value="yes"/>
<customization name="CAP_QUERY_WHERE_FALSE_METADATA" value="yes"/>
<customization name="CAP_QUERY_SUBQUERIES_WITH_TOP" value="yes"/>
<customization name="CAP_SUPPORTS_SPLIT_FROM_LEFT" value="yes"/>
<customization name="CAP_SUPPORTS_SPLIT_FROM_RIGHT" value="yes"/>
<customization name="CAP_SUPPORTS_UNION" value="yes"/>
<customization name="CAP_QUERY_ALLOW_PARTIAL_AGGREGATION" value="no"/>
<customization name="CAP_QUERY_TIME_REQUIRES_CAST" value="yes"/>
</customizations>
</connection-customization>
<oauth-config file="oauth-config.xml"/>
<oauth-config file="oauth-config2.xml"/>
</connector-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>default</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>DEFAULT</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>default</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version='1.0' encoding='utf-8' ?>

<connector-plugin class='test_oauth' superclass='jdbc' plugin-version='0.0.1' name='test' version='18.1'>
<vendor-information>
<company name="Connector SDK"/>
<support-link url = "https://example.com"/>
</vendor-information>
<connection-customization class="test_oauth" enabled="true" version="10.0">
<vendor name="vendor"/>
<driver name="driver"/>
<customizations>
<customization name="CAP_SELECT_INTO" value="yes"/>
<customization name="CAP_SELECT_TOP_INTO" value="yes"/>
<customization name="CAP_CREATE_TEMP_TABLES" value="no"/>
<customization name="CAP_QUERY_BOOLEXPR_TO_INTEXPR" value="no"/>
<customization name="CAP_QUERY_GROUP_BY_BOOL" value="yes"/>
<customization name="CAP_QUERY_GROUP_BY_DEGREE" value="yes"/>
<customization name="CAP_QUERY_SORT_BY" value="yes"/>
<customization name="CAP_QUERY_SUBQUERIES" value="yes"/>
<customization name="CAP_QUERY_TOP_N" value="yes"/>
<customization name="CAP_QUERY_TOP_SAMPLE" value="yes"/>
<customization name="CAP_QUERY_TOP_SAMPLE_PERCENT" value="yes"/>
<customization name="CAP_QUERY_WHERE_FALSE_METADATA" value="yes"/>
<customization name="CAP_QUERY_SUBQUERIES_WITH_TOP" value="yes"/>
<customization name="CAP_SUPPORTS_SPLIT_FROM_LEFT" value="yes"/>
<customization name="CAP_SUPPORTS_SPLIT_FROM_RIGHT" value="yes"/>
<customization name="CAP_SUPPORTS_UNION" value="yes"/>
<customization name="CAP_QUERY_ALLOW_PARTIAL_AGGREGATION" value="no"/>
<customization name="CAP_QUERY_TIME_REQUIRES_CAST" value="yes"/>
</customizations>
</connection-customization>
<oauth-config file="oauth-config.xml"/>
<oauth-config file="oauth-config2.xml"/>
<oauth-config file="oauth-config3.xml"/>
</connector-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>default</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>oauthConfigid</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>oauthConfigid</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version='1.0' encoding='utf-8' ?>

<connector-plugin class='test_oauth' superclass='jdbc' plugin-version='0.0.1' name='test' version='18.1'>
<vendor-information>
<company name="Connector SDK"/>
<support-link url = "https://example.com"/>
</vendor-information>
<connection-customization class="test_oauth" enabled="true" version="10.0">
<vendor name="vendor"/>
<driver name="driver"/>
<customizations>
<customization name="CAP_SELECT_INTO" value="yes"/>
<customization name="CAP_SELECT_TOP_INTO" value="yes"/>
<customization name="CAP_CREATE_TEMP_TABLES" value="no"/>
<customization name="CAP_QUERY_BOOLEXPR_TO_INTEXPR" value="no"/>
<customization name="CAP_QUERY_GROUP_BY_BOOL" value="yes"/>
<customization name="CAP_QUERY_GROUP_BY_DEGREE" value="yes"/>
<customization name="CAP_QUERY_SORT_BY" value="yes"/>
<customization name="CAP_QUERY_SUBQUERIES" value="yes"/>
<customization name="CAP_QUERY_TOP_N" value="yes"/>
<customization name="CAP_QUERY_TOP_SAMPLE" value="yes"/>
<customization name="CAP_QUERY_TOP_SAMPLE_PERCENT" value="yes"/>
<customization name="CAP_QUERY_WHERE_FALSE_METADATA" value="yes"/>
<customization name="CAP_QUERY_SUBQUERIES_WITH_TOP" value="yes"/>
<customization name="CAP_SUPPORTS_SPLIT_FROM_LEFT" value="yes"/>
<customization name="CAP_SUPPORTS_SPLIT_FROM_RIGHT" value="yes"/>
<customization name="CAP_SUPPORTS_UNION" value="yes"/>
<customization name="CAP_QUERY_ALLOW_PARTIAL_AGGREGATION" value="no"/>
<customization name="CAP_QUERY_TIME_REQUIRES_CAST" value="yes"/>
</customizations>
</connection-customization>
<oauth-config file="oauth-config.xml"/>
<oauth-config file="oauth-config2.xml"/>
</connector-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>oauthConfigId</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<pluginOAuthConfig>
<dbclass>test_oauth</dbclass>

<oauthConfigId>oauthConfigId2</oauthConfigId>
<clientIdDesktop>******</clientIdDesktop>
<clientSecretDesktop>******</clientSecretDesktop>
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>

<authUri>/oauth2/v2.0/authorize</authUri>
<tokenUri>/oauth2/v2.0/token</tokenUri>

<scopes>openid</scopes>
<scopes>email</scopes>
<scopes>profile</scopes>
<scopes>offline_access</scopes>

</pluginOAuthConfig>
Loading
Loading