diff --git a/cs3client/share.py b/cs3client/share.py index e06fba3..c7cb41e 100644 --- a/cs3client/share.py +++ b/cs3client/share.py @@ -57,7 +57,8 @@ def create_share( opaque_id: str, idp: str, role: str, - grantee_type: str + grantee_type: str, + user_type: Optional[str] = None ) -> cs3scr.Share: """ Create a share for a resource to the user/group with the specified role, using their opaque id and idp. @@ -68,6 +69,8 @@ def create_share( :param idp: Identity provider, (REQUIRED). :param role: Role to assign to the grantee, VIEWER or EDITOR (REQUIRED). :param grantee_type: Type of grantee, USER or GROUP (REQUIRED). + :param user_type: Type of the user grantee, as in the user id, e.g. USER_TYPE_PRIMARY or + USER_TYPE_LIGHTWEIGHT. The storage needs it to share with lightweight and federated users (OPTIONAL). :return: Share object. :raises: NotFoundException (Resource not found) :raises: AuthenticationException (Operation not permitted) @@ -76,7 +79,7 @@ def create_share( :raises: UnknownException (Unknown error) :raises: ValueError (Invalid values) """ - share_grant = Share._create_share_grant(opaque_id, idp, role, grantee_type) + share_grant = Share._create_share_grant(opaque_id, idp, role, grantee_type, user_type=user_type) req = cs3scapi.CreateShareRequest(resource_info=resource_info, grant=share_grant) res = self._gateway.CreateShare(request=req, metadata=[auth_token]) self._status_code_handler.handle_errors( @@ -569,7 +572,8 @@ def _create_public_share_update( @classmethod def _create_share_grant( - cls, opaque_id: str, idp: str, role: str, grantee_type: str, expiration: Optional[cs3types.Timestamp] = None + cls, opaque_id: str, idp: str, role: str, grantee_type: str, expiration: Optional[cs3types.Timestamp] = None, + user_type: Optional[str] = None ) -> cs3scr.ShareGrant: """ Create a share grant object. @@ -578,14 +582,17 @@ def _create_share_grant( :param idp: Identity provider. :param role: Role to assign to the grantee, VIEWER or EDITOR. :param grantee_type: Type of grantee, USER or GROUP. + :param user_type: Type of the user grantee, e.g. USER_TYPE_PRIMARY. Ignored for groups. :return: ShareGrant object. - :raises: ValueError (Invalid grantee type) + :raises: ValueError (Invalid grantee type or user type) """ grantee = None if grantee_type == "USER": type = cs3spr.GRANTEE_TYPE_USER user_id = cs3iur.UserId(idp=idp, opaque_id=opaque_id) + if user_type: + user_id.type = cs3iur.UserType.Value(user_type.upper()) grantee = cs3spr.Grantee(type=type, user_id=user_id) elif grantee_type == "GROUP": type = cs3spr.GRANTEE_TYPE_GROUP diff --git a/tests/test_share.py b/tests/test_share.py index 49caf15..a22decc 100644 --- a/tests/test_share.py +++ b/tests/test_share.py @@ -13,6 +13,7 @@ import cs3.sharing.collaboration.v1beta1.resources_pb2 as cs3scr import cs3.sharing.link.v1beta1.link_api_pb2 as cs3slapi import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr +import cs3.identity.user.v1beta1.resources_pb2 as cs3iur import cs3.rpc.v1beta1.code_pb2 as cs3code from cs3client.exceptions import ( @@ -84,6 +85,33 @@ def test_create_share( assert result == expected_result +@pytest.mark.parametrize( + "user_type, expected_type", + [ + ("USER_TYPE_LIGHTWEIGHT", cs3iur.UserType.USER_TYPE_LIGHTWEIGHT), + (None, cs3iur.UserType.USER_TYPE_INVALID), + ], +) +def test_create_share_user_type(share_instance, user_type, expected_type): # noqa: F811 (not a redefinition) + resource_info = cs3spr.ResourceInfo(id=cs3spr.ResourceId(storage_id="storage_id", opaque_id="opaque_id")) + mock_response = Mock() + mock_response.status.code = cs3code.CODE_OK + auth_token = ('x-access-token', "some_token") + + with patch.object(share_instance._gateway, "CreateShare", return_value=mock_response) as mock_create: + share_instance.create_share( + auth_token, + resource_info=resource_info, + opaque_id="opaque_id", + idp="idp", + role="VIEWER", + grantee_type="USER", + user_type=user_type + ) + + assert mock_create.call_args.kwargs["request"].grant.grantee.user_id.type == expected_type + + @pytest.mark.parametrize( "status_code, status_message, expected_exception, expected_result", [