Exemplo n.º 1
0
    def test_get_with_invalid_repo_permission(self):

        user_shared_repos = \
                seafile_api.get_share_out_repo_list(self.admin_name, -1, -1)
        for repo in user_shared_repos:
            seafile_api.remove_share(repo.repo_id, self.admin_name, repo.user)

        group_shared_repos = seafile_api.get_group_repos_by_owner(
            self.admin_name)
        for repo in group_shared_repos:
            seafile_api.unset_group_repo(repo.repo_id, repo.group_id,
                                         self.admin_name)

        public_shared_repos = seafile_api.list_inner_pub_repos_by_owner(
            self.admin_name)
        for repo in public_shared_repos:
            seafile_api.remove_inner_pub_repo(repo.repo_id)

        self.share_repo_to_user()
        self.share_repo_to_group()
        self.share_repo_to_public()

        # login with admin, then get user's share repo info
        self.login_as(self.admin)
        resp = self.client.get(self.url)
        self.assertEqual(200, resp.status_code)

        json_resp = json.loads(resp.content)
        assert len(json_resp) == 0
Exemplo n.º 2
0
    def test_can_update_public_share_perm(self):
        for r in seaserv.seafserv_threaded_rpc.list_inner_pub_repos():
            seafile_api.remove_inner_pub_repo(r.repo_id)

        self.share_repo_to_public()

        repos = seafile_api.list_inner_pub_repos_by_owner(self.user_name)
        assert repos[0].permission == 'rw'

        self.login_as(self.user)

        url = reverse('api-v2.1-shared-repo', args=[self.repo_id])
        data = 'permission=r&share_type=public'
        resp = self.client.put(url, data, 'application/x-www-form-urlencoded')

        self.assertEqual(200, resp.status_code)

        repos = seafile_api.list_inner_pub_repos_by_owner(self.user_name)
        assert repos[0].permission == 'r'
def test_get_inner_pub_repos(repo):
    repo = api.get_repo(repo.id)
    api.add_inner_pub_repo(repo.id, 'rw')
    repos = api.get_inner_pub_repo_list()
    assert_public_repos_attr(repo, repos[0])

    repos = api.list_inner_pub_repos_by_owner(USER)
    assert_public_repos_attr(repo, repos[0])

    assert api.remove_inner_pub_repo(repo.id) == 0
Exemplo n.º 4
0
    def test_can_update_public_share_perm(self):
        for r in seaserv.seafserv_threaded_rpc.list_inner_pub_repos():
            seafile_api.remove_inner_pub_repo(r.repo_id)

        self.share_repo_to_public()

        repos = seafile_api.list_inner_pub_repos_by_owner(self.user_name)
        assert repos[0].permission == 'rw'

        self.login_as(self.user)

        url = reverse('api-v2.1-shared-repo', args=[self.repo_id])
        data = 'permission=r&share_type=public'
        resp = self.client.put(url, data, 'application/x-www-form-urlencoded')

        self.assertEqual(200, resp.status_code)

        repos = seafile_api.list_inner_pub_repos_by_owner(self.user_name)
        assert repos[0].permission == 'r'
Exemplo n.º 5
0
    def get(self, request, format=None):
        """ List all shared out repos.

        Permission checking:
        1. all authenticated user can perform this action.
        """

        shared_repos = []
        username = request.user.username
        try:
            if is_org_context(request):
                org_id = request.user.org.org_id
                shared_repos += seafile_api.get_org_share_out_repo_list(
                    org_id, username, -1, -1)
                shared_repos += seaserv.seafserv_threaded_rpc.get_org_group_repos_by_owner(
                    org_id, username)
                shared_repos += seaserv.seafserv_threaded_rpc.list_org_inner_pub_repos_by_owner(
                    org_id, username)
            else:
                shared_repos += seafile_api.get_share_out_repo_list(
                    username, -1, -1)
                shared_repos += seafile_api.get_group_repos_by_owner(username)
                if not request.cloud_mode:
                    shared_repos += seafile_api.list_inner_pub_repos_by_owner(
                        username)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        returned_result = []
        shared_repos.sort(lambda x, y: cmp(x.repo_name, y.repo_name))
        for repo in shared_repos:
            if repo.is_virtual:
                continue

            result = {}
            result['repo_id'] = repo.repo_id
            result['repo_name'] = repo.repo_name
            result['share_type'] = repo.share_type
            result['share_permission'] = repo.permission

            if repo.share_type == 'personal':
                result['user_name'] = email2nickname(repo.user)
                result['user_email'] = repo.user

            if repo.share_type == 'group':
                group = ccnet_api.get_group(repo.group_id)
                result['group_id'] = repo.group_id
                result['group_name'] = group.group_name

            returned_result.append(result)

        return Response(returned_result)
Exemplo n.º 6
0
    def test_delete_public_share(self):
        for r in seaserv.seafserv_threaded_rpc.list_inner_pub_repos():
            seafile_api.remove_inner_pub_repo(r.repo_id)

        self.share_repo_to_public()

        # repo in public
        repos = seafile_api.list_inner_pub_repos_by_owner(self.user_name)
        assert repos[0].permission == 'rw'

        self.login_as(self.user)

        args = '?share_type=public'
        url = reverse('api-v2.1-shared-repo', args=[self.repo_id]) + args
        resp = self.client.delete(url, {}, 'application/x-www-form-urlencoded')

        self.assertEqual(200, resp.status_code)

        # repo NOT in public
        repos = seafile_api.list_inner_pub_repos_by_owner(self.user_name)
        assert len(repos) == 0
Exemplo n.º 7
0
    def test_delete_public_share(self):
        for r in seaserv.seafserv_threaded_rpc.list_inner_pub_repos():
            seafile_api.remove_inner_pub_repo(r.repo_id)

        self.share_repo_to_public()

        # repo in public
        repos = seafile_api.list_inner_pub_repos_by_owner(
                self.user_name)
        assert repos[0].permission == 'rw'

        self.login_as(self.user)

        args = '?share_type=public'
        url = reverse('api-v2.1-shared-repo', args=[self.repo_id]) + args
        resp = self.client.delete(url, {}, 'application/x-www-form-urlencoded')

        self.assertEqual(200, resp.status_code)

        # repo NOT in public
        repos = seafile_api.list_inner_pub_repos_by_owner(
                self.user_name)
        assert len(repos) == 0
Exemplo n.º 8
0
    def get(self, request, format=None):
        """ List all shared out repos.

        Permission checking:
        1. all authenticated user can perform this action.
        """

        shared_repos = []
        username = request.user.username
        try:
            if is_org_context(request):
                org_id = request.user.org.org_id
                shared_repos += seafile_api.get_org_share_out_repo_list(org_id, username, -1, -1)
                shared_repos += seaserv.seafserv_threaded_rpc.get_org_group_repos_by_owner(org_id, username)
                shared_repos += seaserv.seafserv_threaded_rpc.list_org_inner_pub_repos_by_owner(org_id, username)
            else:
                shared_repos += seafile_api.get_share_out_repo_list(username, -1, -1)
                shared_repos += seafile_api.get_group_repos_by_owner(username)
                if not request.cloud_mode:
                    shared_repos += seafile_api.list_inner_pub_repos_by_owner(username)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        returned_result = []
        shared_repos.sort(lambda x, y: cmp(x.repo_name, y.repo_name))
        for repo in shared_repos:
            if repo.is_virtual:
                    continue

            result = {}
            result['repo_id'] = repo.repo_id
            result['repo_name'] = repo.repo_name
            result['share_type'] = repo.share_type
            result['share_permission'] = repo.permission

            if repo.share_type == 'personal':
                result['user_name'] = email2nickname(repo.user)
                result['user_email'] = repo.user

            if repo.share_type == 'group':
                group = ccnet_api.get_group(repo.group_id)
                result['group_id'] = repo.group_id
                result['group_name'] = group.group_name

            returned_result.append(result)

        return Response(returned_result)
Exemplo n.º 9
0
    def put(self, request, repo_id, format=None):
        """ update a library status, transfer a library, rename a library

        Permission checking:
        1. only admin can perform this action.
        """
        # argument check
        new_status = request.data.get('status', None)
        if new_status:
            if new_status not in ('normal', 'read-only'):
                error_msg = 'status invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        new_repo_name = request.data.get('name', None)
        if new_repo_name:
            if not is_valid_dirent_name(new_repo_name):
                error_msg = 'name invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        new_owner = request.data.get('owner', None)
        if new_owner:
            if not is_valid_email(new_owner):
                error_msg = 'owner invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if new_status:
            try:
                seafile_api.set_repo_status(repo_id, normalize_repo_status_str(new_status))
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if new_repo_name:
            try:
                res = seafile_api.edit_repo(repo_id, new_repo_name, '', None)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if res == -1:
                e = 'Admin rename failed: ID of library is %s, edit_repo api called failed.' % \
                        repo_id
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if new_owner:
            try:
                new_owner_obj = User.objects.get(email=new_owner)
            except User.DoesNotExist:
                error_msg = 'User %s not found.' % new_owner
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if not new_owner_obj.permissions.can_add_repo():
                error_msg = _('Transfer failed: role of %s is %s, can not add library.') % \
                        (new_owner, new_owner_obj.role)
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            if MULTI_TENANCY:
                try:
                    if seafile_api.get_org_id_by_repo_id(repo_id) > 0:
                        error_msg = 'Can not transfer organization library.'
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                    if ccnet_api.get_orgs_by_user(new_owner):
                        error_msg = 'Can not transfer library to organization user %s' % new_owner
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)
                except Exception as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            repo_owner = seafile_api.get_repo_owner(repo_id)

            if new_owner == repo_owner:
                error_msg = _("Library can not be transferred to owner.")
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # get repo shared to user/group list
            shared_users = seafile_api.list_repo_shared_to(
                    repo_owner, repo_id)
            shared_groups = seafile_api.list_repo_shared_group_by_user(
                    repo_owner, repo_id)

            # get all pub repos
            pub_repos = []
            if not request.cloud_mode:
                pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner)

            # transfer repo
            seafile_api.set_repo_owner(repo_id, new_owner)

            # reshare repo to user
            for shared_user in shared_users:
                shared_username = shared_user.user

                if new_owner == shared_username:
                    continue

                seafile_api.share_repo(repo_id, new_owner,
                        shared_username, shared_user.perm)

            # reshare repo to group
            for shared_group in shared_groups:
                shared_group_id = shared_group.group_id

                if not is_group_member(shared_group_id, new_owner):
                    continue

                seafile_api.set_group_repo(repo_id, shared_group_id,
                        new_owner, shared_group.perm)

            # reshare repo to links
            try:
                UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
                FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            # check if current repo is pub-repo
            # if YES, reshare current repo to public
            for pub_repo in pub_repos:
                if repo_id != pub_repo.id:
                    continue

                seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission)

                break

            # send admin operation log signal
            admin_op_detail = {
                "id": repo_id,
                "name": repo.name,
                "from": repo_owner,
                "to": new_owner,
            }
            admin_operation.send(sender=None, admin_name=request.user.username,
                    operation=REPO_TRANSFER, detail=admin_op_detail)

        repo = seafile_api.get_repo(repo_id)
        repo_info = get_repo_info(repo)

        return Response(repo_info)
Exemplo n.º 10
0
    def get(self, request, format=None):
        """ List all shared out repos.

        Permission checking:
        1. all authenticated user can perform this action.
        """

        shared_repos = []
        username = request.user.username
        try:
            if is_org_context(request):
                org_id = request.user.org.org_id
                shared_repos += seafile_api.get_org_share_out_repo_list(
                    org_id, username, -1, -1)
                shared_repos += seafile_api.get_org_group_repos_by_owner(
                    org_id, username)
                shared_repos += seafile_api.list_org_inner_pub_repos_by_owner(
                    org_id, username)
            else:
                shared_repos += seafile_api.get_share_out_repo_list(
                    username, -1, -1)
                shared_repos += seafile_api.get_group_repos_by_owner(username)
                if not request.cloud_mode:
                    shared_repos += seafile_api.list_inner_pub_repos_by_owner(
                        username)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        returned_result = []
        shared_repos.sort(lambda x, y: cmp(x.repo_name, y.repo_name))
        usernames = []
        gids = []
        for repo in shared_repos:
            if repo.is_virtual:
                continue

            result = {}
            result['repo_id'] = repo.repo_id
            result['repo_name'] = repo.repo_name
            result['encrypted'] = repo.encrypted
            result['share_type'] = repo.share_type
            result['share_permission'] = repo.permission
            result['modifier_email'] = repo.last_modifier
            result['modifier_name'] = email2nickname(repo.last_modifier)
            result['modifier_contact_email'] = email2contact_email(
                repo.last_modifier)

            if repo.share_type == 'personal':
                result['user_name'] = email2nickname(repo.user)
                result['user_email'] = repo.user
                result[
                    'contact_email'] = Profile.objects.get_contact_email_by_user(
                        repo.user)
                usernames.append((repo.repo_id, repo.user))

            if repo.share_type == 'group':
                group = ccnet_api.get_group(repo.group_id)
                result['group_id'] = repo.group_id
                result['group_name'] = group.group_name if group else ''
                gids.append(repo.group_id)

            returned_result.append(result)

        user_admins = ExtraSharePermission.objects.batch_is_admin(usernames)
        group_admins = ExtraGroupsSharePermission.objects.batch_get_repos_with_admin_permission(
            gids)
        for result in returned_result:
            if result['share_type'] == 'group':
                result['is_admin'] = (result['repo_id'],
                                      result['group_id']) in group_admins
            elif result['share_type'] == 'personal':
                result['is_admin'] = (result['repo_id'],
                                      result['user_email']) in user_admins

        return Response(returned_result)
Exemplo n.º 11
0
    def put(self, request, repo_id, format=None):
        """ transfer a library

        Permission checking:
        1. only admin can perform this action.
        """
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        new_owner = request.data.get('owner', None)
        if not new_owner:
            error_msg = 'owner invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            new_owner_obj = User.objects.get(email=new_owner)
        except User.DoesNotExist:
            error_msg = 'User %s not found.' % new_owner
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if not new_owner_obj.permissions.can_add_repo():
            error_msg = 'Transfer failed: role of %s is %s, can not add library.' % \
                    (new_owner, new_owner_obj.role)
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if MULTI_TENANCY:
            try:
                if seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id) > 0:
                    error_msg = 'Can not transfer organization library.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                if ccnet_api.get_orgs_by_user(new_owner):
                    error_msg = 'Can not transfer library to organization user %s' % new_owner
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        repo_owner = seafile_api.get_repo_owner(repo_id)

        # get repo shared to user/group list
        shared_users = seafile_api.list_repo_shared_to(repo_owner, repo_id)
        shared_groups = seafile_api.list_repo_shared_group_by_user(
            repo_owner, repo_id)

        # get all pub repos
        pub_repos = []
        if not request.cloud_mode:
            pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner)

        # transfer repo
        seafile_api.set_repo_owner(repo_id, new_owner)

        # reshare repo to user
        for shared_user in shared_users:
            shared_username = shared_user.user

            if new_owner == shared_username:
                continue

            seafile_api.share_repo(repo_id, new_owner, shared_username,
                                   shared_user.perm)

        # reshare repo to group
        for shared_group in shared_groups:
            shared_group_id = shared_group.group_id

            if not ccnet_api.is_group_user(shared_group_id, new_owner):
                continue

            seafile_api.set_group_repo(repo_id, shared_group_id, new_owner,
                                       shared_group.perm)

        # check if current repo is pub-repo
        # if YES, reshare current repo to public
        for pub_repo in pub_repos:
            if repo_id != pub_repo.id:
                continue

            seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission)

            break

        # send admin operation log signal
        admin_op_detail = {
            "id": repo_id,
            "name": repo.name,
            "from": repo_owner,
            "to": new_owner,
        }
        admin_operation.send(sender=None,
                             admin_name=request.user.username,
                             operation=REPO_TRANSFER,
                             detail=admin_op_detail)

        repo = seafile_api.get_repo(repo_id)
        repo_info = get_repo_info(repo)

        return Response(repo_info)
Exemplo n.º 12
0
    def get(self, request, format=None):
        """ List all shared out repos.

        Permission checking:
        1. all authenticated user can perform this action.
        """

        shared_repos = []
        username = request.user.username
        try:
            if is_org_context(request):
                org_id = request.user.org.org_id
                shared_repos += seafile_api.get_org_share_out_repo_list(org_id, username, -1, -1)
                shared_repos += seafile_api.get_org_group_repos_by_owner(org_id, username)
                shared_repos += seafile_api.list_org_inner_pub_repos_by_owner(org_id, username)
            else:
                shared_repos += seafile_api.get_share_out_repo_list(username, -1, -1)
                shared_repos += seafile_api.get_group_repos_by_owner(username)
                if not request.cloud_mode:
                    shared_repos += seafile_api.list_inner_pub_repos_by_owner(username)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        returned_result = []
        shared_repos.sort(lambda x, y: cmp(x.repo_name, y.repo_name))
        usernames = []
        gids = []
        for repo in shared_repos:
            if repo.is_virtual:
                    continue

            result = {}
            result['repo_id'] = repo.repo_id
            result['repo_name'] = repo.repo_name
            result['encrypted'] = repo.encrypted
            result['share_type'] = repo.share_type
            result['share_permission'] = repo.permission
            result['modifier_email'] = repo.last_modifier
            result['modifier_name'] = email2nickname(repo.last_modifier)
            result['modifier_contact_email'] = email2contact_email(repo.last_modifier)

            if repo.share_type == 'personal':
                result['user_name'] = email2nickname(repo.user)
                result['user_email'] = repo.user
                result['contact_email'] = Profile.objects.get_contact_email_by_user(repo.user)
                usernames.append((repo.repo_id, repo.user))

            if repo.share_type == 'group':
                group = ccnet_api.get_group(repo.group_id)
                result['group_id'] = repo.group_id
                result['group_name'] = group.group_name if group else ''
                gids.append(repo.group_id)

            returned_result.append(result)

        user_admins = ExtraSharePermission.objects.batch_is_admin(usernames)
        group_admins = ExtraGroupsSharePermission.objects.batch_get_repos_with_admin_permission(gids)
        for result in returned_result:
            if result['share_type'] == 'group':
                result['is_admin'] = (result['repo_id'], result['group_id']) in group_admins
            elif result['share_type'] == 'personal':
                result['is_admin'] = (result['repo_id'], result['user_email']) in user_admins

        return Response(returned_result)
Exemplo n.º 13
0
    def put(self, request, repo_id, format=None):
        """ transfer a library, rename a library

        Permission checking:
        1. only admin can perform this action.
        """
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        new_repo_name = request.data.get('name', None)
        if new_repo_name:
            try:
                res = seafile_api.edit_repo(repo_id, new_repo_name, '', None)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if res == -1:
                e = 'Admin rename failed: ID of library is %s, edit_repo api called failed.' % \
                        repo_id
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        new_owner = request.data.get('owner', None)
        if new_owner:
            try:
                new_owner_obj = User.objects.get(email=new_owner)
            except User.DoesNotExist:
                error_msg = 'User %s not found.' % new_owner
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if not new_owner_obj.permissions.can_add_repo():
                error_msg = _(u'Transfer failed: role of %s is %s, can not add library.') % \
                        (new_owner, new_owner_obj.role)
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            if MULTI_TENANCY:
                try:
                    if seafile_api.get_org_id_by_repo_id(repo_id) > 0:
                        error_msg = 'Can not transfer organization library.'
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                    if ccnet_api.get_orgs_by_user(new_owner):
                        error_msg = 'Can not transfer library to organization user %s' % new_owner
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)
                except Exception as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            repo_owner = seafile_api.get_repo_owner(repo_id)

            if new_owner == repo_owner:
                error_msg = _(u"Library can not be transferred to owner.")
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # get repo shared to user/group list
            shared_users = seafile_api.list_repo_shared_to(
                    repo_owner, repo_id)
            shared_groups = seafile_api.list_repo_shared_group_by_user(
                    repo_owner, repo_id)

            # get all pub repos
            pub_repos = []
            if not request.cloud_mode:
                pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner)

            # transfer repo
            seafile_api.set_repo_owner(repo_id, new_owner)

            # reshare repo to user
            for shared_user in shared_users:
                shared_username = shared_user.user

                if new_owner == shared_username:
                    continue

                seafile_api.share_repo(repo_id, new_owner,
                        shared_username, shared_user.perm)

            # reshare repo to group
            for shared_group in shared_groups:
                shared_group_id = shared_group.group_id

                if not is_group_member(shared_group_id, new_owner):
                    continue

                seafile_api.set_group_repo(repo_id, shared_group_id,
                        new_owner, shared_group.perm)

            # reshare repo to links
            try:
                UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
                FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            # check if current repo is pub-repo
            # if YES, reshare current repo to public
            for pub_repo in pub_repos:
                if repo_id != pub_repo.id:
                    continue

                seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission)

                break

            # send admin operation log signal
            admin_op_detail = {
                "id": repo_id,
                "name": repo.name,
                "from": repo_owner,
                "to": new_owner,
            }
            admin_operation.send(sender=None, admin_name=request.user.username,
                    operation=REPO_TRANSFER, detail=admin_op_detail)

        repo = seafile_api.get_repo(repo_id)
        repo_info = get_repo_info(repo)

        return Response(repo_info)
Exemplo n.º 14
0
    def put(self, request, repo_id, format=None):
        """ transfer a library

        Permission checking:
        1. only admin can perform this action.
        """
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        new_owner = request.data.get('owner', None)
        if not new_owner:
            error_msg = 'owner invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            User.objects.get(email=new_owner)
        except User.DoesNotExist:
            error_msg = 'User %s not found.' % new_owner
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if MULTI_TENANCY:
            try:
                if seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id) > 0:
                    error_msg = 'Can not transfer organization library.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                if ccnet_api.get_orgs_by_user(new_owner):
                    error_msg = 'Can not transfer library to organization user %s' % new_owner
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        repo_owner = seafile_api.get_repo_owner(repo_id)

        # get repo shared to user/group list
        shared_users = seafile_api.list_repo_shared_to(
                repo_owner, repo_id)
        shared_groups = seafile_api.list_repo_shared_group_by_user(
                repo_owner, repo_id)

        # get all pub repos
        pub_repos = []
        if not request.cloud_mode:
            pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner)

        # transfer repo
        seafile_api.set_repo_owner(repo_id, new_owner)

        # reshare repo to user
        for shared_user in shared_users:
            shared_username = shared_user.user

            if new_owner == shared_username:
                continue

            seafile_api.share_repo(repo_id, new_owner,
                    shared_username, shared_user.perm)

        # reshare repo to group
        for shared_group in shared_groups:
            shared_group_id = shared_group.group_id

            if not ccnet_api.is_group_user(shared_group_id, new_owner):
                continue

            seafile_api.set_group_repo(repo_id, shared_group_id,
                    new_owner, shared_group.perm)

        # check if current repo is pub-repo
        # if YES, reshare current repo to public
        for pub_repo in pub_repos:
            if repo_id != pub_repo.id:
                continue

            seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission)

            break

        repo = seafile_api.get_repo(repo_id)
        repo_info = get_repo_info(repo)

        return Response(repo_info)