Esempio n. 1
0
    def test_rename_file_with_invalid_folder_perm(self):

        if not LOCAL_PRO_DEV_ENV:
            return

        # create a file as old file in user repo sub-folder
        old_file_name = randstring(6)
        seafile_api.post_empty_file(repo_id=self.repo_id,
                parent_dir=self.folder_path, filename=old_file_name,
                username=self.user_name)

        # share user's repo to admin with 'rw' permission
        seafile_api.share_repo(self.repo_id, self.user_name,
                self.admin_name, 'rw')

        # set sub-folder permisson as 'r' for admin
        seafile_api.add_folder_user_perm(self.repo_id,
                self.folder_path, 'r', self.admin_name)

        # admin can visit old file with 'r' permission
        old_file_path = posixpath.join(self.folder_path, old_file_name)
        assert seafile_api.check_permission_by_path(self.repo_id,
                old_file_path, self.admin_name) == 'r'

        # login as admin, then rename a 'r' permission old file
        self.login_as(self.admin)

        new_name = randstring(6)
        data = {'operation': 'rename', 'newname': new_name}

        resp = self.client.post(self.url + '?p=' + old_file_path, data)
        self.assertEqual(403, resp.status_code)
Esempio n. 2
0
    def create_empty_resource(self, name):
        """Create an empty (length-0) resource.

        See DAVResource.createEmptyResource()
        """
        assert not "/" in name
        if self.provider.readonly:
            raise DAVError(HTTP_FORBIDDEN)

        if seafile_api.check_permission_by_path(self.repo.id, self.rel_path, self.username) != "rw":
            raise DAVError(HTTP_FORBIDDEN)

        if seafile_api.check_quota(self.repo.id) < 0:
            raise DAVError(HTTP_FORBIDDEN, "The quota of the repo owner is exceeded")

        try:
            seafile_api.post_empty_file(self.repo.id, self.rel_path, name, self.username)
        except SearpcError as e:
            if e.msg == 'Invalid file name':
                raise DAVError(HTTP_BAD_REQUEST)
            raise

        # Repo was updated, can't use self.repo
        repo = seafile_api.get_repo(self.repo.id)
        if not repo:
            raise DAVError(HTTP_INTERNAL_ERROR)

        member_rel_path = "/".join([self.rel_path, name])
        member_path = "/".join([self.path, name])
        obj = resolveRepoPath(repo, member_rel_path)
        if not obj or not isinstance(obj, SeafFile):
            raise DAVError(HTTP_INTERNAL_ERROR)

        return SeafileResource(member_path, repo, member_rel_path, obj, self.environ)
Esempio n. 3
0
    def test_get_dirents(self):

        username = self.user.username
        dir_name = randstring(6)
        file_name = randstring(6)

        seafile_api.post_dir(self.repo_id,
                self.folder_path, dir_name, username)

        seafile_api.post_empty_file(self.repo_id,
                self.folder_path, file_name, username)

        self.login_as(self.admin)
        token = self._add_dir_share_link()
        url = reverse('api-v2.1-admin-share-link-dirents', args=[token])
        resp = self.client.get(url)
        self.assertEqual(200, resp.status_code)

        json_resp = json.loads(resp.content)

        assert json_resp[0]['is_dir'] == True
        assert dir_name in json_resp[0]['obj_name']
        assert json_resp[1]['is_dir'] == False
        assert file_name in json_resp[1]['obj_name']

        self._remove_share_link(token)
Esempio n. 4
0
    def test_rename_file_with_invalid_folder_perm(self):

        if not LOCAL_PRO_DEV_ENV:
            return

        # create a file as old file in user repo sub-folder
        old_file_name = randstring(6)
        seafile_api.post_empty_file(repo_id=self.repo_id,
                                    parent_dir=self.folder_path,
                                    filename=old_file_name,
                                    username=self.user_name)

        # share user's repo to admin with 'rw' permission
        seafile_api.share_repo(self.repo_id, self.user_name, self.admin_name,
                               'rw')

        # set sub-folder permisson as 'r' for admin
        seafile_api.add_folder_user_perm(self.repo_id, self.folder_path, 'r',
                                         self.admin_name)

        # admin can visit old file with 'r' permission
        old_file_path = posixpath.join(self.folder_path, old_file_name)
        assert seafile_api.check_permission_by_path(self.repo_id,
                                                    old_file_path,
                                                    self.admin_name) == 'r'

        # login as admin, then rename a 'r' permission old file
        self.login_as(self.admin)

        new_name = randstring(6)
        data = {'operation': 'rename', 'newname': new_name}

        resp = self.client.post(self.url + '?p=' + old_file_path, data)
        self.assertEqual(403, resp.status_code)
    def setUp(self):
        # add user to group
        self.login_as(self.user)
        self.group_id = self.group.id
        self.endpoint = reverse('api-v2.1-group-members', args=[self.group_id])
        self.client.post(self.endpoint, {'email': self.user.username})
        self.logout()

        # create group workspace
        group_repo_id = seafile_api.create_repo(_("My Workspace"),
                                                _("My Workspace"),
                                                "dtable@seafile")
        self.group_workspace = Workspaces.objects.create_workspace(
            str(self.group_id) + GROUP_DOMAIN, group_repo_id, -1)
        assert Workspaces.objects.all().count() == 1

        # create group dtable
        seafile_api.post_empty_file(group_repo_id, '/', 'group.dtable',
                                    self.user.username)
        self.group_dtable = DTables.objects.create_dtable(
            self.user.username, self.group_workspace, 'group')
        assert DTables.objects.all().count() == 1

        # share group dtable to admin
        DTableShare.objects.add(self.group_dtable,
                                str(self.group_id) + GROUP_DOMAIN,
                                self.admin.username, 'rw')
        assert DTableShare.objects.all().count() == 1

        self.url = reverse(
            'api-v2.1-dtable-related-users',
            args=[self.group_workspace.id, self.group_dtable.name])
Esempio n. 6
0
    def test_delete_file_with_invalid_folder_perm(self):

        if not LOCAL_PRO_DEV_ENV:
            return

        # create a file in user repo sub-folder
        file_name = randstring(6)
        seafile_api.post_empty_file(repo_id=self.repo_id,
                                    parent_dir=self.folder_path,
                                    filename=file_name,
                                    username=self.user_name)

        # share user's repo to admin with 'rw' permission
        seafile_api.share_repo(self.repo_id, self.user_name, self.admin_name,
                               'rw')

        # set sub-folder permisson as 'r' for admin
        seafile_api.add_folder_user_perm(self.repo_id, self.folder_path, 'r',
                                         self.admin_name)

        # admin can visit file with 'r' permission
        file_path = posixpath.join(self.folder_path, file_name)
        assert seafile_api.check_permission_by_path(self.repo_id, file_path,
                                                    self.admin_name) == 'r'

        # login as admin, then delete a 'r' permission file
        self.login_as(self.admin)

        resp = self.client.delete(self.url + '?p=' + file_path, {},
                                  'application/x-www-form-urlencoded')
        self.assertEqual(403, resp.status_code)
Esempio n. 7
0
    def test_delete_file_with_invalid_folder_perm(self):

        if not LOCAL_PRO_DEV_ENV:
            return

        # create a file in user repo sub-folder
        file_name = randstring(6)
        seafile_api.post_empty_file(repo_id=self.repo_id,
                parent_dir=self.folder_path, filename=file_name,
                username=self.user_name)

        # share user's repo to admin with 'rw' permission
        seafile_api.share_repo(self.repo_id, self.user_name,
                self.admin_name, 'rw')

        # set sub-folder permisson as 'r' for admin
        seafile_api.add_folder_user_perm(self.repo_id,
                self.folder_path, 'r', self.admin_name)

        # admin can visit file with 'r' permission
        file_path = posixpath.join(self.folder_path, file_name)
        assert seafile_api.check_permission_by_path(self.repo_id,
                file_path, self.admin_name) == 'r'

        # login as admin, then delete a 'r' permission file
        self.login_as(self.admin)

        resp = self.client.delete(self.url + '?p=' + file_path,
                {}, 'application/x-www-form-urlencoded')
        self.assertEqual(403, resp.status_code)
Esempio n. 8
0
    def test_get(self):
        wiki = Wiki.objects.add('new wiki', self.user.username)
        assert wiki is not None

        seafile_api.post_empty_file(wiki.repo_id, '/', 'home.md',
                                    self.user.username)

        p = get_wiki_page_object(wiki, 'home')
        assert p['updated_at'] is not None
        assert p['last_modifier_name'] is not None
Esempio n. 9
0
    def post(self, request, format=None):
        """Add a new wiki.
        """
        result = {}
        content_type = 'application/json; charset=utf-8'
        name = request.POST.get('name', '')
        if not name:
            return api_error(status.HTTP_400_BAD_REQUEST,
                             _('Name is required.'))

        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)

        permission = request.POST.get('permission', '').lower()
        if permission not in [x[0] for x in Wiki.PERM_CHOICES]:
            msg = 'Permission invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

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

        username = request.user.username
        try:
            wiki = Wiki.objects.add(name,
                                    username,
                                    permission=permission,
                                    org_id=org_id)
        except DuplicateWikiNameError:
            result['error'] = _(
                '%s is taken by others, please try another name.') % name
            return HttpResponse(json.dumps(result),
                                status=400,
                                content_type=content_type)
        except IntegrityError:
            result['error'] = 'Internal Server Error'
            return HttpResponse(json.dumps(result),
                                status=500,
                                content_type=content_type)

        # 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)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response(wiki.to_dict())
Esempio n. 10
0
    def test_can_get_dir_detail(self):

        seafile_api.post_dir(self.repo_id, self.folder_path, randstring(3),
                             self.user_name)
        seafile_api.post_empty_file(self.repo_id, self.folder_path,
                                    randstring(3), self.user_name)

        self.login_as(self.user)
        resp = self.client.get(self.url + '?path=%s' % self.folder_path)
        self.assertEqual(200, resp.status_code)
        json_resp = json.loads(resp.content)

        assert json_resp['name'] == self.folder_name
Esempio n. 11
0
def new_file(repo_id, parent_dir, dirent_name, username):
    """
    Create a new file with ajax.    
    """
    result = {}
    content_type = 'application/json; charset=utf-8'

    # create new dirent
    try:
        seafile_api.post_empty_file(repo_id, parent_dir, dirent_name, username)
    except SearpcError, e:
        result['error'] = str(e)
        return HttpResponse(json.dumps(result), status=500,
                            content_type=content_type)
Esempio n. 12
0
    def post(self, request, slug):
        """ Add a page in a wiki
        """
        try:
            wiki = Wiki.objects.get(slug=slug)
        except Wiki.DoesNotExist:
            error_msg = "Wiki not found."
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # perm check
        username = request.user.username
        if wiki.username != username:
            error_msg = _('Permission denied.')
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        page_name = request.POST.get('name', '')
        if not page_name:
            error_msg = 'name invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        page_name = clean_page_name(page_name)
        filename = page_name + ".md"
        filepath = "/" + page_name + ".md"

        try:
            repo = seafile_api.get_repo(wiki.repo_id)
            if not repo:
                error_msg = "Wiki library not found."
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        except SearpcError:
            error_msg = _("Internal Server Error")
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # check whether file exists
        if get_file_id_by_path(repo.id, filepath):
            error_msg = _('Page "%s" already exists.') % filename
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            seafile_api.post_empty_file(repo.id, '/',
                                        filename, request.user.username)
        except SearpcError as e:
            logger.error(e)
            error_msg = _('Internal Server Error')
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        wiki_page_object = get_wiki_page_object(wiki, page_name)

        return Response(wiki_page_object)
Esempio n. 13
0
    def post(self, request, slug):
        """ Add a page in a wiki
        """
        try:
            wiki = Wiki.objects.get(slug=slug)
        except Wiki.DoesNotExist:
            error_msg = "Wiki not found."
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # perm check
        username = request.user.username
        if wiki.username != username:
            error_msg = _('Permission denied.')
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        page_name = request.POST.get('name', '')
        if not page_name:
            error_msg = 'name invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        page_name = clean_page_name(page_name)
        filename = page_name + ".md"
        filepath = "/" + page_name + ".md"

        try:
            repo = seafile_api.get_repo(wiki.repo_id)
            if not repo:
                error_msg = "Wiki library not found."
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        except SearpcError:
            error_msg = _("Internal Server Error")
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # check whether file exists
        if get_file_id_by_path(repo.id, filepath):
            error_msg = _('Page "%s" already exists.') % filename
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            seafile_api.post_empty_file(repo.id, '/', filename,
                                        request.user.username)
        except SearpcError as e:
            logger.error(e)
            error_msg = _('Internal Server Error')
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        wiki_page_object = get_wiki_page_object(wiki, page_name)

        return Response(wiki_page_object)
Esempio n. 14
0
def new_file(repo_id, parent_dir, dirent_name, username):
    """
    Create a new file with ajax.    
    """
    result = {}
    content_type = 'application/json; charset=utf-8'

    # create new dirent
    try:
        seafile_api.post_empty_file(repo_id, parent_dir, dirent_name, username)
    except SearpcError, e:
        result['error'] = str(e)
        return HttpResponse(json.dumps(result),
                            status=500,
                            content_type=content_type)
Esempio n. 15
0
    def setUp(self):
        # create workspace
        self.workspace = Workspaces.objects.create_workspace(
            self.user.username, self.repo.id)
        assert len(Workspaces.objects.all()) == 1
        # create dtable
        seafile_api.post_empty_file(self.repo.id, '/', 'dtable1.dtable',
                                    self.user.username)
        self.dtable = DTables.objects.create_dtable(self.user.username,
                                                    self.workspace, 'dtable1')
        assert len(DTables.objects.all()) == 1
        # share dtable to admin
        DTableShare.objects.add(self.dtable, self.user.username,
                                self.admin.username, 'rw')
        assert len(DTableShare.objects.all()) == 1

        self.url = reverse('api-v2.1-dtables-share')
Esempio n. 16
0
    def createEmptyResource(self, name):
        """Create an empty (length-0) resource.

        See DAVResource.createEmptyResource()
        """
        assert not "/" in name
        if self.provider.readonly:
            raise DAVError(HTTP_FORBIDDEN)

        if seafile_api.check_permission(self.repo.id, self.username) != "rw":
            raise DAVError(HTTP_FORBIDDEN)

        try:
            seafile_api.post_empty_file(self.repo.id, self.rel_path, name, self.username)
        except SearpcError, e:
            if e.msg == 'Invalid file name':
                raise DAVError(HTTP_BAD_REQUEST)
            raise
Esempio n. 17
0
    def createEmptyResource(self, name):
        """Create an empty (length-0) resource.

        See DAVResource.createEmptyResource()
        """
        assert not "/" in name
        if self.provider.readonly:
            raise DAVError(HTTP_FORBIDDEN)

        if seafile_api.check_permission(self.repo.id, self.username) != "rw":
            raise DAVError(HTTP_FORBIDDEN)

        try:
            seafile_api.post_empty_file(self.repo.id, self.rel_path, name,
                                        self.username)
        except SearpcError, e:
            if e.msg == 'Invalid file name':
                raise DAVError(HTTP_BAD_REQUEST)
            raise
Esempio n. 18
0
    def create_file_with_content(self, file_name, parent_dir='/', content='abc',
                                 username=''):
        seafile_api.post_empty_file(self.repo.id, parent_dir, file_name, username)

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

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

        assert bytesWritten > 0

        seafile_api.put_file(self.repo.id, tmp_file, parent_dir, file_name,
                             '', None)
        return parent_dir + file_name
Esempio n. 19
0
    def create_file_with_content(self, file_name, parent_dir='/', content='junk content',
                                 username=''):
        seafile_api.post_empty_file(self.repo.id, parent_dir, file_name, username)

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

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

        assert bytesWritten > 0

        seafile_api.put_file(self.repo.id, tmp_file, parent_dir, file_name,
                             '', None)
        return parent_dir + file_name
Esempio n. 20
0
    def test_can_get_file_with_thumbnail_info(self):

        self.login_as(self.user)

        # create a image file
        image_file_name = randstring(6) + '.jpg'
        seafile_api.post_empty_file(self.repo_id, self.folder_path,
                                    image_file_name, self.user_name)

        # file has no thumbnail
        resp = self.client.get(self.url + '?t=f&with_thumbnail=true&p=%s' %
                               self.folder_path)
        self.assertEqual(200, resp.status_code)
        json_resp = json.loads(resp.content)
        assert len(json_resp['dirent_list']) == 1
        assert json_resp['dirent_list'][0]['type'] == 'file'
        assert json_resp['dirent_list'][0]['name'] == image_file_name
        assert not json_resp['dirent_list'][0].has_key('encoded_thumbnail_src')

        file_id = json_resp['dirent_list'][0]['id']

        # prepare thumbnail
        size = 48
        thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size))
        if not os.path.exists(thumbnail_dir):
            os.makedirs(thumbnail_dir)
        thumbnail_file = os.path.join(thumbnail_dir, file_id)

        with open(thumbnail_file, 'w'):
            pass
        assert os.path.exists(thumbnail_file)

        # file has thumbnail
        resp = self.client.get(self.url + '?t=f&with_thumbnail=true&p=%s' %
                               self.folder_path)
        self.assertEqual(200, resp.status_code)
        self.assertEqual(200, resp.status_code)
        json_resp = json.loads(resp.content)
        assert len(json_resp['dirent_list']) == 1
        assert json_resp['dirent_list'][0]['type'] == 'file'
        assert json_resp['dirent_list'][0]['name'] == image_file_name
        assert image_file_name in json_resp['dirent_list'][0][
            'encoded_thumbnail_src']
Esempio n. 21
0
    def post(self, request, repo_id, format=None):
        """ create file/folder in a library
        """

        if not request.user.admin_permissions.can_manage_library():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        parent_dir = request.GET.get('parent_dir', '/')
        parent_dir = normalize_dir_path(parent_dir)
        dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
        if not dir_id:
            error_msg = 'Folder %s not found.' % parent_dir
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        is_file = request.data.get('is_file', 'false')
        is_file = is_file.lower()
        if is_file not in ('true', 'false'):
            error_msg = 'is_file invalid.'

        username = request.user.username
        obj_name = check_filename_with_rename(repo_id, parent_dir, obj_name)
        try:
            if is_file == 'true':
                seafile_api.post_empty_file(repo_id, parent_dir, obj_name,
                                            username)
            else:
                seafile_api.post_dir(repo_id, parent_dir, obj_name, username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        dirent_path = posixpath.join(parent_dir, obj_name)
        dirent = seafile_api.get_dirent_by_path(repo_id, dirent_path)
        dirent_info = get_dirent_info(dirent)

        return Response(dirent_info)
Esempio n. 22
0
    def test_download_sub_file_in_shared_dir(self):

        username = self.user.username
        file_name = randstring(6)
        seafile_api.post_empty_file(self.repo_id,
                self.folder_path, file_name, username)

        self.login_as(self.admin)
        token = self._add_dir_share_link()

        url = reverse('api-v2.1-admin-share-link-download', args=[token])
        resp = self.client.get(url + '?path=/%s&type=file' % file_name)
        self.assertEqual(200, resp.status_code)

        json_resp = json.loads(resp.content)

        assert '8082' in json_resp['download_link']
        assert 'files' in json_resp['download_link']

        self._remove_share_link(token)
Esempio n. 23
0
    def test_copy_file_with_invalid_dst_folder_perm(self):

        if not LOCAL_PRO_DEV_ENV:
            return

        # share user's repo to admin with 'rw' permission
        seafile_api.share_repo(self.repo_id, self.user_name, self.admin_name,
                               'rw')

        # set sub-folder permisson as 'r' for admin
        seafile_api.add_folder_user_perm(self.repo_id, self.folder_path, 'r',
                                         self.admin_name)

        # admin can visit sub-folder with 'r' permission
        assert seafile_api.check_permission_by_path(self.repo_id,
                                                    self.folder_path,
                                                    self.admin_name) == 'r'

        # create a file for admin repo
        admin_repo_id = self.admin_create_new_repo()
        admin_file_name = randstring(6)
        seafile_api.post_empty_file(repo_id=admin_repo_id,
                                    parent_dir='/',
                                    filename=admin_file_name,
                                    username=self.admin_name)

        # login as admin, then move file to a 'r' permission folder
        self.login_as(self.admin)

        # create new repo for admin
        data = {
            'operation': 'copy',
            'dst_repo': self.repo_id,
            'dst_dir': self.folder_path,
        }

        url = reverse('api-v2.1-file-view', args=[admin_repo_id])
        resp = self.client.post(url + '?p=/' + admin_file_name, data)
        self.assertEqual(403, resp.status_code)
Esempio n. 24
0
    def post(self, request, repo_id, format=None):
        """ create file/folder in a library
        """

        parent_dir = request.GET.get('parent_dir', '/')
        parent_dir = normalize_dir_path(parent_dir)
        dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
        if not dir_id:
            error_msg = 'Folder %s not found.' % parent_dir
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        is_file = request.data.get('is_file', 'false')
        is_file = is_file.lower()
        if is_file not in ('true', 'false'):
            error_msg = 'is_file invalid.'

        username = request.user.username
        obj_name = check_filename_with_rename(repo_id, parent_dir, obj_name)
        try:
            if is_file == 'true':
                seafile_api.post_empty_file(repo_id, parent_dir, obj_name, username)
            else:
                seafile_api.post_dir(repo_id, parent_dir, obj_name, username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        dirent_path = posixpath.join(parent_dir, obj_name)
        dirent = seafile_api.get_dirent_by_path(repo_id, dirent_path)
        dirent_info = get_dirent_info(dirent)

        return Response(dirent_info)
Esempio n. 25
0
    def test_copy_file_with_invalid_dst_folder_perm(self):

        if not LOCAL_PRO_DEV_ENV:
            return

        # share user's repo to admin with 'rw' permission
        seafile_api.share_repo(self.repo_id, self.user_name,
                self.admin_name, 'rw')

        # set sub-folder permisson as 'r' for admin
        seafile_api.add_folder_user_perm(self.repo_id,
                self.folder_path, 'r', self.admin_name)

        # admin can visit sub-folder with 'r' permission
        assert seafile_api.check_permission_by_path(self.repo_id,
                self.folder_path, self.admin_name) == 'r'

        # create a file for admin repo
        admin_repo_id = self.admin_create_new_repo()
        admin_file_name = randstring(6)
        seafile_api.post_empty_file(repo_id=admin_repo_id,
                parent_dir='/', filename=admin_file_name,
                username=self.admin_name)

        # login as admin, then move file to a 'r' permission folder
        self.login_as(self.admin)

        # create new repo for admin
        data = {
            'operation': 'copy',
            'dst_repo': self.repo_id,
            'dst_dir': self.folder_path,
        }

        url = reverse('api-v2.1-file-view', args=[admin_repo_id])
        resp = self.client.post(url + '?p=/' + admin_file_name, data)
        self.assertEqual(403, resp.status_code)
Esempio n. 26
0
def post_dtable_json(username, repo_id, workspace_id, dtable_uuid,
                     dtable_file_name):
    """
    used to import dtable
    prepare dtable json file and post it at file server

    :param repo_id:
    :param workspace_id:
    :param dtable_uuid:         str
    :param dtable_file_name:    xxx.dtable, the name of zip we imported
    :return:
    """
    # change url in content json, then save it at file server
    content_json_file_path = os.path.join('/tmp/dtable-io', dtable_uuid,
                                          'dtable_zip_extracted/',
                                          'content.json')
    with open(content_json_file_path, 'r') as f:
        content_json = f.read()

    try:
        content = json.loads(content_json)
    except:
        content = ''
    if not content:
        seafile_api.post_empty_file(repo_id, '/', dtable_file_name, username)
        return

    content_json = convert_dtable_import_file_and_image_url(
        content, workspace_id, dtable_uuid)
    with open(content_json_file_path, 'w') as f:
        f.write(json.dumps(content_json))

    try:
        seafile_api.post_file(repo_id, content_json_file_path, '/',
                              dtable_file_name, username)
    except Exception as e:
        raise e
Esempio n. 27
0
    def post(self, request):
        """create a table file

        Permission:
        1. owner
        2. group member
        """
        # argument check
        table_owner = request.POST.get('owner')
        if not table_owner:
            error_msg = 'owner invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        table_name = request.POST.get('name')
        if not table_name:
            error_msg = 'name invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        table_file_name = table_name + FILE_TYPE
        if not is_valid_dirent_name(table_file_name):
            error_msg = 'name invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        workspace = Workspaces.objects.get_workspace_by_owner(table_owner)
        if not workspace:
            if not request.user.permissions.can_add_repo():
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

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

            try:
                if org_id > 0:
                    repo_id = seafile_api.create_org_repo(
                        _("My Workspace"), _("My Workspace"), "dtable@seafile",
                        org_id)
                else:
                    repo_id = seafile_api.create_repo(_("My Workspace"),
                                                      _("My Workspace"),
                                                      "dtable@seafile")
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error.'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            try:
                workspace = Workspaces.objects.create_workspace(
                    table_owner, repo_id)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error.'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        repo_id = workspace.repo_id
        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
        username = request.user.username
        if not check_dtable_permission(username, table_owner):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # repo status check
        repo_status = repo.status
        if repo_status != 0:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # create new empty table
        table_file_name = check_filename_with_rename(repo_id, '/',
                                                     table_file_name)

        try:
            seafile_api.post_empty_file(repo_id, '/', table_file_name,
                                        username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        try:
            dtable = DTables.objects.create_dtable(username, workspace,
                                                   table_name)
        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({"table": dtable.to_dict()},
                        status=status.HTTP_201_CREATED)
Esempio n. 28
0
    def post(self, request, workspace_id):
        """ import dtable from xxx.dtable zip

        :param request:
        :param workspace_id:
        :return:
        """
        # use TemporaryFileUploadHandler, which contains TemporaryUploadedFile
        # TemporaryUploadedFile has temporary_file_path() method
        # in order to change upload_handlers, we must exempt csrf check
        request.upload_handlers = [TemporaryFileUploadHandler(request=request)]
        username = request.user.username

        imported_zip = request.FILES.get('dtable', None)
        if not imported_zip:
            error_msg = 'dtable invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if not imported_zip.name.endswith(('.dtable', '.csv')):
            error_msg = 'dtable %s invalid.' % imported_zip.name
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        dtable_file_name = imported_zip.name   # xxx.dtable
        dtable_name = dtable_file_name.split('.')[0]

        if DTables.objects.filter(workspace_id=workspace_id, name=dtable_name).exists():
            error_msg = _('Table %s already exists.') % dtable_name
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        repo_id = workspace.repo_id
        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)


        # post json file after dtable recored is created
        # because we need to get dtable uuid
        try:
            dtable = DTables.objects.create_dtable(username, workspace, dtable_name)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # permission check
        permission = check_dtable_permission(request.user.username, workspace, dtable)
        if not permission:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # create dtable from csv
        if imported_zip.name.endswith('.csv'):
            try:
                seafile_api.post_empty_file(repo_id, '/', dtable_name + '.dtable', username)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            payload = {
                'exp': int(time.time()) + 60,
                'dtable_uuid': dtable.uuid.hex,
                'username': '******',
                'permission': permission,
            }
            try:
                access_token = jwt.encode(
                    payload, DTABLE_PRIVATE_KEY, algorithm='HS256'
                )
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            headers = {'Authorization': 'Token ' + access_token.decode('utf-8')}
            url = DTABLE_SERVER_URL + 'api/v1/' + dtable.uuid.hex + '/import-csv/'
            data = {
                'table_name': dtable_name,
                'is_create_base': True,
            }
            files = {
                'csv_file': imported_zip
            }

            try:
                res = requests.post(url, headers=headers, data=data, files=files)
            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({"table": dtable.to_dict()})

        uploaded_temp_path = imported_zip.temporary_file_path()
        if not is_zipfile(uploaded_temp_path):
            error_msg = _('A *.dtable file is required.')
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        params = {}
        params['username'] = request.user.username
        params['repo_id'] = repo_id
        params['workspace_id'] = workspace_id
        params['dtable_uuid'] = str(dtable.uuid)
        params['dtable_file_name'] = dtable_file_name
        params['uploaded_temp_path'] = uploaded_temp_path

        try:
            task_id = add_dtable_io_task(type='import', params=params)
        except Exception as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error.')

        return Response({'task_id': task_id, "table": dtable.to_dict()})
def test_file_operation():
    t_repo_version = 1
    t_repo_id1 = api.create_repo('test_file_operation1', '', USER, passwd=None)

    create_the_file()

    # test post_file
    assert api.post_file(t_repo_id1, file_path, '/', file_name, USER) == 0
    t_file_id = api.get_file_id_by_path(t_repo_id1, '/' + file_name)
    t_file_size = len(file_content)
    assert t_file_size == api.get_file_size(t_repo_id1, t_repo_version,
                                            t_file_id)

    # test post_dir
    assert api.post_dir(t_repo_id1, '/', dir_name, USER) == 0

    # test copy_file (synchronize)
    t_copy_file_result1 = api.copy_file(t_repo_id1, '/', file_name, t_repo_id1,
                                        '/', new_file_name, USER, 0, 1)
    assert t_copy_file_result1
    assert t_copy_file_result1.task_id is None
    assert not t_copy_file_result1.background
    t_file_id = api.get_file_id_by_path(t_repo_id1, '/' + new_file_name)
    assert t_file_size == api.get_file_size(t_repo_id1, t_repo_version,
                                            t_file_id)

    # test copy_file (asynchronous)
    t_repo_id2 = api.create_repo('test_file_operation2', '', USER, passwd=None)
    usage = api.get_user_self_usage(USER)
    api.set_user_quota(USER, usage + 1)
    t_copy_file_result2 = api.copy_file(t_repo_id1, '/', file_name, t_repo_id2,
                                        '/', file_name, USER, 1, 0)
    assert t_copy_file_result2
    assert t_copy_file_result2.background
    while True:
        time.sleep(0.1)
        t_copy_task = api.get_copy_task(t_copy_file_result2.task_id)
        assert t_copy_task.failed
        assert t_copy_task.failed_reason == 'Quota is full'
        if t_copy_task.failed:
            break

    api.set_user_quota(USER, -1)
    t_copy_file_result2 = api.copy_file(t_repo_id1, '/', file_name, t_repo_id2,
                                        '/', file_name, USER, 1, 0)
    assert t_copy_file_result2
    assert t_copy_file_result2.task_id
    assert t_copy_file_result2.background
    while True:
        time.sleep(0.1)
        t_copy_task = api.get_copy_task(t_copy_file_result2.task_id)
        if t_copy_task.successful:
            break
    t_file_id = api.get_file_id_by_path(t_repo_id2, '/' + file_name)
    assert t_file_size == api.get_file_size(t_repo_id2, t_repo_version,
                                            t_file_id)

    # test move_file (synchronize)
    t_move_file_info1 = api.get_dirent_by_path(t_repo_id1, '/' + new_file_name)
    t_move_file_result1 = api.move_file(t_repo_id1, '/', new_file_name,
                                        t_repo_id1, '/' + dir_name,
                                        new_file_name, 1, USER, 0, 1)
    assert t_move_file_result1
    t_move_file_info2 = api.get_dirent_by_path(
        t_repo_id1, '/' + dir_name + '/' + new_file_name)
    assert t_move_file_info1.mtime == t_move_file_info2.mtime
    t_file_id = api.get_file_id_by_path(t_repo_id1, '/' + new_file_name)
    assert t_file_id is None

    # test move_file (synchronize)
    t_move_file_result1 = api.move_file(t_repo_id1, '/' + dir_name,
                                        new_file_name, t_repo_id1, '/',
                                        new_file_name_2, 1, USER, 0, 1)
    assert t_move_file_result1
    t_file_id = api.get_file_id_by_path(t_repo_id1,
                                        '/' + dir_name + '/' + new_file_name)
    assert t_file_id is None

    # test move_file (asynchronous)
    usage = api.get_user_self_usage(USER)
    api.set_user_quota(USER, usage + 1)
    t_move_file_result2 = api.move_file(t_repo_id1, '/', file_name, t_repo_id2,
                                        '/', new_file_name, 1, USER, 1, 0)
    assert t_move_file_result2
    assert t_move_file_result2.task_id
    assert t_move_file_result2.background
    while True:
        time.sleep(0.1)
        t_move_task = api.get_copy_task(t_move_file_result2.task_id)
        assert t_move_task.failed
        assert t_move_task.failed_reason == 'Quota is full'
        if t_move_task.failed:
            break

    api.set_user_quota(USER, -1)
    t_move_file_result2 = api.move_file(t_repo_id1, '/', file_name, t_repo_id2,
                                        '/', new_file_name, 1, USER, 1, 0)
    assert t_move_file_result2
    assert t_move_file_result2.task_id
    assert t_move_file_result2.background
    while True:
        time.sleep(0.1)
        t_move_task = api.get_copy_task(t_move_file_result2.task_id)
        if t_move_task.successful:
            break
    t_file_id = api.get_file_id_by_path(t_repo_id2, '/' + new_file_name)
    assert t_file_size == api.get_file_size(t_repo_id2, t_repo_version,
                                            t_file_id)

    # test post_empty_file
    assert api.post_empty_file(t_repo_id1, '/' + dir_name, empty_file_name,
                               USER) == 0
    t_file_id = api.get_file_id_by_path(t_repo_id1,
                                        '/' + dir_name + '/' + empty_file_name)
    assert api.get_file_size(t_repo_id1, t_repo_version, t_file_id) == 0

    # test rename_file
    assert api.rename_file(t_repo_id1, '/' + dir_name, empty_file_name,
                           new_empty_file_name, USER) == 0

    #test put_file
    t_new_file_id = api.put_file(t_repo_id1, file_path, '/' + dir_name,
                                 new_empty_file_name, USER, None)
    assert t_new_file_id

    # test get_file_revisions
    t_commit_list = api.get_file_revisions(t_repo_id2, None, '/' + file_name,
                                           2)
    assert t_commit_list
    assert len(t_commit_list) == 2
    assert t_commit_list[0].creator_name == USER

    # test del_file
    assert api.del_file(t_repo_id2, '/', file_name, USER) == 0

    # test get_deleted
    t_deleted_file_list = api.get_deleted(t_repo_id2, 1)
    assert t_deleted_file_list
    assert len(t_deleted_file_list) == 2
    assert t_deleted_file_list[0].obj_name == file_name
    assert t_deleted_file_list[0].basedir == '/'

    # test del a non-exist file. should return 0.
    assert api.del_file(t_repo_id2, '/', file_name, USER) == 0

    assert api.del_file(t_repo_id1, '/' + dir_name, new_empty_file_name,
                        USER) == 0
    assert api.del_file(t_repo_id1, '/' + dir_name, new_file_name, USER) == 0
    assert api.del_file(t_repo_id2, '/', new_file_name, USER) == 0
    assert api.del_file(t_repo_id1, '/', new_file_name_2, USER) == 0

    time.sleep(1)
    api.remove_repo(t_repo_id1)
Esempio n. 30
0
    def post(self, request, repo_id, format=None):
        """ Create, rename, move, copy, revert file

        Permission checking:
        1. create: user with 'rw' permission for current parent dir;
        2. rename: user with 'rw' permission for current file;
        3. move  : user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        4. copy  : user with 'r' permission for current file, 'rw' permission for dst parent dir;
        4. revert: user with 'rw' permission for current file's parent dir;
        """

        # argument check
        path = request.GET.get('p', None)
        if not path or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        operation = operation.lower()
        if operation not in ('create', 'rename', 'move', 'copy', 'revert'):
            error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        username = request.user.username
        parent_dir = os.path.dirname(path)

        if operation == 'create':
            # resource check
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(
                    repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

            # create file
            new_file_name = os.path.basename(path)
            new_file_name = check_filename_with_rename(repo_id, parent_dir,
                                                       new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name,
                                            username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            new_file_path = posixpath.join(parent_dir, new_file_name)
            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)
Esempio n. 31
0
    def post(self, request, repo_id, format=None):
        """ Create, rename, move, copy, revert file

        Permission checking:
        1. create: user with 'rw' permission for current parent dir;
        2. rename: user with 'rw' permission for current file;
        3. move  : user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        4. copy  : user with 'r' permission for current file, 'rw' permission for dst parent dir;
        4. revert: user with 'rw' permission for current file's parent dir;
        """

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

        path = normalize_file_path(path)

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

        operation = operation.lower()
        if operation not in ('create', 'rename', 'move', 'copy', 'revert'):
            error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        username = request.user.username
        parent_dir = os.path.dirname(path)

        is_draft = request.POST.get('is_draft', '')

        if operation == 'create':
            # resource check
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

            if is_draft.lower() == 'true':
                file_name = os.path.basename(path)
                file_dir = os.path.dirname(path)

                draft_type = os.path.splitext(file_name)[0][-7:]
                file_type = os.path.splitext(file_name)[-1]

                if draft_type != '(draft)':
                    f = os.path.splitext(file_name)[0]
                    path = file_dir + '/' + f + '(draft)' + file_type

            # create new empty file
            new_file_name = os.path.basename(path)

            if not is_valid_dirent_name(new_file_name):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'name invalid.')

            new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if is_draft.lower() == 'true':
                Draft.objects.add(username, repo, path, file_exist=False)

            # update office file by template
            if new_file_name.endswith('.xlsx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx')
            elif new_file_name.endswith('.pptx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx')
            elif new_file_name.endswith('.docx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx')
            else:
                empty_file_path = ''

            if empty_file_path:
                # get file server update url
                update_token = seafile_api.get_fileserver_access_token(
                        repo_id, 'dummy', 'update', username)

                if not update_token:
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

                update_url = gen_inner_file_upload_url('update-api', update_token)
                # update file
                new_file_path = posixpath.join(parent_dir, new_file_name)
                try:
                    requests.post(
                        update_url,
                        data={'filename': new_file_name, 'target_file': new_file_path},
                        files={'file': open(empty_file_path, 'rb')}
                    )
                except Exception as e:
                    logger.error(e)

            new_file_path = posixpath.join(parent_dir, new_file_name)
            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)
Esempio n. 32
0
    def post(self, request, format=None):
        """Add a new wiki.
        """
        username = request.user.username

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

        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)

        # check perm
        if not (request.user.permissions.can_publish_repo() and request.user.permissions.can_generate_share_link()):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        is_owner = is_repo_owner(request, repo_id, username)

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

            if not repo_admin:
                is_group_repo_admin = is_group_repo_staff(request, 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, permission='public')
        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)

        fs = FileShare.objects.get_dir_link_by_path(username, repo_id, '/')
        if not fs:
            fs = FileShare.objects.create_dir_link(username, repo_id, '/',
                    permission='view_download', org_id=org_id)

        return Response(wiki.to_dict())
Esempio n. 33
0
 def create_file(self, **kwargs):
     seafile_api.post_empty_file(**kwargs)
     return kwargs['parent_dir'] + kwargs['filename']
Esempio n. 34
0
    def create_new_file(self):
        new_file_name = u'file-中文'
        seafile_api.post_empty_file(self.repo_id, '/', new_file_name,
                                    self.user_name)

        return new_file_name
Esempio n. 35
0
    def post(self, request, repo_id, format=None):
        """ Create, rename, move, copy, revert file

        Permission checking:
        1. create: user with 'rw' permission for current parent dir;
        2. rename: user with 'rw' permission for current file;
        3. move  : user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        4. copy  : user with 'r' permission for current file, 'rw' permission for dst parent dir;
        4. revert: user with 'rw' permission for current file's parent dir;
        """

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

        path = normalize_file_path(path)

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

        operation = operation.lower()
        if operation not in ('create', 'rename', 'move', 'copy', 'revert'):
            error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        username = request.user.username
        parent_dir = os.path.dirname(path)

        is_draft = request.POST.get('is_draft', '')

        if operation == 'create':
            # resource check
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

            if is_draft.lower() == 'true':
                file_name = os.path.basename(path)
                file_dir = os.path.dirname(path)

                draft_type = os.path.splitext(file_name)[0][-7:]
                file_type = os.path.splitext(file_name)[-1]

                if draft_type != '(draft)':
                    f = os.path.splitext(file_name)[0]
                    path = file_dir + '/' + f + '(draft)' + file_type

            # create new empty file
            new_file_name = os.path.basename(path)

            if not is_valid_dirent_name(new_file_name):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'name invalid.')

            new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if is_draft.lower() == 'true':
                Draft.objects.add(username, repo, path, file_exist=False)

            # update office file by template
            if new_file_name.endswith('.xlsx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx')
            elif new_file_name.endswith('.pptx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx')
            elif new_file_name.endswith('.docx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx')
            else:
                empty_file_path = ''

            if empty_file_path:
                # get file server update url
                update_token = seafile_api.get_fileserver_access_token(
                        repo_id, 'dummy', 'update', username)

                if not update_token:
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

                update_url = gen_inner_file_upload_url('update-api', update_token)
                # update file
                new_file_path = posixpath.join(parent_dir, new_file_name)
                try:
                    requests.post(
                        update_url,
                        data={'filename': new_file_name, 'target_file': new_file_path},
                        files={'file': open(empty_file_path, 'rb')}
                    )
                except Exception as e:
                    logger.error(e)

            new_file_path = posixpath.join(parent_dir, new_file_name)
            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)

        if operation == 'rename':
            # argument check
            new_file_name = request.data.get('newname', None)
            if not new_file_name:
                error_msg = 'newname invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if not is_valid_dirent_name(new_file_name):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'name invalid.')

            if len(new_file_name) > MAX_UPLOAD_FILE_NAME_LEN:
                error_msg = 'newname is too long.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            oldname = os.path.basename(path)
            if oldname == new_file_name:
                error_msg = 'The new name is the same to the old'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            # resource check
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

            # check file lock
            try:
                is_locked, locked_by_me = check_file_lock(repo_id, path, username)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

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

            # rename file
            new_file_name = check_filename_with_rename(repo_id, parent_dir,
                    new_file_name)
            try:
                seafile_api.rename_file(repo_id, parent_dir, oldname,
                        new_file_name, username)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            new_file_path = posixpath.join(parent_dir, new_file_name)

            # rename draft file
            filetype, fileext = get_file_type_and_ext(new_file_name)
            if filetype == MARKDOWN or filetype == TEXT:
                is_draft = is_draft_file(repo.id, path)
                review = get_file_draft(repo.id, path, is_draft)
                draft_id = review['draft_id']
                if is_draft:
                    try:
                        draft = Draft.objects.get(pk=draft_id)
                        draft.draft_file_path = new_file_path
                        draft.save()
                    except Draft.DoesNotExist:
                        pass

            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)

        if operation == 'move':
            # argument check
            dst_repo_id = request.data.get('dst_repo', None)
            dst_dir = request.data.get('dst_dir', None)
            if not dst_repo_id:
                error_msg = 'dst_repo invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if not dst_dir:
                error_msg = 'dst_dir invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_dir = normalize_dir_path(dst_dir)

            # resource check for source file
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # resource check for dst repo and dir
            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # permission check for source file
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if check_folder_permission(request, src_repo_id, src_dir) != PERMISSION_READ_WRITE:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # permission check for dst dir
            if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # check file lock
            try:
                is_locked, locked_by_me = check_file_lock(repo_id, path, username)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

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

            # move file
            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                file_info = self.get_file_info(username, repo_id, path)
                return Response(file_info)

            filename = os.path.basename(path)
            new_file_name = check_filename_with_rename(dst_repo_id, dst_dir, filename)
            try:
                seafile_api.move_file(src_repo_id, src_dir, filename,
                        dst_repo_id, dst_dir, new_file_name, replace=False,
                        username=username, need_progress=0, synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            dst_file_path = posixpath.join(dst_dir, new_file_name)
            dst_file_info = self.get_file_info(username, dst_repo_id, dst_file_path)
            return Response(dst_file_info)

        if operation == 'copy':
            # argument check
            dst_repo_id = request.data.get('dst_repo', None)
            dst_dir = request.data.get('dst_dir', None)
            if not dst_repo_id:
                error_msg = 'dst_repo_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if not dst_dir:
                error_msg = 'dst_dir invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_dir = normalize_dir_path(dst_dir)

            # resource check for source file
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # resource check for dst repo and dir
            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # permission check for source file
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)

            if parse_repo_perm(check_folder_permission(
                            request, src_repo_id, src_dir)).can_copy is False:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # permission check for dst dir
            if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            filename = os.path.basename(path)
            new_file_name = check_filename_with_rename(dst_repo_id, dst_dir, filename)
            try:
                seafile_api.copy_file(src_repo_id, src_dir, filename, dst_repo_id,
                          dst_dir, new_file_name, username, 0, synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            dst_file_path = posixpath.join(dst_dir, new_file_name)
            dst_file_info = self.get_file_info(username, dst_repo_id, dst_file_path)
            return Response(dst_file_info)

        if operation == 'revert':
            commit_id = request.data.get('commit_id', None)
            if not commit_id:
                error_msg = 'commit_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if seafile_api.get_file_id_by_path(repo_id, path):
                # file exists in repo
                if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                # check file lock
                try:
                    is_locked, locked_by_me = check_file_lock(repo_id, path, username)
                except Exception as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

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

            else:
                # file NOT exists in repo
                if check_folder_permission(request, repo_id, '/') != PERMISSION_READ_WRITE:
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            try:
                seafile_api.revert_file(repo_id, commit_id, path, 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})
Esempio n. 36
0
    def post(self, request, format=None):
        """Add a new wiki.
        """
        username = request.user.username

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

        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)

        # check perm
        if not request.user.permissions.can_publish_repo():
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        is_owner = is_repo_owner(request, repo_id, username)

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

            if not repo_admin:
                is_group_repo_admin = is_group_repo_staff(request, 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, permission='public')
        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)

        fs = FileShare.objects.get_dir_link_by_path(username, repo_id, '/')
        if not fs:
            fs = FileShare.objects.create_dir_link(username, repo_id, '/',
                    permission='view_download', org_id=org_id)

        return Response(wiki.to_dict())
Esempio n. 37
0
 def create_file(self, **kwargs):
     seafile_api.post_empty_file(**kwargs)
     return kwargs['parent_dir'] + kwargs['filename']
Esempio n. 38
0
 def create_file(self, **kwargs):
     seafile_api.post_empty_file(**kwargs)
     return kwargs["parent_dir"] + kwargs["filename"]
Esempio n. 39
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 check_folder_permission(request, repo_id, '/') != 'rw':
                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()) 
Esempio n. 40
0
    def post(self, request, repo_id, format=None):
        # rename, move, copy or create file
        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)

        path = request.GET.get('p', '')
        if not path or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        username = request.user.username
        parent_dir = os.path.dirname(path)
        operation = request.POST.get('operation', '')
        if operation.lower() == 'rename':
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, repo_id, path) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            newname = request.POST.get('newname', '')
            if not newname:
                error_msg = 'newname invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if len(newname) > MAX_UPLOAD_FILE_NAME_LEN:
                error_msg = 'newname is too long.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            oldname = os.path.basename(path)
            if oldname == newname:
                error_msg = 'The new name is the same to the old'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            newname = check_filename_with_rename(repo_id, parent_dir, newname)
            try:
                seafile_api.rename_file(repo_id, parent_dir, oldname, newname, username)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, repo, parent_dir)
            else:
                return Response({'success': True})

        elif operation.lower() == 'move':
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # check src validation
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if check_folder_permission(request, src_repo_id, src_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # check dst validation
            dst_repo_id = request.POST.get('dst_repo', '')
            dst_dir = request.POST.get('dst_dir', '')
            if not dst_repo_id:
                error_msg = 'dst_repo_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if not dst_dir:
                error_msg = 'dst_dir invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # move file
            if dst_dir[-1] != '/': # Append '/' to the end of directory if necessary
                dst_dir += '/'

            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                return Response({'success': True})

            filename = os.path.basename(path)
            new_filename = check_filename_with_rename(dst_repo_id, dst_dir, filename)
            try:
                seafile_api.move_file(src_repo_id, src_dir, filename, dst_repo_id,
                      dst_dir, new_filename, username, 0, synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, dst_repo, dst_dir)
            else:
                return Response({'success': True})

        elif operation.lower() == 'copy':
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # check src validation
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if check_folder_permission(request, src_repo_id, src_dir) is None:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # check dst validation
            dst_repo_id = request.POST.get('dst_repo', '')
            dst_dir = request.POST.get('dst_dir', '')
            if not dst_repo_id:
                error_msg = 'dst_repo_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if not dst_dir:
                error_msg = 'dst_dir invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # copy file
            if dst_dir[-1] != '/': # Append '/' to the end of directory if necessary
                dst_dir += '/'

            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                return Response({'success': True})

            filename = os.path.basename(path)
            new_filename = check_filename_with_rename(dst_repo_id, dst_dir, filename)
            try:
                seafile_api.copy_file(src_repo_id, src_dir, filename, dst_repo_id,
                          dst_dir, new_filename, username, 0, synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, dst_repo, dst_dir)
            else:
                return Response({'success': True})

        elif operation.lower() == 'create':
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, repo_id, parent_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            new_file_name = os.path.basename(path)
            new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, repo, parent_dir)
            else:
                return Response({'success': True})
Esempio n. 41
0
    def create_new_file(self, parent_dir='/'):
        new_file_name = '%s-中文' % randstring(6)
        seafile_api.post_empty_file(self.repo_id,
                parent_dir, new_file_name, self.user_name)

        return new_file_name
Esempio n. 42
0
    def post(self, request, repo_id, format=None):
        """ Create, rename, move, copy, revert file

        Permission checking:
        1. create: user with 'rw' permission for current parent dir;
        2. rename: user with 'rw' permission for current file;
        3. move  : user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        4. copy  : user with 'r' permission for current file, 'rw' permission for dst parent dir;
        4. revert: user with 'rw' permission for current file's parent dir;
        """

        # argument check
        path = request.GET.get('p', None)
        if not path or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        operation = operation.lower()
        if operation not in ('create', 'rename', 'move', 'copy', 'revert'):
            error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        username = request.user.username
        parent_dir = os.path.dirname(path)

        if operation == 'create':
            # resource check
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

            # create new empty file
            new_file_name = os.path.basename(path)

            if not is_valid_dirent_name(new_file_name):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'name invalid.')

            new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            # update office file by template
            if new_file_name.endswith('.xlsx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx')
            elif new_file_name.endswith('.pptx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx')
            elif new_file_name.endswith('.docx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx')
            else:
                empty_file_path = ''

            if empty_file_path:
                # get file server update url
                update_token = seafile_api.get_fileserver_access_token(
                        repo_id, 'dummy', 'update', username)
                update_url = gen_file_upload_url(update_token, 'update-api')

                # update file
                try:
                    requests.post(
                        update_url,
                        data={'filename': new_file_name, 'target_file': path},
                        files={'file': open(empty_file_path, 'rb')}
                    )
                except Exception as e:
                    logger.error(e)

            new_file_path = posixpath.join(parent_dir, new_file_name)
            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)
Esempio n. 43
0
    def post(self, request, repo_id, format=None):
        # rename, move, copy or create file
        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)

        path = request.GET.get('p', '')
        if not path or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        username = request.user.username
        parent_dir = os.path.dirname(path)
        operation = request.POST.get('operation', '')
        if operation.lower() == 'rename':
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, repo_id, path) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            newname = request.POST.get('newname', '')
            if not newname:
                error_msg = 'newname invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if len(newname) > MAX_UPLOAD_FILE_NAME_LEN:
                error_msg = 'newname is too long.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            oldname = os.path.basename(path)
            if oldname == newname:
                error_msg = 'The new name is the same to the old'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            newname = check_filename_with_rename(repo_id, parent_dir, newname)
            try:
                seafile_api.rename_file(repo_id, parent_dir, oldname, newname,
                                        username)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, repo, parent_dir)
            else:
                return Response({'success': True})

        elif operation.lower() == 'move':
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # check src validation
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if check_folder_permission(request, src_repo_id, src_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # check dst validation
            dst_repo_id = request.POST.get('dst_repo', '')
            dst_dir = request.POST.get('dst_dir', '')
            if not dst_repo_id:
                error_msg = 'dst_repo_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if not dst_dir:
                error_msg = 'dst_dir invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # move file
            if dst_dir[
                    -1] != '/':  # Append '/' to the end of directory if necessary
                dst_dir += '/'

            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                return Response({'success': True})

            filename = os.path.basename(path)
            new_filename = check_filename_with_rename(dst_repo_id, dst_dir,
                                                      filename)
            try:
                seafile_api.move_file(src_repo_id,
                                      src_dir,
                                      filename,
                                      dst_repo_id,
                                      dst_dir,
                                      new_filename,
                                      username,
                                      0,
                                      synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, dst_repo, dst_dir)
            else:
                return Response({'success': True})

        elif operation.lower() == 'copy':
            try:
                file_id = seafile_api.get_file_id_by_path(repo_id, path)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if not file_id:
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # check src validation
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if check_folder_permission(request, src_repo_id, src_dir) is None:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # check dst validation
            dst_repo_id = request.POST.get('dst_repo', '')
            dst_dir = request.POST.get('dst_dir', '')
            if not dst_repo_id:
                error_msg = 'dst_repo_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if not dst_dir:
                error_msg = 'dst_dir invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # copy file
            if dst_dir[
                    -1] != '/':  # Append '/' to the end of directory if necessary
                dst_dir += '/'

            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                return Response({'success': True})

            filename = os.path.basename(path)
            new_filename = check_filename_with_rename(dst_repo_id, dst_dir,
                                                      filename)
            try:
                seafile_api.copy_file(src_repo_id,
                                      src_dir,
                                      filename,
                                      dst_repo_id,
                                      dst_dir,
                                      new_filename,
                                      username,
                                      0,
                                      synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, dst_repo, dst_dir)
            else:
                return Response({'success': True})

        elif operation.lower() == 'create':
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(
                    repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, repo_id, parent_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            new_file_name = os.path.basename(path)
            new_file_name = check_filename_with_rename(repo_id, parent_dir,
                                                       new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name,
                                            username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                return reloaddir(request, repo, parent_dir)
            else:
                return Response({'success': True})
Esempio n. 44
0
    def post(self, request, repo_id, format=None):
        """ Create, rename, move, copy file

        Permission checking:
        1. create: user with 'rw' permission for current parent dir;
        2. rename: user with 'rw' permission for current file;
        3. move  : user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        4. copy  : user with 'r' permission for current file, 'rw' permission for dst parent dir;
        """

        # argument check
        path = request.GET.get('p', None)
        if not path or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        operation = operation.lower()
        if operation not in ('create', 'rename', 'move', 'copy'):
            error_msg = "operation can only be 'create', 'rename', 'move' or 'copy'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        username = request.user.username
        parent_dir = os.path.dirname(path)

        if operation == 'create':
            # resource check
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if not parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

            # create file
            new_file_name = os.path.basename(path)
            new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            new_file_path = posixpath.join(parent_dir, new_file_name)
            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)