Skip to content

Commit

Permalink
Add share_group, unshare_group, list_shared_with, and a test (#575)
Browse files Browse the repository at this point in the history
Coverage of the new code is good. We lack tests of errors sent by
the API server.
  • Loading branch information
sgillies authored Jun 5, 2024
1 parent c2c0726 commit badbb30
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 8 deletions.
89 changes: 81 additions & 8 deletions src/tiledb/cloud/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import urllib.parse
from typing import Iterable, List, Optional, Tuple, Union

import tiledb.cloud.tiledb_cloud_error as tce
from tiledb.cloud import client
from tiledb.cloud import rest_api
from tiledb.cloud._common import api_v2
from tiledb.cloud._common import utils
from tiledb.cloud.rest_api.models import group_update
from . import client
from . import rest_api
from . import tiledb_cloud_error
from ._common import api_v2
from ._common import utils
from .rest_api import ApiException as GenApiException
from .rest_api import models
from .rest_api.models import group_update

split_uri = utils.split_uri


def create(
Expand Down Expand Up @@ -130,7 +134,7 @@ def update_info(
try:
return groups_v1_client.update_group(namespace, group_name, group_update=info)
except rest_api.ApiException as exc:
raise tce.check_exc(exc)
raise tiledb_cloud_error.check_exc(exc)


def deregister(
Expand Down Expand Up @@ -173,7 +177,9 @@ def deregister(
grp: rest_api.GroupInfo = m.group
deregister(grp.tiledb_uri, recursive=recursive)
else:
raise tce.TileDBCloudError("unexpected group member type")
raise tiledb_cloud_error.TileDBCloudError(
"unexpected group member type"
)
groups_api.deregister_group(group_namespace=namespace, group_name=name)


Expand Down Expand Up @@ -236,3 +242,70 @@ def _add_to(*, namespace: str, name: str, parent_uri: str) -> None:
),
),
)


def list_shared_with(uri, async_req=False):
"""List a group's sharing policies.
:param str uri: tiledb URI of the asset.
:param async_req: return future instead of results for async support.
:return: a list of GroupSharing objects.
"""
(group_namespace, group_name) = split_uri(uri)
api_instance = client.build(rest_api.GroupsApi)

try:
return api_instance.get_group_sharing_policies(
group_namespace=group_namespace, group_name=group_name, async_req=async_req
)
except GenApiException as exc:
raise tiledb_cloud_error.check_exc(exc) from None


def share_group(uri, namespace, permissions, async_req=False):
"""Shares group with given namespace and permissions.
:param str uri: tiledb URI of the asset.
:param str namespace:
:param list(str) permissions:
:param async_req: return future instead of results for async support.
:return: None.
"""

if not isinstance(permissions, list):
permissions = [permissions]

if set([perm.lower() for perm in permissions]) - {
models.GroupActions.READ,
models.GroupActions.WRITE,
}:
raise Exception("Only read or write permissions are accepted")

(group_namespace, group_name) = split_uri(uri)
api_instance = client.build(rest_api.GroupsApi)

try:
return api_instance.share_group(
group_namespace=group_namespace,
group_name=group_name,
group_sharing_request=models.GroupSharingRequest(
namespace=namespace,
group_actions=permissions,
array_actions=permissions,
),
async_req=async_req,
)
except GenApiException as exc:
raise tiledb_cloud_error.check_exc(exc) from None


def unshare_group(uri, namespace, async_req=False):
"""
Removes sharing of a group from given namespace
:param str namespace: namespace to remove shared access to the group
:param async_req: return future instead of results for async support
:return:
:raises: :py:exc:
"""
return share_group(uri, namespace, list(), async_req=async_req)
19 changes: 19 additions & 0 deletions tests/test_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,22 @@ def test_update_group_info(self):
# Cleanup
groups.deregister(group_uri)
self.assert_group_not_exists(group_name)

def test_group_sharing(self):
"""Share a created group with 'public', unshare, then delete."""
group_name = testonly.random_name("test_group_sharing")
group_storage_name = testonly.random_name(group_name)
group_storage_path = f"{self.test_path}/{group_storage_name}"
group_uri = f"tiledb://{self.namespace}/{group_name}"
groups.create(group_name, storage_uri=group_storage_path)
self.assert_group_exists(group_name)

groups.share_group(group_uri, "public", "read")
sharing = groups.list_shared_with(group_uri)
self.assertEqual(len(sharing), 1)
self.assertEqual(sharing[0].namespace, "public")
groups.unshare_group(group_uri, "public")
sharing = groups.list_shared_with(group_uri)
self.assertEqual(len(sharing), 0)

groups.delete(group_uri)

0 comments on commit badbb30

Please sign in to comment.