villebro commented on code in PR #44215:
URL: https://github.com/apache/superset/pull/44215#discussion_r4000494093


##########
superset/dashboards/api.py:
##########
@@ -742,29 +742,44 @@ def get_datasets(self, id_or_slug: str) -> Response:
               $ref: '#/components/responses/404'
         """
         try:
-            datasets = DashboardDAO.get_datasets_for_dashboard(id_or_slug)
+            dashboard, datasets = 
DashboardDAO.get_datasets_for_dashboard(id_or_slug)
             result = [
-                self._serialize_dashboard_dataset(datasource, payload)
+                self._serialize_dashboard_dataset(datasource, payload, 
dashboard)
                 for datasource, payload in datasets
             ]
             return self.response(200, result=result)
         except (TypeError, ValueError) as err:
             raise DatasetValidationError(err) from err
 
     def _serialize_dashboard_dataset(
-        self, datasource: Any, payload: dict[str, Any]
+        self, datasource: Any, payload: dict[str, Any], dashboard: Dashboard
     ) -> dict[str, Any]:
         """Dump a member dataset, narrowed when the caller cannot access it."""
         serialized = self.dashboard_dataset_schema.dump(payload)
-        if not security_manager.can_access_datasource(datasource):
+        if not (
+            security_manager.can_access_datasource(datasource)
+            or security_manager.can_drill_dataset_via_dashboard_access(
+                datasource, dashboard
+            )
+        ):
             for key in DASHBOARD_DATASET_INACCESSIBLE_FIELDS:
                 serialized.pop(key, None)
         return serialized
 
-    def _serialize_dashboard_chart(self, chart: Any) -> dict[str, Any]:
+    def _serialize_dashboard_chart(
+        self, chart: Any, dashboard: Dashboard
+    ) -> dict[str, Any]:
         """Dump a member chart, narrowed when the caller cannot access it."""
         serialized = self.chart_entity_response_schema.dump(chart)
-        if not security_manager.can_access_chart(chart):
+        if not (
+            security_manager.can_access_chart(chart)
+            or (
+                chart.datasource is not None
+                and security_manager.can_drill_dataset_via_dashboard_access(
+                    chart.datasource, dashboard
+                )

Review Comment:
   Good catch — semantic-view charts have no table-backed `chart.datasource`, 
so the original guard skipped the check and stripped `form_data` for them.
   
   Rather than patch the guard, I reworked the approach to match the intended 
model: full dashboard → chart → dataset access inheritance. A dashboard's 
`/charts` and `/datasets` sub-resources only ever return members of that 
dashboard, so the correct test is a pure dashboard-entitlement predicate, not a 
per-dataset membership check. Added 
`SecurityManager.can_inherit_access_via_dashboard(dashboard)` (embedded guest 
with access, or viewer of a published dashboard under 
`VIEWER_PROMISCUOUS_MODE`) and the serializers now use it. This is 
datasource-type agnostic, so semantic-view charts render correctly, and it's 
resolved once per request instead of per member. 
`can_drill_dataset_via_dashboard_access` still layers the dataset-membership 
guard on top for the drill endpoints, which resolve the dataset from an 
untrusted request param. Fixed in 1cf6da52439.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to