Skip to content

Commit d1c8b66

Browse files
committed
Update Permissions
1 parent d5d6459 commit d1c8b66

File tree

5 files changed

+122
-74
lines changed

5 files changed

+122
-74
lines changed

src/posit/connect/content.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ def environment_variables(self) -> EnvVars:
346346

347347
@property
348348
def permissions(self) -> Permissions:
349-
return Permissions(context_to_resource_parameters(self._ctx), self["guid"])
349+
return Permissions(self._ctx)
350350

351351
@property
352352
def owner(self) -> dict:

src/posit/connect/permissions.py

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,46 @@
44

55
from typing import List, overload
66

7-
from requests.sessions import Session as Session
7+
from ._active import ActiveDict
8+
from ._types_content_item import ContentItemContext
9+
from ._types_context import ContextP
810

9-
from .resources import Resource, ResourceParameters, Resources
1011

12+
class PermissionContext(ContentItemContext):
13+
permission_id: str
14+
15+
def __init__(self, ctx: ContentItemContext, /, *, permission_id: str) -> None:
16+
super().__init__(ctx, content_guid=ctx.content_guid)
17+
self.permission_id = permission_id
18+
19+
20+
class Permission(ActiveDict[PermissionContext]):
21+
@classmethod
22+
def _api_path(cls, content_guid: str, permission_id: str) -> str:
23+
return f"v1/content/{content_guid}/permissions/{permission_id}"
24+
25+
def __init__(self, ctx: ContentItemContext, /, **kwargs) -> None:
26+
permission_id = kwargs.get("id")
27+
assert isinstance(
28+
permission_id, str
29+
), f"Permission 'id' must be a string. Got: {permission_id}"
30+
assert permission_id, "Permission 'id' must not be an empty string."
31+
32+
permission_ctx = PermissionContext(
33+
ctx,
34+
permission_id=permission_id,
35+
)
36+
path = self._api_path(permission_ctx.content_guid, permission_ctx.permission_id)
37+
get_data = len(kwargs) == 1 # `id` is required
38+
39+
super().__init__(permission_ctx, path, get_data, **kwargs)
1140

12-
class Permission(Resource):
1341
def delete(self) -> None:
1442
"""Delete the permission."""
15-
path = f"v1/content/{self['content_guid']}/permissions/{self['id']}"
16-
url = self.params.url + path
17-
self.params.session.delete(url)
43+
self._delete_api()
1844

1945
@overload
20-
def update(self, *args, role: str, **kwargs) -> None:
46+
def update(self, *args, role: str, **kwargs) -> Permission:
2147
"""Update the permission.
2248
2349
Parameters
@@ -27,10 +53,10 @@ def update(self, *args, role: str, **kwargs) -> None:
2753
"""
2854

2955
@overload
30-
def update(self, *args, **kwargs) -> None:
56+
def update(self, *args, **kwargs) -> Permission:
3157
"""Update the permission."""
3258

33-
def update(self, *args, **kwargs) -> None:
59+
def update(self, *args, **kwargs) -> Permission:
3460
"""Update the permission."""
3561
body = {
3662
"principal_guid": self.get("principal_guid"),
@@ -39,19 +65,14 @@ def update(self, *args, **kwargs) -> None:
3965
}
4066
body.update(dict(*args))
4167
body.update(**kwargs)
42-
path = f"v1/content/{self['content_guid']}/permissions/{self['id']}"
43-
url = self.params.url + path
44-
response = self.params.session.put(
45-
url,
46-
json=body,
47-
)
48-
super().update(**response.json())
68+
result = self._put_api(json=body)
69+
return Permission(self._ctx, **result) # pyright: ignore[reportCallIssue]
4970

5071

51-
class Permissions(Resources):
52-
def __init__(self, params: ResourceParameters, content_guid: str) -> None:
53-
super().__init__(params)
54-
self.content_guid = content_guid
72+
class Permissions(ContextP[ContentItemContext]):
73+
def __init__(self, ctx: ContentItemContext) -> None:
74+
super().__init__()
75+
self._ctx = ctx
5576

5677
def count(self) -> int:
5778
"""Count the number of permissions.
@@ -93,10 +114,10 @@ def create(self, **kwargs) -> Permission:
93114
-------
94115
Permission
95116
"""
96-
path = f"v1/content/{self.content_guid}/permissions"
97-
url = self.params.url + path
98-
response = self.params.session.post(url, json=kwargs)
99-
return Permission(params=self.params, **response.json())
117+
path = f"v1/content/{self._ctx.content_guid}/permissions"
118+
url = self._ctx.url + path
119+
response = self._ctx.session.post(url, json=kwargs)
120+
return Permission(self._ctx, **response.json())
100121

101122
def find(self, **kwargs) -> List[Permission]:
102123
"""Find permissions.
@@ -105,11 +126,11 @@ def find(self, **kwargs) -> List[Permission]:
105126
-------
106127
List[Permission]
107128
"""
108-
path = f"v1/content/{self.content_guid}/permissions"
109-
url = self.params.url + path
110-
response = self.params.session.get(url, json=kwargs)
129+
path = f"v1/content/{self._ctx.content_guid}/permissions"
130+
url = self._ctx.url + path
131+
response = self._ctx.session.get(url, json=kwargs)
111132
results = response.json()
112-
return [Permission(self.params, **result) for result in results]
133+
return [Permission(self._ctx, **result) for result in results]
113134

114135
def find_one(self, **kwargs) -> Permission | None:
115136
"""Find a permission.
@@ -133,7 +154,4 @@ def get(self, uid: str) -> Permission:
133154
-------
134155
Permission
135156
"""
136-
path = f"v1/content/{self.content_guid}/permissions/{uid}"
137-
url = self.params.url + path
138-
response = self.params.session.get(url)
139-
return Permission(self.params, **response.json())
157+
return Permission(self._ctx, id=uid)
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
[
2-
{
3-
"id": 94,
4-
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
5-
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
6-
"principal_type": "user",
7-
"role": "owner"
8-
},
9-
{
10-
"id": 59,
11-
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
12-
"principal_guid": "75b95fc0-ae02-4d85-8732-79a845143eed",
13-
"principal_type": "group",
14-
"role": "viewer"
15-
}
2+
{
3+
"id": "94",
4+
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
5+
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
6+
"principal_type": "user",
7+
"role": "owner"
8+
},
9+
{
10+
"id": "59",
11+
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
12+
"principal_guid": "75b95fc0-ae02-4d85-8732-79a845143eed",
13+
"principal_type": "group",
14+
"role": "viewer"
15+
}
1616
]
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"id": 94,
3-
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
4-
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
5-
"principal_type": "user",
6-
"role": "owner"
2+
"id": "94",
3+
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
4+
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
5+
"principal_type": "user",
6+
"role": "owner"
77
}

tests/posit/connect/test_permissions.py

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import responses
66
from responses import matchers
77

8+
from posit.connect._types_content_item import ContentItemContext
9+
from posit.connect.context import Context
810
from posit.connect.permissions import Permission, Permissions
9-
from posit.connect.resources import ResourceParameters
1011
from posit.connect.urls import Url
1112

1213
from .api import load_mock, load_mock_dict, load_mock_list
@@ -25,9 +26,12 @@ def test(self):
2526
)
2627

2728
# setup
28-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
29+
ctx = ContentItemContext(
30+
Context(requests.Session(), Url("https://connect.example/__api__")),
31+
content_guid=content_guid,
32+
)
2933
fake_permission = load_mock_dict(f"v1/content/{content_guid}/permissions/{uid}.json")
30-
permission = Permission(params, **fake_permission)
34+
permission = Permission(ctx, **fake_permission)
3135

3236
# invoke
3337
permission.delete()
@@ -40,7 +44,7 @@ class TestPermissionUpdate:
4044
@responses.activate
4145
def test_request_shape(self):
4246
# test data
43-
uid = random.randint(0, 100)
47+
uid = str(random.randint(0, 100))
4448
content_guid = str(uuid.uuid4())
4549
principal_guid = str(uuid.uuid4())
4650
principal_type = "principal_type"
@@ -51,7 +55,9 @@ def test_request_shape(self):
5155
responses.put(
5256
f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}",
5357
json={
54-
# doesn't matter for this test
58+
# doesn't matter for this test, but something more than `id` is needed to avoid an API call
59+
"id": uid,
60+
"content_guid": content_guid,
5561
},
5662
match=[
5763
# assertion
@@ -69,9 +75,13 @@ def test_request_shape(self):
6975
)
7076

7177
# setup
72-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
78+
ctx = ContentItemContext(
79+
Context(requests.Session(), Url("https://connect.example/__api__")),
80+
content_guid=content_guid,
81+
)
82+
7383
permission = Permission(
74-
params,
84+
ctx,
7585
id=uid,
7686
content_guid=content_guid,
7787
principal_guid=principal_guid,
@@ -95,7 +105,7 @@ def test_role_update(self):
95105
fake_permission.update(role=new_role)
96106

97107
# define api behavior
98-
uid = random.randint(0, 100)
108+
uid = str(random.randint(0, 100))
99109
content_guid = str(uuid.uuid4())
100110
responses.put(
101111
f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}",
@@ -112,13 +122,17 @@ def test_role_update(self):
112122
)
113123

114124
# setup
115-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
116-
permission = Permission(params, id=uid, content_guid=content_guid, role=old_role)
125+
ctx = ContentItemContext(
126+
Context(requests.Session(), Url("https://connect.example/__api__")),
127+
content_guid=content_guid,
128+
)
129+
permission = Permission(ctx, id=uid, content_guid=content_guid, role=old_role)
117130

118131
# assert role change with respect to api response
119132
assert permission["role"] == old_role
120-
permission.update(role=new_role)
121-
assert permission["role"] == new_role
133+
updated_permission = permission.update(role=new_role)
134+
assert permission["role"] == old_role
135+
assert updated_permission["role"] == new_role
122136

123137

124138
class TestPermissionsCount:
@@ -135,8 +149,11 @@ def test(self):
135149
)
136150

137151
# setup
138-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
139-
permissions = Permissions(params, content_guid=content_guid)
152+
ctx = ContentItemContext(
153+
Context(requests.Session(), Url("https://connect.example/__api__")),
154+
content_guid=content_guid,
155+
)
156+
permissions = Permissions(ctx)
140157

141158
# invoke
142159
count = permissions.count()
@@ -177,8 +194,12 @@ def test(self):
177194
)
178195

179196
# setup
180-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
181-
permissions = Permissions(params, content_guid=content_guid)
197+
ctx = ContentItemContext(
198+
Context(requests.Session(), Url("https://connect.example/__api__")),
199+
content_guid=content_guid,
200+
)
201+
202+
permissions = Permissions(ctx)
182203

183204
# invoke
184205
permission = permissions.create(
@@ -205,8 +226,11 @@ def test(self):
205226
)
206227

207228
# setup
208-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
209-
permissions = Permissions(params, content_guid=content_guid)
229+
ctx = ContentItemContext(
230+
Context(requests.Session(), Url("https://connect.example/__api__")),
231+
content_guid=content_guid,
232+
)
233+
permissions = Permissions(ctx)
210234

211235
# invoke
212236
permissions = permissions.find()
@@ -229,8 +253,11 @@ def test(self):
229253
)
230254

231255
# setup
232-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
233-
permissions = Permissions(params, content_guid=content_guid)
256+
ctx = ContentItemContext(
257+
Context(requests.Session(), Url("https://connect.example/__api__")),
258+
content_guid=content_guid,
259+
)
260+
permissions = Permissions(ctx)
234261

235262
# invoke
236263
permission = permissions.find_one()
@@ -254,8 +281,11 @@ def test(self):
254281
)
255282

256283
# setup
257-
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
258-
permissions = Permissions(params, content_guid=content_guid)
284+
ctx = ContentItemContext(
285+
Context(requests.Session(), Url("https://connect.example/__api__")),
286+
content_guid=content_guid,
287+
)
288+
permissions = Permissions(ctx)
259289

260290
# invoke
261291
permission = permissions.get(uid)

0 commit comments

Comments
 (0)