rusackas commented on code in PR #41714:
URL: https://github.com/apache/superset/pull/41714#discussion_r3726596180
##########
superset/charts/api.py:
##########
@@ -404,6 +410,104 @@ def get(self, id_or_uuid: str) -> Response:
except ChartNotFoundError:
return self.response_404()
+ @expose("/<pk>/deck_layers/", methods=("GET",))
+ @protect()
+ @safe
+ @statsd_metrics
+ @event_logger.log_this_with_context(
+ action=lambda self, *args, **kwargs:
(f"{self.__class__.__name__}.deck_layers"),
+ log_to_statsd=False,
+ )
+ def deck_layers(self, pk: int) -> Response:
+ """Gets the sub-layer charts declared by a deck.gl Multiple Layers
chart
+ ---
+ get:
+ summary: >-
+ Get the sub-layer charts declared by a deck.gl Multiple Layers
chart
+ description: >-
+ Multiple Layers charts (viz_type "deck_multi") reference other
+ saved charts as layers via their `deck_slices` config, but those
+ layer charts typically sit on no dashboard of their own, so a
+ per-layer `GET /api/v1/chart/<id>` can 404 for a principal
+ (e.g. an embedded guest) who is only entitled to the container.
+ This endpoint gates on the container chart and resolves the
+ layers it declares, mirroring the access the legacy explore_json
+ pipeline granted server-side.
+ parameters:
+ - in: path
+ schema:
+ type: integer
+ name: pk
+ description: The id of the Multiple Layers container chart
+ responses:
+ 200:
+ description: The container's declared layer charts
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ result:
+ type: array
+ items:
+ type: object
+ properties:
+ slice_id:
+ type: integer
+ viz_type:
+ type: string
+ params:
+ type: string
+ datasource_id:
+ type: integer
+ datasource_type:
+ type: string
+ 400:
+ $ref: '#/components/responses/400'
+ 401:
+ $ref: '#/components/responses/401'
+ 404:
+ $ref: '#/components/responses/404'
+ 500:
+ $ref: '#/components/responses/500'
+ """
+ try:
+ container = ChartDAO.get_by_id_or_uuid(str(pk))
+ except ChartNotFoundError:
+ return self.response_404()
+
+ try:
+ container_params = json.loads(container.params or "{}")
+ except (TypeError, ValueError):
+ container_params = {}
+
+ deck_slice_ids = [
+ slice_id
+ for slice_id in container_params.get("deck_slices", [])
+ if isinstance(slice_id, int)
+ ]
+ if not deck_slice_ids:
+ return self.response(200, result=[])
+
+ # The container's own access has already been checked above; the
+ # layers it declares are resolved without the base filter (they
+ # sit on no dashboard of their own), same as the legacy explore_json
+ # pipeline resolved them server-side under the container's access.
+ layers = ChartDAO.find_by_ids(deck_slice_ids, skip_base_filter=True)
Review Comment:
Fair point. Scoped the bypass to guest users only now, an ordinary user's
lookup goes through the normal chart base filter so an inaccessible layer is
just omitted rather than leaked.
##########
superset/migrations/shared/migrate_viz/base.py:
##########
@@ -164,11 +172,22 @@ def upgrade_slice(cls, slc: Slice) -> None:
queries_bak = None
if query_context:
+ # A stored query_context is expected to carry "queries", but
+ # an atypical/malformed one (e.g. hand-edited via the API)
+ # missing it must not raise here: viz_type was already
+ # flipped above, so an uncaught exception at this point
+ # would leave the slice half-migrated (new viz_type, but
+ # stale params/query_context in the old shape). Back up the
+ # whole context in that case so downgrade can restore it
+ # verbatim instead of losing it (see FULL_CONTEXT_BAK_KEY).
+ if "queries" in query_context:
Review Comment:
Good catch, a null queries backed up as a bare None, indistinguishable from
no context at all. Routed it through the same FULL_CONTEXT_BAK_KEY wholesale
backup as a missing key, plus a round-trip test.
--
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]