-
Notifications
You must be signed in to change notification settings - Fork 413
/
permissions_item.py
103 lines (79 loc) · 3.64 KB
/
permissions_item.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import xml.etree.ElementTree as ET
from typing import Dict, List, Optional
from defusedxml.ElementTree import fromstring
from .exceptions import UnknownGranteeTypeError, UnpopulatedPropertyError
from .group_item import GroupItem
from .reference_item import ResourceReference
from .user_item import UserItem
from tableauserverclient.helpers.logging import logger
class Permission:
class Mode:
Allow = "Allow"
Deny = "Deny"
def __repr__(self):
return "<Enum Mode: Allow | Deny>"
class Capability:
AddComment = "AddComment"
ChangeHierarchy = "ChangeHierarchy"
ChangePermissions = "ChangePermissions"
Connect = "Connect"
Delete = "Delete"
Execute = "Execute"
ExportData = "ExportData"
ExportImage = "ExportImage"
ExportXml = "ExportXml"
Filter = "Filter"
ProjectLeader = "ProjectLeader"
Read = "Read"
ShareView = "ShareView"
ViewComments = "ViewComments"
ViewUnderlyingData = "ViewUnderlyingData"
WebAuthoring = "WebAuthoring"
Write = "Write"
RunExplainData = "RunExplainData"
CreateRefreshMetrics = "CreateRefreshMetrics"
SaveAs = "SaveAs"
def __repr__(self):
return "<Enum Capability: AddComment | ChangeHierarchy | ChangePermission ... (17 more) >"
class PermissionsRule(object):
def __init__(self, grantee: ResourceReference, capabilities: Dict[str, str]) -> None:
self.grantee = grantee
self.capabilities = capabilities
def __repr__(self):
return "<PermissionsRule grantee={}, capabilities={}>".format(self.grantee, self.capabilities)
@classmethod
def from_response(cls, resp, ns=None) -> List["PermissionsRule"]:
parsed_response = fromstring(resp)
rules = []
permissions_rules_list_xml = parsed_response.findall(".//t:granteeCapabilities", namespaces=ns)
for grantee_capability_xml in permissions_rules_list_xml:
capability_dict: Dict[str, str] = {}
grantee = PermissionsRule._parse_grantee_element(grantee_capability_xml, ns)
for capability_xml in grantee_capability_xml.findall(".//t:capabilities/t:capability", namespaces=ns):
name = capability_xml.get("name")
mode = capability_xml.get("mode")
if name is None or mode is None:
logger.error("Capability was not valid: {}".format(capability_xml))
raise UnpopulatedPropertyError()
else:
capability_dict[name] = mode
rule = PermissionsRule(grantee, capability_dict)
rules.append(rule)
return rules
@staticmethod
def _parse_grantee_element(grantee_capability_xml: ET.Element, ns: Optional[Dict[str, str]]) -> ResourceReference:
"""Use Xpath magic and some string splitting to get the right object type from the xml"""
# Get the first element in the tree with an 'id' attribute
grantee_element = grantee_capability_xml.findall(".//*[@id]", namespaces=ns).pop()
grantee_id = grantee_element.get("id", None)
grantee_type = grantee_element.tag.split("}").pop()
if grantee_id is None:
logger.error("Cannot find grantee type in response")
raise UnknownGranteeTypeError()
if grantee_type == "user":
grantee = UserItem.as_reference(grantee_id)
elif grantee_type == "group":
grantee = GroupItem.as_reference(grantee_id)
else:
raise UnknownGranteeTypeError("No support for grantee type of {}".format(grantee_type))
return grantee