mirror of
https://github.com/langgenius/dify.git
synced 2026-06-07 16:32:01 +08:00
fix(security): tenant-scope FilePreviewApi text-extract endpoint (GHSA-2qwc-c2cc-2xwv) (#35797)
Signed-off-by: xr843 <137012659+xr843@users.noreply.github.com> Co-authored-by: Ido Shani <ido@zafran.io> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: -LAN- <laipz8200@outlook.com>
This commit is contained in:
parent
55d05fe52d
commit
432a6412a3
@ -105,7 +105,8 @@ class FilePreviewApi(Resource):
|
||||
@account_initialization_required
|
||||
def get(self, file_id):
|
||||
file_id = str(file_id)
|
||||
text = FileService(db.engine).get_file_preview(file_id)
|
||||
_, tenant_id = current_account_with_tenant()
|
||||
text = FileService(db.engine).get_file_preview(file_id, tenant_id)
|
||||
return {"content": text}
|
||||
|
||||
|
||||
|
||||
@ -172,12 +172,14 @@ class FileService:
|
||||
|
||||
return upload_file
|
||||
|
||||
def get_file_preview(self, file_id: str):
|
||||
def get_file_preview(self, file_id: str, tenant_id: str):
|
||||
"""
|
||||
Return a short text preview extracted from a document file.
|
||||
"""
|
||||
with self._session_maker(expire_on_commit=False) as session:
|
||||
upload_file = session.scalar(select(UploadFile).where(UploadFile.id == file_id).limit(1))
|
||||
upload_file = session.scalar(
|
||||
select(UploadFile).where(UploadFile.id == file_id, UploadFile.tenant_id == tenant_id).limit(1)
|
||||
)
|
||||
|
||||
if not upload_file:
|
||||
raise NotFound("File not found")
|
||||
|
||||
@ -514,7 +514,7 @@ class TestFileService:
|
||||
|
||||
db_session_with_containers.commit()
|
||||
|
||||
result = FileService(engine).get_file_preview(file_id=upload_file.id)
|
||||
result = FileService(engine).get_file_preview(file_id=upload_file.id, tenant_id=upload_file.tenant_id)
|
||||
|
||||
assert result == "extracted text content"
|
||||
mock_external_service_dependencies["extract_processor"].load_from_upload_file.assert_called_once()
|
||||
@ -529,7 +529,7 @@ class TestFileService:
|
||||
non_existent_id = str(fake.uuid4())
|
||||
|
||||
with pytest.raises(NotFound, match="File not found"):
|
||||
FileService(engine).get_file_preview(file_id=non_existent_id)
|
||||
FileService(engine).get_file_preview(file_id=non_existent_id, tenant_id=str(fake.uuid4()))
|
||||
|
||||
def test_get_file_preview_unsupported_file_type(
|
||||
self, db_session_with_containers: Session, engine, mock_external_service_dependencies
|
||||
@ -549,7 +549,7 @@ class TestFileService:
|
||||
db_session_with_containers.commit()
|
||||
|
||||
with pytest.raises(UnsupportedFileTypeError):
|
||||
FileService(engine).get_file_preview(file_id=upload_file.id)
|
||||
FileService(engine).get_file_preview(file_id=upload_file.id, tenant_id=upload_file.tenant_id)
|
||||
|
||||
def test_get_file_preview_text_truncation(
|
||||
self, db_session_with_containers: Session, engine, mock_external_service_dependencies
|
||||
@ -572,7 +572,7 @@ class TestFileService:
|
||||
long_text = "x" * 5000 # Longer than PREVIEW_WORDS_LIMIT
|
||||
mock_external_service_dependencies["extract_processor"].load_from_upload_file.return_value = long_text
|
||||
|
||||
result = FileService(engine).get_file_preview(file_id=upload_file.id)
|
||||
result = FileService(engine).get_file_preview(file_id=upload_file.id, tenant_id=upload_file.tenant_id)
|
||||
|
||||
assert len(result) == 3000 # PREVIEW_WORDS_LIMIT
|
||||
assert result == "x" * 3000
|
||||
|
||||
@ -278,7 +278,7 @@ class TestFileApiPost:
|
||||
|
||||
|
||||
class TestFilePreviewApi:
|
||||
def test_get_preview(self, app, mock_file_service):
|
||||
def test_get_preview(self, app, mock_account_context, mock_file_service):
|
||||
api = FilePreviewApi()
|
||||
get_method = unwrap(api.get)
|
||||
mock_file_service.get_file_preview.return_value = "preview text"
|
||||
|
||||
@ -221,7 +221,7 @@ class TestFileService:
|
||||
mock_extract.return_value = "Extracted text content"
|
||||
|
||||
# Execute
|
||||
result = file_service.get_file_preview("file_id")
|
||||
result = file_service.get_file_preview("file_id", "tenant_id")
|
||||
|
||||
# Assert
|
||||
assert result == "Extracted text content"
|
||||
@ -229,7 +229,7 @@ class TestFileService:
|
||||
def test_get_file_preview_not_found(self, file_service, mock_db_session):
|
||||
mock_db_session.scalar.return_value = None
|
||||
with pytest.raises(NotFound, match="File not found"):
|
||||
file_service.get_file_preview("non_existent")
|
||||
file_service.get_file_preview("non_existent", "tenant_id")
|
||||
|
||||
def test_get_file_preview_unsupported_type(self, file_service, mock_db_session):
|
||||
upload_file = MagicMock(spec=UploadFile)
|
||||
@ -237,7 +237,7 @@ class TestFileService:
|
||||
upload_file.extension = "exe"
|
||||
mock_db_session.scalar.return_value = upload_file
|
||||
with pytest.raises(UnsupportedFileTypeError):
|
||||
file_service.get_file_preview("file_id")
|
||||
file_service.get_file_preview("file_id", "tenant_id")
|
||||
|
||||
def test_get_image_preview_success(self, file_service, mock_db_session):
|
||||
# Setup
|
||||
|
||||
Loading…
Reference in New Issue
Block a user