From bcae308a491e3437bc07651ed3a70b349a772939 Mon Sep 17 00:00:00 2001 From: "Charles P. Wright" Date: Tue, 9 Jun 2026 15:34:45 -0400 Subject: [PATCH 1/2] feat: DH-22536: Apply transformations to dh.ui widgets when sending to clients. --- .../deephaven/ui/object_types/ElementType.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugins/ui/src/deephaven/ui/object_types/ElementType.py b/plugins/ui/src/deephaven/ui/object_types/ElementType.py index 02d07ad8e..c0f52efcc 100644 --- a/plugins/ui/src/deephaven/ui/object_types/ElementType.py +++ b/plugins/ui/src/deephaven/ui/object_types/ElementType.py @@ -4,6 +4,12 @@ from ..elements import Element from .ElementMessageStream import ElementMessageStream +# Escape-hatch configuration property. When set to true, deephaven.ui declares no authorization export behavior +# ("unset"), deferring to the server's default policy instead of enforcing the transform. +_DISABLE_AUTHORIZATION_EXPORT_TRANSFORM_PROPERTY = ( + "deephaven.ui.disableAuthorizationExportTransform" +) + class ElementType(BidirectionalObjectType): """ @@ -14,6 +20,28 @@ class ElementType(BidirectionalObjectType): def name(self) -> str: return "deephaven.ui.Element" + @property + def authorization_export_behavior(self) -> str: + """Declares that deephaven.ui must export its references through the authorization transform. + + Server objects (tables, etc.) handed to the client via a deephaven.ui component are run through the + authorization transform in the viewer's context, so they carry the viewer's ACLs rather than the query + owner's. Setting the configuration property ``deephaven.ui.disableAuthorizationExportTransform`` to true + reverts to the server's default ("unset") behavior. If the configuration cannot be read, the transform is + enforced (fail secure). + """ + try: + from deephaven.configuration import get_configuration + + if get_configuration().get_bool( + _DISABLE_AUTHORIZATION_EXPORT_TRANSFORM_PROPERTY, False + ): + return "unset" + except Exception: + # Fail secure: if the escape hatch cannot be evaluated, enforce the transform. + pass + return "transform" + def is_type(self, obj: Any) -> bool: return isinstance(obj, Element) From b96112ebdfd4a40a6b5489064fc2a3d79fbde38e Mon Sep 17 00:00:00 2001 From: "Charles P. Wright" Date: Thu, 11 Jun 2026 09:21:11 -0400 Subject: [PATCH 2/2] review comments --- plugins/ui/src/deephaven/ui/object_types/ElementType.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/ui/src/deephaven/ui/object_types/ElementType.py b/plugins/ui/src/deephaven/ui/object_types/ElementType.py index c0f52efcc..e4695a0da 100644 --- a/plugins/ui/src/deephaven/ui/object_types/ElementType.py +++ b/plugins/ui/src/deephaven/ui/object_types/ElementType.py @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, Literal from deephaven.plugin.object_type import BidirectionalObjectType, MessageStream from ..elements import Element @@ -21,7 +21,7 @@ def name(self) -> str: return "deephaven.ui.Element" @property - def authorization_export_behavior(self) -> str: + def authorization_export_behavior(self) -> Literal["transform", "unset"]: """Declares that deephaven.ui must export its references through the authorization transform. Server objects (tables, etc.) handed to the client via a deephaven.ui component are run through the @@ -31,7 +31,9 @@ def authorization_export_behavior(self) -> str: enforced (fail secure). """ try: - from deephaven.configuration import get_configuration + # deephaven.configuration only exists in the 42.x server package; the import is conditional to + # maintain compatibility with 41.x, where ImportError is caught and the transform is enforced. + from deephaven.configuration import get_configuration # type: ignore[import-untyped,import-not-found] if get_configuration().get_bool( _DISABLE_AUTHORIZATION_EXPORT_TRANSFORM_PROPERTY, False