Skip to content

fix(frontend): fix edit/delete permissions for charts, dashboards, and datasets (#18870) (#32981)#32995

Merged
rusackas merged 9 commits into
apache:masterfrom
fnardin-maystreet:fix/delete-edit-buttons-permissions
Jul 16, 2026
Merged

fix(frontend): fix edit/delete permissions for charts, dashboards, and datasets (#18870) (#32981)#32995
rusackas merged 9 commits into
apache:masterfrom
fnardin-maystreet:fix/delete-edit-buttons-permissions

Conversation

@fnardin-maystreet

@fnardin-maystreet fnardin-maystreet commented Apr 3, 2025

Copy link
Copy Markdown
Contributor

SUMMARY

In both Dashboards, Datasets, Charts pages the delete and edit buttons are shown on the only condition that the user has can_write permission even if not the owner. Attempting to delete or edit an object results in a Forbidden error.

This PR fixes the button disabled status in the frontend preventing the user from attempting to delete or edit a resource it has no permission to.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

All three pages will show the delete and edit buttons as disabled if the user is not an owner or an admin:

Screenshot 2025-04-04 at 12 59 11

fixes: #18870
fixes: #32981

TESTING INSTRUCTIONS

Create a dashboard, a chart, and a dataset with an user and try to edit / delete them with a different user.

ADDITIONAL INFORMATION

@dosubot dosubot Bot added the change:frontend Requires changing the frontend label Apr 3, 2025

@korbit-ai korbit-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've completed my review and didn't find any issues.

Suppressed issues based on your team's Korbit activity
This issue Is similar to Because
lines 412:414:

The owner check uses Array.map() followed by includes(), which is inefficient for checking existence.

It creates a new array unnecessarily.

Inefficient Array Operations

Similar issues were not addressed in the past

When you react to issues (for example, an upvote or downvote) or you fix them, Korbit will tune future reviews based on these signals.

Files scanned
File Path Reviewed
superset-frontend/src/pages/DashboardList/index.tsx
superset-frontend/src/pages/ChartList/index.tsx
superset-frontend/src/pages/DatasetList/index.tsx

Explore our documentation to understand the languages and file types we support and the files we ignore.

Need a new review? Comment /korbit-review on this PR and I'll review your latest changes.

Korbit Guide: Usage and Customization

Interacting with Korbit

  • You can manually ask Korbit to review your PR using the /korbit-review command in a comment at the root of your PR.
  • You can ask Korbit to generate a new PR description using the /korbit-generate-pr-description command in any comment on your PR.
  • Too many Korbit comments? I can resolve all my comment threads if you use the /korbit-resolve command in any comment on your PR.
  • On any given comment that Korbit raises on your pull request, you can have a discussion with Korbit by replying to the comment.
  • Help train Korbit to improve your reviews by giving a 👍 or 👎 on the comments Korbit posts.

Customizing Korbit

  • Check out our docs on how you can make Korbit work best for you and your team.
  • Customize Korbit for your organization through the Korbit Console.

Current Korbit Configuration

General Settings
Setting Value
Review Schedule Automatic excluding drafts
Max Issue Count 10
Automatic PR Descriptions
Issue Categories
Category Enabled
Documentation
Logging
Error Handling
Readability
Design
Performance
Security
Functionality

Feedback and Support

Note

Korbit Pro is free for open source projects 🎉

Looking to add Korbit to your team? Get started with a free 2 week trial here

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congrats on making your first PR and thank you for contributing to Superset! 🎉 ❤️

We hope to see you in our Slack community too! Not signed up? Use our Slack App to self-register.

@pull-request-size pull-request-size Bot added size/L and removed size/M labels Apr 3, 2025
Comment thread superset-frontend/src/pages/ChartList/index.tsx Outdated
Comment thread superset-frontend/src/pages/ChartList/index.tsx Outdated
@sadpandajoe

Copy link
Copy Markdown
Member

This might be a backend problem and not a front end problem. We used to have a can_delete permission but that was collapsed into can_write. CC: @dpgaspar as he might know what is going on.

@fnardin-maystreet

Copy link
Copy Markdown
Contributor Author

This might be a backend problem and not a front end problem. We used to have a can_delete permission but that was collapsed into can_write. CC: @dpgaspar as he might know what is going on.

@sadpandajoe Permissions are obtained through the api/v1/dashboard/_info?q=(keys:!(permissions)) endpoint and apply generically to all dashboards. A can_delete permission is not sufficient to determine if a user can delete a resource, as that also depends on the owner of that resource.

Comment thread superset-frontend/src/components/ListView/ActionsBar.tsx Outdated
Comment thread superset-frontend/src/components/Icons/BaseIcon.tsx Outdated
Comment thread superset-frontend/src/components/Icons/BaseIcon.tsx Outdated
Comment thread superset-frontend/src/pages/ChartList/index.tsx Outdated
@rusackas

rusackas commented Apr 9, 2025

Copy link
Copy Markdown
Member

Not to confuse this issue further, but @geido brought up a good point that perhaps the dimming/disabling shouldn't be the business of the Icon component, but perhaps the link it's wrapped in? In this case it's a with and onClick handler, but maybe we should be using a (modified?) IconButton component for these.

@rusackas

rusackas commented Apr 9, 2025

Copy link
Copy Markdown
Member

Here's another use case along the same lines: #30124

@rusackas

Copy link
Copy Markdown
Member

This needs a rebase at this point, if you're able to do so. We'd love to see it get across the finish line and close out the linked issue(s).

@fnardin-maystreet
fnardin-maystreet force-pushed the fix/delete-edit-buttons-permissions branch from c1ca5aa to 8dc9fbf Compare July 3, 2025 16:20
@fnardin-maystreet

Copy link
Copy Markdown
Contributor Author

@rusackas I rebased the changes to master and implemented the disabled logic into the IconButton component :)

@fnardin-maystreet
fnardin-maystreet force-pushed the fix/delete-edit-buttons-permissions branch from 0751441 to 66dd716 Compare July 3, 2025 16:40
@rusackas

rusackas commented Jul 9, 2025

Copy link
Copy Markdown
Member

Approving CI to run 🤞

@fnardin-maystreet
fnardin-maystreet force-pushed the fix/delete-edit-buttons-permissions branch from 66dd716 to 1ebed37 Compare July 18, 2025 08:22
@fnardin-maystreet

Copy link
Copy Markdown
Contributor Author

Rebased and fixed lint issues in IconButton.tsx

@rusackas
rusackas requested review from geido and msyavuz July 23, 2025 18:15
@rusackas

Copy link
Copy Markdown
Member

We haven't forgotten about this! The logic looks basically good to me, but there are a handful of style/theme related changes that I think we should have someone look at who's closer to the Theming project, so I've tagged some additional reviewers here. In general, we just want to be as "vanilla" as possible with AntD components, and minimize CSS overrides wherever possible.

@github-actions github-actions Bot removed the packages label Jul 10, 2026
Comment thread superset-frontend/src/features/charts/ChartCard.tsx Outdated
Comment thread superset-frontend/src/pages/DatasetList/index.tsx Outdated
@bito-code-review

bito-code-review Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #1bbbaa

Actionable Suggestions - 0
Additional Suggestions - 2
  • superset-frontend/src/pages/DashboardList/index.tsx - 1
    • Type definition mismatch · Line 773-773
      The `user` prop is added but `DashboardCard`'s interface (line 46) declares `user?: { userId?: string | number }` which is narrower than `UserWithPermissionsAndRoles` expected by `isUserEditorOrAdmin` at line 70. Update the prop type to match the full user object being passed.
  • superset-frontend/src/features/charts/ChartCard.tsx - 1
    • Type compatibility with permission utility · Line 53-53
      The `user` prop type is narrower than what `isUserEditorOrAdmin` expects (line 82). While the current type `{ userId?: string | number }` compiles, it omits `roles` and `permissions` properties that the permission utility may rely on. Consider aligning with the full User type from `bootstrapTypes` for type safety.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/features/charts/ChartCard.tsx - 1
    • Semantic duplication across codebase · Line 82-82
  • superset-frontend/spec/helpers/mockBootstrapData.ts - 1
Review Details
  • Files reviewed - 15 · Commit Range: 792c958..60352f9
    • superset-frontend/spec/helpers/mockBootstrapData.ts
    • superset-frontend/src/dashboard/components/IconButton.tsx
    • superset-frontend/src/features/charts/ChartCard.tsx
    • superset-frontend/src/features/dashboards/DashboardCard.tsx
    • superset-frontend/src/features/home/ChartTable.tsx
    • superset-frontend/src/features/home/DashboardTable.tsx
    • superset-frontend/src/pages/ChartList/ChartList.listview.test.tsx
    • superset-frontend/src/pages/ChartList/index.tsx
    • superset-frontend/src/pages/DashboardList/DashboardList.behavior.test.tsx
    • superset-frontend/src/pages/DashboardList/index.tsx
    • superset-frontend/src/pages/DatasetList/DatasetList.behavior.test.tsx
    • superset-frontend/packages/superset-ui-core/src/components/EditableTitle/index.tsx
    • superset-frontend/src/dashboard/util/permissionUtils.ts
    • superset-frontend/src/pages/DatasetList/DatasetList.listview.test.tsx
    • superset-frontend/src/pages/DatasetList/index.tsx
  • Files skipped - 0
  • Tools
    • Eslint (Linter) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@rusackas

rusackas commented Jul 10, 2026

Copy link
Copy Markdown
Member

Thanks for coming back to this and knocking out the earlier notes. EditableTitle's out, the editors check is DRY'd up into isUserInEditors, and the card views are gated now. Nice progress.

Looks like the latest push went red, though. There's a type error in DashboardList/index.tsx (TS2322, around line 772), and the new card/table gating broke a batch of existing tests: ChartList.cardview, DashboardList, plus the ChartTable/DashboardTable home widgets. Worth getting CI green before another pass.

A couple of unrelated bits are still hanging around too, the SliceHeader max-width bump and the blank line in DashboardWrapper. Left suggestions to revert both.

Thanks for sticking with this one!

Comment thread superset-frontend/src/dashboard/components/SliceHeader/index.tsx Outdated
Comment thread superset-frontend/src/dashboard/components/DashboardBuilder/DashboardWrapper.tsx Outdated
@bito-code-review

bito-code-review Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #0d6d7a

Actionable Suggestions - 0
Additional Suggestions - 3
  • superset-frontend/src/features/home/DashboardTable.test.tsx - 1
    • Test coverage gap for edit permissions · Line 86-86
      Test data now includes `editors` field but no assertions verify edit permission behavior. BITO.md rule 6262 requires tests to verify actual behavior they claim to cover, not just component rendering. Consider adding test cases that click edit options and assert the edit modal opens or edit actions are enabled.
  • superset-frontend/src/features/home/ChartTable.test.tsx - 1
    • Missing edit permission test · Line 60-60
      The `editors` field is added to mock chart data but no test asserts the `allowEdit` behavior it enables in `ChartCard`. Per BITO.md rule 6262, tests should verify actual business logic they set up data for — add a test that clicks Edit and confirms `openChartEditModal` is called with the chart.
  • superset-frontend/src/dashboard/components/SliceHeader/index.tsx - 1
    • Missing CSS layout verification · Line 97-97
      The CSS max-width calculation on line 97 controls title truncation behavior relative to controls, but the existing test suite (SliceHeader.test.tsx) only verifies component rendering, not layout behavior. Per BITO.md rule [6262], tests should verify actual business logic — in this case, the overflow calculation that determines when long titles get truncated. Consider adding tests that validate title wrapping behavior at different container widths.
Review Details
  • Files reviewed - 10 · Commit Range: 60352f9..17149f3
    • superset-frontend/src/dashboard/components/SliceHeader/index.tsx
    • superset-frontend/src/dashboard/components/DashboardBuilder/DashboardWrapper.tsx
    • superset-frontend/src/features/home/ChartTable.test.tsx
    • superset-frontend/src/features/home/DashboardTable.test.tsx
    • superset-frontend/src/pages/ChartList/ChartList.cardview.test.tsx
    • superset-frontend/src/pages/ChartList/ChartList.listview.test.tsx
    • superset-frontend/src/pages/DashboardList/DashboardList.behavior.test.tsx
    • superset-frontend/src/pages/DashboardList/DashboardList.test.tsx
    • superset-frontend/src/pages/DashboardList/index.tsx
    • superset-frontend/src/pages/DatasetList/DatasetList.behavior.test.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@bito-code-review

bito-code-review Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #fb7cef

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: 17149f3..9b11693
    • superset-frontend/src/dashboard/components/IconButton.test.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@fnardin-maystreet

Copy link
Copy Markdown
Contributor Author

@rusackas I applied the suggestions, fixed the lint issues, and updated the tests. CI is now passing. Please check again, I think we're near!

@rusackas

Copy link
Copy Markdown
Member

I'll see about rebasing this, since it's my fault you're stuck with more conflicts ;)

@rusackas

rusackas commented Jul 16, 2026

Copy link
Copy Markdown
Member

Taking a review pass while I'm lookin' at the rebase, @fnardin-maystreet, it's really close. Earlier notes are all knocked out, thanks.

The edit/delete gate keys off isUserEditorOrAdmin(user, original.editors), but the user handed in on all three list pages (and the card views) is the narrow { userId } prop. isUserAdmin needs the full user with roles, so with only a userId it always returns false and the gate collapses to editors-only. So an Admin who is not explicitly an editor/owner of a given chart/dashboard/dataset now sees Edit and Delete disabled, where today they can edit anything. That is a regression on a pretty common admin workflow.

The fix should be small, since the full user is already right there. In ChartList/DashboardList you are pulling roles off state.user via useSelector a few lines up, so feeding that user (or its roles) into isUserEditorOrAdmin instead of the { userId } prop should restore admin access. The card props would need the same.

Worth a test for it too. I noticed the DatasetList spec swapped mockAdminUser for mockEditorUser, which sidesteps this rather than covering it. A case with a non-editor admin asserting the buttons stay enabled would lock it in.

Holler if you want a hand wiring the admin user through, happy to push a commit. It also needs a rebase on current master while you are in there.

Comment thread superset-frontend/src/features/dashboards/DashboardCard.tsx Outdated
Comment thread superset-frontend/src/pages/ChartList/index.tsx
Comment thread superset-frontend/src/pages/DashboardList/index.tsx
@fnardin-maystreet

Copy link
Copy Markdown
Contributor Author

@rusackas The issue you're raising is real but a bit overstated as it's the type of the user prop that's narrower than what's actually passed in at runtime. The review bot flagged this earlier and I deemed it out of scope for this PR (here).

This is actually a pre-existing issue: DatasetList on master already uses the user prop to check admin privileges with the same narrow type. The bug is only in the declared type of user. The actual value passed in from App.tsx is the full user object with roles.

I think the better fix is widening those types (ChartListProps/DashboardListProps/DatasetListProps and the card prop types) to match what's actually passed, rather than reworking the logic. I'll rebase and do that. I also see your latest commit conflicts with my changes, so I'll fix that too 😅.

On the DatasetList spec: the test would behave the same with mockAdminUser, since that fixture lacks username/permissions and therefore fails isUserWithPermissionsAndRoles in permissionUtils.ts. isUserAdmin never actually resolves true for it. I swapped to mockEditorUser to mainly to keep the bot quiet.

Good catch though. I'll add a proper fixture (with username/permissions/roles.Admin) that isn't listed as an editor, and a test asserting Edit/Delete stay enabled for it, to actually lock in the admin-bypass behavior.

@fnardin-maystreet
fnardin-maystreet force-pushed the fix/delete-edit-buttons-permissions branch from da4a08a to db96e2f Compare July 16, 2026 19:26

@rusackas rusackas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for staying with this through all the rebases, @fnardin-maystreet. LGTM, and the IconButton/permissionUtils refactor ended up in a nicer shape than where this started. Approving, merging soon, hopefully.

@rusackas
rusackas merged commit 30b93ab into apache:master Jul 16, 2026
70 checks passed
@fnardin-maystreet
fnardin-maystreet deleted the fix/delete-edit-buttons-permissions branch July 17, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authentication:access-control Rlated to access control change:frontend Requires changing the frontend listview:dashboards Related to the Dashboards' list listview Namespace | Anything related to lists, such as Dashboards, Charts, Datasets, etc. size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

User can attempt to delete a dataset even if it's not the owner Gamma user can attempt to Delete dashboards

4 participants