From 1842ccd5fefaca5d84d00ea892132871536ced0d Mon Sep 17 00:00:00 2001 From: Sotnichenko Sergey Date: Thu, 22 Mar 2018 18:26:36 +0300 Subject: [PATCH 1/6] Adding update method for groups --- .../server/endpoint/groups_endpoint.py | 7 +++++++ tableauserverclient/server/request_factory.py | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/tableauserverclient/server/endpoint/groups_endpoint.py b/tableauserverclient/server/endpoint/groups_endpoint.py index bee595b25..b58a73ca6 100644 --- a/tableauserverclient/server/endpoint/groups_endpoint.py +++ b/tableauserverclient/server/endpoint/groups_endpoint.py @@ -55,6 +55,13 @@ def delete(self, group_id): self.delete_request(url) logger.info('Deleted single group (ID: {0})'.format(group_id)) + @api(version="2.0") + def update(self, group_item, default_site_role=UserItem.Roles.Unlicensed): + url = "{0}/{1}".format(self.baseurl, group_item.id) + update_req = RequestFactory.Group.update_req(group_item, default_site_role) + server_response = self.put_request(url, update_req) + logger.info('Updated group item (ID: {0})'.format(group_item.id)) + # Create a 'local' Tableau group @api(version="2.0") def create(self, group_item): diff --git a/tableauserverclient/server/request_factory.py b/tableauserverclient/server/request_factory.py index c4f10d731..d07a30362 100644 --- a/tableauserverclient/server/request_factory.py +++ b/tableauserverclient/server/request_factory.py @@ -107,6 +107,17 @@ def create_req(self, group_item): group_element.attrib['name'] = group_item.name return ET.tostring(xml_request) + def update_req(self, group_item, default_site_role): + xml_request = ET.Element('tsRequest') + group_element = ET.SubElement(xml_request, 'group') + group_element.attrib['name'] = group_item.name + if group_item.domain_name != 'local': + project_element = ET.SubElement(group_element, 'import') + project_element.attrib['source'] = "ActiveDirectory" + project_element.attrib['domainName'] = group_item.domain_name + project_element.attrib['siteRole'] = default_site_role + return ET.tostring(xml_request) + class PermissionRequest(object): def _add_capability(self, parent_element, capability_set, mode): From e32a707db156d71cfc8508a6817b69f698f33e25 Mon Sep 17 00:00:00 2001 From: Sotnichenko Sergey Date: Fri, 23 Mar 2018 11:22:57 +0300 Subject: [PATCH 2/6] Add some docs --- docs/docs/api-ref.md | 45 +++++++++++++++++++ .../server/endpoint/groups_endpoint.py | 3 ++ 2 files changed, 48 insertions(+) diff --git a/docs/docs/api-ref.md b/docs/docs/api-ref.md index 7b22c3517..a57510779 100644 --- a/docs/docs/api-ref.md +++ b/docs/docs/api-ref.md @@ -849,6 +849,51 @@ Error | Description

+#### groups.update + +```py +groups.update(group_item, default_site_role=UserItem.Roles.Unlicensed) +``` + +Updates the group on the site. +If domain_name = 'local' then update only the name of the group. +If not - update group from domain. + +REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Group%3FTocPath%3DAPI%2520Reference%7C_____95){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`group_item` | the group_item specifies the group to update. + + +**Exceptions** + +Error | Description +:--- | :--- +`Group item missing ID` | Raises an exception if a valid `group_item.id` is not provided. + + +**Example** + +```py +# Update a group + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + all_groups, pagination_item = server.groups.get() + + for group in all_groups: + server.groups.update(group) +``` +
+
+ #### groups.get ```py diff --git a/tableauserverclient/server/endpoint/groups_endpoint.py b/tableauserverclient/server/endpoint/groups_endpoint.py index b58a73ca6..b6e1d4a19 100644 --- a/tableauserverclient/server/endpoint/groups_endpoint.py +++ b/tableauserverclient/server/endpoint/groups_endpoint.py @@ -57,6 +57,9 @@ def delete(self, group_id): @api(version="2.0") def update(self, group_item, default_site_role=UserItem.Roles.Unlicensed): + if not group_item.id: + error = "Group item missing ID." + raise MissingRequiredFieldError(error) url = "{0}/{1}".format(self.baseurl, group_item.id) update_req = RequestFactory.Group.update_req(group_item, default_site_role) server_response = self.put_request(url, update_req) From 1b932772c5be87e5b256d76076b8740011c5ac5e Mon Sep 17 00:00:00 2001 From: Sotnichenko Sergey Date: Fri, 23 Mar 2018 11:26:30 +0300 Subject: [PATCH 3/6] Add some docs --- docs/docs/api-ref.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/docs/api-ref.md b/docs/docs/api-ref.md index a57510779..e5c8a48c3 100644 --- a/docs/docs/api-ref.md +++ b/docs/docs/api-ref.md @@ -857,7 +857,7 @@ groups.update(group_item, default_site_role=UserItem.Roles.Unlicensed) Updates the group on the site. If domain_name = 'local' then update only the name of the group. -If not - update group from domain. +If not - update group from the Active Directory with domain_name. REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Group%3FTocPath%3DAPI%2520Reference%7C_____95){:target="_blank"} @@ -867,6 +867,7 @@ REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-u Name | Description :--- | :--- `group_item` | the group_item specifies the group to update. +`default_site_role` | if group updates from Active Directory then this is the default role for the new users. **Exceptions** From 76b6fa38000f1cf6d27579e09ba906a531c7c8ec Mon Sep 17 00:00:00 2001 From: Sotnichenko Sergey Date: Tue, 27 Mar 2018 14:30:12 +0300 Subject: [PATCH 4/6] Add test for update group function --- docs/docs/api-ref.md | 2 +- .../server/endpoint/groups_endpoint.py | 5 ++++- test/assets/group_update.xml | 6 ++++++ test/test_group.py | 15 ++++++++++++++- 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 test/assets/group_update.xml diff --git a/docs/docs/api-ref.md b/docs/docs/api-ref.md index e5c8a48c3..81d1211dd 100644 --- a/docs/docs/api-ref.md +++ b/docs/docs/api-ref.md @@ -859,7 +859,7 @@ Updates the group on the site. If domain_name = 'local' then update only the name of the group. If not - update group from the Active Directory with domain_name. -REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Group%3FTocPath%3DAPI%2520Reference%7C_____95){:target="_blank"} +REST API: [Update Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Group%3FTocPath%3DAPI%2520Reference%7C_____95){:target="_blank"} **Parameters** diff --git a/tableauserverclient/server/endpoint/groups_endpoint.py b/tableauserverclient/server/endpoint/groups_endpoint.py index b6e1d4a19..3a1c599fd 100644 --- a/tableauserverclient/server/endpoint/groups_endpoint.py +++ b/tableauserverclient/server/endpoint/groups_endpoint.py @@ -7,6 +7,7 @@ logger = logging.getLogger('tableau.endpoint.groups') +UNLICENSED_USER = UserItem.Roles.Unlicensed class Groups(Endpoint): @property @@ -56,7 +57,7 @@ def delete(self, group_id): logger.info('Deleted single group (ID: {0})'.format(group_id)) @api(version="2.0") - def update(self, group_item, default_site_role=UserItem.Roles.Unlicensed): + def update(self, group_item, default_site_role=UNLICENSED_USER): if not group_item.id: error = "Group item missing ID." raise MissingRequiredFieldError(error) @@ -64,6 +65,8 @@ def update(self, group_item, default_site_role=UserItem.Roles.Unlicensed): update_req = RequestFactory.Group.update_req(group_item, default_site_role) server_response = self.put_request(url, update_req) logger.info('Updated group item (ID: {0})'.format(group_item.id)) + updated_group = GroupItem.from_response(server_response.content, self.parent_srv.namespace)[0] + return updated_group # Create a 'local' Tableau group @api(version="2.0") diff --git a/test/assets/group_update.xml b/test/assets/group_update.xml new file mode 100644 index 000000000..b5dba4bc6 --- /dev/null +++ b/test/assets/group_update.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/test/test_group.py b/test/test_group.py index 244ba47b8..a0ac98412 100644 --- a/test/test_group.py +++ b/test/test_group.py @@ -14,7 +14,7 @@ ADD_USER_POPULATE = os.path.join(TEST_ASSET_DIR, 'group_users_added.xml') CREATE_GROUP = os.path.join(TEST_ASSET_DIR, 'group_create.xml') CREATE_GROUP_ASYNC = os.path.join(TEST_ASSET_DIR, 'group_create_async.xml') - +UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'group_update.xml') class GroupTests(unittest.TestCase): def setUp(self): @@ -183,3 +183,16 @@ def test_create_group(self): group = self.server.groups.create(group_to_create) self.assertEqual(group.name, u'試供品') self.assertEqual(group.id, '3e4a9ea0-a07a-4fe6-b50f-c345c8c81034') + + def test_update(self): + with open(UPDATE_XML, 'rb') as f: + response_xml = f.read().decode('utf-8') + with requests_mock.mock() as m: + m.put(self.baseurl + '/ef8b19c0-43b6-11e6-af50-63f5805dbe3c', text=response_xml) + group = TSC.GroupItem(name='Test Group') + group._domain_name = 'local' + group._id = 'ef8b19c0-43b6-11e6-af50-63f5805dbe3c' + group = self.server.groups.update(group) + + self.assertEqual('ef8b19c0-43b6-11e6-af50-63f5805dbe3c', group.id) + self.assertEqual('Group updated name', group.name) From d12280a37777a28cba22cb571e089932a5aa53ed Mon Sep 17 00:00:00 2001 From: Sotnichenko Sergey Date: Fri, 30 Mar 2018 13:04:35 +0300 Subject: [PATCH 5/6] Add test for update group function --- tableauserverclient/server/endpoint/groups_endpoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tableauserverclient/server/endpoint/groups_endpoint.py b/tableauserverclient/server/endpoint/groups_endpoint.py index 3a1c599fd..2428ff9be 100644 --- a/tableauserverclient/server/endpoint/groups_endpoint.py +++ b/tableauserverclient/server/endpoint/groups_endpoint.py @@ -9,6 +9,7 @@ UNLICENSED_USER = UserItem.Roles.Unlicensed + class Groups(Endpoint): @property def baseurl(self): From 4c8213ef112ed58a632a8bfe170c50b80082fa10 Mon Sep 17 00:00:00 2001 From: Sotnichenko Sergey Date: Fri, 30 Mar 2018 13:54:07 +0300 Subject: [PATCH 6/6] Add test for update group function --- test/test_group.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_group.py b/test/test_group.py index a0ac98412..7096ca408 100644 --- a/test/test_group.py +++ b/test/test_group.py @@ -16,6 +16,7 @@ CREATE_GROUP_ASYNC = os.path.join(TEST_ASSET_DIR, 'group_create_async.xml') UPDATE_XML = os.path.join(TEST_ASSET_DIR, 'group_update.xml') + class GroupTests(unittest.TestCase): def setUp(self): self.server = TSC.Server('http://test')