feat(rbac): agent RBAC/ACL scenes and resource-locator check bundles (#41768)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Xiyuan Chenandautofix-ci[bot] authored and GitHub committed 2026-09-07 04:39:43 +00:00
1 parent 60e983c493
commit 86134ea99e
152 files changed
+5360 -3405

No files matched your search

+14 -18
View File
@@ -4,13 +4,13 @@ from flask_restx import Resource
from sqlalchemy.orm import Session
from werkzeug.exceptions import NotFound
from controllers.common.rbac import AgentId, PlainApp, RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.app.wraps import agent_manage_required_for_agent_app, get_app_model
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -94,7 +94,7 @@ class WorkflowAgentComposerApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -134,7 +134,7 @@ class WorkflowAgentComposerCopyFromRosterApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -246,8 +246,8 @@ class WorkflowAgentComposerSaveToRosterApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_CREATE, Workspace()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -323,9 +323,7 @@ class SnippetAgentComposerApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -362,9 +360,7 @@ class SnippetAgentComposerCopyFromRosterApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -476,10 +472,8 @@ class SnippetAgentComposerSaveToRosterApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_CREATE, Workspace()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -512,7 +506,7 @@ class AgentComposerApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_tenant_id
@with_session
def get(self, session: Session, tenant_id: str, agent_id: UUID):
@@ -527,7 +521,7 @@ class AgentComposerApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user_id
@with_current_tenant_id
@with_session
@@ -554,6 +548,7 @@ class AgentComposerValidateApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_tenant_id
@with_session
@model_validate(ComposerSavePayload)
@@ -575,6 +570,7 @@ class AgentComposerCandidatesApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user_id
@with_current_tenant_id
@with_session(write=False)
+28 -23
View File
@@ -7,6 +7,7 @@ from pydantic import AliasChoices, BaseModel, Field, field_validator
from sqlalchemy import func, or_, select
from sqlalchemy.orm import Session
from controllers.common.rbac import AgentId, RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -32,10 +33,8 @@ from controllers.console.app.app import (
from controllers.console.app.app import (
UpdateAppPayload as GenericUpdateAppPayload,
)
from controllers.console.app.wraps import agent_manage_required_for_agent_app
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
enterprise_license_required,
@@ -608,7 +607,7 @@ class AgentAppListApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, Workspace()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -668,7 +667,7 @@ class AgentAppListApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_CREATE, Workspace()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -694,7 +693,7 @@ class AgentAppApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@enterprise_license_required
@with_current_user
@with_current_tenant_id
@@ -711,7 +710,7 @@ class AgentAppApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -744,7 +743,7 @@ class AgentAppApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_DELETE, AgentId()))
@with_current_tenant_id
@with_session
def delete(self, session: Session, tenant_id: str, agent_id: UUID):
@@ -765,6 +764,7 @@ class AgentDebugConversationRefreshApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -790,7 +790,7 @@ class AgentPublishApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_RELEASE_AND_VERSION, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -820,7 +820,7 @@ class AgentBuildDraftCheckoutApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -850,6 +850,7 @@ class AgentBuildDraftApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -867,6 +868,7 @@ class AgentBuildDraftApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -892,6 +894,7 @@ class AgentBuildDraftApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -911,7 +914,7 @@ class AgentBuildDraftApplyApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -934,7 +937,8 @@ class AgentAppCopyApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_CREATE, Workspace()))
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -967,7 +971,7 @@ class AgentApiAccessApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_ACCESS_POINT_VIEW, AgentId()))
@with_current_tenant_id
@with_session(write=False)
def get(self, session: Session, tenant_id: str, agent_id: UUID):
@@ -984,7 +988,7 @@ class AgentApiStatusApi(Resource):
@login_required
@is_admin_or_owner_required
@account_initialization_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentId()))
@with_current_tenant_id
@with_session
@model_validate(AgentApiStatusPayload)
@@ -1002,7 +1006,7 @@ class AgentApiKeyListApi(BaseApiKeyListResource):
token_prefix = "app-"
@console_ns.response(200, "Agent service API keys", console_ns.models[ApiKeyList.__name__])
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_ACCESS_POINT_VIEW, AgentId()))
@with_current_tenant_id
@edit_permission_required
@with_session(write=False)
@@ -1014,7 +1018,7 @@ class AgentApiKeyListApi(BaseApiKeyListResource):
@console_ns.response(400, "Maximum keys exceeded")
@with_current_tenant_id
@edit_permission_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentId()))
@with_session
def post(self, session: Session, tenant_id: str, agent_id: UUID) -> tuple[dict[str, object], int]:
app_model = _resolve_agent_app_model(session, tenant_id=tenant_id, agent_id=agent_id)
@@ -1033,7 +1037,7 @@ class AgentApiKeyApi(BaseApiKeyResource):
@console_ns.response(204, "Agent service API key deleted")
@with_current_user
@with_current_tenant_id
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentId()))
@with_session
def delete(
self,
@@ -1055,6 +1059,7 @@ class AgentInviteOptionsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, Workspace()))
@with_current_tenant_id
@with_session(write=False)
@model_validate(AgentInviteOptionsQuery)
@@ -1078,7 +1083,7 @@ class AgentLogsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_LOG_MANAGE, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -1117,7 +1122,7 @@ class AgentLogMessagesApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_LOG_MANAGE, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -1156,7 +1161,7 @@ class AgentLogSourcesApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_LOG_MANAGE, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -1177,7 +1182,7 @@ class AgentStatisticsSummaryApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_MONITOR, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -1210,7 +1215,7 @@ class AgentRosterVersionsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_RELEASE_AND_VERSION, AgentId()))
@with_current_tenant_id
@with_session(write=False)
def get(self, session: Session, tenant_id: str, agent_id: UUID):
@@ -1226,7 +1231,7 @@ class AgentRosterVersionDetailApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_RELEASE_AND_VERSION, AgentId()))
@with_current_tenant_id
@with_session(write=False)
def get(self, session: Session, tenant_id: str, agent_id: UUID, version_id: UUID):
@@ -1247,7 +1252,7 @@ class AgentRosterVersionRestoreApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.AGENT_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_RELEASE_AND_VERSION, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
+16 -11
View File
@@ -11,9 +11,9 @@ from sqlalchemy.orm import Session
from werkzeug.exceptions import Forbidden
from configs import dify_config
from controllers.common.rbac import AgentBehindApp, DatasetId, PlainApp, RBACCheck
from controllers.common.schema import register_response_schema_models
from controllers.common.session import with_session
from controllers.console.app.wraps import agent_manage_required_for_agent_app
from fields.base import ResponseModel
from libs.helper import dump_response, to_timestamp
from libs.login import login_required
@@ -27,7 +27,6 @@ from services.app_service import AppService
from . import console_ns
from .wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
rbac_permission_required,
@@ -242,8 +241,10 @@ class AppApiKeyListResource(BaseApiKeyListResource):
@console_ns.response(200, "API keys retrieved successfully", console_ns.models[ApiKeyList.__name__])
@with_current_tenant_id
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_RELEASE_AND_VERSION)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp("resource_id")),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_VIEW, AgentBehindApp("resource_id")),
)
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, resource_id: UUID) -> dict[str, object]:
"""Get all API keys for an app"""
@@ -259,8 +260,10 @@ class AppApiKeyListResource(BaseApiKeyListResource):
@console_ns.response(400, "Maximum keys exceeded")
@with_current_tenant_id
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_RELEASE_AND_VERSION)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp("resource_id")),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentBehindApp("resource_id")),
)
@with_session
def post(self, session: Session, current_tenant_id: str, resource_id: UUID) -> tuple[dict[str, object], int]:
"""Create a new API key for an app"""
@@ -283,8 +286,10 @@ class AppApiKeyResource(BaseApiKeyResource):
@console_ns.response(204, "API key deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_RELEASE_AND_VERSION)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp("resource_id")),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentBehindApp("resource_id")),
)
@with_session
def delete(
self,
@@ -321,7 +326,7 @@ class DatasetApiKeyListResource(BaseApiKeyListResource):
@console_ns.response(200, "API keys retrieved successfully", console_ns.models[ApiKeyList.__name__])
@with_current_tenant_id
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_API_KEY_MANAGE)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_API_KEY_MANAGE, DatasetId("resource_id")))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, resource_id: UUID) -> dict[str, object]:
"""Get all API keys for a dataset"""
@@ -337,7 +342,7 @@ class DatasetApiKeyListResource(BaseApiKeyListResource):
@console_ns.response(400, "Maximum keys exceeded")
@with_current_tenant_id
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_API_KEY_MANAGE)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_API_KEY_MANAGE, DatasetId("resource_id")))
@with_session
def post(self, session: Session, current_tenant_id: str, resource_id: UUID) -> tuple[dict[str, object], int]:
"""Create a new API key for a dataset"""
@@ -360,7 +365,7 @@ class DatasetApiKeyResource(BaseApiKeyResource):
@console_ns.response(204, "API key deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_API_KEY_MANAGE)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_API_KEY_MANAGE, DatasetId("resource_id")))
@with_session
def delete(
self,
+2 -2
View File
@@ -4,13 +4,13 @@ from flask_restx import Resource
from pydantic import BaseModel, Field, field_validator
from sqlalchemy.orm import Session
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
model_validate,
rbac_permission_required,
@@ -84,7 +84,7 @@ class AgentLogApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model(mode=[AppMode.AGENT_CHAT])
@model_validate(AgentLogQuery)
@@ -11,11 +11,18 @@ from flask_restx import Resource
from pydantic import Field
from sqlalchemy.orm import Session
from controllers.common.rbac import AgentId, RBACCheck
from controllers.common.schema import register_response_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.agent.app_helpers import resolve_agent_app_model
from controllers.console.wraps import account_initialization_required, setup_required, with_current_tenant_id
from controllers.console.wraps import (
RBACPermission,
account_initialization_required,
rbac_permission_required,
setup_required,
with_current_tenant_id,
)
from fields.base import ResponseModel
from libs.login import login_required
from services.agent.roster_service import AgentRosterService
@@ -55,6 +62,7 @@ class AgentAppReferencingWorkflowsResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_tenant_id
@with_session(write=False)
def get(self, session: Session, tenant_id: str, agent_id: UUID):
@@ -16,13 +16,13 @@ from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import AgentId, RBACCheck
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.agent.app_helpers import resolve_agent_runtime_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -83,7 +83,7 @@ class AgentAppFeatureConfigResource(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -15,6 +15,7 @@ from flask_restx import Resource
from pydantic import BaseModel, Field
from clients.agent_backend.errors import backend_error_detail, backend_reported_failure
from controllers.common.rbac import AgentId, PlainApp, RBACCheck
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -23,10 +24,9 @@ from controllers.common.schema import (
)
from controllers.console import console_ns
from controllers.console.app.error import AppNotFoundError
from controllers.console.app.wraps import agent_manage_required_for_agent_app, get_app_model
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
model_validate,
rbac_permission_required,
@@ -153,7 +153,7 @@ class AgentAppSandboxInfoResource(Resource):
@setup_required
@login_required
@account_initialization_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_tenant_id
@with_current_user
def get(self, current_user: Account, tenant_id: str, agent_id: UUID):
@@ -183,7 +183,7 @@ class AgentAppSandboxListResource(Resource):
@setup_required
@login_required
@account_initialization_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_tenant_id
@with_current_user
def get(self, current_user: Account, tenant_id: str, agent_id: UUID):
@@ -214,7 +214,7 @@ class AgentAppSandboxReadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_tenant_id
@with_current_user
def get(self, current_user: Account, tenant_id: str, agent_id: UUID):
@@ -245,7 +245,7 @@ class AgentAppSandboxDownloadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_tenant_id
@with_current_user
@model_validate(AgentSandboxDownloadPayload)
@@ -289,7 +289,7 @@ class WorkflowAgentSandboxListResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_tenant_id
def get(self, tenant_id: str, app_model: App, workflow_run_id: UUID, node_id: str):
@@ -327,7 +327,7 @@ class WorkflowAgentSandboxReadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_tenant_id
def get(self, tenant_id: str, app_model: App, workflow_run_id: UUID, node_id: str):
@@ -358,7 +358,7 @@ class WorkflowAgentSandboxDownloadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_current_user
@with_current_tenant_id
@model_validate(WorkflowAgentSandboxDownloadPayload)
@@ -15,6 +15,7 @@ from flask_restx import Resource
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from controllers.common.rbac import AgentId, PlainApp, RBACCheck
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -27,7 +28,6 @@ from controllers.console.agent.app_helpers import resolve_agent_runtime_app_mode
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -659,6 +659,7 @@ class AgentConfigManifestByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -704,6 +705,7 @@ class AgentConfigSkillUploadByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -733,7 +735,7 @@ class AgentConfigSkillUploadApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@with_session
@get_app_model(mode=_WORKFLOW_APP_MODES)
@@ -751,6 +753,7 @@ class AgentConfigSkillsByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -789,6 +792,7 @@ class AgentConfigFilesByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -808,6 +812,7 @@ class AgentConfigFilesByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -853,7 +858,7 @@ class AgentConfigFilesApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@with_session
@get_app_model(mode=_WORKFLOW_APP_MODES)
@@ -877,6 +882,7 @@ class AgentConfigSkillInspectByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -928,6 +934,7 @@ class AgentConfigSkillFilePreviewByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -988,6 +995,7 @@ class AgentConfigSkillDownloadByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1037,6 +1045,7 @@ class AgentConfigSkillFileDownloadByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1106,6 +1115,7 @@ class AgentConfigSkillFileDownloadContentByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1158,6 +1168,7 @@ class AgentConfigSkillByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1182,7 +1193,7 @@ class AgentConfigSkillApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@with_session
@get_app_model(mode=_WORKFLOW_APP_MODES)
@@ -1205,6 +1216,7 @@ class AgentConfigFilePreviewByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1250,6 +1262,7 @@ class AgentConfigFileDownloadByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_PREVIEW, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1295,6 +1308,7 @@ class AgentConfigFileByAgentApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_EDIT, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -1319,7 +1333,7 @@ class AgentConfigFileApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@with_session
@get_app_model(mode=_WORKFLOW_APP_MODES)
+14 -14
View File
@@ -9,12 +9,12 @@ from sqlalchemy.orm import Session
from werkzeug.exceptions import NotFound
from controllers.common.errors import NoFileUploadedError, TooManyFilesError
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
annotation_import_concurrency_limit,
annotation_import_rate_limit,
@@ -180,7 +180,7 @@ class AnnotationReplyActionApi(Resource):
@account_initialization_required
@cloud_edition_billing_resource_check("annotation")
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@model_validate(AnnotationReplyPayload)
def post(self, req_data: AnnotationReplyPayload, app_id: UUID, action: Literal["enable", "disable"]):
match action:
@@ -211,7 +211,7 @@ class AppAnnotationSettingDetailApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
def get(self, session: Session, app_id: UUID):
result = AppAnnotationService.get_app_annotation_setting_by_app_id(str(app_id), session)
@@ -230,7 +230,7 @@ class AppAnnotationSettingUpdateApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_session
@model_validate(AnnotationSettingUpdatePayload)
def post(
@@ -263,7 +263,7 @@ class AnnotationReplyActionStatusApi(Resource):
@account_initialization_required
@cloud_edition_billing_resource_check("annotation")
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, app_id: UUID, job_id: UUID, action: str):
job_id_str = str(job_id)
app_annotation_job_key = f"{action}_app_annotation_job_{job_id_str}"
@@ -294,7 +294,7 @@ class AnnotationApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@model_validate(AnnotationListQuery)
def get(self, req_data: AnnotationListQuery, session: Session, app_id: UUID):
@@ -321,7 +321,7 @@ class AnnotationApi(Resource):
@account_initialization_required
@cloud_edition_billing_resource_check("annotation")
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_session
@model_validate(CreateAnnotationPayload)
def post(self, req_data: CreateAnnotationPayload, session: Session, app_id: UUID):
@@ -341,7 +341,7 @@ class AnnotationApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp()))
@console_ns.response(204, "Annotations deleted successfully")
@with_session
def delete(self, session: Session, app_id: UUID):
@@ -382,7 +382,7 @@ class AnnotationExportApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
def get(self, session: Session, app_id: UUID):
annotation_list = AppAnnotationService.export_annotation_list_by_app_id(str(app_id), session)
@@ -411,7 +411,7 @@ class AnnotationUpdateDeleteApi(Resource):
@account_initialization_required
@cloud_edition_billing_resource_check("annotation")
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_session
@model_validate(UpdateAnnotationPayload)
def post(self, req_data: UpdateAnnotationPayload, session: Session, app_id: UUID, annotation_id: UUID):
@@ -429,7 +429,7 @@ class AnnotationUpdateDeleteApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@console_ns.response(204, "Annotation deleted successfully")
@with_session
def delete(self, session: Session, app_id: UUID, annotation_id: UUID):
@@ -458,7 +458,7 @@ class AnnotationBatchImportApi(Resource):
@annotation_import_rate_limit
@annotation_import_concurrency_limit
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_session
def post(self, session: Session, app_id: UUID):
from configs import dify_config
@@ -513,7 +513,7 @@ class AnnotationBatchImportStatusApi(Resource):
@account_initialization_required
@cloud_edition_billing_resource_check("annotation")
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, app_id: UUID, job_id: UUID):
indexing_cache_key = f"app_annotation_batch_import_{str(job_id)}"
cache_result = redis_client.get(indexing_cache_key)
@@ -546,7 +546,7 @@ class AnnotationHitHistoryListApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
def get(self, session: Session, app_id: UUID, annotation_id: UUID):
page = request.args.get("page", default=1, type=int)
+35 -23
View File
@@ -13,6 +13,7 @@ from werkzeug.exceptions import BadRequest, Forbidden, NotFound
from configs import dify_config
from controllers.common.app_access import resolve_app_access_filter
from controllers.common.fields import RedirectUrlResponse, SimpleResultResponse
from controllers.common.rbac import AgentBehindApp, PlainApp, RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -21,11 +22,10 @@ from controllers.common.schema import (
register_schema_models,
)
from controllers.console import console_ns
from controllers.console.app.wraps import agent_manage_required_for_agent_app, get_app_model, with_session
from controllers.console.app.wraps import get_app_model, with_session
from controllers.console.workspace.models import LoadBalancingPayload
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
cloud_edition_billing_resource_check,
edit_permission_required,
@@ -691,7 +691,7 @@ class AppListApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_CREATE_AND_MANAGEMENT, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, Workspace()))
@cloud_edition_billing_resource_check("apps")
@edit_permission_required
@with_current_user
@@ -868,7 +868,7 @@ class AppApi(Resource):
@enterprise_license_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model(mode=None)
def get(self, session: Session, current_tenant_id: str, current_user: Account, app_model: App):
@@ -907,8 +907,9 @@ class AppApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_EDIT, PlainApp()), RBACCheck(RBACPermission.AGENT_EDIT, AgentBehindApp())
)
@with_session
@get_app_model(mode=None)
@model_validate(UpdateAppPayload)
@@ -942,8 +943,9 @@ class AppApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_DELETE)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_DELETE, PlainApp()), RBACCheck(RBACPermission.AGENT_DELETE, AgentBehindApp())
)
@with_session
@get_app_model
def delete(self, session: Session, app_model: App):
@@ -967,8 +969,7 @@ class AppCopyApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_CREATE_AND_MANAGEMENT)
@agent_manage_required_for_agent_app
@rbac_permission_required(RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp()))
@with_current_user
@with_current_tenant_id
@get_app_model(mode=None)
@@ -1045,8 +1046,10 @@ class AppExportApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_IMPORT_EXPORT_DSL)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_IMPORT_EXPORT_DSL, PlainApp()),
RBACCheck(RBACPermission.AGENT_IMPORT_EXPORT_DSL, AgentBehindApp()),
)
@get_app_model
@model_validate(AppExportQuery)
def get(self, req_data: AppExportQuery, app_model: App):
@@ -1070,8 +1073,10 @@ class AppPublishToCreatorsPlatformApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_IMPORT_EXPORT_DSL)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_IMPORT_EXPORT_DSL, PlainApp()),
RBACCheck(RBACPermission.AGENT_RELEASE_AND_VERSION, AgentBehindApp()),
)
@with_current_user_id
@get_app_model(mode=None)
def post(self, current_user_id: str, app_model: App):
@@ -1111,8 +1116,9 @@ class AppNameApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_EDIT, PlainApp()), RBACCheck(RBACPermission.AGENT_EDIT, AgentBehindApp())
)
@with_session
@get_app_model(mode=None)
@model_validate(AppNamePayload)
@@ -1139,8 +1145,9 @@ class AppIconApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_EDIT, PlainApp()), RBACCheck(RBACPermission.AGENT_EDIT, AgentBehindApp())
)
@with_session
@get_app_model(mode=None)
@model_validate(AppIconPayload)
@@ -1173,7 +1180,10 @@ class AppSiteStatus(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp()),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentBehindApp()),
)
@with_session
@get_app_model(mode=None)
@model_validate(AppSiteStatusPayload)
@@ -1200,8 +1210,10 @@ class AppApiStatus(Resource):
@login_required
@is_admin_or_owner_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_RELEASE_AND_VERSION)
@agent_manage_required_for_agent_app
@rbac_permission_required(
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp()),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentBehindApp()),
)
@with_session
@get_app_model(mode=None)
@model_validate(AppApiStatusPayload)
@@ -1230,7 +1242,7 @@ class AppTraceApi(Resource):
@login_required
@account_initialization_required
@with_session
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model
def get(self, session: Session, app_model: App):
"""Get app trace"""
@@ -1252,7 +1264,7 @@ class AppTraceApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TRACING_CONFIG)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TRACING_CONFIG, PlainApp()))
@get_app_model
@model_validate(AppTracePayload)
def post(self, req_data: AppTracePayload, app_model: App):
+4 -4
View File
@@ -4,11 +4,11 @@ from sqlalchemy.orm import Session
from werkzeug.exceptions import Forbidden
from configs import dify_config
from controllers.common.rbac import PlainApp, RBACCheck, Workspace
from controllers.common.schema import register_enum_models, register_schema_models
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
cloud_edition_billing_resource_check,
edit_permission_required,
@@ -82,7 +82,7 @@ class AppImportApi(Resource):
@account_initialization_required
@cloud_edition_billing_resource_check("apps")
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_IMPORT_EXPORT_DSL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.APP_IMPORT_EXPORT_DSL, Workspace()))
@with_current_user
@model_validate(AppImportPayload)
def post(self, req_data: AppImportPayload, current_user: Account | None = None):
@@ -149,7 +149,7 @@ class AppImportConfirmApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_IMPORT_EXPORT_DSL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.APP_IMPORT_EXPORT_DSL, Workspace()))
@with_current_user
def post(self, current_user: Account | None = None, import_id: str = ""):
current_user = current_user if current_user is not None else _current_user_and_tenant_id(None)[0]
@@ -208,7 +208,7 @@ class AppImportCheckDependenciesApi(Resource):
@get_app_model
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, app_model: App):
with Session(db.engine, expire_on_commit=False) as session:
import_service = AppDslService(session)
+4 -6
View File
@@ -9,8 +9,8 @@ from werkzeug.datastructures import FileStorage
from werkzeug.exceptions import HTTPException, InternalServerError
import services
from controllers.common.rbac import PlainApp, RBACCheck, enforce_rbac_checks
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.wraps import enforce_rbac_access
from controllers.console import console_ns
from controllers.console.agent.app_helpers import resolve_agent_runtime_app_model
from controllers.console.app.error import (
@@ -28,7 +28,6 @@ from controllers.console.app.error import (
from controllers.console.app.wraps import get_app_model, with_session
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -242,11 +241,10 @@ class AgentChatMessageAudioApi(Resource):
agent_id=agent_id,
)
# Agent routes expose Agent ids, while APP RBAC is keyed by the resolved runtime App id.
enforce_rbac_access(
enforce_rbac_checks(
tenant_id=current_tenant_id,
account_id=current_user.id,
resource_type=RBACResourceScope.APP,
scene=RBACPermission.APP_TEST_AND_RUN,
checks=[RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp())],
path_args={"app_id": app_model.id},
)
agent_soul = AgentComposerService.load_agent_soul_for_debug(
@@ -338,7 +336,7 @@ class TextModesApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model
@model_validate(TextToSpeechVoiceQuery)
def get(self, req_data: TextToSpeechVoiceQuery, app_model: App):
+7 -6
View File
@@ -12,6 +12,7 @@ from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
import services
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import AgentId, PlainApp, RBACCheck
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.agent.app_helpers import resolve_agent_runtime_app_model
@@ -24,10 +25,9 @@ from controllers.console.app.error import (
ProviderNotInitializeError,
ProviderQuotaExceededError,
)
from controllers.console.app.wraps import agent_manage_required_for_agent_app, get_app_model, with_session
from controllers.console.app.wraps import get_app_model, with_session
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -159,7 +159,7 @@ class CompletionMessageApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@with_session
@get_app_model(mode=AppMode.COMPLETION)
@model_validate(CompletionMessagePayload)
@@ -241,7 +241,7 @@ class ChatMessageApi(Resource):
@edit_permission_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@with_session
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.AGENT])
def post(self, session: Session, current_tenant_id: str, current_user: Account, app_model: App):
@@ -263,7 +263,7 @@ class AgentChatMessageApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -292,7 +292,7 @@ class AgentBuildChatFinalizeApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -333,6 +333,7 @@ class AgentChatMessageStopApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user_id
@with_current_tenant_id
@with_session(write=False)
+7 -7
View File
@@ -9,13 +9,13 @@ from sqlalchemy import func, or_
from sqlalchemy.orm import Session, selectinload
from werkzeug.exceptions import NotFound
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -106,7 +106,7 @@ class CompletionConversationApi(Resource):
@account_initialization_required
@edit_permission_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model(mode=AppMode.COMPLETION)
@model_validate(CompletionConversationQuery)
@@ -187,7 +187,7 @@ class CompletionConversationDetailApi(Resource):
@account_initialization_required
@edit_permission_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session
@get_app_model(mode=AppMode.COMPLETION)
def get(self, session: Session, current_user: Account, app_model: App, conversation_id: UUID):
@@ -209,7 +209,7 @@ class CompletionConversationDetailApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@with_session
@get_app_model(mode=AppMode.COMPLETION)
@@ -236,7 +236,7 @@ class ChatConversationApi(Resource):
@account_initialization_required
@edit_permission_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT, AppMode.AGENT])
@model_validate(ChatConversationQuery)
@@ -356,7 +356,7 @@ class ChatConversationDetailApi(Resource):
@account_initialization_required
@edit_permission_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT, AppMode.AGENT])
def get(self, session: Session, current_user: Account, app_model: App, conversation_id: UUID):
@@ -378,7 +378,7 @@ class ChatConversationDetailApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@with_session
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT, AppMode.AGENT])
@@ -8,12 +8,12 @@ from pydantic import BaseModel, Field, field_validator
from sqlalchemy import select
from sqlalchemy.orm import sessionmaker
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
model_validate,
rbac_permission_required,
@@ -99,7 +99,7 @@ class ConversationVariablesApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp()))
@get_app_model(mode=AppMode.ADVANCED_CHAT)
@model_validate(ConversationVariablesQuery)
def get(self, req_data: ConversationVariablesQuery, app_model: App):
+5 -5
View File
@@ -7,12 +7,12 @@ from pydantic import BaseModel, Field, field_validator
from sqlalchemy import select
from werkzeug.exceptions import NotFound
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import register_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -87,7 +87,7 @@ class AppMCPServerController(Resource):
@login_required
@account_initialization_required
@setup_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model
def get(self, app_model: App):
server = db.session.scalar(select(AppMCPServer).where(AppMCPServer.app_id == app_model.id).limit(1))
@@ -107,7 +107,7 @@ class AppMCPServerController(Resource):
@login_required
@setup_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_tenant_id
@get_app_model
@model_validate(MCPServerCreatePayload)
@@ -142,7 +142,7 @@ class AppMCPServerController(Resource):
@setup_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@get_app_model
@model_validate(MCPServerUpdatePayload)
def put(self, req_data: MCPServerUpdatePayload, app_model: App):
@@ -190,7 +190,7 @@ class AppMCPServerRefreshController(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_tenant_id
@get_app_model
def post(self, current_tenant_id: str, app_model: App):
+11 -8
View File
@@ -11,6 +11,7 @@ from werkzeug.exceptions import InternalServerError, NotFound
from controllers.common.controller_schemas import MessageFeedbackPayload as _MessageFeedbackPayloadBase
from controllers.common.fields import SimpleResultResponse, TextFileResponse
from controllers.common.rbac import AgentId, PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
@@ -21,11 +22,10 @@ from controllers.console.app.error import (
ProviderNotInitializeError,
ProviderQuotaExceededError,
)
from controllers.console.app.wraps import agent_manage_required_for_agent_app, get_app_model
from controllers.console.app.wraps import get_app_model
from controllers.console.explore.error import AppSuggestedQuestionsAfterAnswerDisabledError
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -155,7 +155,7 @@ class ChatMessageListApi(Resource):
@setup_required
@edit_permission_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT, AppMode.AGENT])
def get(self, session: Session, current_user: Account, app_model: App):
@@ -174,7 +174,7 @@ class AgentChatMessageListApi(Resource):
@account_initialization_required
@setup_required
@edit_permission_required
@agent_manage_required_for_agent_app(scene=RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -217,6 +217,7 @@ class AgentMessageFeedbackApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -242,7 +243,7 @@ class MessageAnnotationCountApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model
def get(self, app_model: App):
count = db.session.scalar(
@@ -267,7 +268,7 @@ class MessageSuggestedQuestionApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT, AppMode.AGENT])
def get(self, session: Session, current_user: Account, app_model: App, message_id: UUID):
@@ -290,6 +291,7 @@ class AgentMessageSuggestedQuestionApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -319,7 +321,7 @@ class MessageFeedbackExportApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model
@model_validate(FeedbackExportQuery)
def get(self, req_data: FeedbackExportQuery, app_model: App):
@@ -358,7 +360,7 @@ class MessageApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@with_session(write=False)
@get_app_model
def get(self, session: Session, app_model: App, message_id: UUID):
@@ -375,6 +377,7 @@ class AgentMessageApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACCheck(RBACPermission.AGENT_TEST_AND_RUN, AgentId()))
@with_current_tenant_id
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, agent_id: UUID, message_id: UUID):
+2 -2
View File
@@ -7,13 +7,13 @@ from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
rbac_permission_required,
@@ -90,7 +90,7 @@ class ModelConfigResource(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
+5 -9
View File
@@ -4,6 +4,7 @@ from uuid import UUID
from flask_restx import Resource
from pydantic import BaseModel, Field
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.error import (
@@ -18,7 +19,6 @@ from controllers.console.app.error import (
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
model_validate,
)
from extensions.ext_application_services import application_services
@@ -106,8 +106,7 @@ class TraceAppConfigApi(Resource):
@console_ns.response(404, "Application not found")
@console_ns.response(500, "Tracing configuration processing failed")
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_TRACING_CONFIG,
rbac_checks=[RBACCheck(RBACPermission.APP_TRACING_CONFIG, PlainApp())],
)
@model_validate(TraceProviderQuery)
def get(
@@ -155,8 +154,7 @@ class TraceAppConfigApi(Resource):
@console_ns.response(500, "Tracing configuration processing failed")
@console_account_admission(
allowed_roles=_APP_TRACING_CONFIG_EDIT_ROLES,
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_TRACING_CONFIG,
rbac_checks=[RBACCheck(RBACPermission.APP_TRACING_CONFIG, PlainApp())],
)
@model_validate(TraceConfigPayload)
def post(
@@ -205,8 +203,7 @@ class TraceAppConfigApi(Resource):
@console_ns.response(500, "Tracing configuration processing failed")
@console_account_admission(
allowed_roles=_APP_TRACING_CONFIG_EDIT_ROLES,
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_TRACING_CONFIG,
rbac_checks=[RBACCheck(RBACPermission.APP_TRACING_CONFIG, PlainApp())],
)
@model_validate(TraceConfigPayload)
def patch(
@@ -251,8 +248,7 @@ class TraceAppConfigApi(Resource):
@console_ns.response(500, "Tracing configuration processing failed")
@console_account_admission(
allowed_roles=_APP_TRACING_CONFIG_EDIT_ROLES,
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_TRACING_CONFIG,
rbac_checks=[RBACCheck(RBACPermission.APP_TRACING_CONFIG, PlainApp())],
)
@model_validate(TraceProviderQuery)
def delete(
+9 -7
View File
@@ -5,13 +5,13 @@ from pydantic import BaseModel, Field, field_validator
from werkzeug.exceptions import NotFound
from constants.languages import supported_language
from controllers.common.rbac import AgentBehindApp, PlainApp, RBACCheck
from controllers.common.schema import register_schema_models
from controllers.console import console_ns
from controllers.console.app.error import AppNotFoundError
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
model_validate,
)
from extensions.ext_application_services import application_services
@@ -105,9 +105,10 @@ class AppSite(Resource):
@console_ns.response(404, "App not found")
@console_account_admission(
allowed_roles=_APP_SITE_EDIT_ROLES,
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_RELEASE_AND_VERSION,
agent_manage_fallback=True,
rbac_checks=[
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp()),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentBehindApp()),
],
)
@model_validate(AppSiteUpdatePayload)
def post(
@@ -136,9 +137,10 @@ class AppSiteAccessTokenReset(Resource):
@console_ns.response(404, "App or site not found")
@console_account_admission(
allowed_roles=_APP_SITE_TOKEN_RESET_ROLES,
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_RELEASE_AND_VERSION,
agent_manage_fallback=True,
rbac_checks=[
RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp()),
RBACCheck(RBACPermission.AGENT_ACCESS_POINT_MANAGE, AgentBehindApp()),
],
)
def post(self, request_context: RequestContext, app_id: UUID):
try:
+10 -17
View File
@@ -5,11 +5,12 @@ from flask_restx import Resource
from pydantic import BaseModel, Field, field_validator
from werkzeug.exceptions import BadRequest
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import RBACPermission, RBACResourceScope, model_validate
from controllers.console.wraps import RBACPermission, model_validate
from extensions.ext_application_services import application_services
from fields.base import ResponseModel
from libs.datetime_utils import parse_time_range
@@ -158,8 +159,7 @@ class DailyMessageStatistic(Resource):
console_ns.models[DailyMessageStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(StatisticTimeRangeQuery)
@@ -186,8 +186,7 @@ class DailyConversationStatistic(Resource):
console_ns.models[DailyConversationStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(StatisticTimeRangeQuery)
@@ -214,8 +213,7 @@ class DailyTerminalsStatistic(Resource):
console_ns.models[DailyTerminalStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(StatisticTimeRangeQuery)
@@ -242,8 +240,7 @@ class DailyTokenCostStatistic(Resource):
console_ns.models[DailyTokenCostStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(StatisticTimeRangeQuery)
@@ -270,8 +267,7 @@ class AverageSessionInteractionStatistic(Resource):
console_ns.models[AverageSessionInteractionStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT, AppMode.AGENT])
@model_validate(StatisticTimeRangeQuery)
@@ -298,8 +294,7 @@ class UserSatisfactionRateStatistic(Resource):
console_ns.models[UserSatisfactionRateStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(StatisticTimeRangeQuery)
@@ -326,8 +321,7 @@ class AverageResponseTimeStatistic(Resource):
console_ns.models[AverageResponseTimeStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model(mode=AppMode.COMPLETION)
@model_validate(StatisticTimeRangeQuery)
@@ -354,8 +348,7 @@ class TokensPerSecondStatistic(Resource):
console_ns.models[TokensPerSecondStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(StatisticTimeRangeQuery)
+30 -30
View File
@@ -25,6 +25,7 @@ from controllers.common.app_access import resolve_app_access_filter
from controllers.common.controller_schemas import DefaultBlockConfigQuery, WorkflowListQuery, WorkflowUpdatePayload
from controllers.common.errors import InvalidArgumentError
from controllers.common.fields import GeneratedAppResponse, NewAppResponse, SimpleResultResponse
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import (
query_params_from_model,
register_response_schema_model,
@@ -41,7 +42,6 @@ from controllers.console.app.permission_keys import get_app_permission_keys
from controllers.console.app.wraps import get_app_model, with_session
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -582,7 +582,7 @@ class DraftWorkflowApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App):
"""
@@ -625,7 +625,7 @@ class DraftWorkflowApi(Resource):
@console_ns.response(403, "Permission denied")
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def post(self, current_user: Account, app_model: App):
"""
Sync draft workflow
@@ -704,7 +704,7 @@ class AdvancedChatDraftWorkflowRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@with_current_user
@edit_permission_required
@with_session
@@ -760,7 +760,7 @@ class AdvancedChatDraftRunIterationNodeApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT])
@with_current_user
@edit_permission_required
@@ -809,7 +809,7 @@ class WorkflowDraftRunIterationNodeApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -854,7 +854,7 @@ class AdvancedChatDraftRunLoopNodeApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT])
@with_current_user
@edit_permission_required
@@ -902,7 +902,7 @@ class WorkflowDraftRunLoopNodeApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -982,7 +982,7 @@ class AdvancedChatDraftHumanInputFormPreviewApi(Resource):
@get_app_model(mode=[AppMode.ADVANCED_CHAT])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@model_validate(HumanInputFormPreviewPayload)
def post(self, args: HumanInputFormPreviewPayload, current_user: Account, app_model: App, node_id: str):
"""
@@ -1015,7 +1015,7 @@ class AdvancedChatDraftHumanInputFormRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT])
@with_current_user
@edit_permission_required
@@ -1050,7 +1050,7 @@ class WorkflowDraftHumanInputFormPreviewApi(Resource):
@get_app_model(mode=[AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@model_validate(HumanInputFormPreviewPayload)
def post(self, args: HumanInputFormPreviewPayload, current_user: Account, app_model: App, node_id: str):
"""
@@ -1083,7 +1083,7 @@ class WorkflowDraftHumanInputFormRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -1118,7 +1118,7 @@ class WorkflowDraftHumanInputDeliveryTestApi(Resource):
@get_app_model(mode=[AppMode.WORKFLOW, AppMode.ADVANCED_CHAT])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@model_validate(HumanInputDeliveryTestPayload)
def post(self, args: HumanInputDeliveryTestPayload, current_user: Account, app_model: App, node_id: str):
"""
@@ -1151,7 +1151,7 @@ class DraftWorkflowRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@with_current_user
@edit_permission_required
@with_session
@@ -1194,7 +1194,7 @@ class WorkflowTaskStopApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def post(self, app_model: App, task_id: str):
"""
@@ -1226,7 +1226,7 @@ class DraftWorkflowNodeRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -1278,7 +1278,7 @@ class PublishedWorkflowApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App):
"""
@@ -1300,7 +1300,7 @@ class PublishedWorkflowApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -1349,7 +1349,7 @@ class DefaultBlockConfigsApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App):
"""
@@ -1376,7 +1376,7 @@ class DefaultBlockConfigApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@model_validate(DefaultBlockConfigQuery)
def get(self, args: DefaultBlockConfigQuery, app_model: App, block_type: str):
@@ -1416,7 +1416,7 @@ class ConvertToWorkflowApi(Resource):
@with_current_user
@with_current_tenant_id
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@model_validate(ConvertToWorkflowPayload)
def post(self, payload: ConvertToWorkflowPayload, current_tenant_id: str, current_user: Account, app_model: App):
"""
@@ -1458,7 +1458,7 @@ class WorkflowFeaturesApi(Resource):
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@model_validate(WorkflowFeaturesPayload)
def post(self, args: WorkflowFeaturesPayload, current_user: Account, app_model: App):
features = args.features.model_dump(mode="json", exclude_unset=True)
@@ -1485,7 +1485,7 @@ class PublishedAllWorkflowApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -1538,7 +1538,7 @@ class DraftWorkflowRestoreApi(Resource):
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_RELEASE_AND_VERSION)
@rbac_permission_required(RBACCheck(RBACPermission.APP_RELEASE_AND_VERSION, PlainApp()))
def post(self, current_user: Account, app_model: App, workflow_id: str):
workflow_service = WorkflowService()
@@ -1578,7 +1578,7 @@ class WorkflowByIdApi(Resource):
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@model_validate(WorkflowUpdatePayload)
def patch(self, args: WorkflowUpdatePayload, current_user: Account, app_model: App, workflow_id: str):
"""
@@ -1620,7 +1620,7 @@ class WorkflowByIdApi(Resource):
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@console_ns.response(204, "Workflow deleted successfully")
def delete(self, current_user: Account, app_model: App, workflow_id: str):
"""
@@ -1666,7 +1666,7 @@ class DraftWorkflowNodeLastRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, node_id: str):
srv = WorkflowService()
@@ -1711,7 +1711,7 @@ class DraftWorkflowTriggerRunApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@with_current_user
@edit_permission_required
@with_session
@@ -1782,7 +1782,7 @@ class DraftWorkflowTriggerNodeApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@get_app_model(mode=[AppMode.WORKFLOW])
@with_current_user
@edit_permission_required
@@ -1865,7 +1865,7 @@ class DraftWorkflowTriggerRunAllApi(Resource):
@account_initialization_required
@with_current_user
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TEST_AND_RUN)
@rbac_permission_required(RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp()))
@with_session
@get_app_model(mode=[AppMode.WORKFLOW])
@model_validate(DraftWorkflowTriggerRunAllPayload)
@@ -5,15 +5,12 @@ from dateutil.parser import isoparse
from flask_restx import Resource
from pydantic import BaseModel, Field, field_validator
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
model_validate,
)
from controllers.console.wraps import RBACPermission, model_validate
from extensions.ext_application_services import application_services
from fields.base import ResponseModel
from fields.end_user_fields import SimpleEndUser
@@ -133,8 +130,7 @@ class WorkflowAppLogApi(Resource):
console_ns.models[WorkflowAppLogPaginationResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_LOG_AND_ANNOTATION,
rbac_checks=[RBACCheck(RBACPermission.APP_LOG_AND_ANNOTATION, PlainApp())],
)
@get_app_model(mode=[AppMode.WORKFLOW])
@model_validate(WorkflowAppLogQuery)
@@ -11,6 +11,7 @@ from sqlalchemy.orm import sessionmaker
from controllers.common.errors import InvalidArgumentError, NotFoundError
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.error import (
@@ -19,7 +20,6 @@ from controllers.console.app.error import (
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -337,7 +337,7 @@ def _api_prerequisite[T, **P, R](
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@with_current_user
@wraps(f)
@@ -359,7 +359,7 @@ class WorkflowVariableCollectionApi(Resource):
)
@_api_prerequisite
@marshal_with(workflow_draft_variable_list_without_value_model)
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@model_validate(WorkflowDraftVariableListQuery)
def get(self, req_data: WorkflowDraftVariableListQuery, current_user: Account, app_model: App):
"""
@@ -424,7 +424,7 @@ class NodeVariableCollectionApi(Resource):
@console_ns.response(200, "Node variables retrieved successfully", workflow_draft_variable_list_model)
@_api_prerequisite
@marshal_with(workflow_draft_variable_list_model)
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, current_user: Account, app_model: App, node_id: str):
validate_node_id(node_id)
with sessionmaker(bind=db.engine, expire_on_commit=False).begin() as session:
@@ -459,7 +459,7 @@ class VariableApi(Resource):
@console_ns.response(404, "Variable not found")
@_api_prerequisite
@marshal_with(workflow_draft_variable_model)
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, current_user: Account, app_model: App, variable_id: UUID):
draft_var_srv = WorkflowDraftVariableService(
session=db.session(),
@@ -638,7 +638,7 @@ class ConversationVariableCollectionApi(Resource):
@console_ns.response(404, "Draft workflow not found")
@_api_prerequisite
@marshal_with(workflow_draft_variable_list_model)
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, current_user: Account, app_model: App):
# NOTE(QuantumGhost): Prefill conversation variables into the draft variables table
# so their IDs can be returned to the caller.
@@ -664,7 +664,7 @@ class ConversationVariableCollectionApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@get_app_model(mode=AppMode.ADVANCED_CHAT)
@model_validate(ConversationVariableUpdatePayload)
@@ -697,7 +697,7 @@ class SystemVariableCollectionApi(Resource):
@console_ns.response(200, "System variables retrieved successfully", workflow_draft_variable_list_model)
@_api_prerequisite
@marshal_with(workflow_draft_variable_list_model)
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, current_user: Account, app_model: App):
return _get_variable_list(app_model, SYSTEM_VARIABLE_NODE_ID, current_user.id)
@@ -714,7 +714,7 @@ class EnvironmentVariableCollectionApi(Resource):
)
@console_ns.response(404, "Draft workflow not found")
@_api_prerequisite
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
def get(self, _current_user: Account, app_model: App):
"""
Get draft workflow
@@ -759,7 +759,7 @@ class EnvironmentVariableCollectionApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@with_current_user
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@model_validate(EnvironmentVariableUpdatePayload)
@@ -31,12 +31,12 @@ from flask import Response
from flask_restx import Resource
from controllers.common.fields import EventStreamResponse
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import register_response_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
rbac_permission_required,
setup_required,
@@ -157,7 +157,7 @@ class WorkflowDraftRunNodeOutputsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID):
return _serve_snapshot(app_model, run_id)
@@ -181,7 +181,7 @@ class WorkflowDraftRunNodeOutputDetailApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID, node_id: str):
return _serve_node_detail(app_model, run_id, node_id)
@@ -208,7 +208,7 @@ class WorkflowDraftRunNodeOutputPreviewApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID, node_id: str, output_name: str):
return _serve_output_preview(app_model, run_id, node_id, output_name)
@@ -353,7 +353,7 @@ class WorkflowDraftRunNodeOutputEventsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID):
return Response(
@@ -384,7 +384,7 @@ class WorkflowPublishedRunNodeOutputsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID):
return _serve_snapshot(app_model, run_id)
@@ -408,7 +408,7 @@ class WorkflowPublishedRunNodeOutputDetailApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID, node_id: str):
return _serve_node_detail(app_model, run_id, node_id)
@@ -436,7 +436,7 @@ class WorkflowPublishedRunNodeOutputPreviewApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID, node_id: str, output_name: str):
return _serve_output_preview(app_model, run_id, node_id, output_name)
@@ -458,7 +458,7 @@ class WorkflowPublishedRunNodeOutputEventsApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App, run_id: UUID):
return Response(
+7 -13
View File
@@ -6,13 +6,13 @@ from pydantic import BaseModel, Field, field_validator
from configs import dify_config
from controllers.common.errors import NotFoundError
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
model_validate,
)
from extensions.ext_application_services import application_services
@@ -143,8 +143,7 @@ class AdvancedChatAppWorkflowRunListApi(Resource):
console_ns.models[AdvancedChatWorkflowRunPaginationResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_CREATE_AND_MANAGEMENT,
rbac_checks=[RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp())],
)
@get_app_model(mode=[AppMode.ADVANCED_CHAT])
@model_validate(WorkflowRunListQuery)
@@ -174,8 +173,7 @@ class AdvancedChatAppWorkflowRunCountApi(Resource):
console_ns.models[WorkflowRunCountResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_CREATE_AND_MANAGEMENT,
rbac_checks=[RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp())],
)
@get_app_model(mode=[AppMode.ADVANCED_CHAT])
@model_validate(WorkflowRunCountQuery)
@@ -206,8 +204,7 @@ class WorkflowRunListApi(Resource):
console_ns.models[WorkflowRunPaginationResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_CREATE_AND_MANAGEMENT,
rbac_checks=[RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp())],
)
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@model_validate(WorkflowRunListQuery)
@@ -237,8 +234,7 @@ class WorkflowRunCountApi(Resource):
console_ns.models[WorkflowRunCountResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_CREATE_AND_MANAGEMENT,
rbac_checks=[RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp())],
)
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@model_validate(WorkflowRunCountQuery)
@@ -269,8 +265,7 @@ class WorkflowRunDetailApi(Resource):
)
@console_ns.response(404, "Workflow run not found")
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_CREATE_AND_MANAGEMENT,
rbac_checks=[RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp())],
)
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, request_context: RequestContext, app_model: App, run_id: UUID):
@@ -300,8 +295,7 @@ class WorkflowRunNodeExecutionListApi(Resource):
)
@console_ns.response(404, "Workflow run not found")
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_CREATE_AND_MANAGEMENT,
rbac_checks=[RBACCheck(RBACPermission.APP_CREATE_AND_MANAGEMENT, PlainApp())],
)
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, request_context: RequestContext, app_model: App, run_id: UUID):
@@ -4,13 +4,13 @@ from flask_restx import Resource
from pydantic import BaseModel, Field, field_validator
from werkzeug.exceptions import BadRequest
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.wraps import get_app_model
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
model_validate,
)
from extensions.ext_application_services import application_services
@@ -106,8 +106,7 @@ class WorkflowDailyRunsStatistic(Resource):
console_ns.models[WorkflowDailyRunsStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(WorkflowStatisticQuery)
@@ -136,8 +135,7 @@ class WorkflowDailyTerminalsStatistic(Resource):
console_ns.models[WorkflowDailyTerminalsStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(WorkflowStatisticQuery)
@@ -166,8 +164,7 @@ class WorkflowDailyTokenCostStatistic(Resource):
console_ns.models[WorkflowDailyTokenCostStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model
@model_validate(WorkflowStatisticQuery)
@@ -196,8 +193,7 @@ class WorkflowAverageAppInteractionStatistic(Resource):
console_ns.models[WorkflowAverageAppInteractionStatisticResponse.__name__],
)
@console_account_admission(
rbac_resource_scope=RBACResourceScope.APP,
rbac_permission=RBACPermission.APP_MONITOR,
rbac_checks=[RBACCheck(RBACPermission.APP_MONITOR, PlainApp())],
)
@get_app_model(mode=[AppMode.WORKFLOW])
@model_validate(WorkflowStatisticQuery)
@@ -8,6 +8,7 @@ from sqlalchemy.orm import sessionmaker
from werkzeug.exceptions import NotFound
from configs import dify_config
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.common.schema import query_params_from_model, register_schema_models
from extensions.ext_database import db
from fields.base import ResponseModel
@@ -21,7 +22,6 @@ from .. import console_ns
from ..app.wraps import get_app_model
from ..wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -100,7 +100,7 @@ class WebhookTriggerApi(Resource):
@login_required
@account_initialization_required
@console_ns.response(200, "Success", console_ns.models[WebhookTriggerResponse.__name__])
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=AppMode.WORKFLOW)
@model_validate(Parser)
def get(self, req_data: Parser, app_model: App):
@@ -134,7 +134,7 @@ class AppTriggersApi(Resource):
@account_initialization_required
@console_ns.response(200, "Success", console_ns.models[WorkflowTriggerListResponse.__name__])
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp()))
@get_app_model(mode=AppMode.WORKFLOW)
def get(self, current_tenant_id: str, app_model: App):
"""Get app triggers list"""
@@ -171,7 +171,7 @@ class AppTriggerEnableApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.APP_EDIT, PlainApp()))
@console_ns.response(200, "Success", console_ns.models[WorkflowTriggerResponse.__name__])
@with_current_tenant_id
@get_app_model(mode=AppMode.WORKFLOW)
+11 -119
View File
@@ -11,35 +11,37 @@ from functools import wraps
from typing import cast, overload
from sqlalchemy import select
from sqlalchemy.orm import Session
from werkzeug.exceptions import Forbidden
from sqlalchemy.orm import Session, scoped_session
from configs import dify_config
from controllers.common.session import with_session
from controllers.common.wraps import RBACPermission, RBACResourceScope, _extract_resource_id, enforce_rbac_access
from controllers.console.app.error import AppNotFoundError
from extensions.ext_application_services import application_services
from extensions.ext_database import db
from libs.login import current_account_with_tenant
from models import App, AppMode
from models.agent import Agent, AgentScope
from models.agent import AgentScope
from services.app_service import AppService
__all__ = [
"agent_manage_required_for_agent_app",
"enforce_agent_manage_or_app_scene",
"get_app_model",
"get_previewable_app_model",
"with_session",
]
def _is_hidden_backing_app(app_model: App, session: Session | scoped_session) -> bool:
binding = app_model.agent_app_binding_with_session(session=session, include_archived=True)
return binding is not None and binding.scope == AgentScope.WORKFLOW_ONLY
def _load_app_model(session: Session, app_id: str) -> App | None:
"""Load the tenant-scoped app row with the request session owned by `with_session`."""
_, current_tenant_id = current_account_with_tenant()
app_model = session.scalar(
select(App).where(App.id == app_id, App.tenant_id == current_tenant_id, App.status == "normal").limit(1)
)
if app_model is not None and _is_hidden_backing_app(app_model, session):
return None
return app_model
@@ -49,6 +51,8 @@ def _load_app_model_from_scoped_session(app_id: str) -> App | None:
app_model = db.session.scalar(
select(App).where(App.id == app_id, App.tenant_id == current_tenant_id, App.status == "normal").limit(1)
)
if app_model is not None and _is_hidden_backing_app(app_model, db.session):
return None
return app_model
@@ -59,118 +63,6 @@ def _load_previewable_app_model(session: Session, app_id: str) -> App | None:
return AppService.get_normal_app_by_id(app_id, session)
def _agent_app_binding(app_id: str) -> Agent | None:
app_model = _load_app_model_from_scoped_session(app_id)
if app_model is None:
return None
return app_model.agent_app_binding_with_session(session=db.session(), include_archived=True)
def _reject_hidden_agent_backing_app(path_args: dict[str, object]) -> None:
raw_app_id = path_args.get("app_id") or path_args.get("resource_id")
if raw_app_id is None:
return
binding = _agent_app_binding(str(raw_app_id))
if binding is not None and binding.scope == AgentScope.WORKFLOW_ONLY:
raise AppNotFoundError()
def enforce_agent_manage_or_app_scene(
*,
tenant_id: str,
account_id: str,
scene: RBACPermission,
path_args: dict[str, object],
) -> None:
# Must run before the RBAC_ENABLED check below: a hidden workflow-only
# backing App has to stay unreachable regardless of RBAC_ENABLED.
_reject_hidden_agent_backing_app(path_args)
if not dify_config.RBAC_ENABLED:
return
binding = _agent_app_binding(_extract_resource_id(RBACResourceScope.APP, tenant_id, path_args))
if binding is not None:
if binding.scope == AgentScope.WORKFLOW_ONLY:
raise AppNotFoundError()
try:
enforce_rbac_access(
tenant_id=tenant_id,
account_id=account_id,
resource_type=RBACResourceScope.WORKSPACE,
scene=RBACPermission.AGENT_MANAGE,
resource_required=False,
)
return
except Forbidden:
pass # not an agent.manage holder — fall through to the normal scene check
enforce_rbac_access(
tenant_id=tenant_id,
account_id=account_id,
resource_type=RBACResourceScope.APP,
scene=scene,
path_args=path_args,
)
@overload
def agent_manage_required_for_agent_app[**P, R](view: Callable[P, R]) -> Callable[P, R]: ...
@overload
def agent_manage_required_for_agent_app[**P, R](
view: None = None, *, scene: RBACPermission | None = None
) -> Callable[[Callable[P, R]], Callable[P, R]]: ...
def agent_manage_required_for_agent_app[**P, R](
view: Callable[P, R] | None = None, *, scene: RBACPermission | None = None
) -> Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]]:
# Must sit above get_app_model in the decorator stack — get_app_model
# deletes app_id from kwargs, and this decorator needs it.
# TODO: this is a workaround, remove this after ACL for agent app is available
def decorator(view_func: Callable[P, R]) -> Callable[P, R]:
@wraps(view_func)
def decorated(*args: P.args, **kwargs: P.kwargs) -> R:
if scene is not None:
if not dify_config.RBAC_ENABLED:
_reject_hidden_agent_backing_app(kwargs)
return view_func(*args, **kwargs)
current_user, current_tenant_id = current_account_with_tenant()
enforce_agent_manage_or_app_scene(
tenant_id=current_tenant_id,
account_id=current_user.id,
scene=scene,
path_args=kwargs,
)
return view_func(*args, **kwargs)
raw_app_id = kwargs.get("app_id") or kwargs.get("resource_id")
if raw_app_id is not None:
binding = _agent_app_binding(str(raw_app_id))
if binding is not None:
if binding.scope == AgentScope.WORKFLOW_ONLY:
raise AppNotFoundError()
if dify_config.RBAC_ENABLED:
current_user, current_tenant_id = current_account_with_tenant()
enforce_rbac_access(
tenant_id=current_tenant_id,
account_id=current_user.id,
resource_type=RBACResourceScope.WORKSPACE,
scene=RBACPermission.AGENT_MANAGE,
resource_required=False,
)
return view_func(*args, **kwargs)
return decorated
if view is None:
return decorator
return decorator(view)
def _get_injected_session(args: tuple[object, ...]) -> Session | None:
"""Return the request session inserted by `with_session`, if this handler has been migrated."""
if len(args) < 2:
@@ -5,6 +5,7 @@ from flask_restx import Resource
from pydantic import BaseModel, ConfigDict, Field
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.auth.error import (
@@ -14,7 +15,7 @@ from controllers.console.auth.error import (
InvalidDataSourceApiKeyAuthCredentialsRequestError,
)
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import RBACPermission, RBACResourceScope, model_validate
from controllers.console.wraps import RBACPermission, model_validate
from extensions.ext_application_services import application_services
from fields.base import ResponseModel
from libs.helper import dump_response
@@ -104,9 +105,7 @@ class ApiKeyAuthDataSourceBinding(Resource):
@console_ns.expect(console_ns.models[ApiKeyAuthBindingPayload.__name__])
@console_account_admission(
allowed_roles=_ADMIN_OR_OWNER_ROLES,
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.CREDENTIAL_CREATE,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.CREDENTIAL_CREATE, Workspace())],
)
@model_validate(ApiKeyAuthBindingPayload)
def post(self, req_data: ApiKeyAuthBindingPayload, request_context: RequestContext):
@@ -138,9 +137,7 @@ class ApiKeyAuthDataSourceBindingDelete(Resource):
@console_ns.response(HTTPStatus.NO_CONTENT, "Binding deleted successfully")
@console_account_admission(
allowed_roles=_ADMIN_OR_OWNER_ROLES,
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.CREDENTIAL_MANAGE,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace())],
)
def delete(self, request_context: RequestContext, binding_id: UUID):
application_services().data_source_api_key_auth.delete_binding(request_context, str(binding_id))
@@ -9,6 +9,7 @@ from pydantic import BaseModel, Field, ValidationError
from configs import dify_config
from controllers.common.fields import RedirectResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -17,7 +18,7 @@ from controllers.common.schema import (
register_schema_models,
)
from controllers.console.flask_admission import console_account_admission
from core.rbac import RBACPermission, RBACResourceScope
from core.rbac import RBACPermission
from extensions.ext_application_services import application_services
from fields.base import ResponseModel
from libs.helper import dump_response
@@ -111,9 +112,7 @@ class OAuthDataSource(Resource):
@console_ns.response(HTTPStatus.FORBIDDEN, "Admin privileges required")
@console_account_admission(
allowed_roles=_ADMIN_OR_OWNER_ROLES,
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.CREDENTIAL_MANAGE,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace())],
)
def get(self, request_context: RequestContext, provider: str):
try:
@@ -12,6 +12,7 @@ from sqlalchemy.orm import Session
from werkzeug.exceptions import NotFound
from controllers.common.fields import SimpleResultResponse, TextContentResponse
from controllers.common.rbac import DatasetId, RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from core.datasource.entities.datasource_entities import DatasourceProviderType, OnlineDocumentPagesMessage
@@ -34,7 +35,6 @@ from tasks.document_indexing_sync_task import document_indexing_sync_task
from .. import console_ns
from ..wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
is_admin_or_owner_required,
model_validate,
@@ -140,7 +140,7 @@ class DataSourceApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@console_ns.response(200, "Success", console_ns.models[DataSourceIntegrateListResponse.__name__])
@with_current_tenant_id
@@ -191,7 +191,7 @@ class DataSourceApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_tenant_id
@@ -420,7 +420,7 @@ class DataSourceNotionDatasetSyncApi(Resource):
@login_required
@account_initialization_required
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, dataset_id: UUID) -> tuple[dict[str, str], int]:
dataset_id_str = str(dataset_id)
@@ -440,7 +440,7 @@ class DataSourceNotionDocumentSyncApi(Resource):
@login_required
@account_initialization_required
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, dataset_id: UUID, document_id: UUID) -> tuple[dict[str, str], int]:
dataset_id_str = str(dataset_id)
+16 -18
View File
@@ -13,6 +13,7 @@ from werkzeug.exceptions import Forbidden, NotFound
import services
from configs import dify_config
from controllers.common.fields import ApiBaseUrlResponse, SimpleResultResponse, UsageCheckResponse
from controllers.common.rbac import DatasetId, RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
@@ -21,7 +22,6 @@ from controllers.console.app.error import ProviderNotInitializeError
from controllers.console.datasets.error import DatasetInUseError, DatasetNameDuplicateError, IndexingEstimateError
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
cloud_edition_billing_rate_limit_check,
enterprise_license_required,
@@ -589,9 +589,7 @@ class DatasetListApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(
RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, Workspace()))
@cloud_edition_billing_rate_limit_check("knowledge")
@with_current_user
@with_current_tenant_id
@@ -662,7 +660,7 @@ class DatasetApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_current_user
@with_current_tenant_id
@with_session(write=False)
@@ -731,7 +729,7 @@ class DatasetApi(Resource):
@cloud_edition_billing_rate_limit_check("knowledge")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(DatasetUpdatePayload)
def patch(
@@ -798,7 +796,7 @@ class DatasetApi(Resource):
@cloud_edition_billing_rate_limit_check("knowledge")
@console_ns.response(204, "Dataset deleted successfully")
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(self, session: Session, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -831,7 +829,7 @@ class DatasetUseCheckApi(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset = _get_accessible_dataset(dataset_id, current_tenant_id, current_user, session)
@@ -853,7 +851,7 @@ class DatasetQueryApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -1009,7 +1007,7 @@ class DatasetRelatedAppListApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -1048,7 +1046,7 @@ class DatasetIndexingStatusApi(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset = _get_accessible_dataset(dataset_id, current_tenant_id, current_user, session)
@@ -1112,7 +1110,7 @@ class DatasetApiKeyApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_API_KEY_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_API_KEY_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@with_session(write=False)
@@ -1130,7 +1128,7 @@ class DatasetApiKeyApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_API_KEY_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_API_KEY_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@with_session
@@ -1191,7 +1189,7 @@ class DatasetApiDeleteApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_API_KEY_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_API_KEY_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@with_session
@@ -1228,7 +1226,7 @@ class DatasetEnableApiApi(Resource):
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def post(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, status: str):
dataset = _get_accessible_dataset(dataset_id, current_tenant_id, current_user, session)
@@ -1303,7 +1301,7 @@ class DatasetErrorDocs(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset = _get_accessible_dataset(dataset_id, current_tenant_id, current_user, session)
@@ -1330,7 +1328,7 @@ class DatasetPermissionUserListApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -1363,7 +1361,7 @@ class DatasetAutoDisableLogApi(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset = _get_accessible_dataset(dataset_id, current_tenant_id, current_user, session)
@@ -19,10 +19,11 @@ import services
from configs import dify_config
from controllers.common.controller_schemas import DocumentBatchDownloadZipPayload
from controllers.common.fields import SimpleResultMessageResponse, SimpleResultResponse, UrlResponse
from controllers.common.rbac import DatasetId, RBACCheck
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.wraps import RBACPermission, RBACResourceScope, model_validate, rbac_permission_required
from controllers.console.wraps import RBACPermission, model_validate, rbac_permission_required
from core.entities.knowledge_entities import IndexingEstimate
from core.errors.error import (
LLMBadRequestError,
@@ -405,7 +406,7 @@ class DatasetDocumentListApi(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -534,7 +535,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(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def post(self, session: Session, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -585,7 +586,7 @@ class DatasetDocumentListApi(Resource):
@console_ns.response(204, "Documents deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(
self,
@@ -719,7 +720,7 @@ class DocumentIndexingEstimateApi(DocumentResource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
dataset_id_str = str(dataset_id)
@@ -811,7 +812,7 @@ class DocumentBatchIndexingEstimateApi(DocumentResource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, batch: str):
dataset_id_str = str(dataset_id)
@@ -933,7 +934,7 @@ class DocumentBatchIndexingStatusApi(DocumentResource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_user: Account, dataset_id: UUID, batch: str):
dataset_id_str = str(dataset_id)
@@ -993,7 +994,7 @@ class DocumentIndexingStatusApi(DocumentResource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
dataset_id_str = str(dataset_id)
@@ -1059,7 +1060,7 @@ class DocumentApi(DocumentResource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
dataset_id_str = str(dataset_id)
@@ -1133,7 +1134,7 @@ class DocumentApi(DocumentResource):
@console_ns.response(204, "Document deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(
self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID
@@ -1169,7 +1170,7 @@ class DocumentDownloadApi(DocumentResource):
@cloud_edition_billing_rate_limit_check("knowledge")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_DOCUMENT_DOWNLOAD)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_DOCUMENT_DOWNLOAD, DatasetId()))
@with_session(write=False)
def get(
self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID
@@ -1193,7 +1194,7 @@ class DocumentBatchDownloadZipApi(DocumentResource):
@console_ns.expect(console_ns.models[DocumentBatchDownloadZipPayload.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, 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."""
@@ -1245,7 +1246,7 @@ class DocumentProcessingApi(DocumentResource):
@cloud_edition_billing_rate_limit_check("knowledge")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def patch(
self,
@@ -1302,7 +1303,7 @@ class DocumentMetadataApi(DocumentResource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(DocumentMetadataUpdatePayload)
def put(
@@ -1361,7 +1362,7 @@ class DocumentStatusApi(DocumentResource):
@cloud_edition_billing_rate_limit_check("knowledge")
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def patch(
self,
@@ -1407,7 +1408,7 @@ class DocumentPauseApi(DocumentResource):
@console_ns.response(204, "Document paused successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def patch(
self,
@@ -1447,7 +1448,7 @@ class DocumentRecoverApi(DocumentResource):
@console_ns.response(204, "Document resumed successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def patch(
self,
@@ -1487,7 +1488,7 @@ class DocumentRetryApi(DocumentResource):
@console_ns.response(204, "Documents retry started successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(DocumentRetryPayload)
def post(
@@ -1552,7 +1553,7 @@ class DocumentRenameApi(DocumentResource):
@console_ns.response(200, "Document renamed successfully", console_ns.models[DocumentResponse.__name__])
@console_ns.expect(console_ns.models[DocumentRenamePayload.__name__])
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(DocumentRenamePayload)
def post(
@@ -1587,7 +1588,7 @@ class WebsiteDocumentSyncApi(DocumentResource):
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def get(
self,
@@ -1629,7 +1630,7 @@ class DocumentPipelineExecutionLogApi(DocumentResource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(
self,
@@ -1681,7 +1682,7 @@ class DocumentGenerateSummaryApi(Resource):
@account_initialization_required
@cloud_edition_billing_rate_limit_check("knowledge")
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(GenerateSummaryPayload)
def post(self, req_data: GenerateSummaryPayload, session: Session, current_user: Account, dataset_id: UUID):
@@ -1782,7 +1783,7 @@ class DocumentSummaryStatusApi(DocumentResource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_user: Account, dataset_id: UUID, document_id: UUID):
"""
@@ -15,6 +15,7 @@ import services
from configs import dify_config
from controllers.common.controller_schemas import ChildChunkCreatePayload, ChildChunkUpdatePayload
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import DatasetId, RBACCheck
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -31,7 +32,6 @@ from controllers.console.datasets.error import (
)
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
cloud_edition_billing_knowledge_limit_check,
cloud_edition_billing_rate_limit_check,
@@ -191,7 +191,7 @@ class DatasetDocumentSegmentListApi(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
dataset_id_str = str(dataset_id)
@@ -302,7 +302,7 @@ class DatasetDocumentSegmentListApi(Resource):
@console_ns.doc(params=query_params_from_model(SegmentIdListQuery))
@console_ns.response(204, "Segments deleted successfully")
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(self, session: Session, current_user: Account, dataset_id: UUID, document_id: UUID):
# check dataset
@@ -342,7 +342,7 @@ class DatasetDocumentSegmentApi(Resource):
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def patch(
self,
@@ -413,7 +413,7 @@ class DatasetDocumentSegmentAddApi(Resource):
@console_ns.response(200, "Segment created successfully", console_ns.models[SegmentDetailResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(SegmentCreatePayload)
def post(
@@ -485,7 +485,7 @@ class DatasetDocumentSegmentUpdateApi(Resource):
@console_ns.response(200, "Segment updated successfully", console_ns.models[SegmentDetailResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(SegmentUpdatePayload)
def patch(
@@ -566,7 +566,7 @@ class DatasetDocumentSegmentUpdateApi(Resource):
@console_ns.response(204, "Segment deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(
self,
@@ -617,7 +617,7 @@ class DatasetDocumentSegmentBatchImportApi(Resource):
@console_ns.expect(console_ns.models[BatchImportPayload.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(BatchImportPayload)
def post(
@@ -676,7 +676,7 @@ class DatasetDocumentSegmentBatchImportApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
def get(self, job_id=None, dataset_id: UUID | None = None, document_id: UUID | None = None):
if job_id is None:
raise NotFound("The job does not exist.")
@@ -703,7 +703,7 @@ class ChildChunkAddApi(Resource):
@console_ns.response(200, "Child chunk created successfully", console_ns.models[ChildChunkDetailResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(ChildChunkCreatePayload)
def post(
@@ -764,7 +764,7 @@ class ChildChunkAddApi(Resource):
@login_required
@account_initialization_required
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, dataset_id: UUID, document_id: UUID, segment_id: UUID):
# check dataset
@@ -819,7 +819,7 @@ class ChildChunkAddApi(Resource):
@console_ns.expect(console_ns.models[ChildChunkBatchUpdatePayload.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(ChildChunkBatchUpdatePayload)
def patch(
@@ -873,7 +873,7 @@ class ChildChunkUpdateApi(Resource):
@console_ns.response(204, "Child chunk deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(
self,
@@ -926,7 +926,7 @@ class ChildChunkUpdateApi(Resource):
@console_ns.response(200, "Child chunk updated successfully", console_ns.models[ChildChunkDetailResponse.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(ChildChunkUpdatePayload)
def patch(
+3 -5
View File
@@ -12,6 +12,7 @@ from werkzeug.exceptions import Forbidden, InternalServerError, NotFound
import services
from controllers.common.fields import UsageCountResponse
from controllers.common.rbac import DatasetId, RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
register_response_schema_models,
@@ -22,7 +23,6 @@ from controllers.console import console_ns
from controllers.console.datasets.error import DatasetNameDuplicateError
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -350,9 +350,7 @@ class ExternalDatasetCreateApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.DATASET, RBACPermission.DATASET_EXTERNAL_CONNECT, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EXTERNAL_CONNECT, Workspace()))
@with_current_user
@with_current_tenant_id
@with_session
@@ -411,7 +409,7 @@ class ExternalKnowledgeHitTestingApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_PIPELINE_TEST)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_PIPELINE_TEST, DatasetId()))
@with_session
@model_validate(ExternalHitTestingPayload)
def post(self, req_data: ExternalHitTestingPayload, session: Session, current_user: Account, dataset_id: UUID):
@@ -5,9 +5,10 @@ from uuid import UUID
from flask_restx import Resource
from sqlalchemy.orm import Session
from controllers.common.rbac import DatasetId, RBACCheck
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.console.app.wraps import with_session
from controllers.console.wraps import RBACPermission, RBACResourceScope, rbac_permission_required
from controllers.console.wraps import RBACPermission, rbac_permission_required
from fields.hit_testing_fields import HitTestingResponse
from libs.helper import dump_response
from libs.login import login_required
@@ -46,7 +47,7 @@ class HitTestingApi(Resource, DatasetsHitTestingBase):
@cloud_edition_billing_rate_limit_check("knowledge")
@with_current_tenant_id
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_PIPELINE_TEST)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_PIPELINE_TEST, DatasetId()))
@with_session
def post(
self, session: Session, current_user: Account, current_tenant_id: str, dataset_id: UUID
+7 -7
View File
@@ -8,12 +8,12 @@ from werkzeug.exceptions import Forbidden, NotFound
import services
from configs import dify_config
from controllers.common.controller_schemas import MetadataUpdatePayload
from controllers.common.rbac import DatasetId, RBACCheck
from controllers.common.schema import register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
enterprise_license_required,
model_validate,
@@ -61,7 +61,7 @@ class DatasetMetadataCreateApi(Resource):
@console_ns.expect(console_ns.models[MetadataArgs.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(MetadataArgs)
def post(
@@ -92,7 +92,7 @@ class DatasetMetadataCreateApi(Resource):
)
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, DatasetId()))
@with_session(write=False)
def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset_id_str = str(dataset_id)
@@ -118,7 +118,7 @@ class DatasetMetadataApi(Resource):
@console_ns.expect(console_ns.models[MetadataUpdatePayload.__name__])
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(MetadataUpdatePayload)
def patch(
@@ -149,7 +149,7 @@ class DatasetMetadataApi(Resource):
@console_ns.response(204, "Metadata deleted successfully")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def delete(
self,
@@ -195,7 +195,7 @@ class DatasetMetadataBuiltInFieldActionApi(Resource):
@enterprise_license_required
@console_ns.response(204, "Action completed successfully")
@with_current_user
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def post(self, session: Session, current_user: Account, dataset_id: UUID, action: Literal["enable", "disable"]):
dataset_id_str = str(dataset_id)
@@ -227,7 +227,7 @@ class DocumentMetadataEditApi(Resource):
@console_ns.response(404, "Dataset, document, or metadata not found")
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
@model_validate(MetadataOperationData)
def post(
@@ -7,11 +7,11 @@ from werkzeug.exceptions import Forbidden, NotFound
from configs import dify_config
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -167,7 +167,7 @@ class DatasourcePluginOAuthAuthorizationUrl(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_user
@with_current_tenant_id
def get(self, current_tenant_id: str, current_user: Account, provider_id: str):
@@ -310,7 +310,7 @@ class DatasourceAuth(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_CREATE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_CREATE, Workspace()))
@with_current_tenant_id
@model_validate(DatasourceCredentialPayload)
def post(self, req_data: DatasourceCredentialPayload, current_tenant_id: str, provider_id: str):
@@ -337,7 +337,7 @@ class DatasourceAuth(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_user
@with_current_tenant_id
def get(self, current_tenant_id: str, user: Account, provider_id: str):
@@ -362,7 +362,7 @@ class DatasourceAuthDeleteApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(DatasourceCredentialDeletePayload)
def post(self, req_data: DatasourceCredentialDeletePayload, current_tenant_id: str, provider_id: str):
@@ -391,7 +391,7 @@ class DatasourceAuthUpdateApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(DatasourceCredentialUpdatePayload)
def post(self, req_data: DatasourceCredentialUpdatePayload, current_tenant_id: str, provider_id: str):
@@ -459,7 +459,7 @@ class DatasourceAuthOauthCustomClient(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(DatasourceCustomClientPayload)
def post(self, req_data: DatasourceCustomClientPayload, current_tenant_id: str, provider_id: str):
@@ -477,7 +477,7 @@ class DatasourceAuthOauthCustomClient(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_tenant_id
def delete(self, current_tenant_id: str, provider_id: str):
@@ -498,7 +498,7 @@ class DatasourceAuthDefaultApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(DatasourceDefaultPayload)
def post(self, req_data: DatasourceDefaultPayload, current_tenant_id: str, provider_id: str):
@@ -520,7 +520,7 @@ class DatasourceUpdateProviderNameApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(DatasourceUpdateNamePayload)
def post(self, req_data: DatasourceUpdateNamePayload, current_tenant_id: str, provider_id: str):
@@ -8,6 +8,7 @@ from werkzeug.exceptions import Forbidden, NotFound
from configs import dify_config
from controllers.common.fields import SimpleDataResponse
from controllers.common.rbac import DatasetByPipeline, RBACCheck
from controllers.common.schema import (
JsonResponseWithStatus,
query_params_from_model,
@@ -19,7 +20,6 @@ from controllers.console.app.wraps import with_session
from controllers.console.datasets.wraps import get_rag_pipeline
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
enterprise_license_required,
knowledge_pipeline_publish_enabled,
@@ -223,7 +223,7 @@ class PublishCustomizedPipelineTemplateApi(Resource):
@knowledge_pipeline_publish_enabled
@with_current_user
@get_rag_pipeline
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_PIPELINE_RELEASE)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_PIPELINE_RELEASE, DatasetByPipeline()))
@model_validate(CustomizedPipelineTemplatePayload)
def post(
self,
@@ -10,6 +10,7 @@ from pydantic import BaseModel, Field
from sqlalchemy.orm import sessionmaker
from controllers.common.errors import InvalidArgumentError, NotFoundError
from controllers.common.rbac import DatasetByPipeline, RBACCheck
from controllers.common.schema import query_params_from_model, register_schema_models
from controllers.console import console_ns
from controllers.console.app.error import (
@@ -26,7 +27,6 @@ from controllers.console.app.workflow_draft_variable import (
from controllers.console.datasets.wraps import get_rag_pipeline
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -82,7 +82,7 @@ def _api_prerequisite[T, **P, R](
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@wraps(f)
def wrapper(self: T, current_user: Account, *args: P.args, **kwargs: P.kwargs) -> R | Response:
@@ -3,6 +3,7 @@ from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from controllers.common.fields import SimpleDataResponse
from controllers.common.rbac import DatasetByPipeline, RBACCheck, Workspace
from controllers.common.schema import (
JsonResponseWithStatus,
query_params_from_model,
@@ -13,7 +14,6 @@ from controllers.console import console_ns
from controllers.console.datasets.wraps import get_rag_pipeline
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -81,9 +81,7 @@ class RagPipelineImportApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, Workspace()))
@with_current_user
@model_validate(RagPipelineImportPayload)
def post(self, req_data: RagPipelineImportPayload, current_user: Account) -> JsonResponseWithStatus:
@@ -128,9 +126,7 @@ class RagPipelineImportConfirmApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_CREATE_AND_MANAGEMENT, Workspace()))
@with_current_user
def post(self, current_user: Account, import_id: str) -> JsonResponseWithStatus:
with Session(db.engine, expire_on_commit=False) as session:
@@ -160,7 +156,7 @@ class RagPipelineImportCheckDependenciesApi(Resource):
@get_rag_pipeline
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_READONLY, DatasetByPipeline()))
def get(self, pipeline: Pipeline) -> JsonResponseWithStatus:
with Session(db.engine, expire_on_commit=False) as session:
import_service = RagPipelineDslService(session)
@@ -178,7 +174,7 @@ class RagPipelineExportApi(Resource):
@get_rag_pipeline
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_IMPORT_EXPORT_DSL)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_IMPORT_EXPORT_DSL, DatasetByPipeline()))
@model_validate(IncludeSecretQuery)
def get(self, req_data: IncludeSecretQuery, pipeline: Pipeline) -> JsonResponseWithStatus:
# Add include_secret params
@@ -13,6 +13,7 @@ import services
from configs import dify_config
from controllers.common.controller_schemas import DefaultBlockConfigQuery, WorkflowListQuery, WorkflowUpdatePayload
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import DatasetByPipeline, DatasetId, RBACCheck
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.error import (
@@ -32,7 +33,6 @@ from controllers.console.app.wraps import with_session
from controllers.console.datasets.wraps import get_rag_pipeline, load_rag_pipeline
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -197,7 +197,7 @@ class DraftRagPipelineApi(Resource):
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
def get(self, pipeline: Pipeline):
"""
Get draft rag pipeline's workflow
@@ -219,7 +219,7 @@ class DraftRagPipelineApi(Resource):
@with_current_user
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@console_ns.expect(console_ns.models[DraftWorkflowSyncPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineWorkflowSyncResponse.__name__])
def post(self, current_user: Account, pipeline: Pipeline):
@@ -280,7 +280,7 @@ class RagPipelineDraftRunIterationNodeApi(Resource):
@with_current_user
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@model_validate(NodeRunPayload)
def post(self, req_data: NodeRunPayload, current_user: Account, pipeline: Pipeline, node_id: str):
"""
@@ -313,7 +313,7 @@ class RagPipelineDraftRunLoopNodeApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
@model_validate(NodeRunPayload)
@@ -348,7 +348,7 @@ class DraftRagPipelineRunApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@with_session
@model_validate(DraftWorkflowRunPayload)
@@ -382,7 +382,7 @@ class PublishedRagPipelineRunApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@with_session
@model_validate(PublishedWorkflowRunPayload)
@@ -417,7 +417,7 @@ class RagPipelinePublishedDatasourceNodeRunApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
@model_validate(DatasourceNodeRunPayload)
@@ -449,7 +449,7 @@ class RagPipelineDraftDatasourceNodeRunApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@account_initialization_required
@with_current_user
@get_rag_pipeline
@@ -486,7 +486,7 @@ class RagPipelineDraftNodeRunApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@account_initialization_required
@with_current_user
@get_rag_pipeline
@@ -516,7 +516,7 @@ class RagPipelineTaskStopApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@account_initialization_required
@with_current_user
@get_rag_pipeline
@@ -540,7 +540,7 @@ class PublishedRagPipelineApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@get_rag_pipeline
def get(self, pipeline: Pipeline):
"""
@@ -565,7 +565,7 @@ class PublishedRagPipelineApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
def post(self, current_user: Account, pipeline: Pipeline):
@@ -600,7 +600,7 @@ class DefaultRagPipelineBlockConfigsApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@get_rag_pipeline
def get(self, pipeline: Pipeline):
"""
@@ -623,7 +623,7 @@ class DefaultRagPipelineBlockConfigApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@get_rag_pipeline
@model_validate(DefaultBlockConfigQuery)
def get(self, req_data: DefaultBlockConfigQuery, pipeline: Pipeline, block_type: str):
@@ -656,7 +656,7 @@ class PublishedAllRagPipelineApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
@model_validate(WorkflowListQuery)
@@ -702,7 +702,7 @@ class RagPipelineDraftWorkflowRestoreApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
def post(self, current_user: Account, pipeline: Pipeline, workflow_id: str):
@@ -737,7 +737,7 @@ class RagPipelineByIdApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
@console_ns.expect(console_ns.models[WorkflowUpdatePayload.__name__])
@@ -773,7 +773,7 @@ class RagPipelineByIdApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@with_current_user
@get_rag_pipeline
def delete(self, current_user: Account, pipeline: Pipeline, workflow_id: str):
@@ -816,7 +816,7 @@ class PublishedRagPipelineSecondStepApi(Resource):
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@model_validate(NodeIdQuery)
def get(self, req_data: NodeIdQuery, pipeline: Pipeline):
"""
@@ -839,7 +839,7 @@ class PublishedRagPipelineFirstStepApi(Resource):
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@model_validate(NodeIdQuery)
def get(self, req_data: NodeIdQuery, pipeline: Pipeline):
"""
@@ -862,7 +862,7 @@ class DraftRagPipelineFirstStepApi(Resource):
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@model_validate(NodeIdQuery)
def get(self, req_data: NodeIdQuery, pipeline: Pipeline):
"""
@@ -885,7 +885,7 @@ class DraftRagPipelineSecondStepApi(Resource):
@account_initialization_required
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@model_validate(NodeIdQuery)
def get(self, req_data: NodeIdQuery, pipeline: Pipeline):
"""
@@ -1035,7 +1035,7 @@ class RagPipelineTransformApi(Resource):
@account_initialization_required
@with_current_user
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetId()))
@with_session
def post(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
dataset = DatasetService.get_dataset_for_tenant(str(dataset_id), current_tenant_id, session=session)
@@ -1070,7 +1070,7 @@ class RagPipelineDatasourceVariableApi(Resource):
@with_current_user
@get_rag_pipeline
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@rbac_permission_required(RBACCheck(RBACPermission.DATASET_EDIT, DatasetByPipeline()))
@model_validate(DatasourceVariablesPayload)
def post(self, req_data: DatasourceVariablesPayload, current_user: Account, pipeline: Pipeline):
"""
+14 -34
View File
@@ -1,6 +1,6 @@
"""Flask adapter for Console API admission."""
from collections.abc import Callable
from collections.abc import Callable, Sequence
from functools import wraps
from typing import Concatenate
@@ -8,8 +8,7 @@ from flask import Response, abort, request
from werkzeug.exceptions import Forbidden
from configs import dify_config
from controllers.common.wraps import enforce_rbac_access
from controllers.console.app.wraps import enforce_agent_manage_or_app_scene
from controllers.common.rbac import RBAC_CHECKS_ATTR, RBACCheck, enforce_rbac_checks
from controllers.console.wraps import (
account_initialization_required,
enable_change_email,
@@ -17,11 +16,9 @@ from controllers.console.wraps import (
setup_required,
)
from core.logging.context import get_request_id, get_trace_id
from core.rbac import RBACPermission, RBACResourceScope
from enums import DeploymentEdition
from libs.login import current_account_with_tenant, login_required
from machinery.context import RequestContext
from machinery.errors import AdmissionConfigurationError
from models.account import TenantAccountRole
from services.system_feature_service import SystemFeatureService
@@ -50,10 +47,7 @@ def console_account_admission[T, **P, R](
require_initialized: bool = True,
require_valid_enterprise_license: bool = False,
allowed_roles: frozenset[TenantAccountRole] | None = None,
rbac_resource_scope: RBACResourceScope | None = None,
rbac_permission: RBACPermission | None = None,
rbac_resource_required: bool = True,
agent_manage_fallback: bool = False,
rbac_checks: Sequence[RBACCheck] | None = None,
) -> Callable[
[Callable[Concatenate[T, RequestContext, P], R]],
Callable[Concatenate[T, P], R | Response],
@@ -66,40 +60,23 @@ def console_account_admission[T, **P, R](
context construction.
"""
if (rbac_resource_scope is None) != (rbac_permission is None):
raise AdmissionConfigurationError("RBAC resource scope and permission must be configured together")
if agent_manage_fallback and rbac_resource_scope != RBACResourceScope.APP:
raise AdmissionConfigurationError("agent_manage_fallback requires rbac_resource_scope=RBACResourceScope.APP")
if agent_manage_fallback and not rbac_resource_required:
raise AdmissionConfigurationError("agent_manage_fallback requires rbac_resource_required=True")
def decorator(
view: Callable[Concatenate[T, RequestContext, P], R],
) -> Callable[Concatenate[T, P], R | Response]:
@wraps(view)
@wraps(view, updated=())
def inject_request_context(self: T, /, *args: P.args, **kwargs: P.kwargs) -> R:
account_with_tenant = current_account_with_tenant()
account = account_with_tenant.account
tenant_id = account_with_tenant.tenant_id
if allowed_roles is not None and not dify_config.RBAC_ENABLED and account.role not in allowed_roles:
raise Forbidden()
if rbac_resource_scope is not None and rbac_permission is not None:
if agent_manage_fallback:
enforce_agent_manage_or_app_scene(
tenant_id=tenant_id,
account_id=account.id,
scene=rbac_permission,
path_args=kwargs,
)
else:
enforce_rbac_access(
tenant_id=tenant_id,
account_id=account.id,
resource_type=rbac_resource_scope,
scene=rbac_permission,
resource_required=rbac_resource_required,
path_args=kwargs,
)
if rbac_checks is not None:
enforce_rbac_checks(
tenant_id=tenant_id,
account_id=account.id,
checks=rbac_checks,
path_args=kwargs,
)
request_context = RequestContext(
account_id=account.id,
active_workspace_id=tenant_id,
@@ -108,6 +85,9 @@ def console_account_admission[T, **P, R](
)
return view(self, request_context, *args, **kwargs)
if rbac_checks is not None:
setattr(inject_request_context, RBAC_CHECKS_ATTR, rbac_checks)
admitted: Callable[Concatenate[T, P], R | Response] = inject_request_context
if require_change_email_enabled:
admitted = enable_change_email(admitted)
@@ -10,6 +10,7 @@ from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
from controllers.common.controller_schemas import WorkflowUpdatePayload
from controllers.common.fields import GeneratedAppResponse, SimpleResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.app.error import DraftWorkflowNotExist, DraftWorkflowNotSync
@@ -34,7 +35,6 @@ from controllers.console.snippets.payloads import (
)
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -205,9 +205,7 @@ class SnippetDraftWorkflowApi(Resource):
@with_current_user
@get_snippet
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@model_validate(SnippetDraftSyncPayload)
def post(self, req_data: SnippetDraftSyncPayload, current_user: Account, snippet: CustomizedSnippet):
"""Sync draft workflow for snippet."""
@@ -294,9 +292,7 @@ class SnippetPublishedWorkflowApi(Resource):
@with_current_user
@get_snippet
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
def post(self, current_user: Account, snippet: CustomizedSnippet):
"""Publish snippet workflow."""
snippet_service = _snippet_service()
@@ -355,9 +351,7 @@ class SnippetPublishedAllWorkflowApi(Resource):
@account_initialization_required
@get_snippet
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@model_validate(SnippetWorkflowListQuery)
def get(self, req_data: SnippetWorkflowListQuery, snippet: CustomizedSnippet):
"""Get all published workflow versions for snippet."""
@@ -399,9 +393,7 @@ class SnippetDraftWorkflowRestoreApi(Resource):
@with_current_user
@get_snippet
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
def post(self, current_user: Account, snippet: CustomizedSnippet, workflow_id: str):
"""Restore a published snippet workflow version into the draft workflow."""
snippet_service = _snippet_service()
@@ -441,9 +433,7 @@ class SnippetWorkflowByIdApi(Resource):
@with_current_user
@get_snippet
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@model_validate(WorkflowUpdatePayload)
def patch(
self,
@@ -487,9 +477,7 @@ class SnippetWorkflowByIdApi(Resource):
@account_initialization_required
@get_snippet
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
def delete(self, snippet: CustomizedSnippet, workflow_id: str):
"""Delete a published snippet workflow version."""
snippet_service = _snippet_service()
+3 -6
View File
@@ -7,13 +7,12 @@ from werkzeug.exceptions import Forbidden, NotFound
from configs import dify_config
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import RBACCheck, Workspace, enforce_rbac_checks
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.wraps import enforce_rbac_access
from controllers.console import console_ns
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
model_validate,
)
from extensions.ext_application_services import application_services
@@ -102,12 +101,10 @@ def _enforce_snippet_tag_rbac_if_needed(tag_type: TagType | str | None, context:
if not dify_config.RBAC_ENABLED:
return
enforce_rbac_access(
enforce_rbac_checks(
tenant_id=context.active_workspace_id,
account_id=context.account_id,
resource_type=RBACResourceScope.WORKSPACE,
scene=RBACPermission.SNIPPETS_CREATE_AND_MODIFY,
resource_required=False,
checks=[RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace())],
)
+11 -11
View File
@@ -15,11 +15,11 @@ from flask_restx import Resource
from pydantic import BaseModel, Field
from controllers.common.fields import SuccessResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
is_admin_or_owner_required,
model_validate,
@@ -235,7 +235,7 @@ class EndpointCollectionApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -267,7 +267,7 @@ class DeprecatedEndpointCreateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -291,7 +291,7 @@ class EndpointListApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -321,7 +321,7 @@ class EndpointListForSinglePluginApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -355,7 +355,7 @@ class EndpointItemApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -377,7 +377,7 @@ class EndpointItemApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -410,7 +410,7 @@ class DeprecatedEndpointDeleteApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -443,7 +443,7 @@ class DeprecatedEndpointUpdateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -468,7 +468,7 @@ class EndpointEnableApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -493,7 +493,7 @@ class EndpointDisableApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user_id
@with_current_tenant_id
@@ -7,12 +7,12 @@ from pydantic import BaseModel, Field, field_validator
from sqlalchemy.orm import Session
from controllers.common.fields import SimpleResultResponse, ValidationResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
is_admin_or_owner_required,
model_validate,
@@ -208,7 +208,7 @@ class ModelProviderCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserCredentialId)
@@ -226,7 +226,7 @@ class ModelProviderCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_CREATE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_CREATE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserCredentialCreate)
@@ -250,7 +250,7 @@ class ModelProviderCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserCredentialUpdate)
@@ -275,7 +275,7 @@ class ModelProviderCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserCredentialDelete)
@@ -295,7 +295,7 @@ class ModelProviderCredentialSwitchApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_USE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_USE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserCredentialSwitch)
@@ -372,7 +372,7 @@ class PreferredProviderTypeUpdateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_USE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_USE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserPreferredProviderType)
+11 -11
View File
@@ -5,6 +5,7 @@ from flask_restx import Resource
from pydantic import BaseModel, Field, field_validator
from controllers.common.fields import SimpleResultResponse, ValidationResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
register_enum_models,
@@ -14,7 +15,6 @@ from controllers.common.schema import (
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
is_admin_or_owner_required,
model_validate,
@@ -227,7 +227,7 @@ class DefaultModelApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserPostDefault)
@@ -276,7 +276,7 @@ class ModelProviderModelApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserPostModels)
@@ -325,7 +325,7 @@ class ModelProviderModelApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserDeleteModels)
@@ -350,7 +350,7 @@ class ModelProviderModelCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -413,7 +413,7 @@ class ModelProviderModelCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_CREATE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_CREATE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserCreateCredential)
@@ -446,7 +446,7 @@ class ModelProviderModelCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserUpdateCredential)
@@ -474,7 +474,7 @@ class ModelProviderModelCredentialApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserDeleteCredential)
@@ -499,7 +499,7 @@ class ModelProviderModelCredentialSwitchApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_USE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_USE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ParserSwitch)
@@ -526,7 +526,7 @@ class ModelProviderModelEnableApi(Resource):
@login_required
@account_initialization_required
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@model_validate(ParserDeleteModels)
def patch(self, req_data: ParserDeleteModels, tenant_id: str, provider: str):
@@ -548,7 +548,7 @@ class ModelProviderModelDisableApi(Resource):
@login_required
@account_initialization_required
@with_current_tenant_id
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@model_validate(ParserDeleteModels)
def patch(self, req_data: ParserDeleteModels, tenant_id: str, provider: str):
+17 -17
View File
@@ -11,6 +11,7 @@ from werkzeug.exceptions import Forbidden
from configs import dify_config
from controllers.common.fields import BinaryFileResponse, SuccessResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
register_enum_models,
@@ -21,7 +22,6 @@ from controllers.console import console_ns
from controllers.console.workspace import plugin_permission_required
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
is_admin_or_owner_required,
model_validate,
@@ -570,7 +570,7 @@ class PluginDebuggingKeyApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_DEBUG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_DEBUG, Workspace()))
@plugin_permission_required(debug_required=True)
@with_current_tenant_id
def get(self, tenant_id: str):
@@ -750,7 +750,7 @@ class PluginUploadFromPkgApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
def post(self, tenant_id: str):
@@ -771,7 +771,7 @@ class PluginUploadFromGithubApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserGithubUpload)
@@ -793,7 +793,7 @@ class PluginUploadFromBundleApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
def post(self, tenant_id: str):
@@ -814,7 +814,7 @@ class PluginInstallFromPkgApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserPluginIdentifiers)
@@ -835,7 +835,7 @@ class PluginInstallFromGithubApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserGithubInstall)
@@ -862,7 +862,7 @@ class PluginInstallFromMarketplaceApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserPluginIdentifiers)
@@ -883,7 +883,7 @@ class PluginFetchMarketplacePkgApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserPluginIdentifierQuery)
@@ -909,7 +909,7 @@ class PluginFetchManifestApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_INSTALL, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserPluginIdentifierQuery)
@@ -1014,7 +1014,7 @@ class PluginUpgradeFromMarketplaceApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserMarketplaceUpgrade)
@@ -1037,7 +1037,7 @@ class PluginUpgradeFromGithubApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserGithubUpgrade)
@@ -1065,7 +1065,7 @@ class PluginUninstallApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_DELETE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_DELETE, Workspace()))
@plugin_permission_required(install_required=True)
@with_current_tenant_id
@model_validate(ParserUninstall)
@@ -1138,7 +1138,7 @@ class PluginFetchDynamicSelectOptionsApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_MODEL_CONFIG, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -1169,7 +1169,7 @@ class PluginFetchDynamicSelectOptionsWithCredentialsApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -1201,7 +1201,7 @@ class PluginChangeAutoUpgradeApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@with_current_user
@with_current_tenant_id
@model_validate(ParserAutoUpgradeChange)
@@ -1256,7 +1256,7 @@ class PluginAutoUpgradeExcludePluginApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@with_current_tenant_id
@model_validate(ParserExcludePlugin)
def post(self, req_data: ParserExcludePlugin, tenant_id: str):
+323 -379
View File
@@ -1,5 +1,7 @@
from __future__ import annotations
from collections.abc import Callable, Mapping
from dataclasses import dataclass
from typing import Any, Literal
from flask import request
@@ -9,9 +11,10 @@ from sqlalchemy import select
from werkzeug.exceptions import NotFound
from configs import dify_config
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.console import console_ns
from controllers.console.wraps import RBACPermission, RBACResourceScope, model_validate, rbac_permission_required
from controllers.console.wraps import RBACPermission, model_validate, rbac_permission_required
from core.db.session_factory import session_factory
from enums import DeploymentEdition
from extensions.ext_database import db
@@ -50,6 +53,7 @@ register_response_schema_models(
svc.MyPermissionsResponse,
svc.AppAccessMatrix,
svc.DatasetAccessMatrix,
svc.AgentAccessMatrix,
svc.WorkspaceAccessMatrix,
svc.ResourceWhitelist,
svc.ResourceWhitelistConfig,
@@ -282,24 +286,6 @@ class RBACWorkspaceCatalogApi(Resource):
return _dump(svc.RBACService.Catalog.workspace(tenant_id, account_id))
@console_ns.route("/workspaces/current/rbac/role-permissions/catalog/app")
class RBACAppCatalogApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.PermissionCatalogResponse.__name__])
def get(self):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.Catalog.app(tenant_id, account_id))
@console_ns.route("/workspaces/current/rbac/role-permissions/catalog/dataset")
class RBACDatasetCatalogApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.PermissionCatalogResponse.__name__])
def get(self):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.Catalog.dataset(tenant_id, account_id))
# ---------------------------------------------------------------------------
# Roles.
# ---------------------------------------------------------------------------
@@ -323,9 +309,7 @@ class _RoleUpsertRequest(BaseModel):
@console_ns.route("/workspaces/current/rbac/roles")
class RBACRolesApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[_RBACRoleList.__name__])
@model_validate(_RolesListQuery)
def get(self, req_data: _RolesListQuery):
@@ -349,9 +333,7 @@ class RBACRolesApi(Resource):
return _dump(result)
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(201, "Role created", console_ns.models[svc.RBACRole.__name__])
def post(self):
tenant_id, account_id = _current_ids()
@@ -363,9 +345,7 @@ class RBACRolesApi(Resource):
@console_ns.route("/workspaces/current/rbac/roles/<uuid:role_id>")
class RBACRoleItemApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.RBACRole.__name__])
def get(self, role_id):
tenant_id, account_id = _current_ids()
@@ -379,9 +359,7 @@ class RBACRoleItemApi(Resource):
)
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.RBACRole.__name__])
def put(self, role_id):
tenant_id, account_id = _current_ids()
@@ -390,9 +368,7 @@ class RBACRoleItemApi(Resource):
return _dump(role)
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.RBACRole.__name__])
def delete(self, role_id):
tenant_id, account_id = _current_ids()
@@ -403,9 +379,7 @@ class RBACRoleItemApi(Resource):
@console_ns.route("/workspaces/current/rbac/roles/<uuid:role_id>/copy")
class RBACRoleCopyApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(201, "Role copied", console_ns.models[svc.RBACRole.__name__])
def post(self, role_id):
tenant_id, account_id = _current_ids()
@@ -430,9 +404,7 @@ class _AccessPolicyUpdateRequest(BaseModel):
@console_ns.route("/workspaces/current/rbac/access-policies")
class RBACAccessPoliciesApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[_AccessPolicyList.__name__])
def get(self):
tenant_id, account_id = _current_ids()
@@ -449,9 +421,7 @@ class RBACAccessPoliciesApi(Resource):
)
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(201, "Policy created", console_ns.models[svc.AccessPolicy.__name__])
def post(self):
tenant_id, account_id = _current_ids()
@@ -472,18 +442,14 @@ class RBACAccessPoliciesApi(Resource):
@console_ns.route("/workspaces/current/rbac/access-policies/<uuid:policy_id>")
class RBACAccessPolicyItemApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.AccessPolicy.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.AccessPolicies.get(tenant_id, account_id, str(policy_id)))
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.AccessPolicy.__name__])
def put(self, policy_id):
tenant_id, account_id = _current_ids()
@@ -501,9 +467,7 @@ class RBACAccessPolicyItemApi(Resource):
return _dump(policy)
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.AccessPolicy.__name__])
def delete(self, policy_id):
tenant_id, account_id = _current_ids()
@@ -514,9 +478,7 @@ class RBACAccessPolicyItemApi(Resource):
@console_ns.route("/workspaces/current/rbac/access-policies/<uuid:policy_id>/copy")
class RBACAccessPolicyCopyApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(201, "Policy copied", console_ns.models[svc.AccessPolicy.__name__])
def post(self, policy_id):
tenant_id, account_id = _current_ids()
@@ -527,9 +489,7 @@ class RBACAccessPolicyCopyApi(Resource):
@console_ns.route("/workspaces/current/rbac/access-policy-bindings/<uuid:binding_id>/lock")
class RBACAccessPolicyBindingLockApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.AccessPolicyBindingState.__name__])
def put(self, binding_id):
tenant_id, account_id = _current_ids()
@@ -539,20 +499,13 @@ class RBACAccessPolicyBindingLockApi(Resource):
@console_ns.route("/workspaces/current/rbac/access-policy-bindings/<uuid:binding_id>/unlock")
class RBACAccessPolicyBindingUnlockApi(Resource):
@login_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.WORKSPACE_ROLE_MANAGE, Workspace()))
@console_ns.response(200, "Success", console_ns.models[svc.AccessPolicyBindingState.__name__])
def put(self, binding_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.AccessPolicyBindings.unlock(tenant_id, account_id, str(binding_id)))
# ---------------------------------------------------------------------------
# Per-app access (App Access Config).
# ---------------------------------------------------------------------------
class _ResourceAccessScopeRequest(BaseModel):
automatic_include_workspace_members: bool
@@ -611,346 +564,337 @@ class RBACMyPermissionsApi(Resource):
account_id,
app_id=request.args.get("app_id") or None,
dataset_id=request.args.get("dataset_id") or None,
agent_id=request.args.get("agent_id") or None,
session=db.session(),
)
)
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/access-policy")
class RBACAppMatrixApi(Resource):
@login_required
@console_ns.doc(params=query_params_from_model(_AccessControlLanguageQuery))
@console_ns.response(200, "Success", console_ns.models[svc.AppAccessMatrix.__name__])
def get(self, app_id):
tenant_id, account_id = _current_ids()
result = svc.RBACService.AppAccess.matrix(tenant_id, account_id, str(app_id))
_hydrate_access_matrix_account_names(result.items)
return _dump(result)
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/whitelist")
class RBACAppWhitelistApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelist.__name__])
def get(self, app_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.AppAccess.whitelist(tenant_id, account_id, str(app_id)))
@login_required
@console_ns.expect(console_ns.models[_ResourceAccessScopeRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelist.__name__])
def put(self, app_id):
tenant_id, account_id = _current_ids()
request = _payload(_ResourceAccessScopeRequest)
result = svc.RBACService.AppAccess.replace_whitelist(
tenant_id,
account_id,
str(app_id),
svc.ReplaceMemberBindings(automatic_include_workspace_members=request.automatic_include_workspace_members),
)
if request.automatic_include_workspace_members:
initialize_created_app_rbac_access_task.delay(tenant_id, account_id, app_id=str(app_id))
return _dump(result)
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/whitelist_config")
class RBACAppWhitelistConfigApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelistConfig.__name__])
def get(self, app_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.AppAccess.whitelist_config(tenant_id, account_id, str(app_id)))
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/user-access-policies")
class RBACAppUserAccessPoliciesApi(Resource):
@login_required
@console_ns.doc(params=query_params_from_model(_ResourceUserAccessPoliciesQuery))
@console_ns.response(200, "Success", console_ns.models[svc.ResourceUserAccessPoliciesResponse.__name__])
def get(self, app_id):
tenant_id, account_id = _current_ids()
options = _pagination_options()
result = svc.RBACService.AppAccess.user_access_policies(tenant_id, account_id, str(app_id), options=options)
_move_resource_maintainer_first(result.data, svc.app_maintainer_id(tenant_id, str(app_id)))
_hydrate_resource_user_account_names(result.data)
return _dump(result)
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/users/<uuid:target_account_id>/access-policies")
class RBACAppUserAccessPolicyAssignmentApi(Resource):
@login_required
@console_ns.expect(console_ns.models[svc.ReplaceUserAccessPolicies.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.ReplaceUserAccessPoliciesResponse.__name__])
def put(self, app_id, target_account_id):
tenant_id, account_id = _current_ids()
payload = _payload(svc.ReplaceUserAccessPolicies)
return _dump(
svc.RBACService.AppAccess.replace_user_access_policies(
tenant_id,
account_id,
app_id,
target_account_id,
payload,
)
)
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/access-policies/<uuid:policy_id>/role-bindings")
class RBACAppRoleBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.RoleBindingsResponse.__name__])
def get(self, app_id, policy_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.AppAccess.list_role_bindings(tenant_id, account_id, str(app_id), str(policy_id)))
@console_ns.route("/workspaces/current/rbac/apps/<uuid:app_id>/access-policies/<string:policy_id>/member-bindings")
class RBACAppMemberBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def get(self, app_id, policy_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.AppAccess.list_member_bindings(tenant_id, account_id, str(app_id), str(policy_id)))
@login_required
@console_ns.expect(console_ns.models[_DeleteMemberBindingsRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def delete(self, app_id, policy_id):
tenant_id, account_id = _current_ids()
request_body = _payload(_DeleteMemberBindingsRequest)
svc.RBACService.AppAccess.delete_member_bindings(
tenant_id,
account_id,
str(app_id),
str(policy_id),
svc.DeleteMemberBindings(account_ids=request_body.account_ids),
)
return {"result": "success"}
# ---------------------------------------------------------------------------
# Per-dataset access (Knowledge Base Access Config).
# ---------------------------------------------------------------------------
@console_ns.route("/workspaces/current/rbac/datasets/<uuid:dataset_id>/access-policy")
class RBACDatasetMatrixApi(Resource):
@login_required
@console_ns.doc(params=query_params_from_model(_AccessControlLanguageQuery))
@console_ns.response(200, "Success", console_ns.models[svc.DatasetAccessMatrix.__name__])
def get(self, dataset_id):
tenant_id, account_id = _current_ids()
result = svc.RBACService.DatasetAccess.matrix(tenant_id, account_id, str(dataset_id))
_hydrate_access_matrix_account_names(result.items)
return _dump(result)
@console_ns.route("/workspaces/current/rbac/datasets/<uuid:dataset_id>/whitelist_config")
class RBACDatasetWhitelistConfigApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelistConfig.__name__])
def get(self, dataset_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.DatasetAccess.whitelist_config(tenant_id, account_id, str(dataset_id)))
@console_ns.route("/workspaces/current/rbac/datasets/<uuid:dataset_id>/whitelist")
class RBACDatasetWhitelistApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelist.__name__])
def get(self, dataset_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.DatasetAccess.whitelist(tenant_id, account_id, str(dataset_id)))
@login_required
@console_ns.expect(console_ns.models[_ResourceAccessScopeRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelist.__name__])
def put(self, dataset_id):
tenant_id, account_id = _current_ids()
request = _payload(_ResourceAccessScopeRequest)
result = svc.RBACService.DatasetAccess.replace_whitelist(
tenant_id,
account_id,
str(dataset_id),
svc.ReplaceMemberBindings(automatic_include_workspace_members=request.automatic_include_workspace_members),
)
# Widening the scope only records it: the members still need the default access policy
# before they can reach the dataset, same as the app whitelist route above.
if request.automatic_include_workspace_members:
initialize_created_app_rbac_access_task.delay(tenant_id, account_id, dataset_id=str(dataset_id))
return _dump(result)
@console_ns.route("/workspaces/current/rbac/datasets/<uuid:dataset_id>/user-access-policies")
class RBACDatasetUserAccessPoliciesApi(Resource):
@login_required
@console_ns.doc(params=query_params_from_model(_ResourceUserAccessPoliciesQuery))
@console_ns.response(200, "Success", console_ns.models[svc.ResourceUserAccessPoliciesResponse.__name__])
def get(self, dataset_id):
tenant_id, account_id = _current_ids()
options = _pagination_options()
result = svc.RBACService.DatasetAccess.user_access_policies(
tenant_id, account_id, str(dataset_id), options=options
)
_move_resource_maintainer_first(result.data, svc.dataset_maintainer_id(tenant_id, str(dataset_id)))
_hydrate_resource_user_account_names(result.data)
return _dump(result)
@console_ns.route("/workspaces/current/rbac/datasets/<uuid:dataset_id>/users/<uuid:target_account_id>/access-policies")
class RBACDatasetUserAccessPolicyAssignmentApi(Resource):
@login_required
@console_ns.expect(console_ns.models[svc.ReplaceUserAccessPolicies.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.ReplaceUserAccessPoliciesResponse.__name__])
def put(self, dataset_id, target_account_id):
tenant_id, account_id = _current_ids()
payload = _payload(svc.ReplaceUserAccessPolicies)
return _dump(
svc.RBACService.DatasetAccess.replace_user_access_policies(
tenant_id,
account_id,
str(dataset_id),
str(target_account_id),
payload,
)
)
@console_ns.route("/workspaces/current/rbac/datasets/<uuid:dataset_id>/access-policies/<uuid:policy_id>/role-bindings")
class RBACDatasetRoleBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.RoleBindingsResponse.__name__])
def get(self, dataset_id, policy_id):
tenant_id, account_id = _current_ids()
return _dump(
svc.RBACService.DatasetAccess.list_role_bindings(tenant_id, account_id, str(dataset_id), str(policy_id))
)
@console_ns.route(
"/workspaces/current/rbac/datasets/<uuid:dataset_id>/access-policies/<string:policy_id>/member-bindings"
type _ResourceAccessClient = (
type[svc.RBACService.AppAccess] | type[svc.RBACService.DatasetAccess] | type[svc.RBACService.AgentAccess]
)
class RBACDatasetMemberBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def get(self, dataset_id, policy_id):
tenant_id, account_id = _current_ids()
return _dump(
svc.RBACService.DatasetAccess.list_member_bindings(tenant_id, account_id, str(dataset_id), str(policy_id))
)
@login_required
@console_ns.expect(console_ns.models[_DeleteMemberBindingsRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def delete(self, dataset_id, policy_id):
tenant_id, account_id = _current_ids()
request_body = _payload(_DeleteMemberBindingsRequest)
svc.RBACService.DatasetAccess.delete_member_bindings(
tenant_id,
account_id,
str(dataset_id),
str(policy_id),
svc.DeleteMemberBindings(account_ids=request_body.account_ids),
)
return {"result": "success"}
@console_ns.route("/workspaces/current/rbac/workspace/apps/access-policy")
class RBACWorkspaceAppMatrixApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.WorkspaceAccessMatrix.__name__])
def get(self):
tenant_id, account_id = _current_ids()
options = _pagination_options()
result = svc.RBACService.WorkspaceAccess.app_matrix(tenant_id, account_id, options=options)
_hydrate_access_matrix_account_names(result.items)
return _dump(result)
@dataclass(frozen=True)
class _ResourceAccessRoutes:
resource_type: svc.RBACResourceType
class_prefix: str
matrix_model: type[BaseModel]
access: _ResourceAccessClient
catalog: Callable[[str, str], svc.PermissionCatalogResponse]
workspace_matrix: Callable[[str, str, svc.ListOption], svc.WorkspaceAccessMatrix]
workspace_role_bindings: Callable[[str, str, str], svc.RoleBindingsResponse]
workspace_member_bindings: Callable[[str, str, str], svc.MemberBindingsResponse]
replace_workspace_bindings: Callable[[str, str, str, svc.ReplaceBindings], svc.AccessMatrixItem]
maintainer_id: Callable[[str, str], str | None] | None = None
@property
def url_segment(self) -> str:
return self.resource_type.route.segment
@property
def id_param(self) -> str:
return self.resource_type.route.id_param
@console_ns.route("/workspaces/current/rbac/workspace/apps/access-policies/<uuid:policy_id>/role-bindings")
class RBACWorkspaceAppRoleBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.RoleBindingsResponse.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.WorkspaceAccess.list_app_role_bindings(tenant_id, account_id, str(policy_id)))
@dataclass(frozen=True)
class _ResourceAccessApis:
catalog: type[Resource]
matrix: type[Resource]
whitelist: type[Resource]
whitelist_config: type[Resource]
user_access_policies: type[Resource]
user_access_policy_assignment: type[Resource]
role_bindings: type[Resource]
member_bindings: type[Resource]
workspace_matrix: type[Resource]
workspace_role_bindings: type[Resource]
workspace_bindings: type[Resource]
workspace_member_bindings: type[Resource]
@console_ns.route("/workspaces/current/rbac/workspace/apps/access-policies/<uuid:policy_id>/bindings")
class RBACWorkspaceAppBindingsApi(Resource):
@login_required
@console_ns.expect(console_ns.models[_ReplaceBindingsRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.AccessMatrixItem.__name__])
def put(self, policy_id):
tenant_id, account_id = _current_ids()
request = _payload(_ReplaceBindingsRequest)
return _dump(
svc.RBACService.WorkspaceAccess.replace_app_bindings(
_RESOURCE_ACCESS_ROUTES = (
_ResourceAccessRoutes(
resource_type=svc.RBACResourceType.APP,
class_prefix="App",
matrix_model=svc.AppAccessMatrix,
access=svc.RBACService.AppAccess,
catalog=lambda tenant_id, account_id: svc.RBACService.Catalog.app(tenant_id, account_id),
workspace_matrix=lambda tenant_id, account_id, options: svc.RBACService.WorkspaceAccess.app_matrix(
tenant_id, account_id, options=options
),
workspace_role_bindings=lambda tenant_id, account_id, policy_id: (
svc.RBACService.WorkspaceAccess.list_app_role_bindings(tenant_id, account_id, policy_id)
),
workspace_member_bindings=lambda tenant_id, account_id, policy_id: (
svc.RBACService.WorkspaceAccess.list_app_member_bindings(tenant_id, account_id, policy_id)
),
replace_workspace_bindings=lambda tenant_id, account_id, policy_id, payload: (
svc.RBACService.WorkspaceAccess.replace_app_bindings(tenant_id, account_id, policy_id, payload)
),
maintainer_id=lambda tenant_id, resource_id: svc.app_maintainer_id(tenant_id, resource_id),
),
_ResourceAccessRoutes(
resource_type=svc.RBACResourceType.DATASET,
class_prefix="Dataset",
matrix_model=svc.DatasetAccessMatrix,
access=svc.RBACService.DatasetAccess,
catalog=lambda tenant_id, account_id: svc.RBACService.Catalog.dataset(tenant_id, account_id),
workspace_matrix=lambda tenant_id, account_id, options: svc.RBACService.WorkspaceAccess.dataset_matrix(
tenant_id, account_id, options=options
),
workspace_role_bindings=lambda tenant_id, account_id, policy_id: (
svc.RBACService.WorkspaceAccess.list_dataset_role_bindings(tenant_id, account_id, policy_id)
),
workspace_member_bindings=lambda tenant_id, account_id, policy_id: (
svc.RBACService.WorkspaceAccess.list_dataset_member_bindings(tenant_id, account_id, policy_id)
),
replace_workspace_bindings=lambda tenant_id, account_id, policy_id, payload: (
svc.RBACService.WorkspaceAccess.replace_dataset_bindings(tenant_id, account_id, policy_id, payload)
),
maintainer_id=lambda tenant_id, resource_id: svc.dataset_maintainer_id(tenant_id, resource_id),
),
_ResourceAccessRoutes(
resource_type=svc.RBACResourceType.AGENT,
class_prefix="Agent",
matrix_model=svc.AgentAccessMatrix,
access=svc.RBACService.AgentAccess,
catalog=lambda tenant_id, account_id: svc.RBACService.Catalog.agent(tenant_id, account_id),
workspace_matrix=lambda tenant_id, account_id, options: svc.RBACService.WorkspaceAccess.agent_matrix(
tenant_id, account_id, options=options
),
workspace_role_bindings=lambda tenant_id, account_id, policy_id: (
svc.RBACService.WorkspaceAccess.list_agent_role_bindings(tenant_id, account_id, policy_id)
),
workspace_member_bindings=lambda tenant_id, account_id, policy_id: (
svc.RBACService.WorkspaceAccess.list_agent_member_bindings(tenant_id, account_id, policy_id)
),
replace_workspace_bindings=lambda tenant_id, account_id, policy_id, payload: (
svc.RBACService.WorkspaceAccess.replace_agent_bindings(tenant_id, account_id, policy_id, payload)
),
),
)
def _build_resource_access_apis(spec: _ResourceAccessRoutes) -> _ResourceAccessApis:
id_param = spec.id_param
resource_prefix = f"/workspaces/current/rbac/{spec.url_segment}/<uuid:{id_param}>"
workspace_prefix = f"/workspaces/current/rbac/workspace/{spec.url_segment}"
def resource_id(path_params: Mapping[str, object]) -> str:
return str(path_params[id_param])
def register(resource: type[Resource], name: str, url: str) -> type[Resource]:
resource.__name__ = name
resource.__qualname__ = name
console_ns.route(url)(resource)
return resource
class CatalogApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.PermissionCatalogResponse.__name__])
def get(self):
tenant_id, account_id = _current_ids()
return _dump(spec.catalog(tenant_id, account_id))
class MatrixApi(Resource):
@login_required
@console_ns.doc(params=query_params_from_model(_AccessControlLanguageQuery))
@console_ns.response(200, "Success", console_ns.models[spec.matrix_model.__name__])
def get(self, **path_params):
tenant_id, account_id = _current_ids()
result = spec.access.matrix(tenant_id, account_id, resource_id(path_params))
_hydrate_access_matrix_account_names(result.items)
return _dump(result)
class WhitelistApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelist.__name__])
def get(self, **path_params):
tenant_id, account_id = _current_ids()
return _dump(spec.access.whitelist(tenant_id, account_id, resource_id(path_params)))
@login_required
@console_ns.expect(console_ns.models[_ResourceAccessScopeRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelist.__name__])
def put(self, **path_params):
tenant_id, account_id = _current_ids()
target_id = resource_id(path_params)
scope = _payload(_ResourceAccessScopeRequest)
result = spec.access.replace_whitelist(
tenant_id,
account_id,
str(policy_id),
svc.ReplaceBindings(role_ids=list(request.role_ids), account_ids=list(request.account_ids)),
target_id,
svc.ReplaceMemberBindings(
automatic_include_workspace_members=scope.automatic_include_workspace_members
),
)
)
if scope.automatic_include_workspace_members:
initialize_created_app_rbac_access_task.delay(tenant_id, account_id, **{id_param: target_id})
return _dump(result)
class WhitelistConfigApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.ResourceWhitelistConfig.__name__])
def get(self, **path_params):
tenant_id, account_id = _current_ids()
return _dump(spec.access.whitelist_config(tenant_id, account_id, resource_id(path_params)))
@console_ns.route("/workspaces/current/rbac/workspace/apps/access-policies/<uuid:policy_id>/member-bindings")
class RBACWorkspaceAppMemberBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.WorkspaceAccess.list_app_member_bindings(tenant_id, account_id, str(policy_id)))
class UserAccessPoliciesApi(Resource):
@login_required
@console_ns.doc(params=query_params_from_model(_ResourceUserAccessPoliciesQuery))
@console_ns.response(200, "Success", console_ns.models[svc.ResourceUserAccessPoliciesResponse.__name__])
def get(self, **path_params):
tenant_id, account_id = _current_ids()
target_id = resource_id(path_params)
options = _pagination_options()
result = spec.access.user_access_policies(tenant_id, account_id, target_id, options=options)
maintainer_id = spec.maintainer_id(tenant_id, target_id) if spec.maintainer_id else None
_move_resource_maintainer_first(result.data, maintainer_id)
_hydrate_resource_user_account_names(result.data)
return _dump(result)
class UserAccessPolicyAssignmentApi(Resource):
@login_required
@console_ns.expect(console_ns.models[svc.ReplaceUserAccessPolicies.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.ReplaceUserAccessPoliciesResponse.__name__])
def put(self, target_account_id, **path_params):
tenant_id, account_id = _current_ids()
payload = _payload(svc.ReplaceUserAccessPolicies)
return _dump(
spec.access.replace_user_access_policies(
tenant_id,
account_id,
resource_id(path_params),
str(target_account_id),
payload,
)
)
@console_ns.route("/workspaces/current/rbac/workspace/datasets/access-policy")
class RBACWorkspaceDatasetMatrixApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.WorkspaceAccessMatrix.__name__])
def get(self):
tenant_id, account_id = _current_ids()
options = _pagination_options()
result = svc.RBACService.WorkspaceAccess.dataset_matrix(tenant_id, account_id, options=options)
_hydrate_access_matrix_account_names(result.items)
return _dump(result)
class RoleBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.RoleBindingsResponse.__name__])
def get(self, policy_id, **path_params):
tenant_id, account_id = _current_ids()
return _dump(
spec.access.list_role_bindings(tenant_id, account_id, resource_id(path_params), str(policy_id))
)
class MemberBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def get(self, policy_id, **path_params):
tenant_id, account_id = _current_ids()
return _dump(
spec.access.list_member_bindings(tenant_id, account_id, resource_id(path_params), str(policy_id))
)
@console_ns.route("/workspaces/current/rbac/workspace/datasets/access-policies/<uuid:policy_id>/role-bindings")
class RBACWorkspaceDatasetRoleBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.RoleBindingsResponse.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(svc.RBACService.WorkspaceAccess.list_dataset_role_bindings(tenant_id, account_id, str(policy_id)))
@console_ns.route("/workspaces/current/rbac/workspace/datasets/access-policies/<uuid:policy_id>/bindings")
class RBACWorkspaceDatasetBindingsApi(Resource):
@login_required
@console_ns.expect(console_ns.models[_ReplaceBindingsRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.AccessMatrixItem.__name__])
def put(self, policy_id):
tenant_id, account_id = _current_ids()
request = _payload(_ReplaceBindingsRequest)
return _dump(
svc.RBACService.WorkspaceAccess.replace_dataset_bindings(
@login_required
@console_ns.expect(console_ns.models[_DeleteMemberBindingsRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def delete(self, policy_id, **path_params):
tenant_id, account_id = _current_ids()
body = _payload(_DeleteMemberBindingsRequest)
spec.access.delete_member_bindings(
tenant_id,
account_id,
resource_id(path_params),
str(policy_id),
svc.ReplaceBindings(role_ids=list(request.role_ids), account_ids=list(request.account_ids)),
svc.DeleteMemberBindings(account_ids=body.account_ids),
)
)
return {"result": "success"}
class WorkspaceMatrixApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.WorkspaceAccessMatrix.__name__])
def get(self):
tenant_id, account_id = _current_ids()
result = spec.workspace_matrix(tenant_id, account_id, _pagination_options())
_hydrate_access_matrix_account_names(result.items)
return _dump(result)
class WorkspaceRoleBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.RoleBindingsResponse.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(spec.workspace_role_bindings(tenant_id, account_id, str(policy_id)))
class WorkspaceBindingsApi(Resource):
@login_required
@console_ns.expect(console_ns.models[_ReplaceBindingsRequest.__name__])
@console_ns.response(200, "Success", console_ns.models[svc.AccessMatrixItem.__name__])
def put(self, policy_id):
tenant_id, account_id = _current_ids()
body = _payload(_ReplaceBindingsRequest)
return _dump(
spec.replace_workspace_bindings(
tenant_id,
account_id,
str(policy_id),
svc.ReplaceBindings(role_ids=list(body.role_ids), account_ids=list(body.account_ids)),
)
)
class WorkspaceMemberBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(spec.workspace_member_bindings(tenant_id, account_id, str(policy_id)))
prefix = spec.class_prefix
return _ResourceAccessApis(
catalog=register(
CatalogApi,
f"RBAC{prefix}CatalogApi",
f"/workspaces/current/rbac/role-permissions/catalog/{spec.resource_type.value}",
),
matrix=register(MatrixApi, f"RBAC{prefix}MatrixApi", f"{resource_prefix}/access-policy"),
whitelist=register(WhitelistApi, f"RBAC{prefix}WhitelistApi", f"{resource_prefix}/whitelist"),
whitelist_config=register(
WhitelistConfigApi, f"RBAC{prefix}WhitelistConfigApi", f"{resource_prefix}/whitelist_config"
),
user_access_policies=register(
UserAccessPoliciesApi, f"RBAC{prefix}UserAccessPoliciesApi", f"{resource_prefix}/user-access-policies"
),
user_access_policy_assignment=register(
UserAccessPolicyAssignmentApi,
f"RBAC{prefix}UserAccessPolicyAssignmentApi",
f"{resource_prefix}/users/<uuid:target_account_id>/access-policies",
),
role_bindings=register(
RoleBindingsApi,
f"RBAC{prefix}RoleBindingsApi",
f"{resource_prefix}/access-policies/<uuid:policy_id>/role-bindings",
),
member_bindings=register(
MemberBindingsApi,
f"RBAC{prefix}MemberBindingsApi",
f"{resource_prefix}/access-policies/<string:policy_id>/member-bindings",
),
workspace_matrix=register(
WorkspaceMatrixApi, f"RBACWorkspace{prefix}MatrixApi", f"{workspace_prefix}/access-policy"
),
workspace_role_bindings=register(
WorkspaceRoleBindingsApi,
f"RBACWorkspace{prefix}RoleBindingsApi",
f"{workspace_prefix}/access-policies/<uuid:policy_id>/role-bindings",
),
workspace_bindings=register(
WorkspaceBindingsApi,
f"RBACWorkspace{prefix}BindingsApi",
f"{workspace_prefix}/access-policies/<uuid:policy_id>/bindings",
),
workspace_member_bindings=register(
WorkspaceMemberBindingsApi,
f"RBACWorkspace{prefix}MemberBindingsApi",
f"{workspace_prefix}/access-policies/<uuid:policy_id>/member-bindings",
),
)
@console_ns.route("/workspaces/current/rbac/workspace/datasets/access-policies/<uuid:policy_id>/member-bindings")
class RBACWorkspaceDatasetMemberBindingsApi(Resource):
@login_required
@console_ns.response(200, "Success", console_ns.models[svc.MemberBindingsResponse.__name__])
def get(self, policy_id):
tenant_id, account_id = _current_ids()
return _dump(
svc.RBACService.WorkspaceAccess.list_dataset_member_bindings(tenant_id, account_id, str(policy_id))
)
_RESOURCE_ACCESS_APIS = {spec.resource_type: _build_resource_access_apis(spec) for spec in _RESOURCE_ACCESS_ROUTES}
# ---------------------------------------------------------------------------
+11 -31
View File
@@ -10,13 +10,13 @@ from pydantic import BaseModel, ConfigDict, Field, ValidationError
from sqlalchemy.orm import Session
from controllers.common.fields import BinaryFileResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
from controllers.common.session import with_session
from controllers.console import console_ns
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
edit_permission_required,
)
from fields.base import ResponseModel
@@ -298,9 +298,7 @@ class WorkspaceSkillsApi(Resource):
@console_ns.doc(params=query_params_from_model(WorkspaceSkillsQuery))
@console_ns.response(200, "Workspace skills", console_ns.models[SkillListResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_VIEW,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_VIEW, Workspace())],
)
@with_session(write=False)
def get(self, session: Session, request_context: RequestContext):
@@ -325,9 +323,7 @@ class WorkspaceSkillsApi(Resource):
@console_ns.expect(console_ns.models[SkillCreatePayload.__name__])
@console_ns.response(201, "Skill created", console_ns.models[SkillDetailResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_EDIT,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_EDIT, Workspace())],
)
@edit_permission_required
@with_session
@@ -391,9 +387,7 @@ class WorkspaceSkillImportApi(Resource):
@console_ns.doc(description="Import a Skill zip package from multipart form field `file`.")
@console_ns.response(201, "Skill imported", console_ns.models[SkillDetailResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_EDIT,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_EDIT, Workspace())],
)
@edit_permission_required
@with_session
@@ -419,9 +413,7 @@ class WorkspaceSkillImportApi(Resource):
class WorkspaceSkillApi(Resource):
@console_ns.response(200, "Skill detail", console_ns.models[SkillDetailResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_VIEW,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_VIEW, Workspace())],
)
@with_session(write=False)
def get(self, session: Session, request_context: RequestContext, skill_id: str):
@@ -436,9 +428,7 @@ class WorkspaceSkillApi(Resource):
@console_ns.expect(console_ns.models[SkillMetadataPayload.__name__])
@console_ns.response(200, "Skill updated", console_ns.models[SkillResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_EDIT,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_EDIT, Workspace())],
)
@edit_permission_required
@with_session
@@ -462,9 +452,7 @@ class WorkspaceSkillApi(Resource):
@console_ns.expect(console_ns.models[SkillDeletePayload.__name__])
@console_ns.response(200, "Skill deleted", console_ns.models[SkillDeleteResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_DELETE,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_DELETE, Workspace())],
)
@edit_permission_required
@with_session
@@ -487,9 +475,7 @@ class WorkspaceSkillApi(Resource):
class WorkspaceSkillDuplicateApi(Resource):
@console_ns.response(201, "Skill duplicated", console_ns.models[SkillDetailResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_EDIT,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_EDIT, Workspace())],
)
@edit_permission_required
@with_session
@@ -509,9 +495,7 @@ class WorkspaceSkillDuplicateApi(Resource):
class WorkspaceSkillExportApi(Resource):
@console_ns.response(200, "Published Skill zip archive")
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_VIEW,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_VIEW, Workspace())],
)
@with_session(write=False)
def get(self, session: Session, request_context: RequestContext, skill_id: str):
@@ -696,9 +680,7 @@ class WorkspaceSkillPublishApi(Resource):
@console_ns.expect(console_ns.models[SkillPublishPayload.__name__])
@console_ns.response(200, "Skill published", console_ns.models[SkillVersionResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_PUBLISH,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_PUBLISH, Workspace())],
)
@edit_permission_required
@with_session
@@ -723,9 +705,7 @@ class WorkspaceSkillRestoreApi(Resource):
@console_ns.expect(console_ns.models[SkillRestorePayload.__name__])
@console_ns.response(200, "Skill version restored to draft", console_ns.models[SkillDetailResponse.__name__])
@console_account_admission(
rbac_resource_scope=RBACResourceScope.WORKSPACE,
rbac_permission=RBACPermission.SKILL_PUBLISH,
rbac_resource_required=False,
rbac_checks=[RBACCheck(RBACPermission.SKILL_PUBLISH, Workspace())],
)
@edit_permission_required
@with_session
+8 -20
View File
@@ -8,6 +8,7 @@ from sqlalchemy.orm import Session, sessionmaker
from werkzeug.exceptions import NotFound
from controllers.common.fields import TextFileResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
register_response_schema_models,
@@ -24,7 +25,6 @@ from controllers.console.snippets.payloads import (
)
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
model_validate,
@@ -147,9 +147,7 @@ class CustomizedSnippetsApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_user
@with_current_tenant_id
@model_validate(CreateSnippetPayload)
@@ -211,9 +209,7 @@ class CustomizedSnippetDetailApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_user
@with_current_tenant_id
@model_validate(UpdateSnippetPayload)
@@ -258,7 +254,7 @@ class CustomizedSnippetDetailApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_MANAGE, Workspace()))
@with_current_user
@with_current_tenant_id
def delete(self, current_tenant_id: str, current_user: Account, snippet_id: str):
@@ -296,9 +292,7 @@ class CustomizedSnippetExportApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_tenant_id
def get(self, current_tenant_id: str, snippet_id: str):
"""Export snippet as DSL."""
@@ -351,9 +345,7 @@ class CustomizedSnippetImportApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_user
@with_session
@model_validate(SnippetImportPayload)
@@ -390,9 +382,7 @@ class CustomizedSnippetImportConfirmApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_user
@with_session
def post(self, session: Session, current_user: Account, import_id: str):
@@ -420,9 +410,7 @@ class CustomizedSnippetCheckDependenciesApi(Resource):
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(
RBACResourceScope.WORKSPACE, RBACPermission.SNIPPETS_CREATE_AND_MODIFY, resource_required=False
)
@rbac_permission_required(RBACCheck(RBACPermission.SNIPPETS_CREATE_AND_MODIFY, Workspace()))
@with_current_tenant_id
def get(self, current_tenant_id: str, snippet_id: str):
"""Check dependencies for a snippet."""
@@ -20,6 +20,7 @@ from werkzeug.exceptions import Forbidden
from configs import dify_config
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import (
query_params_from_model,
query_params_from_request,
@@ -29,7 +30,6 @@ from controllers.common.schema import (
from controllers.console import console_ns
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
enterprise_license_required,
is_admin_or_owner_required,
@@ -563,7 +563,7 @@ class ToolBuiltinProviderDeleteApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(BuiltinToolCredentialDeletePayload)
@@ -590,7 +590,7 @@ class ToolBuiltinProviderAddApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_CREATE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_CREATE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -621,7 +621,7 @@ class ToolBuiltinProviderUpdateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -689,7 +689,7 @@ class ToolApiProviderAddApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.TOOL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.TOOL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -769,7 +769,7 @@ class ToolApiProviderUpdateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.TOOL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.TOOL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -800,7 +800,7 @@ class ToolApiProviderDeleteApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.TOOL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.TOOL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -908,7 +908,7 @@ class ToolWorkflowProviderCreateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.TOOL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.TOOL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -938,7 +938,7 @@ class ToolWorkflowProviderUpdateApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.TOOL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.TOOL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -968,7 +968,7 @@ class ToolWorkflowProviderDeleteApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.TOOL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.TOOL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -1125,7 +1125,7 @@ class ToolPluginOAuthApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -1251,7 +1251,7 @@ class ToolBuiltinProviderSetDefaultApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_USE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_USE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(BuiltinProviderDefaultCredentialPayload)
@@ -1273,7 +1273,7 @@ class ToolOAuthCustomClient(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(ToolOAuthCustomClientPayload)
@@ -1297,7 +1297,7 @@ class ToolOAuthCustomClient(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
def get(self, current_tenant_id: str, provider: str):
@@ -1309,7 +1309,7 @@ class ToolOAuthCustomClient(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_tenant_id
def delete(self, current_tenant_id: str, provider: str):
@@ -1379,7 +1379,7 @@ class ToolProviderMCPApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.MCP_MANAGE, Workspace()))
@with_current_user
@with_current_tenant_id
@model_validate(MCPProviderCreatePayload)
@@ -1433,7 +1433,7 @@ class ToolProviderMCPApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.MCP_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(MCPProviderUpdatePayload)
def put(self, req_data: MCPProviderUpdatePayload, current_tenant_id: str):
@@ -1487,7 +1487,7 @@ class ToolProviderMCPApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.MCP_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(MCPProviderDeletePayload)
def delete(self, req_data: MCPProviderDeletePayload, current_tenant_id: str):
@@ -1505,7 +1505,7 @@ class ToolMCPAuthApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.MCP_MANAGE, Workspace()))
@with_current_tenant_id
@model_validate(MCPAuthPayload)
def post(self, req_data: MCPAuthPayload, tenant_id: str):
@@ -1617,7 +1617,7 @@ class ToolMCPUpdateApi(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.MCP_MANAGE, Workspace()))
@with_current_tenant_id
def get(self, tenant_id: str, provider_id: str):
with sessionmaker(db.engine).begin() as session:
@@ -10,6 +10,7 @@ from werkzeug.exceptions import BadRequest, Forbidden
from configs import dify_config
from controllers.common.errors import NotFoundError
from controllers.common.fields import SimpleResultResponse
from controllers.common.rbac import RBACCheck, Workspace
from controllers.common.schema import register_response_schema_models, register_schema_models
from core.entities.provider_entities import ProviderConfig
from core.plugin.entities.plugin_daemon import CredentialType
@@ -35,7 +36,6 @@ from services.trigger.trigger_subscription_operator_service import TriggerSubscr
from .. import console_ns
from ..wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
edit_permission_required,
is_admin_or_owner_required,
@@ -199,7 +199,7 @@ class TriggerSubscriptionListApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -235,7 +235,7 @@ class TriggerSubscriptionBuilderCreateApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -271,7 +271,7 @@ class TriggerSubscriptionBuilderGetApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -299,7 +299,7 @@ class TriggerSubscriptionBuilderVerifyApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -344,7 +344,7 @@ class TriggerSubscriptionBuilderUpdateApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.CREDENTIAL_MANAGE, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -389,7 +389,7 @@ class TriggerSubscriptionBuilderLogsApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -420,7 +420,7 @@ class TriggerSubscriptionBuilderBuildApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
@@ -464,7 +464,7 @@ class TriggerSubscriptionUpdateApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(TriggerSubscriptionBuilderUpdatePayload)
@@ -524,7 +524,7 @@ class TriggerSubscriptionDeleteApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
def post(self, tenant_id: str, subscription_id: str):
@@ -716,7 +716,7 @@ class TriggerOAuthClientManageApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
def get(self, tenant_id: str, provider: str):
@@ -763,7 +763,7 @@ class TriggerOAuthClientManageApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
@model_validate(TriggerOAuthClientPayload)
@@ -792,7 +792,7 @@ class TriggerOAuthClientManageApi(Resource):
@setup_required
@login_required
@is_admin_or_owner_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_tenant_id
def delete(self, tenant_id: str, provider: str):
@@ -826,7 +826,7 @@ class TriggerSubscriptionVerifyApi(Resource):
@setup_required
@login_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
@rbac_permission_required(RBACCheck(RBACPermission.PLUGIN_PREFERENCES, Workspace()))
@account_initialization_required
@with_current_user
@with_current_tenant_id
+2 -5
View File
@@ -11,11 +11,8 @@ from sqlalchemy import select
from werkzeug.exceptions import Forbidden, UnprocessableEntity
from configs import dify_config
from controllers.common.wraps import (
RBACPermission,
RBACResourceScope,
rbac_permission_required,
)
from controllers.common.rbac import RBACPermission, RBACResourceScope
from controllers.common.wraps import rbac_permission_required
from controllers.console.auth.error import AuthenticationFailedError, EmailCodeError
from controllers.console.workspace.error import AccountNotInitializedError
from enums import CloudPlan, DeploymentEdition