Skip to content

Commit

Permalink
[SQL Lab] fix gamma metadata access (#2702)
Browse files Browse the repository at this point in the history
  • Loading branch information
mistercrunch authored May 9, 2017
1 parent a471afe commit 04748b4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 28 deletions.
9 changes: 4 additions & 5 deletions superset/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,10 @@ class SupersetTemplateException(SupersetException):

def can_access(sm, permission_name, view_name, user):
"""Protecting from has_access failing from missing perms/view"""
return (
sm.is_item_public(permission_name, view_name) or
(not user.is_anonymous() and
sm._has_view_access(user, permission_name, view_name))
)
if user.is_anonymous():
return sm.is_item_public(permission_name, view_name)
else:
return sm._has_view_access(user, permission_name, view_name)


def flasher(msg, severity=None):
Expand Down
71 changes: 50 additions & 21 deletions superset/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from superset import appbuilder, conf, db, utils, sm, sql_parse
from superset.connectors.connector_registry import ConnectorRegistry
from superset.connectors.sqla.models import SqlaTable


def get_error_msg():
Expand Down Expand Up @@ -101,8 +102,7 @@ def datasource_access_by_name(
return True

schema_perm = utils.get_schema_perm(database, schema)
if schema and utils.can_access(
sm, 'schema_access', schema_perm, g.user):
if schema and self.can_access('schema_access', schema_perm):
return True

datasources = ConnectorRegistry.query_datasources_by_name(
Expand Down Expand Up @@ -130,32 +130,61 @@ def rejected_datasources(self, sql, database, schema):
t for t in superset_query.tables if not
self.datasource_access_by_fullname(database, t, schema)]

def user_datasource_perms(self):
datasource_perms = set()
for r in g.user.roles:
for perm in r.permissions:
if (
perm.permission and
'datasource_access' == perm.permission.name):
datasource_perms.add(perm.view_menu.name)
return datasource_perms

def schemas_accessible_by_user(self, database, schemas):
if self.database_access(database) or self.all_datasource_access():
return schemas

subset = set()
for schema in schemas:
schema_perm = utils.get_schema_perm(database, schema)
if self.can_access('schema_access', schema_perm):
subset.add(schema)

perms = self.user_datasource_perms()
if perms:
tables = (
db.session.query(SqlaTable)
.filter(
SqlaTable.perm.in_(perms),
SqlaTable.database_id == database.id,
)
.all()
)
for t in tables:
if t.schema:
subset.add(t.schema)
return sorted(list(subset))

def accessible_by_user(self, database, datasource_names, schema=None):
if self.database_access(database) or self.all_datasource_access():
return datasource_names

schema_perm = utils.get_schema_perm(database, schema)
if schema and utils.can_access(
sm, 'schema_access', schema_perm, g.user):
return datasource_names
if schema:
schema_perm = utils.get_schema_perm(database, schema)
if self.can_access('schema_access', schema_perm):
return datasource_names

role_ids = set([role.id for role in g.user.roles])
# TODO: cache user_perms or user_datasources
PV = ab_models.PermissionView

pv_role = PV.role # pylint: disable=no-member
user_pvms = (
db.session.query(PV)
.join(ab_models.Permission)
.filter(ab_models.Permission.name == 'datasource_access')
.filter(pv_role.any(ab_models.Role.id.in_(role_ids)))
.all()
)
user_perms = set([pvm.view_menu.name for pvm in user_pvms])
user_perms = self.user_datasource_perms()
user_datasources = ConnectorRegistry.query_datasources_by_permissions(
db.session, database, user_perms)
full_names = set([d.full_name for d in user_datasources])
return [d for d in datasource_names if d in full_names]
if schema:
names = {
d.table_name
for d in user_datasources if d.schema == schema}
return [d for d in datasource_names if d in names]
else:
full_names = {d.full_name for d in user_datasources}
return [d for d in datasource_names if d in full_names]


class SupersetModelView(ModelView):
Expand Down
6 changes: 4 additions & 2 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import print_function
from __future__ import unicode_literals

from collections import defaultdict
from datetime import datetime, timedelta
import json
import logging
Expand Down Expand Up @@ -1198,8 +1199,10 @@ def schemas(self, db_id):
.filter_by(id=db_id)
.one()
)
schemas = database.all_schema_names()
schemas = self.schemas_accessible_by_user(database, schemas)
return Response(
json.dumps({'schemas': database.all_schema_names()}),
json.dumps({'schemas': schemas}),
mimetype="application/json")

@api
Expand Down Expand Up @@ -2179,7 +2182,6 @@ def profile(self, username):
.one()
)
roles = {}
from collections import defaultdict
permissions = defaultdict(set)
for role in user.roles:
perms = set()
Expand Down

0 comments on commit 04748b4

Please sign in to comment.