mirror of https://github.com/apache/superset.git
Filter table list based on the user permissions. (#1769)
* Filter table list based on the user permissions. * Fix tests
This commit is contained in:
parent
43f2a379a1
commit
3597fdb7f8
|
@ -79,6 +79,11 @@ class BaseSupersetView(BaseView):
|
|||
if (self.database_access(database) or
|
||||
self.all_datasource_access()):
|
||||
return True
|
||||
|
||||
schema_perm = utils.get_schema_perm(database, schema)
|
||||
if schema and utils.can_access(sm, 'schema_access', schema_perm):
|
||||
return True
|
||||
|
||||
datasources = SourceRegistry.query_datasources_by_name(
|
||||
db.session, database, datasource_name, schema=schema)
|
||||
for datasource in datasources:
|
||||
|
@ -214,10 +219,7 @@ class SupersetFilter(BaseFilter):
|
|||
"""
|
||||
|
||||
def get_user_roles(self):
|
||||
attr = '__get_user_roles'
|
||||
if not hasattr(self, attr):
|
||||
setattr(self, attr, get_user_roles())
|
||||
return getattr(self, attr)
|
||||
return get_user_roles()
|
||||
|
||||
def get_all_permissions(self):
|
||||
"""Returns a set of tuples with the perm name and view menu name"""
|
||||
|
@ -253,21 +255,12 @@ class SupersetFilter(BaseFilter):
|
|||
self.has_perm('all_datasource_access', 'all_datasource_access'))
|
||||
|
||||
|
||||
class DatabaseFilter(SupersetFilter):
|
||||
def apply(self, query, func): # noqa
|
||||
if (
|
||||
self.has_role('Admin') or
|
||||
self.has_perm('all_database_access', 'all_database_access')):
|
||||
return query
|
||||
perms = self.get_view_menus('database_access')
|
||||
return query.filter(self.model.perm.in_(perms))
|
||||
|
||||
|
||||
class DatasourceFilter(SupersetFilter):
|
||||
def apply(self, query, func): # noqa
|
||||
if self.has_all_datasource_access():
|
||||
return query
|
||||
perms = self.get_view_menus('datasource_access')
|
||||
# TODO(bogdan): add `schema_access` support here
|
||||
return query.filter(self.model.perm.in_(perms))
|
||||
|
||||
|
||||
|
@ -276,6 +269,7 @@ class SliceFilter(SupersetFilter):
|
|||
if self.has_all_datasource_access():
|
||||
return query
|
||||
perms = self.get_view_menus('datasource_access')
|
||||
# TODO(bogdan): add `schema_access` support here
|
||||
return query.filter(self.model.perm.in_(perms))
|
||||
|
||||
|
||||
|
@ -288,6 +282,7 @@ class DashboardFilter(SupersetFilter):
|
|||
return query
|
||||
Slice = models.Slice # noqa
|
||||
Dash = models.Dashboard # noqa
|
||||
# TODO(bogdan): add `schema_access` support here
|
||||
datasource_perms = self.get_view_menus('datasource_access')
|
||||
slice_ids_qry = (
|
||||
db.session
|
||||
|
@ -304,6 +299,7 @@ class DashboardFilter(SupersetFilter):
|
|||
)
|
||||
return query
|
||||
|
||||
|
||||
def validate_json(form, field): # noqa
|
||||
try:
|
||||
json.loads(field.data)
|
||||
|
@ -622,7 +618,6 @@ appbuilder.add_view(
|
|||
|
||||
|
||||
class DatabaseAsync(DatabaseView):
|
||||
base_filters = [['id', DatabaseFilter, lambda: []]]
|
||||
list_columns = [
|
||||
'id', 'database_name',
|
||||
'expose_in_sqllab', 'allow_ctas', 'force_ctas_schema',
|
||||
|
@ -1695,10 +1690,11 @@ class Superset(BaseSupersetView):
|
|||
.filter_by(id=db_id)
|
||||
.one()
|
||||
)
|
||||
payload = {
|
||||
'tables': database.all_table_names(schema),
|
||||
'views': database.all_view_names(schema),
|
||||
}
|
||||
tables = [t for t in database.all_table_names(schema) if
|
||||
self.datasource_access_by_name(database, t, schema=schema)]
|
||||
views = [v for v in database.all_table_names(schema) if
|
||||
self.datasource_access_by_name(database, v, schema=schema)]
|
||||
payload = {'tables': tables, 'views': views}
|
||||
return Response(
|
||||
json.dumps(payload), mimetype="application/json")
|
||||
|
||||
|
@ -2397,7 +2393,7 @@ class Superset(BaseSupersetView):
|
|||
t for t in superset_query.tables if not
|
||||
table_accessible(mydb, t, schema_name=schema)]
|
||||
if rejected_tables:
|
||||
json_error_response(
|
||||
return json_error_response(
|
||||
get_datasource_access_error_msg('{}'.format(rejected_tables)))
|
||||
session.commit()
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import unittest
|
|||
|
||||
from flask_appbuilder.security.sqla import models as ab_models
|
||||
|
||||
from superset import app, cli, db, models, appbuilder, sm
|
||||
from superset import app, cli, db, models, appbuilder, security, sm
|
||||
from superset.security import sync_role_definitions
|
||||
|
||||
os.environ['SUPERSET_CONFIG'] = 'tests.superset_test_config'
|
||||
|
@ -43,6 +43,11 @@ class SupersetTestCase(unittest.TestCase):
|
|||
gamma_sqllab = sm.add_role("gamma_sqllab")
|
||||
for perm in sm.find_role('Gamma').permissions:
|
||||
sm.add_permission_role(gamma_sqllab, perm)
|
||||
db_perm = self.get_main_database(sm.get_session).perm
|
||||
security.merge_perm(sm, 'database_access', db_perm)
|
||||
db_pvm = sm.find_permission_view_menu(
|
||||
view_menu_name=db_perm, permission_name='database_access')
|
||||
gamma_sqllab.permissions.append(db_pvm)
|
||||
for perm in sm.find_role('sql_lab').permissions:
|
||||
sm.add_permission_role(gamma_sqllab, perm)
|
||||
|
||||
|
@ -73,6 +78,7 @@ class SupersetTestCase(unittest.TestCase):
|
|||
'alpha', 'alpha', 'user', 'alpha@fab.org',
|
||||
appbuilder.sm.find_role('Alpha'),
|
||||
password='general')
|
||||
sm.get_session.commit()
|
||||
|
||||
# create druid cluster and druid datasources
|
||||
session = db.session
|
||||
|
|
|
@ -9,7 +9,7 @@ import json
|
|||
import unittest
|
||||
|
||||
from flask_appbuilder.security.sqla import models as ab_models
|
||||
from superset import db, models, utils, appbuilder, sm
|
||||
from superset import db, models, utils, appbuilder, security, sm
|
||||
from .base_tests import SupersetTestCase
|
||||
|
||||
|
||||
|
@ -18,6 +18,8 @@ class SqlLabTests(SupersetTestCase):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SqlLabTests, self).__init__(*args, **kwargs)
|
||||
gamma_sqllab = appbuilder.sm.find_role('gamma_sqllab')
|
||||
security.merge_perm(sm, 'database_access', self.get_main_database(db.session).perm)
|
||||
|
||||
def run_some_queries(self):
|
||||
self.logout()
|
||||
|
@ -93,15 +95,15 @@ class SqlLabTests(SupersetTestCase):
|
|||
self.assertEquals(2, len(data))
|
||||
|
||||
# Run 2 more queries
|
||||
self.run_sql("SELECT * FROM ab_user1", client_id='client_id_4')
|
||||
self.run_sql("SELECT * FROM ab_user2", client_id='client_id_5')
|
||||
self.run_sql("SELECT * FROM ab_user LIMIT 1", client_id='client_id_4')
|
||||
self.run_sql("SELECT * FROM ab_user LIMIT 2", client_id='client_id_5')
|
||||
self.login('admin')
|
||||
data = self.get_json_resp('/superset/queries/0')
|
||||
self.assertEquals(4, len(data))
|
||||
|
||||
now = datetime.now() + timedelta(days=1)
|
||||
query = db.session.query(models.Query).filter_by(
|
||||
sql='SELECT * FROM ab_user1').first()
|
||||
sql='SELECT * FROM ab_user LIMIT 1').first()
|
||||
query.changed_on = now
|
||||
db.session.commit()
|
||||
|
||||
|
@ -140,7 +142,8 @@ class SqlLabTests(SupersetTestCase):
|
|||
self.assertEquals(set([user.id]), user_ids)
|
||||
|
||||
user = appbuilder.sm.find_user('gamma_sqllab')
|
||||
resp = self.get_resp('/superset/search_queries?user_id={}'.format(user.id))
|
||||
resp = self.get_resp(
|
||||
'/superset/search_queries?user_id={}'.format(user.id))
|
||||
data = json.loads(resp)
|
||||
self.assertEquals(1, len(data))
|
||||
self.assertEquals(list(data.values())[0]['userId'] , user.id)
|
||||
|
|
Loading…
Reference in New Issue