Repository navigation
fix(security): keep chart perm in sync when a renamed datasource is already loaded - #45874
aminghadersohi wants to merge 2 commits into
Conversation
…ewrites The permission event hooks rewrite dataset, semantic view and chart perm strings with Core UPDATEs. A datasource instance already loaded in the session kept the previous strings, and set_related_perm copies a chart's perm from that instance, so a chart written later in the same transaction wrote the previous strings back. A viewer whose access came from the dataset grant then got 404 on the chart data call. Record the written values on loaded instances after a database rename, a dataset table/schema/database change and a semantic layer rename.
Restrict the perm read-back to datasets loaded in the session, and clean up the import test's assets even when an import fails.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #45874 +/- ##
===========================================
+ Coverage 65.62% 84.71% +19.09%
===========================================
Files 3069 3069
Lines 205661 205687 +26
Branches 48336 48343 +7
===========================================
+ Hits 134955 174240 +39285
+ Misses 67625 28151 -39474
- Partials 3081 3296 +215
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Acceptance run at 8990688: real Superset app in-process, a real SQLite metadata DB, real requests through the Flask test client. The same script ran at the merge-base (4e6d03b) and at head.
Pre-existing and not changed by this PR (the body already says so): an asset import that renames a database leaves the old database name in |
rebenitez1802
left a comment
There was a problem hiding this comment.
Approve: real stale-perm bug, minimal and well-targeted fix, every new call is pinned by a test that fails on master and passes here; no blocking issues.
SUMMARY
The permission event hooks in
superset/security/manager.pyrewriteperm,schema_permandcatalog_permof datasets, semantic views and charts with CoreUPDATEs on the flush connection. A datasource instance that is already loaded in the session keeps the previous strings.set_related_perm(the chartbefore_updatehook) copies a chart's perm strings from that instance. So a chart written later in the same transaction writes the previous strings back over the Core values.A log probe in
set_related_permduringPUT /api/v1/database/<id>showed this. The dataset was already loaded in the session, and the chart was flushed when the database permission sync set itsschema_perm. At that point the dataset instance heldperm='[old_db].[t1](id:1)', the dataset row held[new_db].[t1](id:1), and the chart already held the new perm before the hook overwrote it. Charts of datasets without a schema are not touched by that sync, so they kept the right perm. A viewer whose access comes from the dataset grant then gets 404 onGET /api/v1/chart/<id>/data/until the chart is saved again.Where it happens:
database_after_update): only when the datasets are already loaded in the session before the rename, e.g. a long-lived app context or a script. A rename from a fresh request session is not affected;test_rename_database_keeps_chart_perms_in_syncpasses before and after this change.dataset_before_update): the dataset being flushed is always loaded. This is reachable through asset import: re-importing a bundle whose dataset has a new table name or schema leaves its chart with the old perm and no schema perm (test_import_assets_dataset_change_keeps_chart_perms).semantic_layer_before_update): the same pattern for loaded semantic views.The fix (commit 8990688, pinned by
test_rename_database_with_loaded_datasets_keeps_chart_perms_in_sync) records the values the CoreUPDATEwrote on the loaded instances withset_committed_value; after a database rename it reads back only the datasets loaded in the session. Attributes that are not loaded, or that carry a pending change, are left alone._update_vm_datasources_accessis not changed: the database rename path reads the rewritten perms back from the table after it runs.Not changed here: a database renamed through asset import keeps the old database name in the
schema_permof its datasets and charts, because import does not run the schema permission sync. That is a separate gap, not this stale-instance problem.Related: #45864 changes
_update_vm_datasources_access; this PR does not touch those lines.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Not applicable (backend only).
TESTING INSTRUCTIONS
New tests, each failing with
superset/security/manager.pyas on master and passing with commit 8990688:tests/integration_tests/security/perm_sync_after_rename_tests.py::TestDatabaseRenamePermissions::test_rename_database_with_loaded_datasets_keeps_chart_perms_in_sync: realPUT /api/v1/database/<id>with a dataset with a schema and one without; asserts every chart'sperm/schema_permuses the new name and that a viewer with only the dataset grant gets 200 onGET /api/v1/chart/<id>/data/.TestDatasetChangePermissions::test_table_rename_then_chart_write,test_schema_change_then_chart_write,test_database_change_then_chart_write(same file).tests/integration_tests/commands_test.py::TestImportAssetsCommand::test_import_assets_dataset_change_keeps_chart_perms.tests/unit_tests/semantic_layers/models_test.py::test_semantic_layer_rename_then_chart_write_keeps_slice_perm.TestDatabaseRenamePermissions::test_rename_database_keeps_chart_perms_in_synccovers the same PUT from a fresh session and passes before and after.ADDITIONAL INFORMATION