Esempio n. 1
0
 def list_group_shared_items(self, request, repo_id, path):
     if is_org_context(request):
         # when calling seafile API to share authority related functions, change the uesrname to repo owner.
         repo_owner = seafile_api.get_org_repo_owner(repo_id)
         org_id = request.user.org.org_id
         if path == '/':
             share_items = seafile_api.list_org_repo_shared_group(org_id,
                     repo_owner, repo_id)
         else:
             share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                     repo_id, path, repo_owner)
     else:
         repo_owner = seafile_api.get_repo_owner(repo_id)
         if path == '/':
             share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
         else:
             share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                    path, repo_owner)
     ret = []
     # change is_admin to True if user in admin groups.
     admin_groups = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(repo_id)
     for item in share_items:
         ret.append({
             "share_type": "group",
             "group_info": {
                 "id": item.group_id,
                 "name": seaserv.get_group(item.group_id).group_name,
             },
             "permission": item.perm,
             "is_admin": item.group_id in admin_groups,
         })
     return ret
Esempio n. 2
0
 def list_group_shared_items(self, request, repo_id, path):
     username = request.user.username
     if is_org_context(request):
         org_id = request.user.org.org_id
         if path == '/':
             share_items = seafile_api.list_org_repo_shared_group(org_id,
                     username, repo_id)
         else:
             share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                     repo_id, path, username)
     else:
         if path == '/':
             share_items = seafile_api.list_repo_shared_group_by_user(username, repo_id)
         else:
             share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                    path, username)
     ret = []
     for item in share_items:
         ret.append({
             "share_type": "group",
             "group_info": {
                 "id": item.group_id,
                 "name": seaserv.get_group(item.group_id).group_name,
             },
             "permission": item.perm,
         })
     return ret
Esempio n. 3
0
    def list_group_shared_items(self, request, repo_id, path):

        repo_owner = seafile_api.get_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
        else:
            share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                    path, repo_owner)

        ret = []
        for item in share_items:

            group_id = item.group_id
            group = ccnet_api.get_group(group_id)

            if not group:
                if path == '/':
                    seafile_api.unset_group_repo(repo_id, group_id,
                            repo_owner)
                else:
                    seafile_api.unshare_subdir_for_group(
                            repo_id, path, repo_owner, group_id)
                continue

            ret.append({
                "group_id": group_id,
                "group_name": group.group_name,
                "permission": item.perm,
            })
        return ret
Esempio n. 4
0
 def list_group_shared_items(self, request, repo_id, path):
     username = request.user.username
     if is_org_context(request):
         org_id = request.user.org.org_id
         if path == '/':
             share_items = seafile_api.list_org_repo_shared_group(
                 org_id, username, repo_id)
         else:
             share_items = seafile_api.get_org_shared_groups_for_subdir(
                 org_id, repo_id, path, username)
     else:
         if path == '/':
             share_items = seafile_api.list_repo_shared_group_by_user(
                 username, repo_id)
         else:
             share_items = seafile_api.get_shared_groups_for_subdir(
                 repo_id, path, username)
     ret = []
     for item in share_items:
         ret.append({
             "share_type": "group",
             "group_info": {
                 "id": item.group_id,
                 "name": seaserv.get_group(item.group_id).group_name,
             },
             "permission": item.perm,
         })
     return ret
Esempio n. 5
0
    def list_group_shared_items(self, request, repo_id, path):
        if is_org_context(request):
            # when calling seafile API to share authority related functions, change the uesrname to repo owner.
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
            org_id = request.user.org.org_id
            if path == '/':
                share_items = seafile_api.list_org_repo_shared_group(
                    org_id, repo_owner, repo_id)
            else:
                share_items = seafile_api.get_org_shared_groups_for_subdir(
                    org_id, repo_id, path, repo_owner)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)
            if path == '/':
                share_items = seafile_api.list_repo_shared_group_by_user(
                    repo_owner, repo_id)
            else:
                share_items = seafile_api.get_shared_groups_for_subdir(
                    repo_id, path, repo_owner)
        ret = []
        # change is_admin to True if user in admin groups.
        admin_groups = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(
            repo_id)
        for item in share_items:

            if '@seafile_group' in repo_owner and \
                    repo_owner.split('@')[0] == str(item.group_id):
                continue

            group_id = item.group_id
            group = ccnet_api.get_group(group_id)
            if not group:
                if is_org_context(request):
                    if path == '/':
                        seafile_api.del_org_group_repo(repo_id, org_id,
                                                       group_id)
                    else:
                        seafile_api.org_unshare_subdir_for_group(
                            org_id, repo_id, path, repo_owner, group_id)
                else:
                    if path == '/':
                        seafile_api.unset_group_repo(repo_id, group_id,
                                                     repo_owner)
                    else:
                        seafile_api.unshare_subdir_for_group(
                            repo_id, path, repo_owner, group_id)
                continue

            ret.append({
                "share_type": "group",
                "group_info": {
                    "id": group_id,
                    "name": group.group_name,
                },
                "permission": item.perm,
                "is_admin": group_id in admin_groups,
            })
        return ret
Esempio n. 6
0
def get_repo_shared_users(repo_id, repo_owner, include_groups=True):
    """Return a list contains users and group users. Repo owner is ommited.
    """
    ret = []
    users = seafile_api.list_repo_shared_to(repo_owner, repo_id)
    ret += [x.user for x in users]
    if include_groups:
        for e in seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id):
            g_members = seaserv.get_group_members(e.group_id)
            ret += [x.user_name for x in g_members if x.user_name != repo_owner]

    return list(set(ret))
Esempio n. 7
0
def get_repo_shared_users(repo_id, repo_owner, include_groups=True):
    """Return a list contains users and group users. Repo owner is ommited.
    """
    ret = []
    users = seafile_api.list_repo_shared_to(repo_owner, repo_id)
    ret += [x.user for x in users]
    if include_groups:
        for e in seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id):
            g_members = seaserv.get_group_members(e.group_id)
            ret += [x.user_name for x in g_members if x.user_name != repo_owner]

    return list(set(ret))
Esempio n. 8
0
    def get_repo_shared_to_groups(self, request, repo_id):
        username = request.user.username
        if is_org_context(request):
            org_id = request.user.org.org_id
            share_items = seafile_api.list_org_repo_shared_group(
                org_id, username, repo_id)
        else:
            share_items = seafile_api.list_repo_shared_group_by_user(
                username, repo_id)

        ret = []
        for item in share_items:
            ret.append(item.group_id)

        return ret
Esempio n. 9
0
    def get_repo_shared_to_groups(self, request, repo_id):
        username = request.user.username
        if is_org_context(request):
            org_id = request.user.org.org_id
            share_items = seafile_api.list_org_repo_shared_group(org_id,
                    username, repo_id)
        else:
            share_items = seafile_api.list_repo_shared_group_by_user(
                    username, repo_id)

        ret = []
        for item in share_items:
            ret.append(item.group_id)

        return ret
Esempio n. 10
0
File: rpc.py Progetto: haiwen/seahub
 def get_shared_groups_by_repo_path(self, repo_id, repo_owner, path='/',
                                    org_id=None):
     if is_valid_org_id(org_id):
         if path == '/':
             return seafile_api.list_org_repo_shared_group(
                 org_id, repo_owner, repo_id)
         else:
             return seafile_api.get_org_shared_groups_for_subdir(
                 org_id, repo_id, path, repo_owner)
     else:
         if path == '/':
             return seafile_api.list_repo_shared_group_by_user(
                 repo_owner, repo_id)
         else:
             return seafile_api.get_shared_groups_for_subdir(
                 repo_id, path, repo_owner)
Esempio n. 11
0
def has_shared_to_group(repo_id, path, gid, org_id=None):
    if org_id:
        # when calling seafile API to share authority related functions, change the uesrname to repo owner.
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_org_repo_shared_group(org_id,
                    repo_owner, repo_id)
        else:
            share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                    repo_id, path, repo_owner)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
        else:
            share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                   path, repo_owner)

    return gid in [item.group_id for item in share_items]
Esempio n. 12
0
def has_shared_to_group(repo_id, path, gid, org_id=None):
    if is_valid_org_id(org_id):
        # when calling seafile API to share authority related functions, change the uesrname to repo owner.
        repo_owner = seafile_api.get_org_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_org_repo_shared_group(org_id,
                    repo_owner, repo_id)
        else:
            share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
                    repo_id, path, repo_owner)
    else:
        repo_owner = seafile_api.get_repo_owner(repo_id)
        if path == '/':
            share_items = seafile_api.list_repo_shared_group_by_user(repo_owner, repo_id)
        else:
            share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
                                                                   path, repo_owner)

    return gid in [item.group_id for item in share_items]
Esempio n. 13
0
 def get_shared_groups_by_repo_path(self,
                                    repo_id,
                                    repo_owner,
                                    path='/',
                                    org_id=None):
     if is_valid_org_id(org_id):
         if path == '/':
             return seafile_api.list_org_repo_shared_group(
                 org_id, repo_owner, repo_id)
         else:
             return seafile_api.get_org_shared_groups_for_subdir(
                 org_id, repo_id, path, repo_owner)
     else:
         if path == '/':
             return seafile_api.list_repo_shared_group_by_user(
                 repo_owner, repo_id)
         else:
             return seafile_api.get_shared_groups_for_subdir(
                 repo_id, path, repo_owner)
Esempio n. 14
0
    def get(self, request, repo_id):
        """ Return repo share info

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

        # 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)

        # permission check
        permission = check_folder_permission(request, repo_id, '/')
        if not permission:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if is_org_context(request):
            org_id = request.user.org.org_id
            repo_owner = seafile_api.get_org_repo_owner(org_id, repo_id)
            shared_users = seafile_api.list_org_repo_shared_to(
                repo_owner, repo_id)
            shared_groups = seafile_api.list_org_repo_shared_group(
                org_id, repo_owner, repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)
            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)

        result = {
            "shared_user_emails": [item.user for item in shared_users],
            "shared_group_ids": [item.group_id for item in shared_groups],
        }

        return Response(result)
Esempio n. 15
0
    def delete(self, request, repo_id, format=None):
        username = request.user.username
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'Library %s not found.' % repo_id)

        path = request.GET.get('p', '/')
        if seafile_api.get_dir_id_by_path(repo.id, path) is None:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'Folder %s not found.' % path)

        if username != self.get_repo_owner(request, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        shared_to_user, shared_to_group = self.handle_shared_to_args(request)

        if path == '/':
            shared_repo = repo
        else:
            try:
                sub_repo = self.get_sub_repo_by_path(request, repo, path)
                if sub_repo:
                    shared_repo = sub_repo
                else:
                    return api_error(status.HTTP_404_NOT_FOUND,
                                     'Sub-library not found.')
            except SearpcError as e:
                logger.error(e)
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 'Failed to get sub-library.')

        if shared_to_user:
            shared_to = request.GET.get('username')
            if shared_to is None or not is_valid_username(shared_to):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'Email %s invalid.' % shared_to)

            try:
                User.objects.get(email=shared_to)
            except User.DoesNotExist:
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'Invalid user, should be registered')

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.org_remove_share(
                    org_id, shared_repo.id, username, shared_to)
            else:
                seaserv.remove_share(shared_repo.id, username, shared_to)

            permission = seafile_api.check_permission_by_path(
                repo.id, path, shared_to)
            send_perm_audit_msg('delete-repo-perm', username, shared_to,
                                repo_id, path, permission)

        if shared_to_group:
            group_id = request.GET.get('group_id')
            try:
                group_id = int(group_id)
            except ValueError:
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'group_id %s invalid' % group_id)

            # hacky way to get group repo permission
            permission = ''
            for e in seafile_api.list_repo_shared_group_by_user(
                    username, shared_repo.id):
                if e.group_id == group_id:
                    permission = e.perm
                    break

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.del_org_group_repo(shared_repo.id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(shared_repo.id, group_id,
                                             username)

            send_perm_audit_msg('delete-repo-perm', username, group_id,
                                repo_id, path, permission)

        return HttpResponse(json.dumps({'success': True}),
                            status=200,
                            content_type=json_content_type)
Esempio n. 16
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)
Esempio n. 17
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)
Esempio n. 18
0
    def get(self, request, repo, path, share_type):
        """ List user/group shares

        Permission checking:
        1. admin user.
        """

        result = []

        # current `request.user.username` is admin user,
        # so need to identify the repo owner specifically.
        repo_owner = seafile_api.get_repo_owner(repo.repo_id)
        if share_type == 'user':
            try:
                if path == '/':
                    share_items = seafile_api.list_repo_shared_to(
                            repo_owner, repo.repo_id)
                else:
                    share_items = seafile_api.get_shared_users_for_subdir(
                            repo.repo_id, path, repo_owner)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            admin_users = ExtraSharePermission.objects.get_admin_users_by_repo(repo.repo_id)
            for share_item in share_items:

                user_email = share_item.user
                user_name = email2nickname(user_email) if user_email else '--'

                share_info = {}
                share_info['repo_id'] = repo.repo_id
                share_info['path'] = path
                share_info['share_type'] = share_type
                share_info['user_email'] = user_email
                share_info['user_name'] = user_name
                share_info['permission'] = share_item.perm
                share_info['is_admin'] = user_email in admin_users

                result.append(share_info)

        if share_type == 'group':
            try:
                if path == '/':
                    share_items = seafile_api.list_repo_shared_group_by_user(
                            repo_owner, repo.repo_id)
                else:
                    share_items = seafile_api.get_shared_groups_for_subdir(
                            repo.repo_id, path, repo_owner)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            admin_groups = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(repo.repo_id)
            for share_item in share_items:

                group_id = share_item.group_id
                group = ccnet_api.get_group(group_id)
                group_name = group.group_name if group else '--'

                share_info = {}
                share_info['repo_id'] = repo.repo_id
                share_info['path'] = path
                share_info['share_type'] = share_type
                share_info['group_id'] = group_id
                share_info['group_name'] = group_name
                share_info['permission'] = share_item.perm
                share_info['is_admin'] = group_id in admin_groups

                result.append(share_info)

        return Response(result)
Esempio n. 19
0
    def delete(self, request, repo_id, format=None):
        """ Unshare a repo.

        Permission checking:
        1. Only repo owner can unshare a library.
        """

        # argument check
        share_type = request.GET.get('share_type', None)
        if not share_type:
            error_msg = 'share_type invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if share_type not in ('personal', 'group', 'public'):
            error_msg = "share_type can only be 'personal' or 'group' or 'public'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        # permission check
        username = request.user.username
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        if username != repo_owner:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # delete share
        org_id = None
        if is_org_context(request):
            org_id = request.user.org.org_id

        if share_type == 'personal':
            user = request.GET.get('user', None)
            if not user or not is_valid_username(user):
                error_msg = 'user invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # if user not found, permission will be None
            permission = seafile_api.check_permission_by_path(
                repo_id, '/', user)

            try:
                if org_id:
                    seafile_api.org_remove_share(org_id, repo_id, username,
                                                 user)
                else:
                    seafile_api.remove_share(repo_id, username, user)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            send_perm_audit_msg('delete-repo-perm', username, user, repo_id,
                                '/', permission)

        if share_type == 'group':
            group_id = request.GET.get('group_id', None)
            if not group_id:
                error_msg = 'group_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                group_id = int(group_id)
            except ValueError:
                error_msg = 'group_id must be integer.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # hacky way to get group repo permission
            permission = ''
            if org_id:
                for e in seafile_api.list_org_repo_shared_group(
                        org_id, username, repo_id):
                    if e.group_id == group_id:
                        permission = e.perm
                        break
            else:
                for e in seafile_api.list_repo_shared_group_by_user(
                        username, repo_id):
                    if e.group_id == group_id:
                        permission = e.perm
                        break

            try:
                if org_id:
                    seaserv.del_org_group_repo(repo_id, org_id, group_id)
                else:
                    seafile_api.unset_group_repo(repo_id, group_id, username)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            send_perm_audit_msg('delete-repo-perm', username, group_id,
                                repo_id, '/', permission)

        if share_type == 'public':
            pub_repos = []
            if org_id:
                pub_repos = seaserv.list_org_inner_pub_repos(org_id, username)

            if not request.cloud_mode:
                pub_repos = seaserv.list_inner_pub_repos(username)

            try:
                if org_id:
                    seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(
                        org_id, repo_id)
                else:
                    seafile_api.remove_inner_pub_repo(repo_id)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            permission = ''
            for repo in pub_repos:
                if repo.repo_id == repo_id:
                    permission = repo.permission
                    break

            if permission:
                send_perm_audit_msg('delete-repo-perm', username, 'all',
                                    repo_id, '/', permission)

        return Response({'success': True})
def test_share_repo_to_group(repo, group, permission):
    assert api.check_permission(repo.id, USER) == 'rw'
    assert api.check_permission(repo.id, USER2) is None

    repos = api.get_repos_by_group(group.id)
    assert len(repos) == 0

    group_list = ccnet_api.get_groups(USER)
    assert len(group_list) == 1
    group_list = ccnet_api.get_groups(USER2)
    assert len(group_list) == 0

    api.group_share_repo(repo.id, group.id, USER, permission)
    repos = api.get_repos_by_group(group.id)
    assert_repo_with_permission(repo, repos, permission)

    group_ids = api.get_shared_group_ids_by_repo(repo.id)
    assert group_ids[0] == str(group.id)

    group_list = api.list_repo_shared_group_by_user(USER, repo.id)
    assert len(group_list) == 1
    group_list = api.list_repo_shared_group_by_user(USER2, repo.id)
    assert len(group_list) == 0

    repo_get = api.get_group_shared_repo_by_path(repo.id, None, group.id)
    assert repo_get and repo_get.repo_id == repo.id

    ccnet_api.group_add_member(group.id, USER, USER2)
    group_list = ccnet_api.get_groups(USER2)
    assert len(group_list) == 1
    group = group_list[0]
    assert group.id == group.id

    repos2 = api.get_repos_by_group(group.id)
    assert_repo_with_permission(repo, repos2, permission)

    assert api.check_permission(repo.id, USER2) == permission

    repos = api.get_group_repos_by_user(USER)
    assert len(repos) == 1

    repoids = api.get_group_repoids(group.id)
    assert len(repoids) == 1

    repos = api.get_group_repos_by_owner(USER)
    assert len(repos) == 1
    api.remove_group_repos_by_owner(group.id, USER)
    repos = api.get_group_repos_by_owner(USER)
    assert len(repos) == 0

    api.set_group_repo(repo.id, group.id, USER, permission)
    repos = api.get_repos_by_group(group.id)
    assert len(repos) == 1
    api.remove_group_repos(group.id)
    repos = api.get_repos_by_group(group.id)
    assert len(repos) == 0

    api.group_unshare_repo(repo.id, group.id, USER)
    repos = api.get_repos_by_group(group.id)
    assert len(repos) == 0

    assert api.check_permission(repo.id, USER2) is None
Esempio n. 21
0
    def delete(self, request, repo_id, format=None):
        username = request.user.username
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id)

        path = request.GET.get('p', '/')
        if seafile_api.get_dir_id_by_path(repo.id, path) is None:
            return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path)

        if username != self.get_repo_owner(request, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        shared_to_user, shared_to_group = self.handle_shared_to_args(request)

        if path == '/':
            shared_repo = repo
        else:
            try:
                sub_repo = self.get_sub_repo_by_path(request, repo, path)
                if sub_repo:
                    shared_repo = sub_repo
                else:
                    return api_error(status.HTTP_404_NOT_FOUND, 'Sub-library not found.')
            except SearpcError as e:
                logger.error(e)
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub-library.')

        if shared_to_user:
            shared_to = request.GET.get('username')
            if shared_to is None or not is_valid_username(shared_to):
                return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % shared_to)

            try:
                User.objects.get(email=shared_to)
            except User.DoesNotExist:
                return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered')

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.org_remove_share(
                    org_id, shared_repo.id, username, shared_to)
            else:
                seaserv.remove_share(shared_repo.id, username, shared_to)

            permission = seafile_api.check_permission_by_path(repo.id, path,
                                                              shared_to)
            send_perm_audit_msg('delete-repo-perm', username, shared_to,
                                repo_id, path, permission)

        if shared_to_group:
            group_id = request.GET.get('group_id')
            try:
                group_id = int(group_id)
            except ValueError:
                return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid' % group_id)

            # hacky way to get group repo permission
            permission = ''
            for e in seafile_api.list_repo_shared_group_by_user(username, shared_repo.id):
                if e.group_id == group_id:
                    permission = e.perm
                    break

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.del_org_group_repo(shared_repo.id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(shared_repo.id, group_id, username)

            send_perm_audit_msg('delete-repo-perm', username, group_id,
                                repo_id, path, permission)

        return HttpResponse(json.dumps({'success': True}), status=200,
                            content_type=json_content_type)
Esempio n. 22
0
def list_lib_dir(request, repo_id):
    '''
        New ajax API for list library directory
    '''
    content_type = 'application/json; charset=utf-8'
    result = {}

    repo = get_repo(repo_id)
    if not repo:
        err_msg = _(u'Library does not exist.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=400, content_type=content_type)

    username = request.user.username
    path = request.GET.get('p', '/')
    if path[-1] != '/':
        path = path + '/'

    # perm for current dir
    user_perm = check_folder_permission(request, repo.id, path)
    if user_perm is None:
        err_msg = _(u'Permission denied.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403, content_type=content_type)

    if repo.encrypted \
            and not seafile_api.is_password_set(repo.id, username):
        err_msg = _(u'Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg, 'lib_need_decrypt': True}),
                            status=403, content_type=content_type)

    head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
    if not head_commit:
        err_msg = _(u'Error: no head commit id')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=500, content_type=content_type)

    dir_list = []
    file_list = []

    try:
        dir_id = seafile_api.get_dir_id_by_path(repo.id, path)
    except SearpcError as e:
        logger.error(e)
        err_msg = 'Internal Server Error'
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=500, content_type=content_type)

    if not dir_id:
        err_msg = 'Folder not found.'
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=404, content_type=content_type)

    dirs = seafserv_threaded_rpc.list_dir_with_perm(repo_id, path, dir_id,
            username, -1, -1)
    starred_files = get_dir_starred_files(username, repo_id, path)

    for dirent in dirs:
        dirent.last_modified = dirent.mtime
        if stat.S_ISDIR(dirent.mode):
            dpath = posixpath.join(path, dirent.obj_name)
            if dpath[-1] != '/':
                dpath += '/'
            dir_list.append(dirent)
        else:
            if repo.version == 0:
                file_size = seafile_api.get_file_size(repo.store_id, repo.version, dirent.obj_id)
            else:
                file_size = dirent.size
            dirent.file_size = file_size if file_size else 0

            dirent.starred = False
            fpath = posixpath.join(path, dirent.obj_name)
            if fpath in starred_files:
                dirent.starred = True

            file_list.append(dirent)

    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
    else:
        repo_owner = seafile_api.get_repo_owner(repo.id)

    result["is_repo_owner"] = False
    result["has_been_shared_out"] = False
    if repo_owner == username:
        result["is_repo_owner"] = True

        try:
            if is_org_context(request):
                org_id = request.user.org.org_id

                is_inner_org_pub_repo = False
                # check if current repo is pub-repo
                org_pub_repos = seafile_api.list_org_inner_pub_repos_by_owner(
                        org_id, username)
                for org_pub_repo in org_pub_repos:
                    if repo_id == org_pub_repo.id:
                        is_inner_org_pub_repo = True
                        break

                if seafile_api.list_org_repo_shared_group(org_id, username, repo_id) or \
                        seafile_api.list_org_repo_shared_to(org_id, username, repo_id) or \
                        is_inner_org_pub_repo:
                    result["has_been_shared_out"] = True
            else:
                if seafile_api.list_repo_shared_to(username, repo_id) or \
                        seafile_api.list_repo_shared_group_by_user(username, repo_id) or \
                        (not request.cloud_mode and seafile_api.is_inner_pub_repo(repo_id)):
                    result["has_been_shared_out"] = True
        except Exception as e:
            logger.error(e)

    result["is_virtual"] = repo.is_virtual
    result["repo_name"] = repo.name
    result["user_perm"] = user_perm
    # check quota for fileupload
    result["no_quota"] = True if seaserv.check_quota(repo.id) < 0 else False
    result["encrypted"] = repo.encrypted

    dirent_list = []
    for d in dir_list:
        d_ = {}
        d_['is_dir'] = True
        d_['obj_name'] = d.obj_name
        d_['last_modified'] = d.last_modified
        d_['last_update'] = translate_seahub_time(d.last_modified)
        d_['p_dpath'] = posixpath.join(path, d.obj_name)
        d_['perm'] = d.permission # perm for sub dir in current dir
        dirent_list.append(d_)

    size = int(request.GET.get('thumbnail_size', THUMBNAIL_DEFAULT_SIZE))

    for f in file_list:
        f_ = {}
        f_['is_file'] = True
        f_['file_icon'] = file_icon_filter(f.obj_name)
        f_['obj_name'] = f.obj_name
        f_['last_modified'] = f.last_modified
        f_['last_update'] = translate_seahub_time(f.last_modified)
        f_['starred'] = f.starred
        f_['file_size'] = filesizeformat(f.file_size)
        f_['obj_id'] = f.obj_id
        f_['perm'] = f.permission # perm for file in current dir

        file_type, file_ext = get_file_type_and_ext(f.obj_name)
        if file_type == IMAGE:
            f_['is_img'] = True
            if not repo.encrypted and ENABLE_THUMBNAIL and \
                os.path.exists(os.path.join(THUMBNAIL_ROOT, str(size), f.obj_id)):
                file_path = posixpath.join(path, f.obj_name)
                src = get_thumbnail_src(repo_id, size, file_path)
                f_['encoded_thumbnail_src'] = urlquote(src)

        if is_pro_version():
            f_['is_locked'] = True if f.is_locked else False
            f_['lock_owner'] = f.lock_owner
            f_['lock_owner_name'] = email2nickname(f.lock_owner)
            if username == f.lock_owner:
                f_['locked_by_me'] = True
            else:
                f_['locked_by_me'] = False

        dirent_list.append(f_)

    result["dirent_list"] = dirent_list

    return HttpResponse(json.dumps(result), content_type=content_type)
Esempio n. 23
0
    def get(self, request, repo, path, share_type):
        """ List user/group shares

        Permission checking:
        1. admin user.
        """

        result = []

        # current `request.user.username` is admin user,
        # so need to identify the repo owner specifically.
        repo_owner = seafile_api.get_repo_owner(repo.repo_id)
        if share_type == 'user':
            try:
                if path == '/':
                    share_items = seafile_api.list_repo_shared_to(
                        repo_owner, repo.repo_id)
                else:
                    share_items = seafile_api.get_shared_users_for_subdir(
                        repo.repo_id, path, repo_owner)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            admin_users = ExtraSharePermission.objects.get_admin_users_by_repo(
                repo.repo_id)
            for share_item in share_items:

                user_email = share_item.user
                user_name = email2nickname(user_email) if user_email else '--'

                share_info = {}
                share_info['repo_id'] = repo.repo_id
                share_info['path'] = path
                share_info['share_type'] = share_type
                share_info['user_email'] = user_email
                share_info['user_name'] = user_name
                share_info['permission'] = share_item.perm
                share_info['is_admin'] = user_email in admin_users

                result.append(share_info)

        if share_type == 'group':
            try:
                if path == '/':
                    share_items = seafile_api.list_repo_shared_group_by_user(
                        repo_owner, repo.repo_id)
                else:
                    share_items = seafile_api.get_shared_groups_for_subdir(
                        repo.repo_id, path, repo_owner)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            admin_groups = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(
                repo.repo_id)
            for share_item in share_items:

                group_id = share_item.group_id
                group = ccnet_api.get_group(group_id)
                group_name = group.group_name if group else '--'

                share_info = {}
                share_info['repo_id'] = repo.repo_id
                share_info['path'] = path
                share_info['share_type'] = share_type
                share_info['group_id'] = group_id
                share_info['group_name'] = group_name
                share_info['permission'] = share_item.perm
                share_info['is_admin'] = group_id in admin_groups

                result.append(share_info)

        return Response(result)
Esempio n. 24
0
    def delete(self, request, repo_id, format=None):
        """ Unshare a repo.

        Permission checking:
        1. Only repo owner can unshare a library.
        """

        # argument check
        share_type = request.GET.get('share_type', None)
        if not share_type:
            error_msg = 'share_type invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if share_type not in ('personal', 'group', 'public'):
            error_msg = "share_type can only be 'personal' or 'group' or 'public'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        # permission check
        username = request.user.username
        if is_org_context(request):
            repo_owner = seafile_api.get_org_repo_owner(repo_id)
        else:
            repo_owner = seafile_api.get_repo_owner(repo_id)

        if username != repo_owner:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # delete share
        org_id = None
        if is_org_context(request):
            org_id = request.user.org.org_id

        if share_type == 'personal':
            user = request.GET.get('user', None)
            if not user or not is_valid_username(user):
                error_msg = 'user invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # if user not found, permission will be None
            permission = seafile_api.check_permission_by_path(
                    repo_id, '/', user)

            try:
                if org_id:
                    seafile_api.org_remove_share(org_id, repo_id,
                                                 username, user)
                else:
                    seafile_api.remove_share(repo_id, username, user)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            send_perm_audit_msg('delete-repo-perm', username, user,
                    repo_id, '/', permission)

        if share_type == 'group':
            group_id = request.GET.get('group_id', None)
            if not group_id:
                error_msg = 'group_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            try:
                group_id = int(group_id)
            except ValueError:
                error_msg = 'group_id must be integer.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # hacky way to get group repo permission
            permission = ''
            if org_id:
                for e in seafile_api.list_org_repo_shared_group(
                        org_id, username, repo_id):
                    if e.group_id == group_id:
                        permission = e.perm
                        break
            else:
                for e in seafile_api.list_repo_shared_group_by_user(username, repo_id):
                    if e.group_id == group_id:
                        permission = e.perm
                        break

            try:
                if org_id:
                    seaserv.del_org_group_repo(repo_id, org_id, group_id)
                else:
                    seafile_api.unset_group_repo(repo_id, group_id, username)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            send_perm_audit_msg('delete-repo-perm', username, group_id,
                                repo_id, '/', permission)

        if share_type == 'public':
            pub_repos = []
            if org_id:
                pub_repos = seaserv.list_org_inner_pub_repos(org_id, username)

            if not request.cloud_mode:
                pub_repos = seaserv.list_inner_pub_repos(username)

            try:
                if org_id:
                    seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id, repo_id)
                else:
                    seafile_api.remove_inner_pub_repo(repo_id)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            permission = ''
            for repo in pub_repos:
                if repo.repo_id == repo_id:
                    permission = repo.permission
                    break

            if permission:
                send_perm_audit_msg('delete-repo-perm', username, 'all', repo_id, '/', permission)

        return Response({'success': True})
Esempio n. 25
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)
Esempio n. 26
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)