Skip to content

Commit 6b17b62

Browse files
authored
Merge branch 'development' into jorwoods/oidc_strs
2 parents e233ce7 + 61062dc commit 6b17b62

20 files changed

+713
-3
lines changed

samples/update_connection_auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def main():
5151
connection = connections[0]
5252
connection.username = args.datasource_username
5353
connection.password = args.datasource_password
54-
connection.authentication_type = args.authentication_type
54+
connection.auth_type = args.authentication_type
5555
connection.embed_password = True
5656

5757
updated_connection = update_function(resource, connection)

samples/update_connections_auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def main():
3535
logging_level = getattr(logging, args.logging_level.upper())
3636
logging.basicConfig(level=logging_level)
3737

38-
tableau_auth = TSC.TableauAuth(args.token_name, args.token_value, site_id=args.site)
38+
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
3939
server = TSC.Server(args.server, use_server_version=True)
4040

4141
with server.auth.sign_in(tableau_auth):

tableauserverclient/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
RevisionItem,
3838
ScheduleItem,
3939
SiteAuthConfiguration,
40+
SiteOIDCConfiguration,
4041
SiteItem,
4142
ServerInfoItem,
4243
SubscriptionItem,
@@ -125,6 +126,7 @@
125126
"ServerResponseError",
126127
"SiteItem",
127128
"SiteAuthConfiguration",
129+
"SiteOIDCConfiguration",
128130
"Sort",
129131
"SubscriptionItem",
130132
"TableauAuth",

tableauserverclient/models/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
)
3131
from tableauserverclient.models.location_item import LocationItem
3232
from tableauserverclient.models.metric_item import MetricItem
33+
from tableauserverclient.models.oidc_item import SiteOIDCConfiguration
3334
from tableauserverclient.models.pagination_item import PaginationItem
3435
from tableauserverclient.models.permissions_item import PermissionsRule, Permission
3536
from tableauserverclient.models.project_item import ProjectItem
@@ -79,6 +80,7 @@
7980
"BackgroundJobItem",
8081
"LocationItem",
8182
"MetricItem",
83+
"SiteOIDCConfiguration",
8284
"PaginationItem",
8385
"Permission",
8486
"PermissionsRule",
@@ -88,6 +90,7 @@
8890
"ServerInfoItem",
8991
"SiteAuthConfiguration",
9092
"SiteItem",
93+
"SiteOIDCConfiguration",
9194
"SubscriptionItem",
9295
"TableItem",
9396
"TableauAuth",
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from typing import Optional
2+
from defusedxml.ElementTree import fromstring
3+
4+
5+
class SiteOIDCConfiguration:
6+
def __init__(self) -> None:
7+
self.enabled: bool = False
8+
self.test_login_url: Optional[str] = None
9+
self.known_provider_alias: Optional[str] = None
10+
self.allow_embedded_authentication: bool = False
11+
self.use_full_name: bool = False
12+
self.idp_configuration_name: Optional[str] = None
13+
self.idp_configuration_id: Optional[str] = None
14+
self.client_id: Optional[str] = None
15+
self.client_secret: Optional[str] = None
16+
self.authorization_endpoint: Optional[str] = None
17+
self.token_endpoint: Optional[str] = None
18+
self.userinfo_endpoint: Optional[str] = None
19+
self.jwks_uri: Optional[str] = None
20+
self.end_session_endpoint: Optional[str] = None
21+
self.custom_scope: Optional[str] = None
22+
self.essential_acr_values: Optional[str] = None
23+
self.email_mapping: Optional[str] = None
24+
self.first_name_mapping: Optional[str] = None
25+
self.last_name_mapping: Optional[str] = None
26+
self.full_name_mapping: Optional[str] = None
27+
self.prompt: Optional[str] = None
28+
self.client_authentication: Optional[str] = None
29+
self.voluntary_acr_values: Optional[str] = None
30+
31+
def __str__(self) -> str:
32+
return (
33+
f"{self.__class__.__qualname__}(enabled={self.enabled}, "
34+
f"test_login_url={self.test_login_url}, "
35+
f"idp_configuration_name={self.idp_configuration_name}, "
36+
f"idp_configuration_id={self.idp_configuration_id}, "
37+
f"client_id={self.client_id})"
38+
)
39+
40+
def __repr__(self) -> str:
41+
return f"<{str(self)}>"
42+
43+
@classmethod
44+
def from_response(cls, raw_xml: bytes, ns) -> "SiteOIDCConfiguration":
45+
"""
46+
Parses the raw XML bytes and returns a SiteOIDCConfiguration object.
47+
"""
48+
root = fromstring(raw_xml)
49+
elem = root.find("t:siteOIDCConfiguration", namespaces=ns)
50+
if elem is None:
51+
raise ValueError("No siteOIDCConfiguration element found in the XML.")
52+
config = cls()
53+
54+
config.enabled = str_to_bool(elem.get("enabled", "false"))
55+
config.test_login_url = elem.get("testLoginUrl")
56+
config.known_provider_alias = elem.get("knownProviderAlias")
57+
config.allow_embedded_authentication = str_to_bool(elem.get("allowEmbeddedAuthentication", "false").lower())
58+
config.use_full_name = str_to_bool(elem.get("useFullName", "false").lower())
59+
config.idp_configuration_name = elem.get("idpConfigurationName")
60+
config.idp_configuration_id = elem.get("idpConfigurationId")
61+
config.client_id = elem.get("clientId")
62+
config.client_secret = elem.get("clientSecret")
63+
config.authorization_endpoint = elem.get("authorizationEndpoint")
64+
config.token_endpoint = elem.get("tokenEndpoint")
65+
config.userinfo_endpoint = elem.get("userinfoEndpoint")
66+
config.jwks_uri = elem.get("jwksUri")
67+
config.end_session_endpoint = elem.get("endSessionEndpoint")
68+
config.custom_scope = elem.get("customScope")
69+
config.essential_acr_values = elem.get("essentialAcrValues")
70+
config.email_mapping = elem.get("emailMapping")
71+
config.first_name_mapping = elem.get("firstNameMapping")
72+
config.last_name_mapping = elem.get("lastNameMapping")
73+
config.full_name_mapping = elem.get("fullNameMapping")
74+
config.prompt = elem.get("prompt")
75+
config.client_authentication = elem.get("clientAuthentication")
76+
config.voluntary_acr_values = elem.get("voluntaryAcrValues")
77+
78+
return config
79+
80+
81+
def str_to_bool(s: str) -> bool:
82+
return s == "true"

tableauserverclient/models/site_item.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ class SiteItem:
8585
state: str
8686
Shows the current state of the site (Active or Suspended).
8787
88+
attribute_capture_enabled: Optional[str]
89+
Enables user attributes for all Tableau Server embedding workflows.
90+
8891
"""
8992

9093
_user_quota: Optional[int] = None
@@ -164,6 +167,7 @@ def __init__(
164167
time_zone=None,
165168
auto_suspend_refresh_enabled: bool = True,
166169
auto_suspend_refresh_inactivity_window: int = 30,
170+
attribute_capture_enabled: Optional[bool] = None,
167171
):
168172
self._admin_mode = None
169173
self._id: Optional[str] = None
@@ -217,6 +221,7 @@ def __init__(
217221
self.time_zone = time_zone
218222
self.auto_suspend_refresh_enabled = auto_suspend_refresh_enabled
219223
self.auto_suspend_refresh_inactivity_window = auto_suspend_refresh_inactivity_window
224+
self.attribute_capture_enabled = attribute_capture_enabled
220225

221226
@property
222227
def admin_mode(self) -> Optional[str]:
@@ -720,6 +725,7 @@ def _parse_common_tags(self, site_xml, ns):
720725
time_zone,
721726
auto_suspend_refresh_enabled,
722727
auto_suspend_refresh_inactivity_window,
728+
attribute_capture_enabled,
723729
) = self._parse_element(site_xml, ns)
724730

725731
self._set_values(
@@ -774,6 +780,7 @@ def _parse_common_tags(self, site_xml, ns):
774780
time_zone,
775781
auto_suspend_refresh_enabled,
776782
auto_suspend_refresh_inactivity_window,
783+
attribute_capture_enabled,
777784
)
778785
return self
779786

@@ -830,6 +837,7 @@ def _set_values(
830837
time_zone,
831838
auto_suspend_refresh_enabled,
832839
auto_suspend_refresh_inactivity_window,
840+
attribute_capture_enabled,
833841
):
834842
if id is not None:
835843
self._id = id
@@ -937,6 +945,7 @@ def _set_values(
937945
self.auto_suspend_refresh_enabled = auto_suspend_refresh_enabled
938946
if auto_suspend_refresh_inactivity_window is not None:
939947
self.auto_suspend_refresh_inactivity_window = auto_suspend_refresh_inactivity_window
948+
self.attribute_capture_enabled = attribute_capture_enabled
940949

941950
@classmethod
942951
def from_response(cls, resp, ns) -> list["SiteItem"]:
@@ -996,6 +1005,7 @@ def from_response(cls, resp, ns) -> list["SiteItem"]:
9961005
time_zone,
9971006
auto_suspend_refresh_enabled,
9981007
auto_suspend_refresh_inactivity_window,
1008+
attribute_capture_enabled,
9991009
) = cls._parse_element(site_xml, ns)
10001010

10011011
site_item = cls(name, content_url)
@@ -1051,6 +1061,7 @@ def from_response(cls, resp, ns) -> list["SiteItem"]:
10511061
time_zone,
10521062
auto_suspend_refresh_enabled,
10531063
auto_suspend_refresh_inactivity_window,
1064+
attribute_capture_enabled,
10541065
)
10551066
all_site_items.append(site_item)
10561067
return all_site_items
@@ -1132,6 +1143,9 @@ def _parse_element(site_xml, ns):
11321143

11331144
flows_enabled = string_to_bool(site_xml.get("flowsEnabled", ""))
11341145
cataloging_enabled = string_to_bool(site_xml.get("catalogingEnabled", ""))
1146+
attribute_capture_enabled = (
1147+
string_to_bool(ace) if (ace := site_xml.get("attributeCaptureEnabled")) is not None else None
1148+
)
11351149

11361150
return (
11371151
id,
@@ -1185,6 +1199,7 @@ def _parse_element(site_xml, ns):
11851199
time_zone,
11861200
auto_suspend_refresh_enabled,
11871201
auto_suspend_refresh_inactivity_window,
1202+
attribute_capture_enabled,
11881203
)
11891204

11901205

tableauserverclient/server/endpoint/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from tableauserverclient.server.endpoint.linked_tasks_endpoint import LinkedTasks
1818
from tableauserverclient.server.endpoint.metadata_endpoint import Metadata
1919
from tableauserverclient.server.endpoint.metrics_endpoint import Metrics
20+
from tableauserverclient.server.endpoint.oidc_endpoint import OIDC
2021
from tableauserverclient.server.endpoint.projects_endpoint import Projects
2122
from tableauserverclient.server.endpoint.schedules_endpoint import Schedules
2223
from tableauserverclient.server.endpoint.server_info_endpoint import ServerInfo
@@ -52,6 +53,7 @@
5253
"LinkedTasks",
5354
"Metadata",
5455
"Metrics",
56+
"OIDC",
5557
"Projects",
5658
"Schedules",
5759
"ServerInfo",

0 commit comments

Comments
 (0)