python-sysaid 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_sysaid-0.1.0.dist-info/METADATA +205 -0
- python_sysaid-0.1.0.dist-info/RECORD +26 -0
- python_sysaid-0.1.0.dist-info/WHEEL +4 -0
- python_sysaid-0.1.0.dist-info/licenses/LICENSE +21 -0
- sysaid/__init__.py +37 -0
- sysaid/_params.py +80 -0
- sysaid/_unverified.py +33 -0
- sysaid/auth.py +62 -0
- sysaid/client.py +160 -0
- sysaid/exceptions.py +95 -0
- sysaid/models.py +76 -0
- sysaid/oauth.py +85 -0
- sysaid/py.typed +0 -0
- sysaid/resources/__init__.py +0 -0
- sysaid/resources/_base.py +70 -0
- sysaid/resources/action_items.py +127 -0
- sysaid/resources/addons.py +63 -0
- sysaid/resources/assets.py +61 -0
- sysaid/resources/cis.py +134 -0
- sysaid/resources/filters.py +44 -0
- sysaid/resources/lists.py +56 -0
- sysaid/resources/password_services.py +74 -0
- sysaid/resources/reports.py +30 -0
- sysaid/resources/resource_bundle.py +18 -0
- sysaid/resources/service_requests.py +260 -0
- sysaid/resources/users.py +108 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Users: ``/users``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterator, Sequence
|
|
6
|
+
from os import PathLike
|
|
7
|
+
|
|
8
|
+
from .._params import quote_segment
|
|
9
|
+
from ..models import Record
|
|
10
|
+
from ._base import DEFAULT_PAGE_SIZE, JSONDict, RecordList, Resource, query, read_upload
|
|
11
|
+
|
|
12
|
+
MAX_PHOTO_BYTES = 500 * 1024
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Users(Resource):
|
|
16
|
+
"""Users and their photos and permissions."""
|
|
17
|
+
|
|
18
|
+
def list(
|
|
19
|
+
self,
|
|
20
|
+
*,
|
|
21
|
+
view: str | None = None,
|
|
22
|
+
fields: Sequence[str] | None = None,
|
|
23
|
+
type: str | None = None,
|
|
24
|
+
offset: int | None = None,
|
|
25
|
+
limit: int | None = None,
|
|
26
|
+
) -> RecordList:
|
|
27
|
+
"""One page of users. ``type`` is ``admin``, ``user`` or ``manager``."""
|
|
28
|
+
params = query(view=view, fields=fields, type=type, offset=offset, limit=limit)
|
|
29
|
+
return self._list("/users", params)
|
|
30
|
+
|
|
31
|
+
def iter(
|
|
32
|
+
self,
|
|
33
|
+
*,
|
|
34
|
+
view: str | None = None,
|
|
35
|
+
fields: Sequence[str] | None = None,
|
|
36
|
+
type: str | None = None,
|
|
37
|
+
page_size: int = DEFAULT_PAGE_SIZE,
|
|
38
|
+
) -> Iterator[Record]:
|
|
39
|
+
"""Every user, fetching pages transparently."""
|
|
40
|
+
return self._iter("/users", query(view=view, fields=fields, type=type), page_size=page_size)
|
|
41
|
+
|
|
42
|
+
def get(
|
|
43
|
+
self, user_id: int | str, *, view: str | None = None, fields: Sequence[str] | None = None
|
|
44
|
+
) -> Record:
|
|
45
|
+
"""One user."""
|
|
46
|
+
return self._get(f"/users/{quote_segment(user_id)}", query(view=view, fields=fields))
|
|
47
|
+
|
|
48
|
+
def search(
|
|
49
|
+
self,
|
|
50
|
+
text: str,
|
|
51
|
+
*,
|
|
52
|
+
view: str | None = None,
|
|
53
|
+
fields: Sequence[str] | None = None,
|
|
54
|
+
type: str | None = None,
|
|
55
|
+
offset: int | None = None,
|
|
56
|
+
limit: int | None = None,
|
|
57
|
+
sort: str | None = None,
|
|
58
|
+
direction: str | None = None,
|
|
59
|
+
) -> RecordList:
|
|
60
|
+
"""Search users by free text."""
|
|
61
|
+
params = query(
|
|
62
|
+
view=view,
|
|
63
|
+
fields=fields,
|
|
64
|
+
sort=sort,
|
|
65
|
+
direction=direction,
|
|
66
|
+
query=text,
|
|
67
|
+
type=type,
|
|
68
|
+
offset=offset,
|
|
69
|
+
limit=limit,
|
|
70
|
+
)
|
|
71
|
+
return self._list("/users/search", params)
|
|
72
|
+
|
|
73
|
+
def get_photo(self, user_id: int | str) -> bytes:
|
|
74
|
+
"""Raw bytes of the user's photo."""
|
|
75
|
+
response = self._client.request("GET", f"/users/{quote_segment(user_id)}/photo", raw=True)
|
|
76
|
+
return bytes(response.content)
|
|
77
|
+
|
|
78
|
+
def upload_photo(
|
|
79
|
+
self, user_id: int | str, photo: bytes | str | PathLike[str], filename: str | None = None
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Upload a photo, given as bytes or a file path. The server limit is 500 KB."""
|
|
82
|
+
filename, content = read_upload(photo, filename)
|
|
83
|
+
if len(content) > MAX_PHOTO_BYTES:
|
|
84
|
+
raise ValueError(f"photo is {len(content)} bytes; the limit is {MAX_PHOTO_BYTES}")
|
|
85
|
+
self._client.request(
|
|
86
|
+
"POST",
|
|
87
|
+
f"/users/{quote_segment(user_id)}/photo",
|
|
88
|
+
files={"file": (filename, content)},
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def permissions(self, user_id: int | str) -> JSONDict:
|
|
92
|
+
"""``{id, name, permissions: [{key, value}]}`` for the user."""
|
|
93
|
+
result: JSONDict = self._client.request(
|
|
94
|
+
"GET", f"/users/{quote_segment(user_id)}/permission"
|
|
95
|
+
)
|
|
96
|
+
return result
|
|
97
|
+
|
|
98
|
+
def permission(self, user_id: int | str, permission_id: str) -> JSONDict:
|
|
99
|
+
"""``{key, value}`` for one permission; ``KeyError`` if the user has no such key.
|
|
100
|
+
|
|
101
|
+
Read from :meth:`permissions`: the single-permission endpoint in the REST guide
|
|
102
|
+
answers 404 on SysAid 24.4.
|
|
103
|
+
"""
|
|
104
|
+
for item in self.permissions(user_id)["permissions"]:
|
|
105
|
+
if item["key"] == permission_id:
|
|
106
|
+
result: JSONDict = item
|
|
107
|
+
return result
|
|
108
|
+
raise KeyError(permission_id)
|