8000 Fixes groups.update to match server requests/responses (#772) · tableau/server-client-python@1c7480f · GitHub
[go: up one dir, main page]

Skip to content

Commit 1c7480f

Browse files
author
Chris Shin
authored
Fixes groups.update to match server requests/responses (#772)
1 parent 861c653 commit 1c7480f

File tree

5 files changed

+59
-24
lines changed

5 files changed

+59
-24
lines changed

tableauserverclient/models/group_item.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,18 @@ def from_response(cls, resp, ns):
8383
name = group_xml.get('name', None)
8484
group_item = cls(name)
8585
group_item._id = group_xml.get('id', None)
86-
# AD groups have an extra element under this
86+
87+
# Domain name is returned in a domain element for some calls
88+
domain_elem = group_xml.find('.//t:domain', namespaces=ns)
89+
if domain_elem is not None:
90+
group_item.domain_name = domain_elem.get('name', None)
91+
92+
# Import element is returned for both local and AD groups (2020.3+)
8793
import_elem = group_xml.find('.//t:import', namespaces=ns)
88-
if (import_elem is not None):
89-
group_item.domain_name = import_elem.get('domainName')
90-
group_item.license_mode = import_elem.get('grantLicenseMode')
91-
group_item.minimum_site_role = import_elem.get('siteRole')
92-
else:
93-
# local group, we will just have two extra attributes here
94-
group_item.domain_name = 'local'
95-
group_item.license_mode = group_xml.get('grantLicenseMode')
96-
group_item.minimum_site_role = group_xml.get('siteRole')
94+
if import_elem is not None:
95+
group_item.domain_name = import_elem.get('domainName', None)
96+
group_item.license_mode = import_elem.get('grantLicenseMode', None)
97+
group_item.minimum_site_role = import_elem.get('siteRole', None)
9798

9899
all_group_items.append(group_item)
99100
return all_group_items

tableauserverclient/server/endpoint/groups_endpoint.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
logger = logging.getLogger('tableau.endpoint.groups')
99

10-
UNLICENSED_USER = UserItem.Roles.Unlicensed
11-
1210

1311
class Groups(Endpoint):
1412
@property
@@ -58,15 +56,28 @@ def delete(self, group_id):
5856
logger.info('Deleted single group (ID: {0})'.format(group_id))
5957

6058
@api(version="2.0")
61-
def update(self, group_item, default_site_role=UNLICENSED_USER, as_job=False):
59+
def update(self, group_item, default_site_role=None, as_job=False):
60+
# (1/8/2021): Deprecated starting v0.15
61+
if default_site_role is not None:
62+
import warnings
63+
warnings.simplefilter('always', DeprecationWarning)
64+
warnings.warn('Groups.update(...default_site_role=""...) is deprecated, '
65+
'please set the minimum_site_role field of GroupItem',
66+
DeprecationWarning)
67+
group_item.minimum_site_role = default_site_role
68+
6269
if not group_item.id:
6370
error = "Group item missing ID."
6471
raise MissingRequiredFieldError(error)
72+
if as_job and (group_item.domain_name is None or group_item.domain_name == 'local'):
73+
error = "Local groups cannot be updated asynchronously."
74+
raise ValueError(error)
75+
6576
url = "{0}/{1}".format(self.baseurl, group_item.id)
66-
update_req = RequestFactory.Group.update_req(group_item, default_site_role)
77+
update_req = RequestFactory.Group.update_req(group_item, None)
6778
server_response = self.put_request(url, update_req)
6879
logger.info('Updated group item (ID: {0})'.format(group_item.id))
69-
if (as_job):
80+
if as_job:
7081
return JobItem.from_response(server_response.content, self.parent_srv.namespace)[0]
7182
else:
7283
return GroupItem.from_response(server_response.content, self.parent_srv.namespace)[0]

tableauserverclient/server/request_factory.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,17 +299,30 @@ def create_ad_req(self, group_item):
299299
return ET.tostring(xml_request)
300300

301301
def update_req(self, group_item, default_site_role=None):
302+
# (1/8/2021): Deprecated starting v0.15
302303
if default_site_role is not None:
304+
import warnings
305+
warnings.simplefilter('always', DeprecationWarning)
306+
warnings.warn('RequestFactory.Group.update_req(...default_site_role="") is deprecated, '
307+
'please set the minimum_site_role field of GroupItem',
308+
DeprecationWarning)
303309
group_item.minimum_site_role = default_site_role
310+
304311
xml_request = ET.Element('tsRequest')
305312
group_element = ET.SubElement(xml_request, 'group')
306313
group_element.attrib['name'] = group_item.name
307-
if group_item.domain_name != 'local':
308-
project_element = ET.SubElement(group_element, 'import')
309-
project_element.attrib['source'] = "ActiveDirectory"
310-
project_element.attrib['domainName'] = group_item.domain_name
311-
project_element.attrib['siteRole'] = group_item.minimum_site_role
312-
project_element.attrib['grantLicenseMode'] = group_item.license_mode
314+
if group_item.domain_name is not None and group_item.domain_name != 'local':
315+
# Import element is only accepted in the request for AD groups
316+
import_element = ET.SubElement(group_element, 'import')
317+
import_element.attrib['source'] = "ActiveDirectory"
318+
import_element.attrib['domainName'] = group_item.domain_name
319+
import_element.attrib['siteRole'] = group_item.minimum_site_role
320+
if group_item.license_mode is not None:
321+
import_element.attrib['grantLicenseMode'] = group_item.license_mode
322+
else:
323+
# Local group request does not accept an 'import' element
324+
if group_item.minimum_site_role is not None:
325+
group_element.attrib['minimumSiteRole'] = group_item.minimum_site_role
313326

314327
return ET.tostring(xml_request)
315328

test/assets/group_update.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<tsResponse xmlns="http://tableau.com/api"
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
5-
<group id="ef8b19c0-43b6-11e6-af50-63f5805dbe3c" name="Group updated name"
6-
siteRole="ExplorerCanPublish"
7-
grantLicenseMode='onLogin'/>/>
5+
<group id="ef8b19c0-43b6-11e6-af50-63f5805dbe3c" name="Group updated name">
6+
<import domainName="local" siteRole="ExplorerCanPublish" grantLicenseMode="onLogin" />
7+
</group>
88
</tsResponse>

test/test_group.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,13 @@ def test_update(self):
224224
self.assertEqual('Group updated name', group.name)
225225
self.assertEqual('ExplorerCanPublish', group.minimum_site_role)
226226
self.assertEqual('onLogin', group.license_mode)
227+
228+
# async update is not supported for local groups
229+
def test_update_local_async(self):
230+
group = TSC.GroupItem("myGroup")
231+
group._id = 'ef8b19c0-43b6-11e6-af50-63f5805dbe3c'
232+
self.assertRaises(ValueError, self.server.groups.update, group, as_job=True)
233+
234+
# mimic group returned from server where domain name is set to 'local'
235+
group.domain_name = "local"
236+
self.assertRaises(ValueError, self.server.groups.update, group, as_job=True)

0 commit comments

Comments
 (0)
0