diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts index a2915fef4380..8f660e1a776b 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts @@ -438,3 +438,23 @@ test('should handle metrics without labels', () => { expect(grid!.rowHeaders).toEqual(['']); expect(grid!.colHeaders).toEqual(['count']); }); + +test('should preserve slice_id and dashboardId for embedded dashboard permissions', () => { + const formDataWithDashboardContext: TestFormData = { + ...baseFormData, + slice_id: 42, + dashboardId: 123, + }; + + const grid = generateMatrixifyGrid(formDataWithDashboardContext); + + expect(grid).not.toBeNull(); + const cell = grid!.cells[0][0]; + + // slice_id must be preserved for embedded dashboard permission checks + // The backend uses slice_id to verify the chart belongs to the dashboard + expect(cell!.formData.slice_id).toBe(42); + + // dashboardId must be preserved for embedded dashboard context + expect(cell!.formData.dashboardId).toBe(123); +}); diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts index cc12d396b9ec..59c5f9ed7337 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts @@ -125,9 +125,9 @@ function generateCellFormData( }); // Override fields that could cause issues in grid cells + // Note: slice_id is intentionally preserved for embedded dashboard permission checks const overrides: Partial = { slice_name: undefined, - slice_id: undefined, header_font_size: undefined, subheader: undefined, show_title: undefined, diff --git a/superset/jinja_context.py b/superset/jinja_context.py index dc9411030e53..15b8d0495a1b 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -122,13 +122,13 @@ class ExtraCache: # be added to the cache key. regex = re.compile( r"(\{\{|\{%)[^{}]*?(" - r"current_user_id\([^()]*\)|" - r"current_username\([^()]*\)|" - r"current_user_email\([^()]*\)|" - r"current_user_rls_rules\([^()]*\)|" - r"current_user_roles\([^()]*\)|" - r"cache_key_wrapper\([^()]*\)|" - r"url_param\([^()]*\)" + r"current_user_id\([^)]*\)|" + r"current_username\([^)]*\)|" + r"current_user_email\([^)]*\)|" + r"current_user_rls_rules\([^)]*\)|" + r"current_user_roles\([^)]*\)|" + r"cache_key_wrapper\([^)]*\)|" + r"url_param\([^)]*\)" r")" r"[^{}]*?(\}\}|\%\})" ) diff --git a/tests/unit_tests/jinja_context_test.py b/tests/unit_tests/jinja_context_test.py index 929c470b3159..9ba84315fac4 100644 --- a/tests/unit_tests/jinja_context_test.py +++ b/tests/unit_tests/jinja_context_test.py @@ -1693,3 +1693,24 @@ def test_undefined_template_variable_not_function(mocker: MockerFixture) -> None template = "SELECT {{ undefined_variable.some_method() }}" with pytest.raises(UndefinedError): processor.process_template(template) + + +@pytest.mark.parametrize( + ("sql", "expected"), + [ + ("SELECT {{ cache_key_wrapper(abc) }}", True), + ("SELECT {{ cache_key_wrapper(myfunc()) }}", True), + ("SELECT {{ url_param('foo') }}", True), + ("SELECT {{ url_param(get_param('foo')) }}", True), + ("SELECT {{ current_user_id() }}", True), + ("SELECT {{ current_username() }}", True), + ("SELECT {{ current_user_email() }}", True), + ("SELECT {{ current_user_roles() }}", True), + ("SELECT {{ current_user_rls_rules() }}", True), + ("SELECT 'cache_key_wrapper(abc)' AS false_positive", False), + ("SELECT 1", False), + ("SELECT '{{ 1 + 1 }}'", False), + ], +) +def test_extra_cache_regex(sql: str, expected: bool) -> None: + assert bool(ExtraCache.regex.search(sql)) is expected