mirror of
https://github.com/apache/superset.git
synced 2026-04-17 07:05:04 +00:00
[SQL Lab] fix gamma metadata access (#2702)
This commit is contained in:
committed by
GitHub
parent
a471afe206
commit
04748b4cda
@@ -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):
|
||||
|
||||
@@ -15,6 +15,7 @@ from flask_appbuilder.security.sqla import models as ab_models
|
||||
|
||||
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():
|
||||
@@ -101,8 +102,7 @@ class BaseSupersetView(BaseView):
|
||||
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(
|
||||
@@ -130,32 +130,61 @@ class BaseSupersetView(BaseView):
|
||||
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):
|
||||
|
||||
@@ -3,6 +3,7 @@ from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
import json
|
||||
import logging
|
||||
@@ -1198,8 +1199,10 @@ class Superset(BaseSupersetView):
|
||||
.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
|
||||
@@ -2179,7 +2182,6 @@ class Superset(BaseSupersetView):
|
||||
.one()
|
||||
)
|
||||
roles = {}
|
||||
from collections import defaultdict
|
||||
permissions = defaultdict(set)
|
||||
for role in user.roles:
|
||||
perms = set()
|
||||
|
||||
Reference in New Issue
Block a user