Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
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 11 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 22 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 15 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 27 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.