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
11 changes: 11 additions & 0 deletions tableauserverclient/models/user_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def __init__(self, name=None, site_role=None, auth_setting=None):
self._last_login = None
self._workbooks = None
self._favorites = None
self._groups = None
self.email = None
self.fullname = None
self.name = name
Expand Down Expand Up @@ -107,12 +108,22 @@ def favorites(self):
raise UnpopulatedPropertyError(error)
return self._favorites

@property
def groups(self):
if self._groups is None:
error = "User item must be populated with groups first."
raise UnpopulatedPropertyError(error)
return self._groups()

def to_reference(self):
return ResourceReference(id_=self.id, tag_name=self.tag_name)

def _set_workbooks(self, workbooks):
self._workbooks = workbooks

def _set_groups(self, groups):
self._groups = groups

def _parse_common_tags(self, user_xml, ns):
if not isinstance(user_xml, ET.Element):
user_xml = ET.fromstring(user_xml).find('.//t:user', namespaces=ns)
Expand Down
22 changes: 21 additions & 1 deletion tableauserverclient/server/endpoint/users_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .endpoint import QuerysetEndpoint, api
from .exceptions import MissingRequiredFieldError
from .. import RequestFactory, RequestOptions, UserItem, WorkbookItem, PaginationItem
from .. import RequestFactory, RequestOptions, UserItem, WorkbookItem, PaginationItem, GroupItem
from ..pager import Pager

import copy
Expand Down Expand Up @@ -96,3 +96,23 @@ def _get_wbs_for_user(self, user_item, req_options=None):

def populate_favorites(self, user_item):
self.parent_srv.favorites.get(user_item)

# Get groups for user
@api(version="3.7")
def populate_groups(self, user_item, req_options=None):
if not user_item.id:
error = "User item missing ID."
raise MissingRequiredFieldError(error)

def groups_for_user_pager():
return Pager(lambda options: self._get_groups_for_user(user_item, options), req_options)

user_item._set_groups(groups_for_user_pager)

def _get_groups_for_user(self, user_item, req_options=None):
url = "{0}/{1}/groups".format(self.baseurl, user_item.id)
server_response = self.get_request(url, req_options)
logger.info('Populated groups for user (ID: {0})'.format(user_item.id))
group_item = GroupItem.from_response(server_response.content, self.parent_srv.namespace)
pagination_item = PaginationItem.from_response(server_response.content, self.parent_srv.namespace)
return group_item, pagination_item
15 changes: 15 additions & 0 deletions test/assets/user_populate_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version='1.0' encoding='UTF-8'?>
<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-3.7.xsd">
<pagination pageNumber="1" pageSize="100" totalAvailable="3" />
<groups>
<group id="ef8b19c0-43b6-11e6-af50-63f5805dbe3c" name="All Users">
<domain name="local" />
</group>
<group id="e7833b48-c6f7-47b5-a2a7-36e7dd232758" name="Another group">
<domain name="local" />
</group>
<group id="86a66d40-f289-472a-83d0-927b0f954dc8" name="TableauExample">
<domain name="local" />
</group>
</groups>
</tsResponse>
27 changes: 27 additions & 0 deletions test/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ADD_XML = os.path.join(TEST_ASSET_DIR, 'user_add.xml')
POPULATE_WORKBOOKS_XML = os.path.join(TEST_ASSET_DIR, 'user_populate_workbooks.xml')
GET_FAVORITES_XML = os.path.join(TEST_ASSET_DIR, 'favorites_get.xml')
POPULATE_GROUPS_XML = os.path.join(TEST_ASSET_DIR, 'user_populate_groups.xml')


class UserTests(unittest.TestCase):
Expand Down Expand Up @@ -175,3 +176,29 @@ def test_populate_favorites(self):
self.assertEqual(view.id, 'd79634e1-6063-4ec9-95ff-50acbf609ff5')
self.assertEqual(datasource.id, 'e76a1461-3b1d-4588-bf1b-17551a879ad9')
self.assertEqual(project.id, '1d0304cd-3796-429f-b815-7258370b9b74')

def test_populate_groups(self):
self.server.version = '3.7'
with open(POPULATE_GROUPS_XML, 'rb') as f:
response_xml = f.read().decode('utf-8')
with requests_mock.mock() as m:
m.get(self.server.users.baseurl + '/dd2239f6-ddf1-4107-981a-4cf94e415794/groups',
text=response_xml)
single_user = TSC.UserItem('test', 'Interactor')
single_user._id = 'dd2239f6-ddf1-4107-981a-4cf94e415794'
self.server.users.populate_groups(single_user)

group_list = list(single_user.groups)

self.assertEqual(3, len(group_list))
self.assertEqual('ef8b19c0-43b6-11e6-af50-63f5805dbe3c', group_list[0].id)
self.assertEqual('All Users', group_list[0].name)
self.assertEqual('local', group_list[0].domain_name)

self.assertEqual('e7833b48-c6f7-47b5-a2a7-36e7dd232758', group_list[1].id)
self.assertEqual('Another group', group_list[1].name)
self.assertEqual('local', group_list[1].domain_name)

self.assertEqual('86a66d40-f289-472a-83d0-927b0f954dc8', group_list[2].id)
self.assertEqual('TableauExample', group_list[2].name)
self.assertEqual('local', group_list[2].domain_name)