Example #1
0
def download_file(request, repo_id, obj_id):
    """Download file.

    Arguments:
    - `request`:
    - `repo_id`:
    - `obj_id`:
    """
    username = request.user.username
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if repo.encrypted and not seafile_api.is_password_set(repo_id, username):
        return HttpResponseRedirect(reverse('repo', args=[repo_id]))

    # If vistor's file shared token in url params matches the token in db,
    # then we know the vistor is from file shared link.
    share_token = request.GET.get('t', '')
    fileshare = FileShare.objects.get(
        token=share_token) if share_token else None
    shared_by = None
    if fileshare:
        from_shared_link = True
        shared_by = fileshare.username
    else:
        from_shared_link = False

    if from_shared_link:
        # check whether owner's traffic over the limit
        if user_traffic_over_limit(fileshare.username):
            messages.error(
                request,
                _(u'Unable to access file: share link traffic is used up.'))
            next = request.META.get('HTTP_REFERER', settings.SITE_ROOT)
            return HttpResponseRedirect(next)

    # Permission check and generate download link
    path = request.GET.get('p', '')
    if check_repo_access_permission(repo_id, request.user) or \
            get_file_access_permission(repo_id, path, username) or from_shared_link:
        # Get a token to access file
        token = seafserv_rpc.web_get_access_token(repo_id, obj_id, 'download',
                                                  username)
    else:
        messages.error(request, _(u'Unable to download file'))
        next = request.META.get('HTTP_REFERER', settings.SITE_ROOT)
        return HttpResponseRedirect(next)

    # send stats message
    if from_shared_link:
        try:
            file_size = seafile_api.get_file_size(repo.store_id, repo.version,
                                                  obj_id)
            send_message(
                'seahub.stats', 'file-download\t%s\t%s\t%s\t%s' %
                (repo.id, shared_by, obj_id, file_size))
        except Exception, e:
            logger.error('Error when sending file-download message: %s' %
                         str(e))
Example #2
0
def repo_revert_history(request, repo_id):

    next_page = request.META.get('HTTP_REFERER', None)
    if not next_page:
        next_page = settings.SITE_ROOT

    repo = get_repo(repo_id)
    if not repo:
        messages.error(request, _("Library does not exist"))
        return HttpResponseRedirect(next_page)

    # perm check
    perm = check_folder_permission(request, repo_id, '/')
    username = request.user.username
    repo_owner = seafile_api.get_repo_owner(repo.id)

    if perm is None or repo_owner != username:
        messages.error(request, _("Permission denied"))
        return HttpResponseRedirect(next_page)

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    password_set = False
    if repo.props.encrypted and \
            (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)):
        try:
            ret = seafile_api.is_password_set(repo_id, username)
            if ret == 1:
                password_set = True
        except SearpcError as e:
            return render_error(request, e.msg)

        if not password_set:
            reverse_url = reverse('lib_view', args=[repo_id, repo.name, ''])
            return HttpResponseRedirect(reverse_url)

    commit_id = request.GET.get('commit_id', '')
    if not commit_id:
        return render_error(request, _('Please specify history ID'))

    try:
        seafserv_threaded_rpc.revert_on_server(repo_id, commit_id,
                                               request.user.username)
        messages.success(request, _('Successfully restored the library.'))
    except SearpcError as e:
        if e.msg == 'Bad arguments':
            return render_error(request, _('Invalid arguments.'))
        elif e.msg == 'No such repo':
            return render_error(request, _('Library does not exist'))
        elif e.msg == "Commit doesn't exist":
            return render_error(request,
                                _('History you specified does not exist'))
        else:
            return render_error(request, _('Unknown error'))

    return HttpResponseRedirect(next_page)
Example #3
0
    def _decorated(request, *args, **kwargs):
        repo_id = kwargs.get('repo_id', None)
        if not repo_id:
            raise Exception('Repo id is not found in url.')
        repo = get_repo(repo_id)
        if not repo:
            raise Http404
        username = request.user.username
        if repo.encrypted:
            try:
                server_crypto = UserOptions.objects.is_server_crypto(username)
            except CryptoOptionNotSetError:
                return render(request, 'options/set_user_options.html', {})

            if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
                    and not seafile_api.is_password_set(repo_id, username):
                return render(request, 'decrypt_repo_form.html', {
                    'repo': repo,
                    'next': request.get_full_path(),
                })

            if repo.enc_version == 2 and not server_crypto:
                return render_error(
                    request,
                    _('Files in this library can not be viewed online.'))

        return func(request, *args, **kwargs)
Example #4
0
def repo_history_changes(request, repo_id):
    changes = {}
    content_type = 'application/json; charset=utf-8'

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

    # perm check
    if check_folder_permission(request, repo_id, '/') is None:
        if request.user.is_staff is True:
            pass  # Allow system staff to check repo changes
        else:
            err_msg = _("Permission denied")
            return HttpResponse(json.dumps({"error": err_msg}),
                                status=403,
                                content_type=content_type)

    username = request.user.username
    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    if repo.encrypted and \
            (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
            and not seafile_api.is_password_set(repo_id, username):
        err_msg = _('Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403,
                            content_type=content_type)

    commit_id = request.GET.get('commit_id', '')
    if not commit_id:
        err_msg = _('Argument missing')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=400,
                            content_type=content_type)

    changes = get_diff(repo_id, '', commit_id)

    c = get_commit(repo.id, repo.version, commit_id)
    if c.parent_id is None:
        # A commit is a first commit only if it's parent id is None.
        changes['cmt_desc'] = repo.desc
    elif c.second_parent_id is None:
        # Normal commit only has one parent.
        if c.desc.startswith('Changed library'):
            changes['cmt_desc'] = _('Changed library name or description')
    else:
        # A commit is a merge only if it has two parents.
        changes['cmt_desc'] = _('No conflict in the merge.')

    changes['date_time'] = tsstr_sec(c.ctime)

    return HttpResponse(json.dumps(changes), content_type=content_type)
Example #5
0
def list_dir_more(request, repo_id):
    """
    List 'more' entries in a directory with AJAX.
    """
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, username)
    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}),
                            status=403, content_type=content_type)

    head_commit = get_commit(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)

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

    offset = int(request.GET.get('start'))
    if not offset:
        err_msg = _(u'Argument missing')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=400, content_type=content_type)
    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset, limit=100)
    if dirent_more:
        more_start = offset + 100

    ctx = { 
        'repo': repo,
        'user_perm': user_perm,
        'path': path,
        'dir_list': dir_list,
        'file_list': file_list,
        'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
    }   
    html = render_to_string('snippets/repo_dirents.html', ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({'html': html, 'dirent_more': dirent_more, 'more_start': more_start}),
                        content_type=content_type)
Example #6
0
def test_password(encrypted_repo):

    old_passwd = '123'
    new_passwd = '456'

    assert api.set_passwd(encrypted_repo.id, encrypted_repo.name,
                          old_passwd) == 0
    assert api.get_decrypt_key(encrypted_repo.id, encrypted_repo.name)
    api.change_repo_passwd(encrypted_repo.repo_id, old_passwd, new_passwd,
                           encrypted_repo.name) == 0
    assert api.set_passwd(encrypted_repo.id, encrypted_repo.name,
                          new_passwd) == 0

    assert api.is_password_set(encrypted_repo.id, encrypted_repo.name)
    assert api.unset_passwd(encrypted_repo.id, encrypted_repo.name,
                            new_passwd) == 0
    assert api.is_password_set(encrypted_repo.id, encrypted_repo.name) == 0
Example #7
0
def test_encrypted_repo(rpc, enc_version):
    test_repo_name = 'test_enc_repo'
    test_repo_desc = 'test_enc_repo'
    test_repo_passwd = 'test_enc_repo'
    if rpc == 'create_repo':
        repo_id = api.create_repo(test_repo_name, test_repo_desc, USER,
                                  test_repo_passwd, enc_version)
        assert repo_id
    else:
        if enc_version == 2:
            repo_id = 'd17bf8ca-3019-40ee-8fdb-0258c89fb762'
        elif enc_version == 3:
            repo_id = 'd17bf8ca-3019-40ee-8fdb-0258c89fb763'
        else:
            repo_id = 'd17bf8ca-3019-40ee-8fdb-0258c89fb764'
        enc_info = api.generate_magic_and_random_key(enc_version, repo_id,
                                                     test_repo_passwd)
        assert enc_info
        ret_repo_id = api.create_enc_repo(repo_id, test_repo_name,
                                          test_repo_desc, USER, enc_info.magic,
                                          enc_info.random_key, enc_info.salt,
                                          enc_version)
        assert ret_repo_id == repo_id

    repo = api.get_repo(repo_id)
    assert repo
    assert repo.enc_version == enc_version
    assert len(repo.magic) == 64
    assert len(repo.random_key) == 96
    if enc_version == 3 or enc_version == 4:
        assert len(repo.salt) == 64

    new_passwd = 'new password'

    assert api.set_passwd(repo.id, USER, test_repo_passwd) == 0
    assert api.get_decrypt_key(repo.id, USER)
    api.change_repo_passwd(repo.repo_id, test_repo_passwd, new_passwd,
                           USER) == 0
    assert api.set_passwd(repo.id, USER, new_passwd) == 0

    assert api.is_password_set(repo.id, USER)
    assert api.unset_passwd(repo.id, USER) == 0
    assert api.is_password_set(repo.id, USER) == 0

    api.remove_repo(repo_id)
Example #8
0
    def get(self, request, repo_id):
        """ Return repo 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 permission is None:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        username = request.user.username

        lib_need_decrypt = False
        if repo.encrypted \
                and not seafile_api.is_password_set(repo.id, username):
            lib_need_decrypt = True

        repo_owner = get_repo_owner(request, repo_id)

        try:
            has_been_shared_out = repo_has_been_shared_out(request, repo_id)
        except Exception as e:
            has_been_shared_out = False
            logger.error(e)

        result = {
            "repo_id": repo.id,
            "repo_name": repo.name,

            "owner_email": repo_owner,
            "owner_name": email2nickname(repo_owner),
            "owner_contact_email": email2contact_email(repo_owner),

            "size": repo.size,
            "encrypted": repo.encrypted,
            "file_count": repo.file_count,
            "permission": permission,
            "no_quota": True if seafile_api.check_quota(repo_id) < 0 else False,
            "is_admin": is_repo_admin(username, repo_id),
            "is_virtual": repo.is_virtual,
            "has_been_shared_out": has_been_shared_out,

            "lib_need_decrypt": lib_need_decrypt,
            "last_modified": timestamp_to_isoformat_timestr(repo.last_modify),
            "status": normalize_repo_status_code(repo.status),
        }

        return Response(result)
Example #9
0
    def get(self, request, repo_id):
        """ Return repo 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 permission is None:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        username = request.user.username

        lib_need_decrypt = False
        if repo.encrypted \
                and not seafile_api.is_password_set(repo.id, username):
            lib_need_decrypt = True

        repo_owner = get_repo_owner(request, repo_id)

        try:
            has_been_shared_out = repo_has_been_shared_out(request, repo_id)
        except Exception as e:
            has_been_shared_out = False
            logger.error(e)

        result = {
            "repo_id": repo.id,
            "repo_name": repo.name,

            "owner_email": repo_owner,
            "owner_name": email2nickname(repo_owner),
            "owner_contact_email": email2contact_email(repo_owner),

            "size": repo.size,
            "encrypted": repo.encrypted,
            "file_count": repo.file_count,
            "permission": permission,
            "no_quota": True if seafile_api.check_quota(repo_id) < 0 else False,
            "is_admin": is_repo_admin(username, repo_id),
            "is_virtual": repo.is_virtual,
            "has_been_shared_out": has_been_shared_out,

            "lib_need_decrypt": lib_need_decrypt,
            "last_modified": timestamp_to_isoformat_timestr(repo.last_modify),
        }

        return Response(result)
Example #10
0
def download_file(request, repo_id, obj_id):
    """Download file.

    Arguments:
    - `request`:
    - `repo_id`:
    - `obj_id`:
    """
    username = request.user.username
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if repo.encrypted and not seafile_api.is_password_set(repo_id, username):
        return HttpResponseRedirect(reverse("repo", args=[repo_id]))

    # If vistor's file shared token in url params matches the token in db,
    # then we know the vistor is from file shared link.
    share_token = request.GET.get("t", "")
    fileshare = FileShare.objects.get(token=share_token) if share_token else None
    shared_by = None
    if fileshare:
        from_shared_link = True
        shared_by = fileshare.username
    else:
        from_shared_link = False

    if from_shared_link:
        # check whether owner's traffic over the limit
        if user_traffic_over_limit(fileshare.username):
            messages.error(request, _(u"Unable to access file: share link traffic is used up."))
            next = request.META.get("HTTP_REFERER", settings.SITE_ROOT)
            return HttpResponseRedirect(next)

    # Permission check and generate download link
    path = request.GET.get("p", "")
    if (
        check_repo_access_permission(repo_id, request.user)
        or get_file_access_permission(repo_id, path, username)
        or from_shared_link
    ):
        # Get a token to access file
        token = seafserv_rpc.web_get_access_token(repo_id, obj_id, "download", username)
    else:
        messages.error(request, _(u"Unable to download file"))
        next = request.META.get("HTTP_REFERER", settings.SITE_ROOT)
        return HttpResponseRedirect(next)

    # send stats message
    if from_shared_link:
        try:
            file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)
            send_message("seahub.stats", "file-download\t%s\t%s\t%s\t%s" % (repo.id, shared_by, obj_id, file_size))
        except Exception, e:
            logger.error("Error when sending file-download message: %s" % str(e))
Example #11
0
def get_current_commit(request, repo_id):
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, request.user)
    if user_perm is None:
        err_msg = _(u'Permission denied.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403,
                            content_type=content_type)

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

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

    head_commit = get_commit(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)
    if new_merge_with_no_conflict(head_commit):
        head_commit = get_commit_before_new_merge(head_commit)

    ctx = {'repo': repo, 'current_commit': head_commit}
    html = render_to_string('snippets/current_commit.html',
                            ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({'html': html}), content_type=content_type)
Example #12
0
    def post(self, request, repo_id, commit_id, format=None):
        """ revert commit in repo history

        Permission checking:
        1. only repo owner can perform this action.
        """
        username = request.user.username

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

        commit = seafile_api.get_commit(repo.id, repo.version, commit_id)
        if not commit:
            error_msg = 'Commit %s not found.' % commit_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        has_perm = is_repo_owner(request, repo.id, username)
        if not has_perm:
            repo_owner = get_repo_owner(request, repo_id)
            # department admin
            if '@seafile_group' in repo_owner:
                group_id = get_group_id_by_repo_owner(repo_owner)
                has_perm = is_group_admin(group_id, username)
        if not has_perm:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # main
        if repo.encrypted:
            ret = seafile_api.is_password_set(repo_id, username)
            is_decrypted = False if ret == 0 else True

            if not is_decrypted:
                error_msg = _('This library has not been decrypted.')
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            seafile_api.revert_repo(repo_id, commit_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)

        return Response({'success': True})
Example #13
0
def get_current_commit(request, repo_id):
    if not request.is_ajax():
        raise Http404
    
    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, request.user)
    if user_perm is None:
        err_msg = _(u'Permission denied.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403, content_type=content_type)

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False   
    
    if repo.encrypted and \
            (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
            and not seafile_api.is_password_set(repo.id, username):
        err_msg = _(u'Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403, content_type=content_type)

    head_commit = get_commit(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)
    if new_merge_with_no_conflict(head_commit):
        head_commit = get_commit_before_new_merge(head_commit)

    ctx = { 
        'repo': repo,
        'current_commit': head_commit
    }   
    html = render_to_string('snippets/current_commit.html', ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({'html': html}),
                        content_type=content_type)
Example #14
0
def get_current_commit(request, repo_id):
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, username)
    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 \
            (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \
            and not seafile_api.is_password_set(repo.id, username):
        err_msg = _(u'Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403,
                            content_type=content_type)

    head_commit = get_commit(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)

    ctx = {'repo': repo, 'current_commit': head_commit}
    html = render_to_string('snippets/current_commit.html',
                            ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({'html': html}), content_type=content_type)
Example #15
0
    def _get_events_inner(ev_session, username, start, limit, org_id=None):
        '''Read events from seafevents database, and remove events that are
        no longer valid

        Return 'limit' events or less than 'limit' events if no more events remain
        '''
        valid_events = []
        next_start = start
        while True:
            if org_id > 0:
                events = seafevents.get_org_user_events(
                    ev_session, org_id, username, next_start, limit)
            else:
                events = seafevents.get_user_events(ev_session, username,
                                                    next_start, limit)
            if not events:
                break

            for ev in events:
                if ev.etype == 'repo-update':
                    repo = seafile_api.get_repo(ev.repo_id)
                    if not repo:
                        # delete the update event for repo which has been deleted
                        seafevents.delete_event(ev_session, ev.uuid)
                        continue
                    if repo.encrypted:
                        repo.password_set = seafile_api.is_password_set(
                            repo.id, username)
                    ev.repo = repo
                    ev.commit = seaserv.get_commit(repo.id, repo.version,
                                                   ev.commit_id)

                valid_events.append(ev)
                if len(valid_events) == limit:
                    break

            if len(valid_events) == limit:
                break
            next_start = next_start + len(valid_events)

        return valid_events
Example #16
0
    def _get_events_inner(ev_session, username, start, limit, org_id=None):
        '''Read events from seafevents database, and remove events that are
        no longer valid

        Return 'limit' events or less than 'limit' events if no more events remain
        '''
        valid_events = []
        next_start = start
        while True:
            if org_id > 0:
                events = seafevents.get_org_user_events(ev_session, org_id,
                                                        username, next_start,
                                                        limit)
            else:
                events = seafevents.get_user_events(ev_session, username,
                                                    next_start, limit)
            if not events:
                break

            for ev in events:
                if ev.etype == 'repo-update':
                    repo = seafile_api.get_repo(ev.repo_id)
                    if not repo:
                        # delete the update event for repo which has been deleted
                        seafevents.delete_event(ev_session, ev.uuid)
                        continue
                    if repo.encrypted:
                        repo.password_set = seafile_api.is_password_set(
                            repo.id, username)
                    ev.repo = repo
                    ev.commit = seaserv.get_commit(repo.id, repo.version, ev.commit_id)

                valid_events.append(ev)
                if len(valid_events) == limit:
                    break

            if len(valid_events) == limit:
                break
            next_start = next_start + len(valid_events)

        return valid_events
Example #17
0
    def remove_org_repo_passwds(self, org_id):
        """
        Remove all org repo decryption passwords stored on server.
        """
        from seahub.utils import get_user_repos
        owned_repos, shared_repos, groups_repos, public_repos = get_user_repos(self.email, org_id=org_id)

        def has_repo(repos, repo):
            for r in repos:
                if repo.id == r.id:
                    return True
            return False

        passwd_setted_repos = []
        for r in owned_repos + shared_repos + groups_repos + public_repos:
            if not has_repo(passwd_setted_repos, r) and r.encrypted and \
                    seafile_api.is_password_set(r.id, self.email):
                passwd_setted_repos.append(r)

        for r in passwd_setted_repos:
            unset_repo_passwd(r.id, self.email)
Example #18
0
def get_current_commit(request, repo_id):
    if not request.is_ajax():
        raise Http404
    
    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, username)
    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 \
            (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \
            and not seafile_api.is_password_set(repo.id, username):
        err_msg = _(u'Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403, content_type=content_type)

    head_commit = get_commit(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)

    ctx = { 
        'repo': repo,
        'current_commit': head_commit
    }   
    html = render_to_string('snippets/current_commit.html', ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({'html': html}),
                        content_type=content_type)
Example #19
0
def file_edit(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if request.method == 'POST':
        return file_edit_submit(request, repo_id)

    if check_repo_access_permission(repo_id, request.user) != 'rw':
        return render_permission_error(request, _(u'Unable to edit file'))

    path = request.GET.get('p', '/')
    if path[-1] == '/':
        path = path[:-1]
    u_filename = os.path.basename(path)
    filename = urllib2.quote(u_filename.encode('utf-8'))

    head_id = repo.head_cmmt_id

    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'The file does not exist.'))

    token = web_get_access_token(repo_id, obj_id, 'view',
                                 request.user.username)

    # generate path and link
    zipped = gen_path_link(path, repo.name)

    filetype, fileext = get_file_type_and_ext(filename)

    op = None
    err = ''
    file_content = None
    encoding = None
    file_encoding_list = FILE_ENCODING_LIST
    if filetype == TEXT or filetype == MARKDOWN or filetype == SF:
        if repo.encrypted:
            repo.password_set = seafile_api.is_password_set(
                repo_id, request.user.username)
            if not repo.password_set:
                op = 'decrypt'
        if not op:
            inner_path = gen_inner_file_get_url(token, filename)
            file_enc = request.GET.get('file_enc', 'auto')
            if not file_enc in FILE_ENCODING_LIST:
                file_enc = 'auto'
            err, file_content, encoding = repo_file_get(inner_path, file_enc)
            if encoding and encoding not in FILE_ENCODING_LIST:
                file_encoding_list.append(encoding)
    else:
        err = _(u'Edit online is not offered for this type of file.')

    # Redirect to different place according to from page when user click
    # cancel button on file edit page.
    cancel_url = reverse('repo_view_file', args=[repo.id
                                                 ]) + '?p=' + urlquote(path)
    page_from = request.GET.get('from', '')
    gid = request.GET.get('gid', '')
    wiki_name = os.path.splitext(u_filename)[0]
    if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new':
        cancel_url = reverse('group_wiki', args=[gid, wiki_name])
    elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new':
        cancel_url = reverse('personal_wiki', args=[wiki_name])

    return render_to_response('file_edit.html', {
        'repo': repo,
        'u_filename': u_filename,
        'wiki_name': wiki_name,
        'path': path,
        'zipped': zipped,
        'filetype': filetype,
        'fileext': fileext,
        'op': op,
        'err': err,
        'file_content': file_content,
        'encoding': encoding,
        'file_encoding_list': file_encoding_list,
        'head_id': head_id,
        'from': page_from,
        'gid': gid,
        'cancel_url': cancel_url,
    },
                              context_instance=RequestContext(request))
Example #20
0
def file_edit_submit(request, repo_id):
    content_type = 'application/json; charset=utf-8'

    def error_json(error_msg=_(u'Internal Error'), op=None):
        return HttpResponse(json.dumps({
            'error': error_msg,
            'op': op
        }),
                            status=400,
                            content_type=content_type)

    username = request.user.username
    if check_repo_access_permission(repo_id, request.user) != 'rw':
        return error_json(_(u'Permission denied'))

    repo = get_repo(repo_id)
    if not repo:
        return error_json(_(u'The library does not exist.'))
    if repo.encrypted:
        repo.password_set = seafile_api.is_password_set(repo_id, username)
        if not repo.password_set:
            return error_json(_(u'The library is encrypted.'), 'decrypt')

    content = request.POST.get('content')
    encoding = request.POST.get('encoding')
    path = request.GET.get('p')

    if content is None or not path or encoding not in ["gbk", "utf-8"]:
        return error_json(_(u'Invalid arguments'))
    head_id = request.GET.get('head', None)

    content = content.encode(encoding)

    # first dump the file content to a tmp file, then update the file
    fd, tmpfile = mkstemp()

    def remove_tmp_file():
        try:
            os.remove(tmpfile)
        except:
            pass

    try:
        bytesWritten = os.write(fd, content)
    except:
        bytesWritten = -1
    finally:
        os.close(fd)

    if bytesWritten != len(content):
        remove_tmp_file()
        return error_json()

    req_from = request.GET.get('from', '')
    if req_from == 'wiki_page_edit' or req_from == 'wiki_page_new':
        try:
            gid = int(request.GET.get('gid', 0))
        except ValueError:
            gid = 0

        wiki_name = os.path.splitext(os.path.basename(path))[0]
        next = reverse('group_wiki', args=[gid, wiki_name])
    elif req_from == 'personal_wiki_page_edit' or req_from == 'personal_wiki_page_new':
        wiki_name = os.path.splitext(os.path.basename(path))[0]
        next = reverse('personal_wiki', args=[wiki_name])
    else:
        next = reverse('repo_view_file', args=[repo_id
                                               ]) + '?p=' + urlquote(path)

    parent_dir = os.path.dirname(path).encode('utf-8')
    filename = os.path.basename(path).encode('utf-8')
    try:
        seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename,
                                       username, head_id)
        remove_tmp_file()
        return HttpResponse(json.dumps({'href': next}),
                            content_type=content_type)
    except SearpcError, e:
        remove_tmp_file()
        return error_json(str(e))
Example #21
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 = _('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', '/')
    path = normalize_dir_path(path)
    dir_id = seafile_api.get_dir_id_by_path(repo.id, path)
    if not dir_id:
        err_msg = 'Folder not found.'
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=404,
                            content_type=content_type)

    # perm for current dir
    user_perm = check_folder_permission(request, repo_id, path)
    if not user_perm:
        return convert_repo_path_when_can_not_view_folder(
            request, repo_id, path)

    if repo.encrypted \
            and not seafile_api.is_password_set(repo.id, username):
        err_msg = _('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 = _('Error: no head commit id')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=500,
                            content_type=content_type)

    dir_list = []
    file_list = []

    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["repo_owner"] = repo_owner
    result["is_repo_owner"] = False
    result["has_been_shared_out"] = False
    result["is_admin"] = is_repo_admin(username, repo_id)
    if repo_owner == username:
        result["is_repo_owner"] = True
        try:
            result["has_been_shared_out"] = repo_has_been_shared_out(
                request, repo_id)
        except Exception as e:
            logger.error(e)

    if result["is_admin"]:
        result["has_been_shared_out"] = True

    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_['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

        if not repo.encrypted and ENABLE_THUMBNAIL:
            # used for providing a way to determine
            # if send a request to create thumbnail.

            fileExt = os.path.splitext(f.obj_name)[1][1:].lower()
            file_type = FILEEXT_TYPE_MAP.get(fileExt)
            if file_type == IMAGE:
                f_['is_img'] = True

            if file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL:
                f_['is_video'] = True

            if file_type == XMIND:
                f_['is_xmind'] = True

            if file_type in (IMAGE, XMIND) or \
                    file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL:
                # if thumbnail has already been created, return its src.
                # Then web browser will use this src to get thumbnail instead of
                # recreating it.
                thumbnail_file_path = os.path.join(THUMBNAIL_ROOT, str(size),
                                                   f.obj_id)
                thumbnail_exist = os.path.exists(thumbnail_file_path)
                if thumbnail_exist:
                    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)

            f_['locked_by_me'] = False
            if f.lock_owner == username:
                f_['locked_by_me'] = True

            if f.lock_owner == ONLINE_OFFICE_LOCK_OWNER and \
                    user_perm == PERMISSION_READ_WRITE:
                f_['locked_by_me'] = True

        dirent_list.append(f_)

    result["dirent_list"] = dirent_list

    return HttpResponse(json.dumps(result), content_type=content_type)
Example #22
0
def file_edit(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if request.method == "POST":
        return file_edit_submit(request, repo_id)

    if check_repo_access_permission(repo_id, request.user) != "rw":
        return render_permission_error(request, _(u"Unable to edit file"))

    path = request.GET.get("p", "/")
    if path[-1] == "/":
        path = path[:-1]
    u_filename = os.path.basename(path)
    filename = urllib2.quote(u_filename.encode("utf-8"))

    head_id = repo.head_cmmt_id

    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u"The file does not exist."))

    token = web_get_access_token(repo_id, obj_id, "view", request.user.username)

    # generate path and link
    zipped = gen_path_link(path, repo.name)

    filetype, fileext = get_file_type_and_ext(filename)

    op = None
    err = ""
    file_content = None
    encoding = None
    file_encoding_list = FILE_ENCODING_LIST
    if filetype == TEXT or filetype == MARKDOWN or filetype == SF:
        if repo.encrypted:
            repo.password_set = seafile_api.is_password_set(repo_id, request.user.username)
            if not repo.password_set:
                op = "decrypt"
        if not op:
            inner_path = gen_inner_file_get_url(token, filename)
            file_enc = request.GET.get("file_enc", "auto")
            if not file_enc in FILE_ENCODING_LIST:
                file_enc = "auto"
            err, file_content, encoding = repo_file_get(inner_path, file_enc)
            if encoding and encoding not in FILE_ENCODING_LIST:
                file_encoding_list.append(encoding)
    else:
        err = _(u"Edit online is not offered for this type of file.")

    # Redirect to different place according to from page when user click
    # cancel button on file edit page.
    cancel_url = reverse("repo_view_file", args=[repo.id]) + "?p=" + urlquote(path)
    page_from = request.GET.get("from", "")
    gid = request.GET.get("gid", "")
    wiki_name = os.path.splitext(u_filename)[0]
    if page_from == "wiki_page_edit" or page_from == "wiki_page_new":
        cancel_url = reverse("group_wiki", args=[gid, wiki_name])
    elif page_from == "personal_wiki_page_edit" or page_from == "personal_wiki_page_new":
        cancel_url = reverse("personal_wiki", args=[wiki_name])

    return render_to_response(
        "file_edit.html",
        {
            "repo": repo,
            "u_filename": u_filename,
            "wiki_name": wiki_name,
            "path": path,
            "zipped": zipped,
            "filetype": filetype,
            "fileext": fileext,
            "op": op,
            "err": err,
            "file_content": file_content,
            "encoding": encoding,
            "file_encoding_list": file_encoding_list,
            "head_id": head_id,
            "from": page_from,
            "gid": gid,
            "cancel_url": cancel_url,
        },
        context_instance=RequestContext(request),
    )
Example #23
0
def list_dir_more(request, repo_id):
    """
    List 'more' entries in a directory with AJAX.
    """
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, username)
    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 \
            (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \
           and not seafile_api.is_password_set(repo.id, username):
        err_msg = _(u'Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403,
                            content_type=content_type)

    head_commit = get_commit(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)

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

    offset = int(request.GET.get('start'))
    if not offset:
        err_msg = _(u'Argument missing')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=400,
                            content_type=content_type)
    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request,
                                                        repo.id,
                                                        head_commit,
                                                        path,
                                                        offset,
                                                        limit=100)
    if dirent_more:
        more_start = offset + 100

    ctx = {
        'repo': repo,
        'user_perm': user_perm,
        'path': path,
        'dir_list': dir_list,
        'file_list': file_list,
        'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
    }
    html = render_to_string('snippets/repo_dirents.html',
                            ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({
        'html': html,
        'dirent_more': dirent_more,
        'more_start': more_start
    }),
                        content_type=content_type)
Example #24
0
def list_dir(request, repo_id):
    """
    List directory entries in AJAX.
    """
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, username)
    if user_perm is None:
        err_msg = _(u'Permission denied.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403, content_type=content_type)

    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)

    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False   
    
    if repo.encrypted and \
            (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
            and not seafile_api.is_password_set(repo.id, username):
        err_msg = _(u'Library is encrypted.')
        return HttpResponse(json.dumps({'error': err_msg}),
                            status=403, content_type=content_type)

    head_commit = get_commit(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)

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

    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset=0, limit=100)
    if dirent_more:
        more_start = 100
    zipped = get_nav_path(path, repo.name)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_dir_share_link(fileshare)
    uploadlink = get_uploadlink(repo.id, username, path)
    dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)

    ctx = { 
        'repo': repo,
        'zipped': zipped,
        'user_perm': user_perm,
        'path': path,
        'server_crypto': server_crypto,
        'fileshare': fileshare,
        'dir_shared_link': dir_shared_link,
        'uploadlink': uploadlink,
        'dir_shared_upload_link': dir_shared_upload_link,
        'dir_list': dir_list,
        'file_list': file_list,
        'dirent_more': dirent_more,
        'more_start': more_start,
        'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
        "sub_lib_enabled": sub_lib_enabled,
    }   
    html = render_to_string('snippets/repo_dir_data.html', ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({'html': html, 'path': path}),
                        content_type=content_type)
Example #25
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)
Example #26
0
    def get(self, request, repo_id, format=None):
        """ Return history of library

        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
        if check_folder_permission(request, repo_id, '/') is None:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        username = request.user.username
        try:
            server_crypto = UserOptions.objects.is_server_crypto(username)
        except CryptoOptionNotSetError:
            # Assume server_crypto is ``False`` if this option is not set.
            server_crypto = False

        password_set = False
        if repo.encrypted and \
                (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)):
            try:
                ret = seafile_api.is_password_set(repo_id, username)
                if ret == 1:
                    password_set = True
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not password_set:
                error_msg = 'Library is encrypted, but password is not set in server.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            page = int(request.GET.get('page', '1'))
            per_page = int(request.GET.get('per_page', '100'))
        except ValueError:
            page = 1
            per_page = 100

        if page <= 0:
            error_msg = 'page invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if per_page <= 0:
            error_msg = 'per_page invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        start = (page - 1) * per_page
        limit = per_page + 1

        try:
            all_commits = seafile_api.get_commit_list(repo_id, start, limit)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        items = []
        commits = all_commits[:per_page]
        for commit in commits:
            if new_merge_with_no_conflict(commit):
                continue

            item_info = self.get_item_info(commit)
            items.append(item_info)

        commit_tag_dict = {}
        if ENABLE_REPO_SNAPSHOT_LABEL:
            try:
                revision_tags = RevisionTags.objects.filter(repo_id=repo_id)
            except Exception as e:
                logger.error(e)
                revision_tags = []

            for tag in revision_tags:
                if commit_tag_dict.has_key(tag.revision_id):
                    commit_tag_dict[tag.revision_id].append(tag.tag.name)
                else:
                    commit_tag_dict[tag.revision_id] = [tag.tag.name]

        for item in items:
            item['tags'] = []
            for commit_id, tags in commit_tag_dict.items():
                if commit_id == item['commit_id']:
                    item['tags'] = tags

        result = {
            'data': items,
            'more': True if len(all_commits) == per_page + 1 else False
        }

        return Response(result)
Example #27
0
def is_password_set(repo_id, username):
    return seafile_api.is_password_set(repo_id, username)
Example #28
0
def file_edit(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if request.method == 'POST':
        return file_edit_submit(request, repo_id)

    if check_repo_access_permission(repo_id, request.user) != 'rw':
        return render_permission_error(request, _(u'Unable to edit file'))

    path = request.GET.get('p', '/')
    if path[-1] == '/':
        path = path[:-1]
    u_filename = os.path.basename(path)
    filename = urllib2.quote(u_filename.encode('utf-8'))

    head_id = repo.head_cmmt_id

    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'The file does not exist.'))

    token = web_get_access_token(repo_id, obj_id, 'view', request.user.username)

    # generate path and link
    zipped = gen_path_link(path, repo.name)

    filetype, fileext = get_file_type_and_ext(filename)

    op = None
    err = ''
    file_content = None
    encoding = None
    file_encoding_list = FILE_ENCODING_LIST
    if filetype == TEXT or filetype == MARKDOWN or filetype == SF: 
        if repo.encrypted:
            repo.password_set = seafile_api.is_password_set(repo_id, request.user.username)
            if not repo.password_set:
                op = 'decrypt'
        if not op:
            inner_path = gen_inner_file_get_url(token, filename)
            file_enc = request.GET.get('file_enc', 'auto')
            if not file_enc in FILE_ENCODING_LIST:
                file_enc = 'auto'
            err, file_content, encoding = repo_file_get(inner_path, file_enc)
            if encoding and encoding not in FILE_ENCODING_LIST:
                file_encoding_list.append(encoding)
    else:
        err = _(u'Edit online is not offered for this type of file.')

    # Redirect to different place according to from page when user click
    # cancel button on file edit page.
    cancel_url = reverse('repo_view_file', args=[repo.id]) + '?p=' + urlquote(path)
    page_from = request.GET.get('from', '')
    gid = request.GET.get('gid', '')
    wiki_name = os.path.splitext(u_filename)[0]
    if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new':
        cancel_url = reverse('group_wiki', args=[gid, wiki_name])
    elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new':
        cancel_url = reverse('personal_wiki', args=[wiki_name])

    return render_to_response('file_edit.html', {
        'repo':repo,
        'u_filename':u_filename,
        'wiki_name': wiki_name,
        'path':path,
        'zipped':zipped,
        'filetype':filetype,
        'fileext':fileext,
        'op':op,
        'err':err,
        'file_content':file_content,
        'encoding': encoding,
        'file_encoding_list':file_encoding_list,
        'head_id': head_id,
        'from': page_from,
        'gid': gid,
        'cancel_url': cancel_url,
    }, context_instance=RequestContext(request))
Example #29
0
def file_edit_submit(request, repo_id):
    content_type = 'application/json; charset=utf-8'
    def error_json(error_msg=_(u'Internal Error'), op=None):
        return HttpResponse(json.dumps({'error': error_msg, 'op': op}),
                            status=400,
                            content_type=content_type)

    username = request.user.username
    if check_repo_access_permission(repo_id, request.user) != 'rw':
        return error_json(_(u'Permission denied'))
        
    repo = get_repo(repo_id)
    if not repo:
        return error_json(_(u'The library does not exist.'))
    if repo.encrypted:
        repo.password_set = seafile_api.is_password_set(repo_id, username)
        if not repo.password_set:
            return error_json(_(u'The library is encrypted.'), 'decrypt')

    content = request.POST.get('content')
    encoding = request.POST.get('encoding')
    path = request.GET.get('p')

    if content is None or not path or encoding not in ["gbk", "utf-8"]:
        return error_json(_(u'Invalid arguments'))
    head_id = request.GET.get('head', None)

    content = content.encode(encoding)

    # first dump the file content to a tmp file, then update the file
    fd, tmpfile = mkstemp()
    def remove_tmp_file():
        try:
            os.remove(tmpfile)
        except:
            pass

    try:
        bytesWritten = os.write(fd, content)
    except:
        bytesWritten = -1
    finally:
        os.close(fd)

    if bytesWritten != len(content):
        remove_tmp_file()
        return error_json()

    req_from = request.GET.get('from', '')
    if req_from == 'wiki_page_edit' or req_from == 'wiki_page_new':
        try:
            gid = int(request.GET.get('gid', 0))
        except ValueError:
            gid = 0
        
        wiki_name = os.path.splitext(os.path.basename(path))[0]
        next = reverse('group_wiki', args=[gid, wiki_name])
    elif req_from == 'personal_wiki_page_edit' or req_from == 'personal_wiki_page_new':
        wiki_name = os.path.splitext(os.path.basename(path))[0]
        next = reverse('personal_wiki', args=[wiki_name])
    else:
        next = reverse('repo_view_file', args=[repo_id]) + '?p=' + urlquote(path)

    parent_dir = os.path.dirname(path).encode('utf-8')
    filename = os.path.basename(path).encode('utf-8')
    try:
        seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir,
                                 filename, username, head_id)
        remove_tmp_file()
        return HttpResponse(json.dumps({'href': next}),
                            content_type=content_type)
    except SearpcError, e:
        remove_tmp_file()
        return error_json(str(e))
Example #30
0
def list_dir(request, repo_id):
    """
    List directory entries in AJAX.
    """
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'

    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
    user_perm = check_repo_access_permission(repo.id, username)
    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}),
                            status=403,
                            content_type=content_type)

    head_commit = get_commit(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)

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

    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request,
                                                        repo.id,
                                                        head_commit,
                                                        path,
                                                        offset=0,
                                                        limit=100)
    if dirent_more:
        more_start = 100
    zipped = get_nav_path(path, repo.name)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_dir_share_link(fileshare)

    ctx = {
        'repo': repo,
        'zipped': zipped,
        'user_perm': user_perm,
        'path': path,
        'fileshare': fileshare,
        'dir_shared_link': dir_shared_link,
        'dir_list': dir_list,
        'file_list': file_list,
        'dirent_more': dirent_more,
        'more_start': more_start,
        'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
    }
    html = render_to_string('snippets/repo_dir_data.html',
                            ctx,
                            context_instance=RequestContext(request))
    return HttpResponse(json.dumps({
        'html': html,
        'path': path
    }),
                        content_type=content_type)
Example #31
0
def repo_history(request, repo_id):
    """
    List library modification histories.
    """
    user_perm = check_folder_permission(request, repo_id, '/')
    if not user_perm:
        return render_permission_error(
            request, _('Unable to view library modification'))

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

    username = request.user.username
    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    password_set = False
    if repo.props.encrypted and \
            (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)):
        try:
            ret = seafile_api.is_password_set(repo_id, username)
            if ret == 1:
                password_set = True
        except SearpcError as e:
            return render_error(request, e.msg)

        if not password_set:
            reverse_url = reverse('lib_view', args=[repo_id, repo.name, ''])
            return HttpResponseRedirect(reverse_url)

    try:
        current_page = int(request.GET.get('page', '1'))
    except ValueError:
        current_page = 1

    per_page = 100
    commits_all = get_commits(repo_id, per_page * (current_page - 1),
                              per_page + 1)
    commits = commits_all[:per_page]
    for c in commits:
        c.show = False if new_merge_with_no_conflict(c) else True

    show_label = False
    if ENABLE_REPO_SNAPSHOT_LABEL:
        show_label = True
        snapshot_labels = RevisionTags.objects.filter(repo_id=repo_id)
        for c in commits:
            if c.show:
                c.labels = []
                for label in snapshot_labels:
                    if label.revision_id == c.id:
                        c.labels.append(label.tag.name)

    if len(commits_all) == per_page + 1:
        page_next = True
    else:
        page_next = False

    # for 'go back'
    referer = request.GET.get('referer', '')

    #template = 'repo_history.html'
    template = 'repo_history_react.html'

    return render(
        request, template, {
            "repo": repo,
            "commits": commits,
            'current_page': current_page,
            'prev_page': current_page - 1,
            'next_page': current_page + 1,
            'page_next': page_next,
            'user_perm': user_perm,
            'show_label': show_label,
            'referer': referer,
        })
Example #32
0
def file_edit_submit(request, repo_id):
    content_type = "application/json; charset=utf-8"

    def error_json(error_msg=_(u"Internal Error"), op=None):
        return HttpResponse(json.dumps({"error": error_msg, "op": op}), status=400, content_type=content_type)

    username = request.user.username
    if check_repo_access_permission(repo_id, request.user) != "rw":
        return error_json(_(u"Permission denied"))

    repo = get_repo(repo_id)
    if not repo:
        return error_json(_(u"The library does not exist."))
    if repo.encrypted:
        repo.password_set = seafile_api.is_password_set(repo_id, username)
        if not repo.password_set:
            return error_json(_(u"The library is encrypted."), "decrypt")

    content = request.POST.get("content")
    encoding = request.POST.get("encoding")
    path = request.GET.get("p")

    if content is None or not path or encoding not in ["gbk", "utf-8"]:
        return error_json(_(u"Invalid arguments"))
    head_id = request.GET.get("head", None)

    content = content.encode(encoding)

    # first dump the file content to a tmp file, then update the file
    fd, tmpfile = mkstemp()

    def remove_tmp_file():
        try:
            os.remove(tmpfile)
        except:
            pass

    try:
        bytesWritten = os.write(fd, content)
    except:
        bytesWritten = -1
    finally:
        os.close(fd)

    if bytesWritten != len(content):
        remove_tmp_file()
        return error_json()

    req_from = request.GET.get("from", "")
    if req_from == "wiki_page_edit" or req_from == "wiki_page_new":
        try:
            gid = int(request.GET.get("gid", 0))
        except ValueError:
            gid = 0

        wiki_name = os.path.splitext(os.path.basename(path))[0]
        next = reverse("group_wiki", args=[gid, wiki_name])
    elif req_from == "personal_wiki_page_edit" or req_from == "personal_wiki_page_new":
        wiki_name = os.path.splitext(os.path.basename(path))[0]
        next = reverse("personal_wiki", args=[wiki_name])
    else:
        next = reverse("repo_view_file", args=[repo_id]) + "?p=" + urlquote(path)

    parent_dir = os.path.dirname(path).encode("utf-8")
    filename = os.path.basename(path).encode("utf-8")
    try:
        seafserv_threaded_rpc.put_file(repo_id, tmpfile, parent_dir, filename, username, head_id)
        remove_tmp_file()
        return HttpResponse(json.dumps({"href": next}), content_type=content_type)
    except SearpcError, e:
        remove_tmp_file()
        return error_json(str(e))
Example #33
0
File: repo.py Project: genba/seahub
def is_password_set(repo_id, username):
    return seafile_api.is_password_set(repo_id, username)
Example #34
0
    def get(self, request, repo_id, format=None):
        """ Return history of library

        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
        if check_folder_permission(request, repo_id, '/') is None:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        username = request.user.username
        try:
            server_crypto = UserOptions.objects.is_server_crypto(username)
        except CryptoOptionNotSetError:
            # Assume server_crypto is ``False`` if this option is not set.
            server_crypto = False

        password_set = False
        if repo.encrypted and \
                (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)):
            try:
                ret = seafile_api.is_password_set(repo_id, username)
                if ret == 1:
                    password_set = True
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not password_set:
                error_msg = 'Library is encrypted, but password is not set in server.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            page = int(request.GET.get('page', '1'))
            per_page = int(request.GET.get('per_page', '100'))
        except ValueError:
            page = 1
            per_page = 100

        if page <= 0:
            error_msg = 'page invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if per_page <= 0:
            error_msg = 'per_page invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        start = (page - 1) * per_page
        limit = per_page + 1

        try:
            all_commits = seafile_api.get_commit_list(repo_id, start, limit)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        items = []
        commits = all_commits[:per_page]
        for commit in commits:
            if new_merge_with_no_conflict(commit):
                continue

            item_info = self.get_item_info(commit)
            items.append(item_info)

        result = {
            'data': items,
            'more': True if len(all_commits) == per_page + 1 else False
        }

        return Response(result)