vikash7485 opened a new pull request, #38347:
URL: https://github.com/apache/superset/pull/38347

   ## Description
   
   Fixes #38187
   
   `dashboard_id` and `slice_id` columns in the `logs` table were always
   `NULL` for every REST API mutation endpoint (POST, PUT, DELETE). This
   made audit logs useless for filtering by dashboard or chart.
   
   ### Root Cause
   
   `log_with_context()` in `utils/log.py` reads IDs from the merged HTTP
   payload:
   ```python
   dashboard_id = to_int(payload.get("dashboard_id"))  # always None
   slice_id     = to_int(payload.get("slice_id"))       # always None
   ```
   
   `collect_request_payload()` only reads `request.form`, `request.args`,
   and `request.json` body. URL path params (e.g. `/api/v1/dashboard/42`)
   are never included, so the IDs were never captured.
   
   ### Fix
   
   Used the existing `allow_extra_payload=True` mechanism — already
   proven working in `DashboardRestApi.get` — to explicitly inject
   `dashboard_id` / `slice_id` into the log payload after each operation.
   
   **11 endpoints fixed across 2 files:**
   
   `superset/dashboards/api.py` (7 endpoints):
   - `post` → `add_extra_log_payload(dashboard_id=new_model.id)`
   - `put` → `add_extra_log_payload(dashboard_id=changed_model.id)`
   - `put_filters` → `add_extra_log_payload(dashboard_id=pk)`
   - `put_chart_customizations` → `add_extra_log_payload(dashboard_id=pk)`
   - `put_colors` → `add_extra_log_payload(dashboard_id=pk)`
   - `delete` → `add_extra_log_payload(dashboard_id=pk)` called **before**
     `DeleteDashboardCommand.run()` so the ID is captured before the row
     is gone
   - `bulk_delete` → `add_extra_log_payload(dashboard_ids=item_ids)` stores
     the list in the `json` column (cannot fit multiple IDs in a single
     integer column — this is intentional)
   
   `superset/charts/api.py` (4 endpoints):
   - `post` → `add_extra_log_payload(slice_id=new_model.id)`
   - `put` → `add_extra_log_payload(slice_id=changed_model.id)`
   - `delete` → `add_extra_log_payload(slice_id=pk)` called before deletion
   - `bulk_delete` → `add_extra_log_payload(slice_ids=item_ids)`
   
   Also added missing `Callable` to the `from typing import` line in
   `charts/api.py`.
   
   ### Testing
   
   **Unit tests** — `tests/integration_tests/event_logger_tests.py`
   
   Added `TestMutationEndpointAuditIds` with 6 regression tests that mock
   `DBEventLogger.log` and assert the correct ID is passed as a kwarg:
   
   | Test | Asserts |
   |---|---|
   | `test_dashboard_put_logs_dashboard_id` | `dashboard_id == 42` |
   | `test_dashboard_delete_logs_dashboard_id` | `dashboard_id == 42` |
   | `test_dashboard_post_logs_dashboard_id` | `dashboard_id == 42` |
   | `test_chart_put_logs_slice_id` | `slice_id == 42` |
   | `test_chart_delete_logs_slice_id` | `slice_id == 42` |
   | `test_chart_post_logs_slice_id` | `slice_id == 42` |
   
   **Integration tests** — `tests/integration_tests/dashboards/api_tests.py`
   and `tests/integration_tests/charts/api_tests.py`
   
   Added DB-level assertions that query the `Log` model directly after
   each mutation and confirm the ID column is non-NULL:
   
   - `test_update_dashboard` → asserts `log.dashboard_id == dashboard_id`
   - `test_delete_dashboard` → asserts `log.dashboard_id == dashboard_id`
   - `test_update_chart` → asserts `log.slice_id == chart_id`
   - `test_delete_chart` → asserts `log.slice_id == chart_id`
   
   **SQL verification query (run after deployment):**
   ```sql
   SELECT id, action, dashboard_id, slice_id, dttm
   FROM logs
   ORDER BY dttm DESC
   LIMIT 20;
   ```
   After this fix, `dashboard_id` will be non-NULL for all
   `DashboardRestApi.*` actions and `slice_id` will be non-NULL for all
   `ChartRestApi.*` actions.
   
   ### Checklist
   
   - [x] Added unit tests
   - [x] Added integration tests with DB-level assertions
   - [x] Tested `delete` captures ID before row deletion
   - [x] `bulk_delete` stores ID list in `json` column (documented above)
   - [x] `Callable` import fix in `charts/api.py`
   - [x] AST syntax check passed on all changed files
   - [ ] Full test suite run pending (requires Flask-capable environment)


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