mirror of
https://github.com/langgenius/dify.git
synced 2026-11-13 14:51:39 +08:00
Add a shared file malware-scanning module and use it in the Classic Knowledge Base, RAG Pipeline local files and the Agent Knowledge Base. - core/file_scan: scanner adapters for ClamAV (deployment-configured), Cloudmersive, Scanii, OPSWAT MetaDefender Cloud and API-based extensions (new `file.malware_scan` extension point). - services/file_scan: FileScanService is the single entry point other modules call. Providers are workspace-wide; a policy belongs to a scope (dataset, knowledge_fs_space), so further modules can adopt scanning without schema changes. - Each file is scanned on its own: a rejected file fails only its own document. Malware always blocks and deletes the stored original; invalid credentials and exhausted quota stop processing regardless of the "allow" fallback. - Console: workspace scanner management and a per-knowledge-base policy section in both settings forms; the Agent Knowledge Base upload keeps going after a rejected file and explains each failure. - Off by default behind FILE_SCAN_ENABLED. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
26 lines
700 B
Python
26 lines
700 B
Python
from services.file_scan.entities import ScanOutcome
|
|
|
|
|
|
class FileScanError(Exception):
|
|
"""Base error of the file scan services."""
|
|
|
|
|
|
class FileScanValidationError(FileScanError, ValueError):
|
|
"""Provider or policy input is invalid."""
|
|
|
|
|
|
class FileScanProviderNotFoundError(FileScanError):
|
|
pass
|
|
|
|
|
|
class FileScanProviderInUseError(FileScanError):
|
|
"""The provider is selected by at least one policy and cannot be deleted."""
|
|
|
|
|
|
class FileScanBlockedError(FileScanError):
|
|
"""Raised by callers that stop a pipeline when ``ScanOutcome.allowed`` is false."""
|
|
|
|
def __init__(self, outcome: ScanOutcome) -> None:
|
|
super().__init__(outcome.describe())
|
|
self.outcome = outcome
|