codeant-ai-for-open-source[bot] commented on code in PR #41133:
URL: https://github.com/apache/superset/pull/41133#discussion_r3486016131


##########
superset/dashboards/schemas.py:
##########
@@ -633,3 +633,21 @@ class CacheScreenshotSchema(Schema):
         fields.List(fields.Str(), validate=lambda x: len(x) == 2), 
required=False
     )
     permalinkKey = fields.Str(required=False)  # noqa: N815
+
+
+class DashboardExportXlsxPostSchema(Schema):
+    active_data_mask = fields.Dict(
+        keys=fields.Str(),
+        values=fields.Dict(),
+        load_default=dict,

Review Comment:
   **Suggestion:** The request schema only validates each `active_data_mask` 
entry as a generic dict and does not enforce that `extraFormData` is itself a 
dict, so malformed payloads can pass validation and later crash filter-context 
merging in the Celery task. Tighten this to a nested schema that requires 
`extraFormData` to be a dict so invalid requests are rejected with 400 instead 
of failing during export. [type error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Filter context with malformed extraFormData crashes per-chart export.
   - ⚠️ Export email omits affected charts; user receives incomplete workbook.
   - ⚠️ Logs contain AttributeError from _merge_extra_form_data merging filters.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Configure Excel export so the endpoint runs end-to-end by setting a 
non-empty
   `EXCEL_EXPORT_S3_BUCKET` in config (checked at 
`superset/dashboards/api.py:58-61` in
   `DashboardRestApi.export_xlsx`); start Superset API and Celery workers 
normally.
   
   2. Send a POST to `/api/v1/dashboard/<dashboard_id>/export_xlsx/` (handled by
   `DashboardRestApi.export_xlsx` at `superset/dashboards/api.py:9-18`) with 
JSON body:
   
      `{"active_data_mask": {"NATIVE_FILTER-1": {"extraFormData": ["not", "a", 
"dict"]}}}` so
      that each mask entry is a dict but its `extraFormData` value is a list.
   
   3. Observe in `export_xlsx` that `DashboardExportXlsxPostSchema().load(...)` 
(schema
   defined at `superset/dashboards/schemas.py:39-48`) accepts the payload: 
`active_data_mask`
   is a dict and each value is a dict, and no validation is applied to the 
nested
   `extraFormData` field; the method then enqueues 
`export_dashboard_excel.apply_async(...)`
   passing `payload.get("active_data_mask", {})` at 
`superset/dashboards/api.py:28-35`.
   
   4. When the Celery worker processes `export_dashboard_excel`
   (`superset/tasks/export_dashboard_excel.py:168-214`), `_build_workbook` calls
   `_write_chart_sheets` with `active_data_mask` (lines 114-129); inside
   `_write_chart_sheets`, `get_dashboard_filter_context(...,
   active_data_mask=active_data_mask)` is called at
   `superset/tasks/export_dashboard_excel.py:84-88`, which in turn calls
   `_resolve_filter_extra_form_data` at
   `superset/charts/data/dashboard_filter_context.py:202-224`. For the 
malformed filter,
   `active_efd = (active_data_mask[flt_id] or {}).get("extraFormData") or {}` 
becomes a list,
   and `get_dashboard_filter_context` passes this list as `extra_form_data` into
   `_merge_extra_form_data` at 
`superset/charts/data/dashboard_filter_context.py:120-167`,
   where `new.get(...)` raises `AttributeError: 'list' object has no attribute 
'get'`. This
   exception is caught by `_build_workbook`'s per-chart `except Exception` 
block at
   `superset/tasks/export_dashboard_excel.py:128-135`, causing the chart to be 
skipped and
   logged as failed instead of rejecting the request up front with a 400.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=b5d253f4b4c242a4a752b12676bfd7fb&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=b5d253f4b4c242a4a752b12676bfd7fb&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/dashboards/schemas.py
   **Line:** 639:642
   **Comment:**
        *Type Error: The request schema only validates each `active_data_mask` 
entry as a generic dict and does not enforce that `extraFormData` is itself a 
dict, so malformed payloads can pass validation and later crash filter-context 
merging in the Celery task. Tighten this to a nested schema that requires 
`extraFormData` to be a dict so invalid requests are rejected with 400 instead 
of failing during export.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41133&comment_hash=c13f44ef951daa1cd03a508ae7dbe7bbd2a91949623c138eeb8bf52a41d57abc&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41133&comment_hash=c13f44ef951daa1cd03a508ae7dbe7bbd2a91949623c138eeb8bf52a41d57abc&reaction=dislike'>👎</a>



-- 
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