Example #1
0
    def get(self, request, format=None):
        username = request.user.username
        shared_repos = []
        shared_repos += seafile_api.get_share_in_repo_list(username, -1, -1)

        joined_groups = get_personal_groups_by_user(username)
        for grp in joined_groups:
        # Get group repos, and for each group repos...
            for r_id in get_group_repoids(grp.id):
                # No need to list my own repo
                if seafile_api.is_repo_owner(username, r_id):
                    continue
                 # Convert repo properties due to the different collumns in Repo
                 # and SharedRepo
                r = get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                cmmts = get_commits(r_id, 0, 1)
                last_commit = cmmts[0] if cmmts else None
                r.last_modified = last_commit.ctime if last_commit else 0
                r.share_type = 'group'
                r.user = seafile_api.get_repo_owner(r_id)
                r.user_perm = check_permission(r_id, username)
                shared_repos.append(r)

        if not CLOUD_MODE:
            shared_repos += list_inner_pub_repos(username)

        return HttpResponse(json.dumps(shared_repos, cls=SearpcObjEncoder),
                            status=200, content_type=json_content_type)
Example #2
0
    def get(self, request, format=None):
        username = request.user.username
        shared_repos = []
        shared_repos += seafile_api.get_share_in_repo_list(username, -1, -1)

        joined_groups = get_personal_groups_by_user(username)
        for grp in joined_groups:
            # Get group repos, and for each group repos...
            for r_id in get_group_repoids(grp.id):
                # No need to list my own repo
                if seafile_api.is_repo_owner(username, r_id):
                    continue
                # Convert repo properties due to the different collumns in Repo
                # and SharedRepo
                r = get_repo(r_id)
                if not r:
                    continue
                r.repo_id = r.id
                r.repo_name = r.name
                r.repo_desc = r.desc
                cmmts = get_commits(r_id, 0, 1)
                last_commit = cmmts[0] if cmmts else None
                r.last_modified = last_commit.ctime if last_commit else 0
                r.share_type = 'group'
                r.user = seafile_api.get_repo_owner(r_id)
                r.user_perm = check_permission(r_id, username)
                shared_repos.append(r)

        if not CLOUD_MODE:
            shared_repos += list_inner_pub_repos(username)

        return HttpResponse(json.dumps(shared_repos, cls=SearpcObjEncoder),
                            status=200,
                            content_type=json_content_type)
Example #3
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_400_BAD_REQUEST, \
                    'Library does not exist.')

        if not seafile_api.is_repo_owner(username, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, \
                    'Only library owner can perform this operation.')

        seafile_api.remove_repo(repo_id)
        return Response('success', status=status.HTTP_200_OK)
Example #4
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_400_BAD_REQUEST, \
                    'Library does not exist.')

        if not seafile_api.is_repo_owner(username, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, \
                    'Only library owner can perform this operation.')

        seafile_api.remove_repo(repo_id)
        return Response('success', status=status.HTTP_200_OK)
Example #5
0
    def delete(self, request, repo_id, pk, format=None):
        """Delete a comment, only comment author or repo owner can perform
        this op.
        """
        try:
            o = FileComment.objects.get(pk=pk)
        except FileComment.DoesNotExist:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong comment id')

        username = request.user.username
        if username != o.author and \
           not seafile_api.is_repo_owner(username, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        o.delete()

        return Response(status=204)
Example #6
0
    def delete(self, request, repo_id, pk, format=None):
        """Delete a comment, only comment author or repo owner can perform
        this op.
        """
        try:
            o = FileComment.objects.get(pk=pk)
        except FileComment.DoesNotExist:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong comment id')

        username = request.user.username
        if username != o.author and \
           not seafile_api.is_repo_owner(username, repo_id):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        o.delete()

        return Response(status=204)
Example #7
0
def ajax_private_share_dir(request):
    content_type = 'application/json; charset=utf-8'

    repo_id = request.POST.get('repo_id', '')
    path = request.POST.get('path', '')
    username = request.user.username
    result = {}

    repo = seafile_api.get_repo(repo_id)
    if not repo:
        result['error'] = _(u'Library does not exist.')
        return HttpResponse(json.dumps(result),
                            status=400,
                            content_type=content_type)

    if seafile_api.get_dir_id_by_path(repo_id, path) is None:
        result['error'] = _(u'Directory does not exist.')
        return HttpResponse(json.dumps(result),
                            status=400,
                            content_type=content_type)

    if path != '/':
        # if share a dir, check sub-repo first
        try:
            if is_org_context(request):
                org_id = request.user.org.org_id
                sub_repo = seaserv.seafserv_threaded_rpc.get_org_virtual_repo(
                    org_id, repo_id, path, username)
            else:
                sub_repo = seafile_api.get_virtual_repo(
                    repo_id, path, username)
        except SearpcError as e:
            result['error'] = e.msg
            return HttpResponse(json.dumps(result),
                                status=500,
                                content_type=content_type)

        if not sub_repo:
            name = os.path.basename(path)
            # create a sub-lib
            try:
                # use name as 'repo_name' & 'repo_desc' for sub_repo
                if is_org_context(request):
                    org_id = request.user.org.org_id
                    sub_repo_id = seaserv.seafserv_threaded_rpc.create_org_virtual_repo(
                        org_id, repo_id, path, name, name, username)
                else:
                    sub_repo_id = seafile_api.create_virtual_repo(
                        repo_id, path, name, name, username)
                sub_repo = seafile_api.get_repo(sub_repo_id)
            except SearpcError as e:
                result['error'] = e.msg
                return HttpResponse(json.dumps(result),
                                    status=500,
                                    content_type=content_type)

        shared_repo_id = sub_repo.id
        shared_repo = sub_repo
    else:
        shared_repo_id = repo_id
        shared_repo = repo

    emails_string = request.POST.get('emails', '')
    groups_string = request.POST.get('groups', '')
    perm = request.POST.get('perm', '')

    emails = string2list(emails_string)
    groups = string2list(groups_string)

    # Test whether user is the repo owner.
    if not seafile_api.is_repo_owner(username, shared_repo_id) and \
            not is_org_repo_owner(username, shared_repo_id):
        result['error'] = _(
            u'Only the owner of the library has permission to share it.')
        return HttpResponse(json.dumps(result),
                            status=500,
                            content_type=content_type)

    # Parsing input values.
    # no 'share_to_all'
    share_to_groups, share_to_users, shared_success, shared_failed = [], [], [], []

    for email in emails:
        email = email.lower()
        if is_valid_username(email):
            share_to_users.append(email)
        else:
            shared_failed.append(email)

    for group_id in groups:
        share_to_groups.append(seaserv.get_group(group_id))

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        if share_to_user(request, shared_repo, email, perm):
            shared_success.append(email)
        else:
            shared_failed.append(email)

    for group in share_to_groups:
        if share_to_group(request, shared_repo, group, perm):
            shared_success.append(group.group_name)
        else:
            shared_failed.append(group.group_name)

    if len(shared_success) > 0:
        return HttpResponse(json.dumps({
            "shared_success": shared_success,
            "shared_failed": shared_failed
        }),
                            content_type=content_type)
    else:
        # for case: only share to users and the emails are not valid
        data = json.dumps(
            {"error": _("Please check the email(s) you entered")})
        return HttpResponse(data, status=400, content_type=content_type)
Example #8
0
def view_file(request, repo_id):
    """
    Steps to view file:
    1. Get repo id and file path.
    2. Check user's permission.
    3. Check whether this file can be viewed online.
    4.1 Get file content if file is text file.
    4.2 Prepare flash if file is document.
    4.3 Prepare or use pdfjs if file is pdf.
    4.4 Other file return it's raw path.
    """
    username = request.user.username
    # check arguments
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = request.GET.get('p', '/').rstrip('/')
    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))

    # construct some varibles
    u_filename = os.path.basename(path)
    current_commit = get_commits(repo_id, 0, 1)[0]

    # Check whether user has permission to view file and get file raw path,
    # render error page if permission deny.
    raw_path, inner_path, user_perm = get_file_view_path_and_perm(request,
                                                                  repo_id,
                                                                  obj_id, path)
    if not user_perm:
        return render_permission_error(request, _(u'Unable to view file'))

    # check if the user is the owner or not, for 'private share'
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
        is_repo_owner = True if repo_owner == username else False
    else:
        is_repo_owner = seafile_api.is_repo_owner(username, repo.id)

    # get file type and extension
    filetype, fileext = get_file_type_and_ext(u_filename)

    img_prev = None
    img_next = None
    ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '',
                'file_encoding_list': [], 'html_exists': False,
                'filetype': filetype}

    fsize = get_file_size(repo.store_id, repo.version, obj_id)

    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        ret_dict['err'] = err_msg
    else:
        """Choose different approach when dealing with different type of file."""
        if is_textual_file(file_type=filetype):
            handle_textual_file(request, filetype, inner_path, ret_dict)
            if filetype == MARKDOWN:
                c = ret_dict['file_content']
                ret_dict['file_content'] = convert_md_link(c, repo_id, username)
        elif filetype == DOCUMENT:
            handle_document(inner_path, obj_id, fileext, ret_dict)
        elif filetype == SPREADSHEET:
            handle_spreadsheet(inner_path, obj_id, fileext, ret_dict)
        elif filetype == OPENDOCUMENT:
            if fsize == 0:
                ret_dict['err'] = _(u'Invalid file format.')
        elif filetype == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)
        elif filetype == IMAGE:
            parent_dir = os.path.dirname(path)
            dirs = seafile_api.list_dir_by_commit_and_path(current_commit.repo_id,
                                                           current_commit.id, parent_dir)
            if not dirs:
                raise Http404

            img_list = []
            for dirent in dirs:
                if not stat.S_ISDIR(dirent.props.mode):
                    fltype, flext = get_file_type_and_ext(dirent.obj_name)
                    if fltype == 'Image':
                        img_list.append(dirent.obj_name)

            if len(img_list) > 1:
                img_list.sort(lambda x, y : cmp(x.lower(), y.lower()))
                cur_img_index = img_list.index(u_filename)
                if cur_img_index != 0:
                    img_prev = posixpath.join(parent_dir, img_list[cur_img_index - 1])
                if cur_img_index != len(img_list) - 1:
                    img_next = posixpath.join(parent_dir, img_list[cur_img_index + 1])
        else:
            pass

    # generate file path navigator
    zipped = gen_path_link(path, repo.name)

    # file shared link
    l = FileShare.objects.filter(repo_id=repo_id).filter(
        username=username).filter(path=path)
    fileshare = l[0] if len(l) > 0 else None
    http_or_https = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain
    if fileshare:
        file_shared_link = gen_file_share_link(fileshare.token)
    else:
        file_shared_link = ''

    for g in request.user.joined_groups:
        g.avatar = grp_avatar(g.id, 20)

    """List repo groups"""
    # Get groups this repo is shared.    
    if request.user.org:
        org_id = request.user.org.org_id
        repo_shared_groups = get_org_groups_by_repo(org_id, repo_id)
    else:
        repo_shared_groups = get_shared_groups_by_repo(repo_id)
    # Filter out groups that user in joined.
    groups = [x for x in repo_shared_groups if is_group_user(x.id, username)]
    if len(groups) > 1:
        ctx = {}
        ctx['groups'] = groups
        repogrp_str = render_to_string("snippets/repo_group_list.html", ctx)
    else:
        repogrp_str = ''

    file_path_hash = hashlib.md5(urllib2.quote(path.encode('utf-8'))).hexdigest()[:12]

    # fetch file contributors and latest contributor
    contributors, last_modified, last_commit_id = \
        FileContributors.objects.get_file_contributors(
        repo_id, path.encode('utf-8'), file_path_hash, obj_id)
    latest_contributor = contributors[0] if contributors else None

    # check whether file is starred
    is_starred = False
    org_id = -1
    if request.user.org:
        org_id = request.user.org.org_id
    is_starred = is_file_starred(username, repo.id, path.encode('utf-8'), org_id)

    template = 'view_file_%s.html' % ret_dict['filetype'].lower()

    return render_to_response(template, {
            'repo': repo,
            'is_repo_owner': is_repo_owner,
            'obj_id': obj_id,
            'filename': u_filename,
            'path': path,
            'zipped': zipped,
            'current_commit': current_commit,
            'fileext': fileext,
            'raw_path': raw_path,
            'fileshare': fileshare,
            'protocol': http_or_https,
            'domain': domain,
            'file_shared_link': file_shared_link,
            'err': ret_dict['err'],
            'file_content': ret_dict['file_content'],
            'file_enc': ret_dict['file_enc'],
            'encoding': ret_dict['encoding'],
            'file_encoding_list': ret_dict['file_encoding_list'],
            'html_exists': ret_dict['html_exists'],
            'html_detail': ret_dict.get('html_detail', {}),
            'filetype': ret_dict['filetype'],
            'groups': groups,
            'use_pdfjs': USE_PDFJS,
            'contributors': contributors,
            'latest_contributor': latest_contributor,
            'last_modified': last_modified,
            'last_commit_id': last_commit_id,
            'repo_group_str': repogrp_str,
            'is_starred': is_starred,
            'user_perm': user_perm,
            'img_prev': img_prev,
            'img_next': img_next,
            'highlight_keyword': settings.HIGHLIGHT_KEYWORD,
            }, context_instance=RequestContext(request))
Example #9
0
def render_repo(request, repo):
    """Steps to show repo page:
    If user has permission to view repo
      If repo is encrypt and password is not set on server
        return decrypt repo page
      If repo is not encrypt or password is set on server
        Show repo direntries based on requested path
    If user does not have permission to view repo
      return permission deny page
    """
    username = request.user.username
    user_perm = check_repo_access_permission(repo.id, username)
    if user_perm is None:
        return render_to_response('repo_access_deny.html', {
            'repo': repo,
        },
                                  context_instance=RequestContext(request))

    if repo.encrypted and not is_password_set(repo.id, username):
        return render_to_response('decrypt_repo_form.html', {
                'repo': repo,
                'next': get_next_url_from_request(request) or \
                    reverse('repo', args=[repo.id])
                }, context_instance=RequestContext(request))

    # query context args
    applet_root = get_ccnetapplet_root()
    httpserver_root = get_httpserver_root()
    max_upload_file_size = MAX_UPLOAD_FILE_SIZE

    protocol = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain
    path = get_path_from_request(request)

    contacts = Contact.objects.get_contacts_by_user(username)
    accessible_repos = [
        repo
    ] if repo.encrypted else get_unencry_rw_repos_by_user(username)

    head_commit = get_commit(repo.head_cmmt_id)
    if not head_commit:
        raise Http404
    repo_size = get_repo_size(repo.id)
    no_quota = is_no_quota(repo.id)
    history_limit = seaserv.get_repo_history_limit(repo.id)
    search_repo_id = None if repo.encrypted else repo.id

    is_repo_owner = seafile_api.is_repo_owner(username, repo.id)
    file_list, dir_list = get_repo_dirents(request, repo.id, head_commit, path)
    zipped = get_nav_path(path, repo.name)
    repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
    if len(repo_groups) > 1:
        repo_group_str = render_to_string("snippets/repo_group_list.html",
                                          {'groups': repo_groups})
    else:
        repo_group_str = ''
    upload_url = get_upload_url(request, repo.id)
    update_url = get_update_url(request, repo.id)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_shared_link(request, fileshare)

    return render_to_response('repo.html', {
        'repo': repo,
        'user_perm': user_perm,
        'is_repo_owner': is_repo_owner,
        'current_commit': head_commit,
        'password_set': True,
        'repo_size': repo_size,
        'dir_list': dir_list,
        'file_list': file_list,
        'path': path,
        'zipped': zipped,
        'accessible_repos': accessible_repos,
        'applet_root': applet_root,
        'groups': repo_groups,
        'repo_group_str': repo_group_str,
        'no_quota': no_quota,
        'max_upload_file_size': max_upload_file_size,
        'upload_url': upload_url,
        'update_url': update_url,
        'httpserver_root': httpserver_root,
        'protocol': protocol,
        'domain': domain,
        'contacts': contacts,
        'fileshare': fileshare,
        'dir_shared_link': dir_shared_link,
        'history_limit': history_limit,
        'search_repo_id': search_repo_id,
        'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
    },
                              context_instance=RequestContext(request))
Example #10
0
    def delete(self, request, repo_id, format=None):

        if not seafile_api.get_repo(repo_id):
            return api_error(status.HTTP_400_BAD_REQUEST, 'Library does not exist')

        username = request.user.username
        share_type = request.GET.get('share_type', None)
        if share_type == 'personal':

            from_email = request.GET.get('from', None)
            if not is_valid_username(from_email):
                return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid argument')

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.org_remove_share(org_id,
                                                               repo_id,
                                                               from_email,
                                                               username)
            else:
                seaserv.remove_share(repo_id, from_email, username)

        elif share_type == 'group':

            from_email = request.GET.get('from', None)
            if not is_valid_username(from_email):
                return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid argument')

            group_id = request.GET.get('group_id', None)
            group = seaserv.get_group(group_id)
            if not group:
                return api_error(status.HTTP_400_BAD_REQUEST, 'Group does not exist')

            if not seaserv.check_group_staff(group_id, username) and \
                not seafile_api.is_repo_owner(username, repo_id):
                return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied')

            if seaserv.is_org_group(group_id):
                org_id = seaserv.get_org_id_by_group(group_id)
                seaserv.del_org_group_repo(repo_id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(repo_id, group_id, from_email)

        elif share_type == 'public':

            if is_org_context(request):
                org_repo_owner = seafile_api.get_org_repo_owner(repo_id)
                is_org_repo_owner = True if org_repo_owner == username else False

                if not request.user.org.is_staff and not is_org_repo_owner:
                    return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied')

                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id,
                                                                       repo_id)
            else:
                if not seafile_api.is_repo_owner(username, repo_id) and \
                    not request.user.is_staff:
                    return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied')

                seaserv.unset_inner_pub_repo(repo_id)
        else:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid argument')

        return Response({'success': True}, status=status.HTTP_200_OK)
Example #11
0
    def post(self, request):

        # argument check
        operation = request.data.get('operation')

        # operation could be `share`, `delete`, `transfer`
        # we now only use `share`
        if not operation or operation not in ('share'):
            error_msg = 'operation invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        result = {}
        result['failed'] = []
        result['success'] = []

        username = request.user.username
        repo_id_list = request.data.getlist('repo_id')
        valid_repo_id_list = []

        # filter out invalid repo id
        for repo_id in repo_id_list:

            if not seafile_api.get_repo(repo_id):
                result['failed'].append({
                    'repo_id':
                    repo_id,
                    'error_msg':
                    'Library %s not found.' % repo_id
                })
                continue

            if is_org_context(request):
                org_id = request.user.org.org_id
                org_repo_owner = seafile_api.get_org_repo_owner(repo_id)
                if not username == org_repo_owner:
                    result['failed'].append({
                        'repo_id': repo_id,
                        'error_msg': 'Permission denied.'
                    })
                    continue
            else:
                if not seafile_api.is_repo_owner(username, repo_id):
                    result['failed'].append({
                        'repo_id': repo_id,
                        'error_msg': 'Permission denied.'
                    })
                    continue

            valid_repo_id_list.append(repo_id)

        # share repo
        if operation == 'share':

            share_type = request.data.get('share_type')
            if share_type != 'user' and share_type != 'group':
                error_msg = 'share_type invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            permission = request.data.get('permission', 'rw')
            if permission not in ('r', 'rw'):
                error_msg = 'permission invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # share repo to user
            if share_type == 'user':
                to_username = request.data.get('username', None)
                if not to_username:
                    error_msg = 'username invalid.'
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

                # check if to_user is an org user
                try:
                    org_of_to_user = ccnet_api.get_orgs_by_user(to_username)
                except Exception as e:
                    logger.debug(e)
                    org_of_to_user = []

                if is_org_context(request):
                    org_id = request.user.org.org_id
                    org_name = request.user.org.org_name
                    if len(org_of_to_user
                           ) == 0 or org_id != org_of_to_user[0].org_id:
                        error_msg = 'User %s is not member of organization %s.' \
                                % (to_username, org_name)
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)
                else:
                    if len(org_of_to_user) >= 1:
                        error_msg = 'User %s is member of organization %s.' \
                                % (to_username, org_of_to_user[0].org_name)
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                for repo_id in valid_repo_id_list:
                    if self.has_shared_to_user(request, repo_id, to_username):
                        result['failed'].append({
                            'repo_id':
                            repo_id,
                            'error_msg':
                            'This item has been shared to %s.' % to_username
                        })
                        continue

                    try:
                        org_id = None
                        if is_org_context(request):
                            org_id = request.user.org.org_id
                            seaserv.seafserv_threaded_rpc.org_add_share(
                                org_id, repo_id, username, to_username,
                                permission)
                        else:
                            seafile_api.share_repo(repo_id, username,
                                                   to_username, permission)

                        # send a signal when sharing repo successful
                        repo = seafile_api.get_repo(repo_id)
                        share_repo_to_user_successful.send(sender=None,
                                                           from_user=username,
                                                           to_user=to_username,
                                                           repo=repo,
                                                           path='/',
                                                           org_id=org_id)

                        result['success'].append({
                            "repo_id": repo_id,
                            "username": to_username,
                            "permission": permission
                        })

                        send_perm_audit_msg('add-repo-perm', username,
                                            to_username, repo_id, '/',
                                            permission)
                    except Exception as e:
                        logger.error(e)
                        result['failed'].append({
                            'repo_id':
                            repo_id,
                            'error_msg':
                            'Internal Server Error'
                        })

            # share repo to group
            if share_type == 'group':
                to_group_id = request.data.get('group_id', None)
                if not to_group_id:
                    error_msg = 'group_id invalid.'
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                try:
                    to_group_id = int(to_group_id)
                except ValueError:
                    error_msg = 'group_id invalid.'
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                group = ccnet_api.get_group(to_group_id)
                if not group:
                    error_msg = 'Group %s not found.' % to_group_id
                    return api_error(status.HTTP_404_NOT_FOUND, error_msg)

                group_name = group.group_name
                if not is_group_member(to_group_id, username):
                    error_msg = 'User %s is not member of group %s.' % (
                        username, group_name)
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                for repo_id in valid_repo_id_list:
                    if self.has_shared_to_group(request, repo_id, to_group_id):
                        result['failed'].append({
                            'repo_id':
                            repo_id,
                            'error_msg':
                            'This item has been shared to %s.' % group_name
                        })
                        continue

                    try:
                        org_id = None
                        if is_org_context(request):
                            org_id = request.user.org.org_id
                            seafile_api.add_org_group_repo(
                                repo_id, org_id, to_group_id, username,
                                permission)
                        else:
                            seafile_api.set_group_repo(repo_id, to_group_id,
                                                       username, permission)

                        # send a signal when sharing repo successful
                        repo = seafile_api.get_repo(repo_id)
                        share_repo_to_group_successful.send(
                            sender=None,
                            from_user=username,
                            group_id=to_group_id,
                            repo=repo,
                            path='/',
                            org_id=org_id)

                        result['success'].append({
                            "repo_id": repo_id,
                            "group_id": to_group_id,
                            "group_name": group_name,
                            "permission": permission
                        })

                        send_perm_audit_msg('add-repo-perm', username,
                                            to_group_id, repo_id, '/',
                                            permission)

                    except SearpcError as e:
                        logger.error(e)
                        result['failed'].append({
                            'repo_id':
                            repo_id,
                            'error_msg':
                            'Internal Server Error'
                        })

        return Response(result)
Example #12
0
def view_file(request, repo_id):
    """
    Steps to view file:
    1. Get repo id and file path.
    2. Check user's permission.
    3. Check whether this file can be viewed online.
    4.1 Get file content if file is text file.
    4.2 Prepare flash if file is document.
    4.3 Prepare or use pdfjs if file is pdf.
    4.4 Other file return it's raw path.
    """
    username = request.user.username
    # check arguments
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = request.GET.get('p', '/').rstrip('/')
    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))

    # construct some varibles
    u_filename = os.path.basename(path)
    current_commit = get_commits(repo_id, 0, 1)[0]

    # Check whether user has permission to view file and get file raw path,
    # render error page if permission deny.
    raw_path, inner_path, user_perm = get_file_view_path_and_perm(
        request, repo_id, obj_id, path)
    if not user_perm:
        return render_permission_error(request, _(u'Unable to view file'))

    # check if the user is the owner or not, for 'private share'
    if is_org_context(request):
        repo_owner = seafile_api.get_org_repo_owner(repo.id)
        is_repo_owner = True if repo_owner == username else False
    else:
        is_repo_owner = seafile_api.is_repo_owner(username, repo.id)

    # get file type and extension
    filetype, fileext = get_file_type_and_ext(u_filename)

    img_prev = None
    img_next = None
    ret_dict = {
        'err': '',
        'file_content': '',
        'encoding': '',
        'file_enc': '',
        'file_encoding_list': [],
        'html_exists': False,
        'filetype': filetype
    }

    fsize = get_file_size(repo.store_id, repo.version, obj_id)

    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        ret_dict['err'] = err_msg
    else:
        """Choose different approach when dealing with different type of file."""
        if is_textual_file(file_type=filetype):
            handle_textual_file(request, filetype, inner_path, ret_dict)
            if filetype == MARKDOWN:
                c = ret_dict['file_content']
                ret_dict['file_content'] = convert_md_link(
                    c, repo_id, username)
        elif filetype == DOCUMENT:
            handle_document(inner_path, obj_id, fileext, ret_dict)
        elif filetype == SPREADSHEET:
            handle_spreadsheet(inner_path, obj_id, fileext, ret_dict)
        elif filetype == OPENDOCUMENT:
            if fsize == 0:
                ret_dict['err'] = _(u'Invalid file format.')
        elif filetype == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)
        elif filetype == IMAGE:
            parent_dir = os.path.dirname(path)
            dirs = seafile_api.list_dir_by_commit_and_path(
                current_commit.repo_id, current_commit.id, parent_dir)
            if not dirs:
                raise Http404

            img_list = []
            for dirent in dirs:
                if not stat.S_ISDIR(dirent.props.mode):
                    fltype, flext = get_file_type_and_ext(dirent.obj_name)
                    if fltype == 'Image':
                        img_list.append(dirent.obj_name)

            if len(img_list) > 1:
                img_list.sort(lambda x, y: cmp(x.lower(), y.lower()))
                cur_img_index = img_list.index(u_filename)
                if cur_img_index != 0:
                    img_prev = posixpath.join(parent_dir,
                                              img_list[cur_img_index - 1])
                if cur_img_index != len(img_list) - 1:
                    img_next = posixpath.join(parent_dir,
                                              img_list[cur_img_index + 1])
        else:
            pass

    # generate file path navigator
    zipped = gen_path_link(path, repo.name)

    # file shared link
    l = FileShare.objects.filter(repo_id=repo_id).filter(
        username=username).filter(path=path)
    fileshare = l[0] if len(l) > 0 else None
    http_or_https = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain
    if fileshare:
        file_shared_link = gen_file_share_link(fileshare.token)
    else:
        file_shared_link = ''

    for g in request.user.joined_groups:
        g.avatar = grp_avatar(g.id, 20)
    """List repo groups"""
    # Get groups this repo is shared.
    if request.user.org:
        org_id = request.user.org.org_id
        repo_shared_groups = get_org_groups_by_repo(org_id, repo_id)
    else:
        repo_shared_groups = get_shared_groups_by_repo(repo_id)
    # Filter out groups that user in joined.
    groups = [x for x in repo_shared_groups if is_group_user(x.id, username)]
    if len(groups) > 1:
        ctx = {}
        ctx['groups'] = groups
        repogrp_str = render_to_string("snippets/repo_group_list.html", ctx)
    else:
        repogrp_str = ''

    file_path_hash = hashlib.md5(urllib2.quote(
        path.encode('utf-8'))).hexdigest()[:12]

    # fetch file contributors and latest contributor
    contributors, last_modified, last_commit_id = \
        FileContributors.objects.get_file_contributors(
        repo_id, path.encode('utf-8'), file_path_hash, obj_id)
    latest_contributor = contributors[0] if contributors else None

    # check whether file is starred
    is_starred = False
    org_id = -1
    if request.user.org:
        org_id = request.user.org.org_id
    is_starred = is_file_starred(username, repo.id, path.encode('utf-8'),
                                 org_id)

    template = 'view_file_%s.html' % ret_dict['filetype'].lower()

    return render_to_response(
        template, {
            'repo': repo,
            'is_repo_owner': is_repo_owner,
            'obj_id': obj_id,
            'filename': u_filename,
            'path': path,
            'zipped': zipped,
            'current_commit': current_commit,
            'fileext': fileext,
            'raw_path': raw_path,
            'fileshare': fileshare,
            'protocol': http_or_https,
            'domain': domain,
            'file_shared_link': file_shared_link,
            'err': ret_dict['err'],
            'file_content': ret_dict['file_content'],
            'file_enc': ret_dict['file_enc'],
            'encoding': ret_dict['encoding'],
            'file_encoding_list': ret_dict['file_encoding_list'],
            'html_exists': ret_dict['html_exists'],
            'html_detail': ret_dict.get('html_detail', {}),
            'filetype': ret_dict['filetype'],
            'groups': groups,
            'use_pdfjs': USE_PDFJS,
            'contributors': contributors,
            'latest_contributor': latest_contributor,
            'last_modified': last_modified,
            'last_commit_id': last_commit_id,
            'repo_group_str': repogrp_str,
            'is_starred': is_starred,
            'user_perm': user_perm,
            'img_prev': img_prev,
            'img_next': img_next,
            'highlight_keyword': settings.HIGHLIGHT_KEYWORD,
        },
        context_instance=RequestContext(request))
Example #13
0
            try:
                seafile_api.lock_file(repo_id, path, username, expire)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        if operation == 'unlock':

            if not is_locked:
                error_msg = _("File is not locked.")
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # file can only be locked by normal user or OnlineOffice
            is_repo_owner = seafile_api.is_repo_owner(username, repo_id)
            if locked_by_me or \
                    (locked_by_online_office and is_repo_owner):
                # unlock file
                try:
                    seafile_api.unlock_file(repo_id, path)
                except SearpcError, e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     error_msg)
            else:
                error_msg = 'You can not unlock this file.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if operation == 'refresh-lock':
Example #14
0
def ajax_repo_remove_share(request):
    """
    Remove repo shared to user/group/public
    """
    content_type = 'application/json; charset=utf-8'

    repo_id = request.POST.get('repo_id', None)
    share_type = request.POST.get('share_type', None)

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

    username = request.user.username

    if share_type == 'personal':

        from_email = request.POST.get('from', None)
        if not is_valid_username(from_email):
            return HttpResponse(json.dumps({'error': _(u'Invalid argument')}), status=400,
                                content_type=content_type)

        if is_org_context(request):
            org_id = request.user.org.org_id
            org_remove_share(org_id, repo_id, from_email, username)
        else:
            seaserv.remove_share(repo_id, from_email, username)
        return HttpResponse(json.dumps({'success': True}), status=200,
                            content_type=content_type)

    elif share_type == 'group':

        from_email = request.POST.get('from', None)
        if not is_valid_username(from_email):
            return HttpResponse(json.dumps({'error': _(u'Invalid argument')}), status=400,
                                content_type=content_type)

        group_id = request.POST.get('group_id', None)
        group = seaserv.get_group(group_id)
        if not group:
            return HttpResponse(json.dumps({'error': _(u"Group does not exist")}), status=400,
                                content_type=content_type)

        if seaserv.check_group_staff(group_id, username) or \
            seafile_api.is_repo_owner(username, repo_id):
            if is_org_group(group_id):
                org_id = get_org_id_by_group(group_id)
                del_org_group_repo(repo_id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(repo_id, group_id, from_email)
            return HttpResponse(json.dumps({'success': True}), status=200,
                                content_type=content_type)
        else:
            return HttpResponse(json.dumps({'error': _(u'Permission denied')}), status=400,
                                content_type=content_type)

    elif share_type == 'public':

        if is_org_context(request):

            org_repo_owner = seafile_api.get_org_repo_owner(repo_id)
            is_org_repo_owner = True if org_repo_owner == username else False
            if request.user.org.is_staff or is_org_repo_owner:
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id,
                                                                       repo_id)
                return HttpResponse(json.dumps({'success': True}), status=200,
                                    content_type=content_type)
            else:
                return HttpResponse(json.dumps({'error': _(u'Permission denied')}), status=403,
                                    content_type=content_type)

        else:
            if seafile_api.is_repo_owner(username, repo_id) or \
                request.user.is_staff:
                unset_inner_pub_repo(repo_id)
                return HttpResponse(json.dumps({'success': True}), status=200,
                                    content_type=content_type)
            else:
                return HttpResponse(json.dumps({'error': _(u'Permission denied')}), status=403,
                                    content_type=content_type)
    else:
        return HttpResponse(json.dumps({'error': _(u'Invalid argument')}), status=400,
                            content_type=content_type)
Example #15
0
def share_repo(request):
    """
    Handle POST method to share a repo to public/groups/users based on form
    data. Return to ``myhome`` page and notify user whether success or failure.
    """
    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT

    form = RepoShareForm(request.POST)
    if not form.is_valid():
        # TODO: may display error msg on form
        raise Http404

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']

    repo = seafile_api.get_repo(repo_id)
    if not repo:
        raise Http404

    # Test whether user is the repo owner.
    username = request.user.username
    if not seafile_api.is_repo_owner(username, repo_id) and \
            not is_org_repo_owner(username, repo_id):
        msg = _(u'Only the owner of the library has permission to share it.')
        messages.error(request, msg)
        return HttpResponseRedirect(next)

    # Parsing input values.
    share_to_all, share_to_groups, share_to_users = False, [], []
    user_groups = request.user.joined_groups
    share_to_list = string2list(email_or_group)
    for share_to in share_to_list:
        if share_to == 'all':
            share_to_all = True
        elif share_to.find('@') == -1:
            for user_group in user_groups:
                if user_group.group_name == share_to:
                    share_to_groups.append(user_group)
        else:
            share_to = share_to.lower()
            if is_valid_username(share_to):
                share_to_users.append(share_to)

    origin_repo_id, origin_path = get_origin_repo_info(repo.id)
    if origin_repo_id is not None:
        perm_repo_id = origin_repo_id
        perm_path = origin_path
    else:
        perm_repo_id = repo.id
        perm_path =  '/'

    if share_to_all:
        share_to_public(request, repo, permission)
        send_perm_audit_msg('add-repo-perm', username, 'all', \
                            perm_repo_id, perm_path, permission)

    for group in share_to_groups:
        if share_to_group(request, repo, group, permission):
            send_perm_audit_msg('add-repo-perm', username, group.id, \
                                perm_repo_id, perm_path, permission)

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        if share_to_user(request, repo, email, permission):
            send_perm_audit_msg('add-repo-perm', username, email, \
                                perm_repo_id, perm_path, permission)

    return HttpResponseRedirect(next)
Example #16
0
def ajax_private_share_dir(request):
    content_type = 'application/json; charset=utf-8'

    repo_id = request.POST.get('repo_id', '')
    path = request.POST.get('path', '')
    username = request.user.username
    result = {}

    repo = seafile_api.get_repo(repo_id)
    if not repo:
        result['error'] = _(u'Library does not exist.')
        return HttpResponse(json.dumps(result), status=400, content_type=content_type)

    if seafile_api.get_dir_id_by_path(repo_id, path) is None:
        result['error'] = _(u'Directory does not exist.')
        return HttpResponse(json.dumps(result), status=400, content_type=content_type)

    if path != '/':
        # if share a dir, check sub-repo first
        try:
            if is_org_context(request):
                org_id = request.user.org.org_id
                sub_repo = seaserv.seafserv_threaded_rpc.get_org_virtual_repo(
                    org_id, repo_id, path, username)
            else:
                sub_repo = seafile_api.get_virtual_repo(repo_id, path, username)
        except SearpcError as e:
            result['error'] = e.msg
            return HttpResponse(json.dumps(result), status=500, content_type=content_type)

        if not sub_repo:
            name = os.path.basename(path)
            # create a sub-lib
            try:
                # use name as 'repo_name' & 'repo_desc' for sub_repo
                if is_org_context(request):
                    org_id = request.user.org.org_id
                    sub_repo_id = seaserv.seafserv_threaded_rpc.create_org_virtual_repo(
                        org_id, repo_id, path, name, name, username)
                else:
                    sub_repo_id = seafile_api.create_virtual_repo(repo_id, path,
                        name, name, username)
                sub_repo = seafile_api.get_repo(sub_repo_id)
            except SearpcError as e:
                result['error'] = e.msg
                return HttpResponse(json.dumps(result), status=500, content_type=content_type)

        shared_repo_id = sub_repo.id
        shared_repo = sub_repo
    else:
        shared_repo_id = repo_id
        shared_repo = repo

    emails_string = request.POST.get('emails', '')
    groups_string = request.POST.get('groups', '')
    perm = request.POST.get('perm', '')

    emails = string2list(emails_string)
    groups = string2list(groups_string)

    # Test whether user is the repo owner.
    if not seafile_api.is_repo_owner(username, shared_repo_id) and \
            not is_org_repo_owner(username, shared_repo_id):
        result['error'] = _(u'Only the owner of the library has permission to share it.')
        return HttpResponse(json.dumps(result), status=500, content_type=content_type)

    # Parsing input values.
    # no 'share_to_all'
    share_to_groups, share_to_users, shared_success, shared_failed = [], [], [], []

    for email in emails:
        email = email.lower()
        if is_valid_username(email):
            share_to_users.append(email)
        else:
            shared_failed.append(email)

    for group_id in groups:
        share_to_groups.append(seaserv.get_group(group_id))

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        if share_to_user(request, shared_repo, email, perm):
            shared_success.append(email)
        else:
            shared_failed.append(email)

    for group in share_to_groups:
        if share_to_group(request, shared_repo, group, perm):
            shared_success.append(group.group_name)
        else:
            shared_failed.append(group.group_name)

    if len(shared_success) > 0:
        return HttpResponse(json.dumps({
            "shared_success": shared_success,
            "shared_failed": shared_failed
            }), content_type=content_type)
    else:
        # for case: only share to users and the emails are not valid
        data = json.dumps({"error": _("Please check the email(s) you entered")})
        return HttpResponse(data, status=400, content_type=content_type)
Example #17
0
def share_repo(request):
    """
    Handle POST method to share a repo to public/groups/users based on form
    data. Return to ``myhome`` page and notify user whether success or failure.
    """
    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT

    form = RepoShareForm(request.POST)
    if not form.is_valid():
        # TODO: may display error msg on form
        raise Http404

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']

    repo = seafile_api.get_repo(repo_id)
    if not repo:
        raise Http404

    # Test whether user is the repo owner.
    username = request.user.username
    if not seafile_api.is_repo_owner(username, repo_id) and \
            not is_org_repo_owner(username, repo_id):
        msg = _(u'Only the owner of the library has permission to share it.')
        messages.error(request, msg)
        return HttpResponseRedirect(next)

    # Parsing input values.
    share_to_all, share_to_groups, share_to_users = False, [], []
    user_groups = request.user.joined_groups
    share_to_list = string2list(email_or_group)
    for share_to in share_to_list:
        if share_to == 'all':
            share_to_all = True
        elif share_to.find('@') == -1:
            for user_group in user_groups:
                if user_group.group_name == share_to:
                    share_to_groups.append(user_group)
        else:
            share_to = share_to.lower()
            if is_valid_username(share_to):
                share_to_users.append(share_to)

    origin_repo_id, origin_path = get_origin_repo_info(repo.id)
    if origin_repo_id is not None:
        perm_repo_id = origin_repo_id
        perm_path = origin_path
    else:
        perm_repo_id = repo.id
        perm_path = '/'

    if share_to_all:
        share_to_public(request, repo, permission)
        send_perm_audit_msg('add-repo-perm', username, 'all', \
                            perm_repo_id, perm_path, permission)

    for group in share_to_groups:
        if share_to_group(request, repo, group, permission):
            send_perm_audit_msg('add-repo-perm', username, group.id, \
                                perm_repo_id, perm_path, permission)

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        if share_to_user(request, repo, email, permission):
            send_perm_audit_msg('add-repo-perm', username, email, \
                                perm_repo_id, perm_path, permission)

    return HttpResponseRedirect(next)
Example #18
0
def share_repo(request):
    """
    Handle POST method to share a repo to public/groups/users based on form
    data. Return to ``myhome`` page and notify user whether success or failure.
    """
    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT

    form = RepoShareForm(request.POST)
    if not form.is_valid():
        # TODO: may display error msg on form
        raise Http404

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']

    repo = seafile_api.get_repo(repo_id)
    if not repo:
        raise Http404

    # Test whether user is the repo owner.
    username = request.user.username
    if not seafile_api.is_repo_owner(username, repo_id) and \
            not is_org_repo_owner(username, repo_id):
        msg = _(u'Only the owner of the library has permission to share it.')
        messages.error(request, msg)
        return HttpResponseRedirect(next)

    # Parsing input values.
    share_to_all, share_to_groups, share_to_users = False, [], []
    user_groups = request.user.joined_groups
    share_to_list = string2list(email_or_group)
    for share_to in share_to_list:
        if share_to == 'all':
            share_to_all = True
        elif share_to.find('@') == -1:
            for user_group in user_groups:
                if user_group.group_name == share_to:
                    share_to_groups.append(user_group)
        else:
            share_to = share_to.lower()
            if is_valid_username(share_to):
                share_to_users.append(share_to)

    if share_to_all:
        share_to_public(request, repo, permission)

    if not check_user_share_quota(
            username, repo, users=share_to_users, groups=share_to_groups):
        messages.error(
            request,
            _('Failed to share "%s", no enough quota. <a href="http://seafile.com/">Upgrade account.</a>'
              ) % repo.name)
        return HttpResponseRedirect(next)

    for group in share_to_groups:
        share_to_group(request, repo, group, permission)

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        share_to_user(request, repo, email, permission)

    return HttpResponseRedirect(next)
Example #19
0
def ajax_repo_remove_share(request):
    """
    Remove repo shared to user/group/public
    """
    content_type = 'application/json; charset=utf-8'

    repo_id = request.POST.get('repo_id', None)
    share_type = request.POST.get('share_type', None)

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

    username = request.user.username

    if share_type == 'personal':

        from_email = request.POST.get('from', None)
        if not is_valid_username(from_email):
            return HttpResponse(json.dumps({'error': _(u'Invalid argument')}),
                                status=400,
                                content_type=content_type)

        if is_org_context(request):
            org_id = request.user.org.org_id
            org_remove_share(org_id, repo_id, from_email, username)
        else:
            seaserv.remove_share(repo_id, from_email, username)
        return HttpResponse(json.dumps({'success': True}),
                            status=200,
                            content_type=content_type)

    elif share_type == 'group':

        from_email = request.POST.get('from', None)
        if not is_valid_username(from_email):
            return HttpResponse(json.dumps({'error': _(u'Invalid argument')}),
                                status=400,
                                content_type=content_type)

        group_id = request.POST.get('group_id', None)
        group = seaserv.get_group(group_id)
        if not group:
            return HttpResponse(json.dumps(
                {'error': _(u"Group does not exist")}),
                                status=400,
                                content_type=content_type)

        if seaserv.check_group_staff(group_id, username) or \
            seafile_api.is_repo_owner(username, repo_id):
            if is_org_group(group_id):
                org_id = get_org_id_by_group(group_id)
                del_org_group_repo(repo_id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(repo_id, group_id, from_email)
            return HttpResponse(json.dumps({'success': True}),
                                status=200,
                                content_type=content_type)
        else:
            return HttpResponse(json.dumps({'error': _(u'Permission denied')}),
                                status=400,
                                content_type=content_type)

    elif share_type == 'public':

        if is_org_context(request):

            org_repo_owner = seafile_api.get_org_repo_owner(repo_id)
            is_org_repo_owner = True if org_repo_owner == username else False
            if request.user.org.is_staff or is_org_repo_owner:
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(
                    org_id, repo_id)
                return HttpResponse(json.dumps({'success': True}),
                                    status=200,
                                    content_type=content_type)
            else:
                return HttpResponse(json.dumps(
                    {'error': _(u'Permission denied')}),
                                    status=403,
                                    content_type=content_type)

        else:
            if seafile_api.is_repo_owner(username, repo_id) or \
                request.user.is_staff:
                unset_inner_pub_repo(repo_id)
                return HttpResponse(json.dumps({'success': True}),
                                    status=200,
                                    content_type=content_type)
            else:
                return HttpResponse(json.dumps(
                    {'error': _(u'Permission denied')}),
                                    status=403,
                                    content_type=content_type)
    else:
        return HttpResponse(json.dumps({'error': _(u'Invalid argument')}),
                            status=400,
                            content_type=content_type)
def test_repo_manipulation():

    #test get_system_default_repo_id
    t_default_repo_id = api.get_system_default_repo_id()
    assert t_default_repo_id

    #test create_repo
    t_repo_id = api.create_repo('test_repo_manipulation',
                                '',
                                USER,
                                passwd=None)
    assert t_repo_id

    #test counts_repo
    t_repo_count = 0
    t_repo_count = api.count_repos()
    assert t_repo_count != 0

    #test get_repo ,edit_repo
    t_new_name = 'n_name'
    t_new_desc = 'n_desc'
    t_repo_version = 1
    t_repo = api.get_repo(t_repo_id)
    assert t_repo

    api.edit_repo(t_repo_id, t_new_name, t_new_desc, USER)
    t_repo = api.get_repo(t_repo_id)
    assert t_repo.name == t_new_name and t_repo.desc == t_new_desc

    #test revert_repo and get_commit
    t_commit_id_before_changing = t_repo.head_cmmt_id

    api.post_dir(t_repo_id, '/', 'dir1', USER)
    t_repo = api.get_repo(t_repo_id)

    api.revert_repo(t_repo_id, t_commit_id_before_changing, USER)

    t_repo = api.get_repo(t_repo_id)
    t_commit_id_after_revert = t_repo.head_cmmt_id

    t_commit_before_changing = api.get_commit(t_repo_id, t_repo_version,
                                              t_commit_id_before_changing)
    t_commit_after_revert = api.get_commit(t_repo_id, t_repo_version,
                                           t_commit_id_after_revert)
    assert t_commit_before_changing.root_id == t_commit_after_revert.root_id

    #test is_repo_owner
    assert api.is_repo_owner(USER, t_repo_id)
    assert api.is_repo_owner(USER2, t_repo_id) == 0

    #test get_repo_owner
    owner_get = api.get_repo_owner(t_repo_id)
    assert owner_get == USER

    #test set_repo_owner
    api.set_repo_owner(t_repo_id, USER2)
    assert api.is_repo_owner(USER2, t_repo_id)

    #test create_enc_repo
    t_enc_repo_id = '826d1b7b-f110-46f2-8d5e-7b5ac3e11f4d'
    t_enc_version = 2
    t_passwd = '123'
    magic_and_random_key = api.generate_magic_and_random_key(
        t_enc_version, t_enc_repo_id, t_passwd)
    t_magic = magic_and_random_key.magic
    t_random_key = magic_and_random_key.random_key
    t_enc_repo_id = api.create_enc_repo(t_enc_repo_id, 'test_encrypted_repo',
                                        '', USER, t_magic, t_random_key,
                                        t_enc_version)
    assert t_enc_repo_id == '826d1b7b-f110-46f2-8d5e-7b5ac3e11f4d'

    #test get_repo_list
    t_start = -1
    t_limit = -1
    t_repo_list = api.get_repo_list(t_start, t_limit)
    assert t_repo_list and len(t_repo_list)

    t_start = 1
    t_limit = 1
    t_repo_list = api.get_repo_list(t_start, t_limit)
    assert t_repo_list and len(t_repo_list) == 1

    #test get_owned_repo_list
    t_repo_list = api.get_owned_repo_list(USER2)
    assert t_repo_list and len(t_repo_list)

    #test get_commit_list
    t_offset = 0
    t_limit = 0
    t_commit_list = api.get_commit_list(t_repo_id, t_offset, t_limit)
    assert t_commit_list and len(t_commit_list) == 4

    t_offset = 1
    t_limit = 1
    t_commit_list = api.get_commit_list(t_repo_id, t_offset, t_limit)
    assert t_commit_list and len(t_commit_list) == 1

    #test remove_repo
    api.remove_repo(t_repo_id)
    t_repo = api.get_repo(t_repo_id)
    assert t_repo == None
Example #21
0
    def delete(self, request, repo_id, format=None):

        if not seafile_api.get_repo(repo_id):
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'Library does not exist')

        username = request.user.username
        share_type = request.GET.get('share_type', None)
        if share_type == 'personal':

            from_email = request.GET.get('from', None)
            if not is_valid_username(from_email):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'Invalid argument')

            if is_org_context(request):
                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.org_remove_share(
                    org_id, repo_id, from_email, username)
            else:
                seaserv.remove_share(repo_id, from_email, username)

        elif share_type == 'group':

            from_email = request.GET.get('from', None)
            if not is_valid_username(from_email):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'Invalid argument')

            group_id = request.GET.get('group_id', None)
            group = seaserv.get_group(group_id)
            if not group:
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'Group does not exist')

            if not seaserv.check_group_staff(group_id, username) and \
                not seafile_api.is_repo_owner(username, repo_id):
                return api_error(status.HTTP_403_FORBIDDEN,
                                 'Permission denied')

            if seaserv.is_org_group(group_id):
                org_id = seaserv.get_org_id_by_group(group_id)
                seaserv.del_org_group_repo(repo_id, org_id, group_id)
            else:
                seafile_api.unset_group_repo(repo_id, group_id, from_email)

        elif share_type == 'public':

            if is_org_context(request):
                org_repo_owner = seafile_api.get_org_repo_owner(repo_id)
                is_org_repo_owner = True if org_repo_owner == username else False

                if not request.user.org.is_staff and not is_org_repo_owner:
                    return api_error(status.HTTP_403_FORBIDDEN,
                                     'Permission denied')

                org_id = request.user.org.org_id
                seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(
                    org_id, repo_id)
            else:
                if not seafile_api.is_repo_owner(username, repo_id) and \
                    not request.user.is_staff:
                    return api_error(status.HTTP_403_FORBIDDEN,
                                     'Permission denied')

                seaserv.unset_inner_pub_repo(repo_id)
        else:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid argument')

        return Response({'success': True}, status=status.HTTP_200_OK)
Example #22
0
def render_repo(request, repo):
    """Steps to show repo page:
    If user has permission to view repo
      If repo is encrypt and password is not set on server
        return decrypt repo page
      If repo is not encrypt or password is set on server
        Show repo direntries based on requested path
    If user does not have permission to view repo
      return permission deny page

    """
    username = request.user.username
    user_perm = check_repo_access_permission(repo.id, username)
    if user_perm is None:
        return render_to_response('repo_access_deny.html', {
                'repo': repo,
                }, context_instance=RequestContext(request))

    if repo.encrypted and not is_password_set(repo.id, username):
        return render_to_response('decrypt_repo_form.html', {
                'repo': repo,
                'next': get_next_url_from_request(request) or \
                    reverse('repo', args=[repo.id])
                }, context_instance=RequestContext(request))

    # query context args
    applet_root = get_ccnetapplet_root()
    httpserver_root = get_httpserver_root()
    max_upload_file_size = MAX_UPLOAD_FILE_SIZE
    
    protocol = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain
    path = get_path_from_request(request)

    contacts = Contact.objects.get_contacts_by_user(username)
    accessible_repos = [repo] if repo.encrypted else get_unencry_rw_repos_by_user(username)

    head_commit = get_commit(repo.head_cmmt_id)
    if not head_commit:
        raise Http404
    repo_size = get_repo_size(repo.id)
    no_quota = is_no_quota(repo.id)
    history_limit = seaserv.get_repo_history_limit(repo.id)
    search_repo_id = None if repo.encrypted else repo.id
    
    is_repo_owner = seafile_api.is_repo_owner(username, repo.id)
    file_list, dir_list = get_repo_dirents(request, repo.id, head_commit, path)
    zipped = get_nav_path(path, repo.name)
    repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
    if len(repo_groups) > 1:
        repo_group_str = render_to_string("snippets/repo_group_list.html",
                                          {'groups': repo_groups})
    else:
        repo_group_str = ''
    upload_url = get_upload_url(request, repo.id)
    update_url = get_update_url(request, repo.id)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_shared_link(request, fileshare)

    return render_to_response('repo.html', {
            'repo': repo,
            'user_perm': user_perm,
            'is_repo_owner': is_repo_owner,
            'current_commit': head_commit,
            'password_set': True,
            'repo_size': repo_size,
            'dir_list': dir_list,
            'file_list': file_list,
            'path': path,
            'zipped': zipped,
            'accessible_repos': accessible_repos,
            'applet_root': applet_root,
            'groups': repo_groups,
            'repo_group_str': repo_group_str,
            'no_quota': no_quota,
            'max_upload_file_size': max_upload_file_size,
            'upload_url': upload_url,
            'update_url': update_url,
            'httpserver_root': httpserver_root,
            'protocol': protocol,
            'domain': domain,
            'contacts': contacts,
            'fileshare': fileshare,
            'dir_shared_link': dir_shared_link,
            'history_limit': history_limit,
            'search_repo_id': search_repo_id,
            }, context_instance=RequestContext(request))
Example #23
0
def share_repo(request):
    """
    Handle POST method to share a repo to public/groups/users based on form
    data. Return to ``myhome`` page and notify user whether success or failure.
    """
    next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = SITE_ROOT

    form = RepoShareForm(request.POST)
    if not form.is_valid():
        # TODO: may display error msg on form
        raise Http404

    email_or_group = form.cleaned_data['email_or_group']
    repo_id = form.cleaned_data['repo_id']
    permission = form.cleaned_data['permission']

    repo = seafile_api.get_repo(repo_id)
    if not repo:
        raise Http404

    # Test whether user is the repo owner.
    username = request.user.username
    if not seafile_api.is_repo_owner(username, repo_id) and \
            not is_org_repo_owner(username, repo_id):
        msg = _(u'Only the owner of the library has permission to share it.')
        messages.error(request, msg)
        return HttpResponseRedirect(next)

    # Parsing input values.
    share_to_all, share_to_groups, share_to_users = False, [], []
    user_groups = request.user.joined_groups
    share_to_list = string2list(email_or_group)
    for share_to in share_to_list:
        if share_to == 'all':
            share_to_all = True
        elif share_to.find('@') == -1:
            for user_group in user_groups:
                if user_group.group_name == share_to:
                    share_to_groups.append(user_group)
        else:
            share_to = share_to.lower()
            if is_valid_username(share_to):
                share_to_users.append(share_to)

    if share_to_all:
        share_to_public(request, repo, permission)

    if not check_user_share_quota(username, repo, users=share_to_users,
                                  groups=share_to_groups):
        messages.error(request, _('Failed to share "%s", no enough quota. <a href="http://seafile.com/">Upgrade account.</a>') % repo.name)
        return HttpResponseRedirect(next)

    for group in share_to_groups:
        share_to_group(request, repo, group, permission)

    for email in share_to_users:
        # Add email to contacts.
        mail_sended.send(sender=None, user=request.user.username, email=email)
        share_to_user(request, repo, email, permission)

    return HttpResponseRedirect(next)
Example #24
0
    def post(self, request, format=None):
        """Add a new wiki.
        """
        use_exist_repo = request.POST.get('use_exist_repo', '')
        if not use_exist_repo:
            msg = 'Use exist repo is invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        name = request.POST.get('name', '')
        if not name:
            msg = 'Name is invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        if not is_valid_wiki_name(name):
            msg = _(
                'Name can only contain letters, numbers, blank, hyphen or underscore.'
            )
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        username = request.user.username

        org_id = -1
        if is_org_context(request):
            org_id = request.user.org.org_id

        if use_exist_repo == 'false':
            try:
                wiki = Wiki.objects.add(name, username, org_id=org_id)
            except DuplicateWikiNameError:
                msg = _(
                    '%s is taken by others, please try another name.') % name
                return api_error(status.HTTP_400_BAD_REQUEST, msg)
            except IntegrityError:
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

            # create home page
            page_name = "home.md"
            try:
                seafile_api.post_empty_file(wiki.repo_id, '/', page_name,
                                            request.user.username)
            except SearpcError as e:
                logger.error(e)
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

            return Response(wiki.to_dict())

        if use_exist_repo == 'true':
            repo_id = request.POST.get('repo_id', '')
            if not repo_id:
                msg = 'Repo id is invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, msg)

            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)

            # repo owner
            is_repo_owner = seafile_api.is_repo_owner(username, repo_id)

            if not is_repo_owner:
                repo_admin = is_repo_admin(username, repo_id)

                if not repo_admin:
                    is_group_repo_admin = is_group_repo_staff(
                        repo_id, username)

                    if not is_group_repo_admin:
                        error_msg = _('Permission denied.')
                        return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            try:
                wiki = Wiki.objects.add(wiki_name=repo.repo_name,
                                        username=username,
                                        repo_id=repo.repo_id,
                                        org_id=org_id)
            except DuplicateWikiNameError:
                msg = _('%s is taken by others, please try another name.'
                        ) % repo.repo_name
                return api_error(status.HTTP_400_BAD_REQUEST, msg)
            except IntegrityError:
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

            # create home page if not exist
            page_name = "home.md"
            if not seafile_api.get_file_id_by_path(repo_id, "/" + page_name):
                try:
                    seafile_api.post_empty_file(repo_id, '/', page_name,
                                                username)
                except SearpcError as e:
                    logger.error(e)
                    msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     msg)

            return Response(wiki.to_dict())