From c278148c8f30fc2223fd4e0c4f32cfc9d7de38f2 Mon Sep 17 00:00:00 2001 From: wangxiaolei Date: Tue, 14 Jul 2026 17:07:33 +0800 Subject: [PATCH] feat: when knowledge permission is all team need update rbac setttings (#38911) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- api/controllers/console/app/app.py | 2 +- api/controllers/console/datasets/datasets.py | 12 +++++++ .../service_api/dataset/dataset.py | 11 ++++++ api/services/enterprise/rbac_service.py | 2 +- ...initialize_created_app_rbac_access_task.py | 36 +++++++++++++------ .../console/app/test_app_response_models.py | 2 +- 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/api/controllers/console/app/app.py b/api/controllers/console/app/app.py index fb07207376d..65e9357d9ee 100644 --- a/api/controllers/console/app/app.py +++ b/api/controllers/console/app/app.py @@ -654,7 +654,7 @@ class AppListApi(Resource): app_id=str(app.id), payload=enterprise_rbac_service.ReplaceMemberBindings(scope=RBACResourceWhitelistScope.ALL), ) - initialize_created_app_rbac_access_task.delay(current_tenant_id, current_user.id, app.id) + initialize_created_app_rbac_access_task.delay(current_tenant_id, current_user.id, app_id=app.id) permission_keys_map = enterprise_rbac_service.RBACService.AppPermissions.batch_get( str(current_tenant_id), current_user.id, diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 15cc4f4cc06..0bf249f026b 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -53,6 +53,8 @@ from models.provider_ids import ModelProviderID from services.api_token_service import ApiTokenCache from services.dataset_service import DatasetPermissionService, DatasetService, DocumentService from services.enterprise import rbac_service as enterprise_rbac_service +from services.enterprise.rbac_service import RBACResourceWhitelistScope, ReplaceMemberBindings +from tasks.initialize_created_app_rbac_access_task import initialize_created_app_rbac_access_task register_response_schema_models(console_ns, ApiBaseUrlResponse, SimpleResultResponse, UsageCheckResponse) @@ -560,6 +562,16 @@ class DatasetListApi(Resource): except services.errors.dataset.DatasetNameDuplicateError: raise DatasetNameDuplicateError() + if dify_config.RBAC_ENABLED: + if permission == DatasetPermissionEnum.ALL_TEAM: + enterprise_rbac_service.RBACService.DatasetAccess.replace_whitelist( + current_tenant_id, + current_user.id, + dataset.id, + ReplaceMemberBindings(scope=RBACResourceWhitelistScope.ALL), + ) + initialize_created_app_rbac_access_task.delay(current_tenant_id, current_user.id, dataset_id=dataset.id) + permission_keys_map = enterprise_rbac_service.RBACService.DatasetPermissions.batch_get( current_tenant_id, current_user.id, diff --git a/api/controllers/service_api/dataset/dataset.py b/api/controllers/service_api/dataset/dataset.py index b9f6a6424af..a8a47f4819f 100644 --- a/api/controllers/service_api/dataset/dataset.py +++ b/api/controllers/service_api/dataset/dataset.py @@ -45,6 +45,7 @@ from models.dataset import DatasetPermissionEnum from models.enums import TagType from models.provider_ids import ModelProviderID from services.dataset_service import DatasetPermissionService, DatasetService, DocumentService +from services.enterprise.rbac_service import RBACResourceWhitelistScope, RBACService, ReplaceMemberBindings from services.entities.knowledge_entities.knowledge_entities import ( ExternalRetrievalModel, KnowledgeProvider, @@ -60,6 +61,7 @@ from services.tag_service import ( from services.tag_service import ( UpdateTagPayload as UpdateTagServicePayload, ) +from tasks.initialize_created_app_rbac_access_task import initialize_created_app_rbac_access_task register_enum_models(service_api_ns, DatasetPermissionEnum) @@ -527,6 +529,15 @@ class DatasetListApi(DatasetApiResource): except services.errors.dataset.DatasetNameDuplicateError: raise DatasetNameDuplicateError() + if payload.permission == DatasetPermissionEnum.ALL_TEAM and dify_config.RBAC_ENABLED: + RBACService.DatasetAccess.replace_whitelist( + tenant_id, + current_user.id, + dataset.id, + ReplaceMemberBindings(scope=RBACResourceWhitelistScope.ALL), + ) + initialize_created_app_rbac_access_task.delay(tenant_id, current_user.id, dataset_id=dataset.id) + return _dump_service_dataset_detail(dataset), 200 diff --git a/api/services/enterprise/rbac_service.py b/api/services/enterprise/rbac_service.py index b90f2ab6183..86cf4c210bd 100644 --- a/api/services/enterprise/rbac_service.py +++ b/api/services/enterprise/rbac_service.py @@ -1297,7 +1297,7 @@ class RBACService: tenant_id: str, account_id: str | None, dataset_id: str, - target_account_id: str, + target_account_id: str | None, payload: ReplaceUserAccessPolicies, ) -> ReplaceUserAccessPoliciesResponse: data = _inner_call( diff --git a/api/tasks/initialize_created_app_rbac_access_task.py b/api/tasks/initialize_created_app_rbac_access_task.py index c55126102e9..cb46d34beb4 100644 --- a/api/tasks/initialize_created_app_rbac_access_task.py +++ b/api/tasks/initialize_created_app_rbac_access_task.py @@ -17,7 +17,9 @@ APP_RBAC_QUEUE = "app_rbac" @shared_task(queue=APP_RBAC_QUEUE, bind=True, max_retries=3, default_retry_delay=60) -def initialize_created_app_rbac_access_task(self, tenant_id: str, account_id: str, app_id: str) -> None: +def initialize_created_app_rbac_access_task( + self, tenant_id: str, account_id: str, app_id: str | None = None, dataset_id: str | None = None +) -> None: """Grant the default app policy to current workspace members. App scope is persisted synchronously before this task is queued. Replacing @@ -33,16 +35,28 @@ def initialize_created_app_rbac_access_task(self, tenant_id: str, account_id: st APP_RBAC_ACCOUNT_POLICY_BATCH_SIZE, session=db.session(), ): - enterprise_rbac_service.RBACService.AppAccess.replace_user_access_policies( - tenant_id=tenant_id, - account_id=account_id, - app_id=app_id, - target_account_id=None, - payload=enterprise_rbac_service.ReplaceUserAccessPolicies( - access_policy_ids=[APP_RBAC_DEFAULT_ACCESS_POLICY_ID], - account_ids=account_ids, - ), - ) + if app_id is not None: + enterprise_rbac_service.RBACService.AppAccess.replace_user_access_policies( + tenant_id=tenant_id, + account_id=account_id, + app_id=app_id, + target_account_id=None, + payload=enterprise_rbac_service.ReplaceUserAccessPolicies( + access_policy_ids=[APP_RBAC_DEFAULT_ACCESS_POLICY_ID], + account_ids=account_ids, + ), + ) + elif dataset_id is not None: + enterprise_rbac_service.RBACService.DatasetAccess.replace_user_access_policies( + tenant_id=tenant_id, + account_id=account_id, + dataset_id=dataset_id, + target_account_id=None, + payload=enterprise_rbac_service.ReplaceUserAccessPolicies( + access_policy_ids=[APP_RBAC_DEFAULT_ACCESS_POLICY_ID], + account_ids=account_ids, + ), + ) except Exception as exc: logger.exception( "Failed to initialize app RBAC access; retrying: tenant_id=%s app_id=%s attempt=%s", diff --git a/api/tests/unit_tests/controllers/console/app/test_app_response_models.py b/api/tests/unit_tests/controllers/console/app/test_app_response_models.py index 0bd45e41935..d4935ba2efd 100644 --- a/api/tests/unit_tests/controllers/console/app/test_app_response_models.py +++ b/api/tests/unit_tests/controllers/console/app/test_app_response_models.py @@ -590,7 +590,7 @@ def test_app_create_api_attaches_permission_keys(app, app_module): assert status == 201 assert resp["permission_keys"] == ["app.acl.view_layout", "app.acl.edit"] assert replace_whitelist.call_args.kwargs["payload"].scope is app_module.RBACResourceWhitelistScope.ALL - initialize_rbac_task.delay.assert_called_once_with("tenant-1", "acct-1", "app-new") + initialize_rbac_task.delay.assert_called_once_with("tenant-1", "acct-1", app_id="app-new") def test_app_list_api_attaches_permission_keys(app, app_module):