Skip to content

Commit

Permalink
Update Permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
schloerke committed Nov 14, 2024
1 parent d5d6459 commit d1c8b66
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/posit/connect/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ def environment_variables(self) -> EnvVars:

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

@property
def owner(self) -> dict:
Expand Down
82 changes: 50 additions & 32 deletions src/posit/connect/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,46 @@

from typing import List, overload

from requests.sessions import Session as Session
from ._active import ActiveDict
from ._types_content_item import ContentItemContext
from ._types_context import ContextP

from .resources import Resource, ResourceParameters, Resources

class PermissionContext(ContentItemContext):
permission_id: str

def __init__(self, ctx: ContentItemContext, /, *, permission_id: str) -> None:
super().__init__(ctx, content_guid=ctx.content_guid)
self.permission_id = permission_id


class Permission(ActiveDict[PermissionContext]):
@classmethod
def _api_path(cls, content_guid: str, permission_id: str) -> str:
return f"v1/content/{content_guid}/permissions/{permission_id}"

def __init__(self, ctx: ContentItemContext, /, **kwargs) -> None:
permission_id = kwargs.get("id")
assert isinstance(
permission_id, str
), f"Permission 'id' must be a string. Got: {permission_id}"
assert permission_id, "Permission 'id' must not be an empty string."

permission_ctx = PermissionContext(
ctx,
permission_id=permission_id,
)
path = self._api_path(permission_ctx.content_guid, permission_ctx.permission_id)
get_data = len(kwargs) == 1 # `id` is required

super().__init__(permission_ctx, path, get_data, **kwargs)

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

@overload
def update(self, *args, role: str, **kwargs) -> None:
def update(self, *args, role: str, **kwargs) -> Permission:
"""Update the permission.
Parameters
Expand All @@ -27,10 +53,10 @@ def update(self, *args, role: str, **kwargs) -> None:
"""

@overload
def update(self, *args, **kwargs) -> None:
def update(self, *args, **kwargs) -> Permission:
"""Update the permission."""

def update(self, *args, **kwargs) -> None:
def update(self, *args, **kwargs) -> Permission:
"""Update the permission."""
body = {
"principal_guid": self.get("principal_guid"),
Expand All @@ -39,19 +65,14 @@ def update(self, *args, **kwargs) -> None:
}
body.update(dict(*args))
body.update(**kwargs)
path = f"v1/content/{self['content_guid']}/permissions/{self['id']}"
url = self.params.url + path
response = self.params.session.put(
url,
json=body,
)
super().update(**response.json())
result = self._put_api(json=body)
return Permission(self._ctx, **result) # pyright: ignore[reportCallIssue]


class Permissions(Resources):
def __init__(self, params: ResourceParameters, content_guid: str) -> None:
super().__init__(params)
self.content_guid = content_guid
class Permissions(ContextP[ContentItemContext]):
def __init__(self, ctx: ContentItemContext) -> None:
super().__init__()
self._ctx = ctx

def count(self) -> int:
"""Count the number of permissions.
Expand Down Expand Up @@ -93,10 +114,10 @@ def create(self, **kwargs) -> Permission:
-------
Permission
"""
path = f"v1/content/{self.content_guid}/permissions"
url = self.params.url + path
response = self.params.session.post(url, json=kwargs)
return Permission(params=self.params, **response.json())
path = f"v1/content/{self._ctx.content_guid}/permissions"
url = self._ctx.url + path
response = self._ctx.session.post(url, json=kwargs)
return Permission(self._ctx, **response.json())

def find(self, **kwargs) -> List[Permission]:
"""Find permissions.
Expand All @@ -105,11 +126,11 @@ def find(self, **kwargs) -> List[Permission]:
-------
List[Permission]
"""
path = f"v1/content/{self.content_guid}/permissions"
url = self.params.url + path
response = self.params.session.get(url, json=kwargs)
path = f"v1/content/{self._ctx.content_guid}/permissions"
url = self._ctx.url + path
response = self._ctx.session.get(url, json=kwargs)
results = response.json()
return [Permission(self.params, **result) for result in results]
return [Permission(self._ctx, **result) for result in results]

def find_one(self, **kwargs) -> Permission | None:
"""Find a permission.
Expand All @@ -133,7 +154,4 @@ def get(self, uid: str) -> Permission:
-------
Permission
"""
path = f"v1/content/{self.content_guid}/permissions/{uid}"
url = self.params.url + path
response = self.params.session.get(url)
return Permission(self.params, **response.json())
return Permission(self._ctx, id=uid)
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
[
{
"id": 94,
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
"principal_type": "user",
"role": "owner"
},
{
"id": 59,
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
"principal_guid": "75b95fc0-ae02-4d85-8732-79a845143eed",
"principal_type": "group",
"role": "viewer"
}
{
"id": "94",
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
"principal_type": "user",
"role": "owner"
},
{
"id": "59",
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
"principal_guid": "75b95fc0-ae02-4d85-8732-79a845143eed",
"principal_type": "group",
"role": "viewer"
}
]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": 94,
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
"principal_type": "user",
"role": "owner"
"id": "94",
"content_guid": "f2f37341-e21d-3d80-c698-a935ad614066",
"principal_guid": "78974391-d89f-4f11-916a-ba50cfe993db",
"principal_type": "user",
"role": "owner"
}
74 changes: 52 additions & 22 deletions tests/posit/connect/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import responses
from responses import matchers

from posit.connect._types_content_item import ContentItemContext
from posit.connect.context import Context
from posit.connect.permissions import Permission, Permissions
from posit.connect.resources import ResourceParameters
from posit.connect.urls import Url

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

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)
fake_permission = load_mock_dict(f"v1/content/{content_guid}/permissions/{uid}.json")
permission = Permission(params, **fake_permission)
permission = Permission(ctx, **fake_permission)

# invoke
permission.delete()
Expand All @@ -40,7 +44,7 @@ class TestPermissionUpdate:
@responses.activate
def test_request_shape(self):
# test data
uid = random.randint(0, 100)
uid = str(random.randint(0, 100))
content_guid = str(uuid.uuid4())
principal_guid = str(uuid.uuid4())
principal_type = "principal_type"
Expand All @@ -51,7 +55,9 @@ def test_request_shape(self):
responses.put(
f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}",
json={
# doesn't matter for this test
# doesn't matter for this test, but something more than `id` is needed to avoid an API call
"id": uid,
"content_guid": content_guid,
},
match=[
# assertion
Expand All @@ -69,9 +75,13 @@ def test_request_shape(self):
)

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)

permission = Permission(
params,
ctx,
id=uid,
content_guid=content_guid,
principal_guid=principal_guid,
Expand All @@ -95,7 +105,7 @@ def test_role_update(self):
fake_permission.update(role=new_role)

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

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
permission = Permission(params, id=uid, content_guid=content_guid, role=old_role)
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)
permission = Permission(ctx, id=uid, content_guid=content_guid, role=old_role)

# assert role change with respect to api response
assert permission["role"] == old_role
permission.update(role=new_role)
assert permission["role"] == new_role
updated_permission = permission.update(role=new_role)
assert permission["role"] == old_role
assert updated_permission["role"] == new_role


class TestPermissionsCount:
Expand All @@ -135,8 +149,11 @@ def test(self):
)

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
permissions = Permissions(params, content_guid=content_guid)
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)
permissions = Permissions(ctx)

# invoke
count = permissions.count()
Expand Down Expand Up @@ -177,8 +194,12 @@ def test(self):
)

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
permissions = Permissions(params, content_guid=content_guid)
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)

permissions = Permissions(ctx)

# invoke
permission = permissions.create(
Expand All @@ -205,8 +226,11 @@ def test(self):
)

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
permissions = Permissions(params, content_guid=content_guid)
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)
permissions = Permissions(ctx)

# invoke
permissions = permissions.find()
Expand All @@ -229,8 +253,11 @@ def test(self):
)

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
permissions = Permissions(params, content_guid=content_guid)
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)
permissions = Permissions(ctx)

# invoke
permission = permissions.find_one()
Expand All @@ -254,8 +281,11 @@ def test(self):
)

# setup
params = ResourceParameters(requests.Session(), Url("https://connect.example/__api__"))
permissions = Permissions(params, content_guid=content_guid)
ctx = ContentItemContext(
Context(requests.Session(), Url("https://connect.example/__api__")),
content_guid=content_guid,
)
permissions = Permissions(ctx)

# invoke
permission = permissions.get(uid)
Expand Down

0 comments on commit d1c8b66

Please sign in to comment.