remove: document download file permission (#24459)
This commit is contained in:
@@ -84,7 +84,6 @@ from .datasets import (
|
|||||||
external,
|
external,
|
||||||
hit_testing,
|
hit_testing,
|
||||||
metadata,
|
metadata,
|
||||||
upload_file,
|
|
||||||
website,
|
website,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,62 +0,0 @@
|
|||||||
from flask_login import current_user
|
|
||||||
from flask_restx import Resource
|
|
||||||
from werkzeug.exceptions import NotFound
|
|
||||||
|
|
||||||
from controllers.console import api
|
|
||||||
from controllers.console.wraps import (
|
|
||||||
account_initialization_required,
|
|
||||||
setup_required,
|
|
||||||
)
|
|
||||||
from core.file import helpers as file_helpers
|
|
||||||
from extensions.ext_database import db
|
|
||||||
from models.dataset import Dataset
|
|
||||||
from models.model import UploadFile
|
|
||||||
from services.dataset_service import DocumentService
|
|
||||||
|
|
||||||
|
|
||||||
class UploadFileApi(Resource):
|
|
||||||
@setup_required
|
|
||||||
@account_initialization_required
|
|
||||||
def get(self, dataset_id, document_id):
|
|
||||||
"""Get upload file."""
|
|
||||||
# check dataset
|
|
||||||
dataset_id = str(dataset_id)
|
|
||||||
dataset = (
|
|
||||||
db.session.query(Dataset)
|
|
||||||
.filter(Dataset.tenant_id == current_user.current_tenant_id, Dataset.id == dataset_id)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
if not dataset:
|
|
||||||
raise NotFound("Dataset not found.")
|
|
||||||
# check document
|
|
||||||
document_id = str(document_id)
|
|
||||||
document = DocumentService.get_document(dataset.id, document_id)
|
|
||||||
if not document:
|
|
||||||
raise NotFound("Document not found.")
|
|
||||||
# check upload file
|
|
||||||
if document.data_source_type != "upload_file":
|
|
||||||
raise ValueError(f"Document data source type ({document.data_source_type}) is not upload_file.")
|
|
||||||
data_source_info = document.data_source_info_dict
|
|
||||||
if data_source_info and "upload_file_id" in data_source_info:
|
|
||||||
file_id = data_source_info["upload_file_id"]
|
|
||||||
upload_file = db.session.query(UploadFile).where(UploadFile.id == file_id).first()
|
|
||||||
if not upload_file:
|
|
||||||
raise NotFound("UploadFile not found.")
|
|
||||||
else:
|
|
||||||
raise ValueError("Upload file id not found in document data source info.")
|
|
||||||
|
|
||||||
url = file_helpers.get_signed_file_url(upload_file_id=upload_file.id)
|
|
||||||
return {
|
|
||||||
"id": upload_file.id,
|
|
||||||
"name": upload_file.name,
|
|
||||||
"size": upload_file.size,
|
|
||||||
"extension": upload_file.extension,
|
|
||||||
"url": url,
|
|
||||||
"download_url": f"{url}&as_attachment=true",
|
|
||||||
"mime_type": upload_file.mime_type,
|
|
||||||
"created_by": upload_file.created_by,
|
|
||||||
"created_at": upload_file.created_at.timestamp(),
|
|
||||||
}, 200
|
|
||||||
|
|
||||||
|
|
||||||
api.add_resource(UploadFileApi, "/datasets/<uuid:dataset_id>/documents/<uuid:document_id>/upload-file")
|
|
@@ -7,7 +7,6 @@ import { pick, uniq } from 'lodash-es'
|
|||||||
import {
|
import {
|
||||||
RiArchive2Line,
|
RiArchive2Line,
|
||||||
RiDeleteBinLine,
|
RiDeleteBinLine,
|
||||||
RiDownloadLine,
|
|
||||||
RiEditLine,
|
RiEditLine,
|
||||||
RiEqualizer2Line,
|
RiEqualizer2Line,
|
||||||
RiLoopLeftLine,
|
RiLoopLeftLine,
|
||||||
@@ -35,7 +34,6 @@ import type { ColorMap, IndicatorProps } from '@/app/components/header/indicator
|
|||||||
import Indicator from '@/app/components/header/indicator'
|
import Indicator from '@/app/components/header/indicator'
|
||||||
import { asyncRunSafe } from '@/utils'
|
import { asyncRunSafe } from '@/utils'
|
||||||
import { formatNumber } from '@/utils/format'
|
import { formatNumber } from '@/utils/format'
|
||||||
import { useDocumentDownload } from '@/service/knowledge/use-document'
|
|
||||||
import NotionIcon from '@/app/components/base/notion-icon'
|
import NotionIcon from '@/app/components/base/notion-icon'
|
||||||
import ProgressBar from '@/app/components/base/progress-bar'
|
import ProgressBar from '@/app/components/base/progress-bar'
|
||||||
import { ChunkingMode, DataSourceType, DocumentActionType, type DocumentDisplayStatus, type SimpleDocumentDetail } from '@/models/datasets'
|
import { ChunkingMode, DataSourceType, DocumentActionType, type DocumentDisplayStatus, type SimpleDocumentDetail } from '@/models/datasets'
|
||||||
@@ -189,7 +187,6 @@ export const OperationAction: FC<{
|
|||||||
scene?: 'list' | 'detail'
|
scene?: 'list' | 'detail'
|
||||||
className?: string
|
className?: string
|
||||||
}> = ({ embeddingAvailable, datasetId, detail, onUpdate, scene = 'list', className = '' }) => {
|
}> = ({ embeddingAvailable, datasetId, detail, onUpdate, scene = 'list', className = '' }) => {
|
||||||
const downloadDocument = useDocumentDownload()
|
|
||||||
const { id, enabled = false, archived = false, data_source_type, display_status } = detail || {}
|
const { id, enabled = false, archived = false, data_source_type, display_status } = detail || {}
|
||||||
const [showModal, setShowModal] = useState(false)
|
const [showModal, setShowModal] = useState(false)
|
||||||
const [deleting, setDeleting] = useState(false)
|
const [deleting, setDeleting] = useState(false)
|
||||||
@@ -298,32 +295,6 @@ export const OperationAction: FC<{
|
|||||||
)}
|
)}
|
||||||
{embeddingAvailable && (
|
{embeddingAvailable && (
|
||||||
<>
|
<>
|
||||||
<Tooltip
|
|
||||||
popupContent={t('datasetDocuments.list.action.download')}
|
|
||||||
popupClassName='text-text-secondary system-xs-medium'
|
|
||||||
needsDelay={false}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className={cn('mr-2 cursor-pointer rounded-lg',
|
|
||||||
!isListScene
|
|
||||||
? 'shadow-shadow-3 border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg p-2 shadow-xs backdrop-blur-[5px] hover:border-components-button-secondary-border-hover hover:bg-components-button-secondary-bg-hover'
|
|
||||||
: 'p-0.5 hover:bg-state-base-hover')}
|
|
||||||
onClick={() => {
|
|
||||||
downloadDocument.mutateAsync({
|
|
||||||
datasetId,
|
|
||||||
documentId: detail.id,
|
|
||||||
}).then((response) => {
|
|
||||||
if (response.download_url)
|
|
||||||
window.location.href = response.download_url
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error)
|
|
||||||
notify({ type: 'error', message: t('common.actionMsg.downloadFailed') })
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RiDownloadLine className='h-4 w-4 text-components-button-secondary-text' />
|
|
||||||
</button>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
popupContent={t('datasetDocuments.list.action.settings')}
|
popupContent={t('datasetDocuments.list.action.settings')}
|
||||||
popupClassName='text-text-secondary system-xs-medium'
|
popupClassName='text-text-secondary system-xs-medium'
|
||||||
|
@@ -32,7 +32,6 @@ const translation = {
|
|||||||
sync: 'Sync',
|
sync: 'Sync',
|
||||||
pause: 'Pause',
|
pause: 'Pause',
|
||||||
resume: 'Resume',
|
resume: 'Resume',
|
||||||
download: 'Download File',
|
|
||||||
},
|
},
|
||||||
index: {
|
index: {
|
||||||
enable: 'Enable',
|
enable: 'Enable',
|
||||||
|
@@ -8,9 +8,7 @@ import type { MetadataType, SortType } from '../datasets'
|
|||||||
import { pauseDocIndexing, resumeDocIndexing } from '../datasets'
|
import { pauseDocIndexing, resumeDocIndexing } from '../datasets'
|
||||||
import type { DocumentDetailResponse, DocumentListResponse, UpdateDocumentBatchParams } from '@/models/datasets'
|
import type { DocumentDetailResponse, DocumentListResponse, UpdateDocumentBatchParams } from '@/models/datasets'
|
||||||
import { DocumentActionType } from '@/models/datasets'
|
import { DocumentActionType } from '@/models/datasets'
|
||||||
import type { CommonResponse, FileDownloadResponse } from '@/models/common'
|
import type { CommonResponse } from '@/models/common'
|
||||||
// Download document with authentication (sends Authorization header)
|
|
||||||
import Toast from '@/app/components/base/toast'
|
|
||||||
|
|
||||||
const NAME_SPACE = 'knowledge/document'
|
const NAME_SPACE = 'knowledge/document'
|
||||||
|
|
||||||
@@ -97,21 +95,6 @@ export const useSyncDocument = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download document with authentication (sends Authorization header)
|
|
||||||
export const useDocumentDownload = () => {
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async ({ datasetId, documentId }: { datasetId: string; documentId: string }) => {
|
|
||||||
// The get helper automatically adds the Authorization header from localStorage
|
|
||||||
return get<FileDownloadResponse>(`/datasets/${datasetId}/documents/${documentId}/upload-file`)
|
|
||||||
},
|
|
||||||
onError: (error: any) => {
|
|
||||||
// Show a toast notification if download fails
|
|
||||||
const message = error?.message || 'Download failed.'
|
|
||||||
Toast.notify({ type: 'error', message })
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useSyncWebsite = () => {
|
export const useSyncWebsite = () => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: ({ datasetId, documentId }: UpdateDocumentBatchParams) => {
|
mutationFn: ({ datasetId, documentId }: UpdateDocumentBatchParams) => {
|
||||||
|
Reference in New Issue
Block a user