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

[BUGFIX]: Fixing permission rollup database/schema to table in SupersetFilter #4004

Closed

Conversation

fabianmenges
Copy link
Contributor

Currently the SupersetFilter (base class that filters on slices, datasources and dashboards) does not respect access to a database or schema. This can have the effect that if a user is allowed to use SQL lab, the user is not able to see the datasource she created when clicking on Visualize.

@fabianmenges fabianmenges changed the title [BUGFIX]: Fixing permission rollup database to table [BUGFIX]: Fixing permission rollup database/schema to table in SupersetFilter Dec 5, 2017
@fabianmenges fabianmenges force-pushed the fmenges/permission_rollup_fix branch 2 times, most recently from 4d9e8a6 to e53a096 Compare December 5, 2017 02:42
Copy link
Contributor

@xrmx xrmx left a comment

Choose a reason for hiding this comment

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

We can probably add some tests to avoid regression in the future

Copy link
Member

@mistercrunch mistercrunch left a comment

Choose a reason for hiding this comment

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

I also would like to see some tests in this area. I think it's also pretty important to do a single database call to list Slices and Dashboards

self.has_perm(ALL_DATASOURCE_ACCESS, ALL_DATASOURCE_ACCESS))

def datasources_with_access(self):
datasources = ConnectorRegistry.get_all_datasources(db.session)
Copy link
Member

Choose a reason for hiding this comment

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

It should be possible to avoid doing 2 database roundtrips when loading the slices or dashboard lists. If that doesn't work the second best option is to @memoize this method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can probably refactor and get rid of one call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So this is not easy, for the DatasourceFilter I can refactor to something like this:

        permissions = self.get_all_permissions()
        return query.filter(or_(
          self.model.perm.in_(permissions(DATASOURCE_ACCESS)),
          self.model.schema_perm.in_(permissions(SCHEMA_ACCESS)),
          self.model.database.perm.in_(permissions(DATABASE_ACCESS)),
        ))

But that does not work for slices, since slices don't have a foreign key relationship to the datasource they reference (because we have different tables for Druid and SQL datasources).

If I'm memoizing the call (lets say for datasources_with_access), I have to handle cache invalidation when a new datasources is added. Cache invalidation does not seem to be implemented right now so I don't really want to pen that can of worms for this fix.

I think the best I can do is refactor the DatasourceFilter and leave the SliceFilter and DasboardFilter as is.

Copy link
Member

Choose a reason for hiding this comment

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

It should be possible even without the FK, may be tricky though. You'll probably have to left join to LEFT JOIN to both tables and look for whether the it joins to either.

def datasources_with_access(self):
datasources = ConnectorRegistry.get_all_datasources(db.session)
permissions = self.get_all_permissions()
if (ALL_DATASOURCE_ACCESS in permissions.get(
Copy link
Member

Choose a reason for hiding this comment

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

@fabianmenges per my comment in #4737 I'm concerned that this could make the IN clause contain thousands of perm strings depending on the number of entities in database. That said if a role has a whitelist of databases one must enumerate all the datasources in it.

A possible performance improvement would for the case of a role where it contains either all_datasource_access or all_database_access to return None (or True) to signify that no additional filter is required (as opposed from listing every single datasource) for a given database. One would have to augment the logic in query.filter(self.model.perm.in_(perms)) to be database specific and included only when neither of all_datasource_access or all_database_access are present.

@kristw kristw added !deprecated-label:bug Deprecated label - Use #bug instead inactive Inactive for >= 30 days and removed !deprecated-label:bug Deprecated label - Use #bug instead labels Jan 23, 2019
@stale stale bot closed this Apr 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
!deprecated-label:bug Deprecated label - Use #bug instead inactive Inactive for >= 30 days
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants