From d9482fcab10d87b2c037509b9b6759922f556cd2 Mon Sep 17 00:00:00 2001 From: jahnavikachhia Date: Sat, 2 May 2026 23:17:25 -0700 Subject: [PATCH] Respect output policy validation result --- .../syft/service/code/user_code_service.py | 5 +- .../service/code/user_code_service_test.py | 59 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 packages/syft/tests/syft/service/code/user_code_service_test.py diff --git a/packages/syft/src/syft/service/code/user_code_service.py b/packages/syft/src/syft/service/code/user_code_service.py index 5ba617ef62e..8b53076797e 100644 --- a/packages/syft/src/syft/service/code/user_code_service.py +++ b/packages/syft/src/syft/service/code/user_code_service.py @@ -357,10 +357,13 @@ def is_execution_allowed( return IsExecutionAllowedEnum.OUTPUT_POLICY_NONE try: - output_policy.is_valid(context) + output_policy_is_valid = output_policy.is_valid(context) except Exception: return IsExecutionAllowedEnum.INVALID_OUTPUT_POLICY + if not output_policy_is_valid: + return IsExecutionAllowedEnum.INVALID_OUTPUT_POLICY + return IsExecutionAllowedEnum.ALLOWED def is_execution_on_owned_args_allowed(self, context: AuthedServiceContext) -> bool: diff --git a/packages/syft/tests/syft/service/code/user_code_service_test.py b/packages/syft/tests/syft/service/code/user_code_service_test.py new file mode 100644 index 00000000000..fbeae215e9a --- /dev/null +++ b/packages/syft/tests/syft/service/code/user_code_service_test.py @@ -0,0 +1,59 @@ +# stdlib +from unittest.mock import Mock + +# syft absolute +from syft.service.code.user_code_service import HasCodePermissionEnum +from syft.service.code.user_code_service import IsExecutionAllowedEnum +from syft.service.code.user_code_service import UserCodeService + + +class _Result: + def __init__(self, value): + self.value = value + + def unwrap(self): + return self.value + + +def _approved_code(): + status = Mock() + status.get_is_approved.return_value = True + + code = Mock() + code.get_status.return_value = _Result(status) + code.is_output_policy_approved.return_value = True + return code + + +def _service_with_code_permission(): + service = UserCodeService.__new__(UserCodeService) + service.has_code_permission = Mock(return_value=HasCodePermissionEnum.ACCEPTED) + return service + + +def test_is_execution_allowed_rejects_false_output_policy() -> None: + service = _service_with_code_permission() + output_policy = Mock() + output_policy.is_valid.return_value = False + + result = service.is_execution_allowed( + code=_approved_code(), + context=Mock(), + output_policy=output_policy, + ) + + assert result is IsExecutionAllowedEnum.INVALID_OUTPUT_POLICY + + +def test_is_execution_allowed_accepts_true_output_policy() -> None: + service = _service_with_code_permission() + output_policy = Mock() + output_policy.is_valid.return_value = True + + result = service.is_execution_allowed( + code=_approved_code(), + context=Mock(), + output_policy=output_policy, + ) + + assert result is IsExecutionAllowedEnum.ALLOWED