Skip to content

Commit d736286

Browse files
authored
@W-12971206 - [OAuth][SDK] Backport instanceUrlSuffix support to 2023.1 (#1113)
* Add instanceUrlSuffix support * Add additional changes from configLabel MR
1 parent d2733b7 commit d736286

File tree

8 files changed

+124
-1
lines changed

8 files changed

+124
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Tableau Connector SDK Changelog
2+
## 2023-04-04
3+
### Changed
4+
- Update `oauth_config.xsd` to include `instanceUrlSuffix` field and update `min-version-tableau` to be 2023.1 if present
25
## 2022-12-16
36
### Changed
47
- Convert database impersonation sample to Connection Dialog V2

connector-packager/connector_packager/jar_jdk_packager.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,13 @@ def get_min_support_version(file_list: List[ConnectorFile], cur_min_version_tabl
5757
elif connector_file.file_type == "oauth-config":
5858
# Check to see if we're using oauthConfigId, which needs 2021.4+
5959
pluginOAuthConfigRoot = ET.parse(input_dir / connector_file.file_name).getroot()
60+
6061
oauthConfigId = pluginOAuthConfigRoot.find('.//oauthConfigId')
61-
if (oauthConfigId is not None and 2021.4 > float(min_version_tableau)):
62+
instanceUrlSuffix = pluginOAuthConfigRoot.find('.//instanceUrlSuffix')
63+
if (instanceUrlSuffix is not None and 2023.1 > float(min_version_tableau)):
64+
min_version_tableau = "2023.1"
65+
reasons.append("Connector uses instanceUrlSuffix field, which was added in the 2023.1 release")
66+
elif (oauthConfigId is not None and 2021.4 > float(min_version_tableau)):
6267
min_version_tableau = "2021.4"
6368
reasons.append("Connector contains an oauthConfigId field, which was added in the 2021.4 release")
6469
elif 2021.1 > float(min_version_tableau):

connector-packager/tests/test_jar_packager.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,36 @@ def test_jdk_create_jar_with_multiple_configs(self):
326326

327327
if dest_dir.exists():
328328
shutil.rmtree(dest_dir)
329+
330+
def test_jdk_create_jar_oauth_with_instance_url_suffix(self):
331+
files_list = [
332+
ConnectorFile("manifest.xml", "manifest"),
333+
ConnectorFile("connectionFields.xml", "connection-fields"),
334+
ConnectorFile("connectionMetadata.xml", "connection-metadata"),
335+
ConnectorFile("connectionBuilder.js", "script"),
336+
ConnectorFile("dialect.xml", "dialect"),
337+
ConnectorFile("connectionResolver.xml", "connection-resolver"),
338+
ConnectorFile("connectionProperties.js", "script"),
339+
ConnectorFile("oauth-config-with-suffix.xml", "oauth-config")]
340+
source_dir = TEST_FOLDER / Path("oauth_connector")
341+
dest_dir = TEST_FOLDER / Path("packaged-connector-by-jdk/")
342+
package_name = "test_oauth.taco"
343+
344+
jdk_create_jar(source_dir, files_list, package_name, dest_dir)
345+
346+
path_to_test_file = dest_dir / Path(package_name)
347+
self.assertTrue(os.path.isfile(path_to_test_file), "taco file doesn't exist")
348+
349+
# test min support tableau version is stamped
350+
args = ["jar", "xf", package_name, MANIFEST_FILE_NAME]
351+
p = subprocess.Popen(args, cwd=os.path.abspath(dest_dir))
352+
self.assertEqual(p.wait(), 0, "can not extract manfifest file from taco")
353+
path_to_extracted_manifest = dest_dir / MANIFEST_FILE_NAME
354+
self.assertTrue(os.path.isfile(path_to_extracted_manifest), "extracted manifest file doesn't exist")
355+
356+
manifest = ET.parse(path_to_extracted_manifest)
357+
self.assertEqual(manifest.getroot().get("min-version-tableau"),
358+
VERSION_2023_1, "wrong min-version-tableau attr or doesn't exist")
359+
360+
if dest_dir.exists():
361+
shutil.rmtree(dest_dir)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<pluginOAuthConfig>
3+
<dbclass>test_oauth</dbclass>
4+
5+
<oauthConfigId>oauthConfigid</oauthConfigId>
6+
<clientIdDesktop>******</clientIdDesktop>
7+
<clientSecretDesktop>******</clientSecretDesktop>
8+
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>
9+
10+
<authUri>/oauth2/v2.0/authorize</authUri>
11+
<tokenUri>/oauth2/v2.0/token</tokenUri>
12+
13+
<instanceUrlSuffix>/oidc</instanceUrlSuffix>
14+
15+
<scopes>openid</scopes>
16+
<scopes>email</scopes>
17+
<scopes>profile</scopes>
18+
<scopes>offline_access</scopes>
19+
20+
</pluginOAuthConfig>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<pluginOAuthConfig>
3+
<dbclass>test_oauth</dbclass>
4+
5+
<oauthConfigId>oauthConfigid</oauthConfigId>
6+
<clientIdDesktop>******</clientIdDesktop>
7+
<clientSecretDesktop>******</clientSecretDesktop>
8+
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>
9+
<instanceUrlSuffix>/oidc</instanceUrlSuffix>
10+
11+
<authUri>/oauth2/v2.0/authorize</authUri>
12+
<tokenUri>/oauth2/v2.0/token</tokenUri>
13+
14+
<scopes>openid</scopes>
15+
<scopes>email</scopes>
16+
<scopes>profile</scopes>
17+
<scopes>offline_access</scopes>
18+
19+
</pluginOAuthConfig>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<pluginOAuthConfig>
3+
<dbclass>test_oauth</dbclass>
4+
5+
<oauthConfigId>oauthConfigid</oauthConfigId>
6+
<clientIdDesktop>******</clientIdDesktop>
7+
<clientSecretDesktop>******</clientSecretDesktop>
8+
<redirectUrisDesktop>http://localhost:55555/Callback</redirectUrisDesktop>
9+
10+
<authUri>/oauth2/v2.0/authorize</authUri>
11+
<tokenUri>/oauth2/v2.0/token</tokenUri>
12+
13+
<instanceUrlSuffix>/oidc</instanceUrlSuffix>
14+
15+
<scopes>openid</scopes>
16+
<scopes>email</scopes>
17+
<scopes>profile</scopes>
18+
<scopes>offline_access</scopes>
19+
20+
</pluginOAuthConfig>

connector-packager/tests/test_xsd_validator.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,25 @@ def test_validate_multiple_oauth_config(self):
402402
test_file = TEST_FOLDER / "multiple_oauth_config/test_manifest_files/manifest_2_config.xml"
403403
self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties),
404404
"3 OAuth Config Fields are marked as invalid")
405+
406+
def test_validate_instance_url_suffix(self):
407+
test_file = TEST_FOLDER / "oauth_instance_url_suffix/valid/oauth-config.xml"
408+
file_to_test = ConnectorFile("oauth-config.xml", "oauth-config")
409+
xml_violations_buffer = []
410+
411+
self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties),
412+
"Valid XML file not marked as valid")
413+
414+
test_file = TEST_FOLDER / "oauth_connector/oauth-config.xml"
415+
file_to_test = ConnectorFile("oauth-config.xml", "oauth-config")
416+
xml_violations_buffer = []
417+
418+
self.assertTrue(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties),
419+
"oauthConfig should be able to have no instanceUrlSuffix field")
420+
421+
test_file = TEST_FOLDER / "oauth_instance_url_suffix/invalid/oauth-config.xml"
422+
file_to_test = ConnectorFile("oauth-config.xml", "oauth-config")
423+
xml_violations_buffer = []
424+
425+
self.assertFalse(validate_single_file(file_to_test, test_file, xml_violations_buffer, dummy_properties),
426+
"The instanceUrlSuffix must be located after authUri and tokenUri.")

validation/oauth_config.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<xs:element type="xs:string" name="authUri"/>
3535
<xs:element type="xs:string" name="tokenUri"/>
3636
<xs:element type="xs:string" name="userInfoUri" maxOccurs="1" minOccurs="0"/>
37+
<xs:element type="xs:string" name="instanceUrlSuffix" maxOccurs="1" minOccurs="0"/>
3738
<xs:element type="xs:string" name="instanceUrlValidationRegex" maxOccurs="1" minOccurs="0"/>
3839
<xs:element type="xs:string" name="scopes" maxOccurs="unbounded" minOccurs="1"/>
3940
<xs:element type="xs:string" name="requiredAuthAttrs" maxOccurs="unbounded" minOccurs="0"/>

0 commit comments

Comments
 (0)