Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Refactor ownership checks #20499

Merged

Conversation

john-bodley
Copy link
Member

@john-bodley john-bodley commented Jun 25, 2022

SUMMARY

Yak shaving at its finest. Originally I drafted this PR to fix an issue with inconsistencies between ownership checks as described in this Slack thread. BTW this PR does not address said issue—I believe we only need a migration for legacy charts/datasets.

Things quickly spiraled out of control as I realized that the DAO check_access method checks whether the actor is an owner alongside a check whether the current user is an admin—this clearly is wrong, i.e., both checks should be for the same user. Digging further I realize that the actor is always g.user and thus continuing my crusade to simplify the whole user space (removing passing g.user all around the place) I opted to fully deprecate the actor concept—which touched a huge swatch of files. The main reason being is that Superset is really only configured to work with the logged in user and overrides should be done—if needed—via the override_user context manager.

The TL;DR of this PR:

  1. Removes the actor construct across all the DAO models.
  2. Refactors check_ownership which either raised or returned a bool into the raise_for_owernship and is_owner methods—the later being a wrapper of the former. This helps to improve code readability, i.e., it is apparent that raise_for_owernship raises. These methods have been moved to the security manager to allow for customization.
  3. Removes duplicate methods, i.e., whether a user is an admin or owner.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

TESTING INSTRUCTIONS

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@john-bodley john-bodley marked this pull request as ready for review June 25, 2022 03:00
@codecov
Copy link

codecov bot commented Jun 25, 2022

Codecov Report

Merging #20499 (844a8b0) into master (f910958) will decrease coverage by 0.23%.
The diff coverage is 88.58%.

❗ Current head 844a8b0 differs from pull request most recent head 823b9d3. Consider uploading reports for the commit 823b9d3 to get more accurate results

@@            Coverage Diff             @@
##           master   #20499      +/-   ##
==========================================
- Coverage   66.82%   66.59%   -0.24%     
==========================================
  Files        1752     1751       -1     
  Lines       65620    65504     -116     
  Branches     6938     6940       +2     
==========================================
- Hits        43853    43620     -233     
- Misses      20007    20122     +115     
- Partials     1760     1762       +2     
Flag Coverage Δ
hive ?
mysql 82.33% <93.37%> (-0.06%) ⬇️
postgres 82.40% <93.37%> (-0.06%) ⬇️
presto ?
python 82.48% <93.37%> (-0.41%) ⬇️
sqlite 82.19% <93.37%> (-0.06%) ⬇️
unit ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...frontend/src/components/ImportModal/ErrorAlert.tsx 33.33% <ø> (ø)
superset-frontend/src/views/CRUD/hooks.ts 46.56% <ø> (ø)
superset/dashboards/permalink/commands/create.py 88.88% <ø> (-0.77%) ⬇️
superset/datasets/dao.py 94.11% <ø> (+0.54%) ⬆️
superset/explore/form_data/commands/get.py 90.90% <ø> (-0.27%) ⬇️
superset/explore/form_data/commands/parameters.py 100.00% <ø> (ø)
superset/temporary_cache/commands/parameters.py 100.00% <ø> (ø)
superset/views/base.py 75.36% <ø> (-1.36%) ⬇️
superset/views/dashboard/views.py 66.27% <0.00%> (+0.76%) ⬆️
superset/views/utils.py 80.84% <ø> (-0.22%) ⬇️
... and 103 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f910958...823b9d3. Read the comment docs.

@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch 12 times, most recently from 9d16076 to 80d717b Compare June 25, 2022 23:37
owners.append(resource.owner)

if hasattr(resource, "created_by"):
owners.append(resource.created_by)
Copy link
Member

Choose a reason for hiding this comment

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

I was comparing this method to the old one which pulled out the original object from the db rather than use the one that was passed in. Could the resource here come from user input rather than the db? I'm thinking of the scenario where a non-owner might try to grant themselves ownership by adding themselves to the list of owners on a resource. Since it's not making a db call to the original resource could we be allowing them to define their own set of owners? One example perhaps is the pre_update hook for the SliceModelView.

Copy link
Member Author

Choose a reason for hiding this comment

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

@eschutho apologies for the delay in responding as I was away on PTO. I think the point you raise is a good call and I'll revert the logic.

As a side note I think a lot of the pre_update logic is possibly obsolete with the DAO model—which merely complicates the code base—and we likely could deprecate some of that. I'm planning on authoring another PR to address said issue.

@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch from 80d717b to f71f182 Compare July 5, 2022 21:15
@john-bodley
Copy link
Member Author

@eschutho I've addressed your question and thus this should be ready for re-review. @dpgaspar would you mind also reviewing said change given that it updates the DAO logic that you and @villebro authored.

@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch 4 times, most recently from 88c5910 to 91c9b14 Compare July 6, 2022 17:32
@john-bodley john-bodley requested a review from eschutho July 6, 2022 17:33
@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch 3 times, most recently from d0b4273 to e220a4c Compare July 6, 2022 21:50
@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch from e220a4c to 560ff4a Compare July 6, 2022 23:18
@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch 3 times, most recently from 50b921d to 6aa4855 Compare July 7, 2022 02:07
@john-bodley john-bodley requested a review from ktmud July 7, 2022 02:50
Copy link
Member

@ktmud ktmud left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Member

@dpgaspar dpgaspar left a comment

Choose a reason for hiding this comment

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

This does shave the Yak a bit more ;)

On the other hand we will loose some future flexibility if we would ever wanted to use DAO or commands with different users, celery context for example?

return

orig_resource = (
db.session.query(resource.__class__).filter_by(id=resource.id).first()
Copy link
Member

Choose a reason for hiding this comment

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

nit: db.session.query(resource.__class__).filter_by(id=resource.id).one_or_none() or db.session.query(resource.__class__).get(resource.id)

Copy link
Member Author

Choose a reason for hiding this comment

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

@dpgaspar I agree with the one_or_none. This was a copy-and-paste from check_ownership but I'll make the update.

@john-bodley
Copy link
Member Author

@dpgaspar

On the other hand we will loose some future flexibility if we would ever wanted to use DAO or commands with different users, celery context for example?

I don't disagree in terms of lose of flexibility, however the g.user is so engrained in the entire application workflow that we would need a very major refactor in order to support this. Per the PR description the actor is somewhat misleading given that some checks are in relation to the specified actor whereas others (like is_user_admin et al.) are based on g.user.

@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch from 6aa4855 to 7f71252 Compare July 7, 2022 16:47
@john-bodley john-bodley force-pushed the john-bodley--refactor-check-ownership branch from 7f71252 to 823b9d3 Compare July 7, 2022 16:59
@john-bodley john-bodley merged commit f0ca158 into apache:master Jul 7, 2022
@john-bodley john-bodley deleted the john-bodley--refactor-check-ownership branch July 7, 2022 18:04
akshatsri pushed a commit to charan1314/superset that referenced this pull request Jul 19, 2022
Co-authored-by: John Bodley <john.bodley@airbnb.com>
@john-bodley john-bodley mentioned this pull request Oct 25, 2022
9 tasks
@john-bodley john-bodley mentioned this pull request Feb 16, 2024
9 tasks
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 2.1.0 labels Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels size/XXL 🚢 2.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants