fix(api): protect agent sandbox reads (#40794)

This commit is contained in:
WH-2099 2026-08-14 13:51:41 +00:00 committed by GitHub
parent 96bfcf20cd
commit fc7b51634d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 2 deletions

View File

@ -24,8 +24,11 @@ from controllers.console import console_ns
from controllers.console.app.error import AppNotFoundError
from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import (
RBACPermission,
RBACResourceScope,
account_initialization_required,
model_validate,
rbac_permission_required,
setup_required,
with_current_tenant_id,
with_current_user,
@ -154,6 +157,7 @@ class AgentAppSandboxInfoResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@with_current_tenant_id
@with_current_user
def get(self, current_user: Account, tenant_id: str, agent_id: UUID):
@ -183,6 +187,7 @@ class AgentAppSandboxListResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@with_current_tenant_id
@with_current_user
def get(self, current_user: Account, tenant_id: str, agent_id: UUID):
@ -213,6 +218,7 @@ class AgentAppSandboxReadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@with_current_tenant_id
@with_current_user
def get(self, current_user: Account, tenant_id: str, agent_id: UUID):
@ -243,6 +249,7 @@ class AgentAppSandboxDownloadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@with_current_tenant_id
@with_current_user
@model_validate(AgentSandboxDownloadPayload)
@ -286,6 +293,7 @@ class WorkflowAgentSandboxListResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@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):
@ -323,6 +331,7 @@ class WorkflowAgentSandboxReadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@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):
@ -353,6 +362,7 @@ class WorkflowAgentSandboxDownloadResource(Resource):
@setup_required
@login_required
@account_initialization_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
@with_current_user
@with_current_tenant_id
@model_validate(WorkflowAgentSandboxDownloadPayload)

View File

@ -1,7 +1,7 @@
from __future__ import annotations
from inspect import unwrap
from types import SimpleNamespace
from inspect import getclosurevars, unwrap
from types import FunctionType, SimpleNamespace
import pytest
from dify_agent.client import DifyAgentClientError, DifyAgentHTTPError, DifyAgentTimeoutError
@ -139,6 +139,27 @@ def _app_model(app_id: str = "app-1") -> App:
)
@pytest.mark.parametrize(
"method",
[
module.AgentAppSandboxInfoResource.get,
module.AgentAppSandboxListResource.get,
module.AgentAppSandboxReadResource.get,
module.AgentAppSandboxDownloadResource.post,
module.WorkflowAgentSandboxListResource.get,
module.WorkflowAgentSandboxReadResource.get,
module.WorkflowAgentSandboxDownloadResource.post,
],
)
def test_sandbox_resources_require_app_view_layout(method: FunctionType) -> None:
rbac_wrapper = unwrap(method, stop=lambda wrapper: "rbac_permission_required" in wrapper.__code__.co_qualname)
config = getclosurevars(rbac_wrapper).nonlocals
assert config["resource_type"] == module.RBACResourceScope.APP
assert config["scene"] == module.RBACPermission.APP_VIEW_LAYOUT
assert config["resource_required"] is True
def test_handle_maps_sandbox_and_agent_backend_errors() -> None:
assert module._handle(AgentSandboxInspectorError("no_sandbox", "no sandbox", status_code=404)) == (
{"code": "no_sandbox", "message": "no sandbox"},