mirror of
https://github.com/langgenius/dify.git
synced 2026-11-10 21:35:45 +08:00
fix(api): enforce dataset operation permissions (#42758)
This commit is contained in:
1 parent
486bcb0b08
commit
f6561d8cc0
4 files changed
+29
-5
No files matched your search
@@ -806,7 +806,7 @@ class DatasetApi(Resource):
|
||||
@cloud_edition_billing_rate_limit_check("knowledge")
|
||||
@console_ns.response(204, "Dataset deleted successfully")
|
||||
@with_current_user
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_DELETE, DatasetId()))
|
||||
@with_session
|
||||
def delete(self, session: Session, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
|
||||
@@ -544,7 +544,7 @@ class DatasetDocumentListApi(Resource):
|
||||
@console_ns.expect(console_ns.models[KnowledgeConfig.__name__])
|
||||
@console_ns.response(200, "Documents created successfully", console_ns.models[DatasetAndDocumentResponse.__name__])
|
||||
@with_current_user
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_USE, DatasetId()))
|
||||
@with_session
|
||||
def post(self, session: Session, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
@@ -595,7 +595,7 @@ class DatasetDocumentListApi(Resource):
|
||||
@console_ns.response(204, "Documents deleted successfully")
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_DELETE_FILE, DatasetId()))
|
||||
@with_session
|
||||
def delete(
|
||||
self,
|
||||
@@ -1125,7 +1125,7 @@ class DocumentApi(DocumentResource):
|
||||
@console_ns.response(204, "Document deleted successfully")
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_DELETE_FILE, DatasetId()))
|
||||
@with_session
|
||||
def delete(
|
||||
self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID
|
||||
@@ -1185,7 +1185,7 @@ class DocumentBatchDownloadZipApi(DocumentResource):
|
||||
@console_ns.expect(console_ns.models[DocumentBatchDownloadZipPayload.__name__])
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
|
||||
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_DOCUMENT_DOWNLOAD, DatasetId()))
|
||||
@with_session(write=False)
|
||||
def post(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
|
||||
"""Stream a ZIP archive containing the requested uploaded documents."""
|
||||
|
||||
@@ -58,6 +58,7 @@ from models.model import ApiToken, App, AppMode, DatasetApiTokenBinding, IconTyp
|
||||
from services.dataset_ref_service import DatasetRef
|
||||
from services.dataset_service import DatasetPermissionService, DatasetService
|
||||
from services.enterprise import rbac_service as enterprise_rbac_service
|
||||
from tests.unit_tests.controllers.rbac_introspection import rbac_checks
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -151,6 +152,13 @@ def make_related_app(**overrides) -> App:
|
||||
return App(**base)
|
||||
|
||||
|
||||
def test_dataset_delete_requires_dataset_delete_permission() -> None:
|
||||
[check] = rbac_checks(DatasetApi.delete)
|
||||
|
||||
assert check.scene is RBACPermission.DATASET_DELETE
|
||||
assert isinstance(check.locator, DatasetId)
|
||||
|
||||
|
||||
def make_document_status(**overrides) -> Document:
|
||||
base = {
|
||||
"id": "doc-1",
|
||||
|
||||
@@ -256,6 +256,22 @@ def test_document_indexing_estimates_require_dataset_use_permission(method) -> N
|
||||
assert isinstance(check.locator, DatasetId)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("method", "expected_scene"),
|
||||
[
|
||||
(DatasetDocumentListApi.post, RBACPermission.DATASET_USE),
|
||||
(DatasetDocumentListApi.delete, RBACPermission.DATASET_DELETE_FILE),
|
||||
(DocumentApi.delete, RBACPermission.DATASET_DELETE_FILE),
|
||||
(DocumentBatchDownloadZipApi.post, RBACPermission.DATASET_DOCUMENT_DOWNLOAD),
|
||||
],
|
||||
)
|
||||
def test_document_mutation_routes_require_operation_specific_permissions(method, expected_scene) -> None:
|
||||
[check] = rbac_checks(method)
|
||||
|
||||
assert check.scene is expected_scene
|
||||
assert isinstance(check.locator, DatasetId)
|
||||
|
||||
|
||||
class TestGetProcessRuleApi(_UsesSQLiteSession):
|
||||
def test_get_default_success(self, app: Flask, patch_tenant):
|
||||
api = GetProcessRuleApi()
|
||||
|
||||
Reference in new issue
Block a user