mirror of
https://github.com/apache/superset.git
synced 2026-04-27 03:55:47 +00:00
[security] improving the security scheme (#1587)
* [security] improving the security scheme * Addressing comments * improving docs * Creating security module to organize things * Moving CLI to its own module * perms * Materializung perms * progrss * Addressing comments, linting
This commit is contained in:
committed by
GitHub
parent
aad9744d85
commit
bce02e3f51
@@ -20,7 +20,6 @@ import parsedatetime
|
||||
import sqlalchemy as sa
|
||||
from dateutil.parser import parse
|
||||
from flask import flash, Markup
|
||||
from flask_appbuilder.security.sqla import models as ab_models
|
||||
import markdown as md
|
||||
from sqlalchemy.types import TypeDecorator, TEXT
|
||||
from pydruid.utils.having import Having
|
||||
@@ -109,23 +108,6 @@ class memoized(object): # noqa
|
||||
return functools.partial(self.__call__, obj)
|
||||
|
||||
|
||||
def get_or_create_main_db(superset):
|
||||
db = superset.db
|
||||
config = superset.app.config
|
||||
DB = superset.models.Database
|
||||
logging.info("Creating database reference")
|
||||
dbobj = db.session.query(DB).filter_by(database_name='main').first()
|
||||
if not dbobj:
|
||||
dbobj = DB(database_name="main")
|
||||
logging.info(config.get("SQLALCHEMY_DATABASE_URI"))
|
||||
dbobj.set_sqlalchemy_uri(config.get("SQLALCHEMY_DATABASE_URI"))
|
||||
dbobj.expose_in_sqllab = True
|
||||
dbobj.allow_run_sync = True
|
||||
db.session.add(dbobj)
|
||||
db.session.commit()
|
||||
return dbobj
|
||||
|
||||
|
||||
class DimSelector(Having):
|
||||
def __init__(self, **args):
|
||||
# Just a hack to prevent any exceptions
|
||||
@@ -185,12 +167,6 @@ def dttm_from_timtuple(d):
|
||||
d.tm_year, d.tm_mon, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec)
|
||||
|
||||
|
||||
def merge_perm(sm, permission_name, view_menu_name):
|
||||
pv = sm.find_permission_view_menu(permission_name, view_menu_name)
|
||||
if not pv:
|
||||
sm.add_permission_view_menu(permission_name, view_menu_name)
|
||||
|
||||
|
||||
def parse_human_timedelta(s):
|
||||
"""
|
||||
Returns ``datetime.datetime`` from natural language time deltas
|
||||
@@ -224,113 +200,6 @@ class JSONEncodedDict(TypeDecorator):
|
||||
return value
|
||||
|
||||
|
||||
def init(superset):
|
||||
"""Inits the Superset application with security roles and such"""
|
||||
ADMIN_ONLY_VIEW_MENUES = set([
|
||||
'ResetPasswordView',
|
||||
'RoleModelView',
|
||||
'Security',
|
||||
'UserDBModelView',
|
||||
'SQL Lab',
|
||||
'AccessRequestsModelView',
|
||||
'Manage',
|
||||
])
|
||||
|
||||
ADMIN_ONLY_PERMISSIONS = set([
|
||||
'can_sync_druid_source',
|
||||
'can_override_role_permissions',
|
||||
'can_approve',
|
||||
])
|
||||
|
||||
ALPHA_ONLY_PERMISSIONS = set([
|
||||
'all_datasource_access',
|
||||
'can_add',
|
||||
'can_download',
|
||||
'can_delete',
|
||||
'can_edit',
|
||||
'can_save',
|
||||
'datasource_access',
|
||||
'database_access',
|
||||
'muldelete',
|
||||
])
|
||||
|
||||
db = superset.db
|
||||
models = superset.models
|
||||
config = superset.app.config
|
||||
sm = superset.appbuilder.sm
|
||||
alpha = sm.add_role("Alpha")
|
||||
admin = sm.add_role("Admin")
|
||||
get_or_create_main_db(superset)
|
||||
|
||||
merge_perm(sm, 'all_datasource_access', 'all_datasource_access')
|
||||
|
||||
perms = db.session.query(ab_models.PermissionView).all()
|
||||
# set alpha and admin permissions
|
||||
for perm in perms:
|
||||
if (
|
||||
perm.permission and
|
||||
perm.permission.name in ('datasource_access', 'database_access')):
|
||||
continue
|
||||
if (
|
||||
perm.view_menu and
|
||||
perm.view_menu.name not in ADMIN_ONLY_VIEW_MENUES and
|
||||
perm.permission and
|
||||
perm.permission.name not in ADMIN_ONLY_PERMISSIONS):
|
||||
|
||||
sm.add_permission_role(alpha, perm)
|
||||
sm.add_permission_role(admin, perm)
|
||||
|
||||
gamma = sm.add_role("Gamma")
|
||||
public_role = sm.find_role("Public")
|
||||
public_role_like_gamma = \
|
||||
public_role and config.get('PUBLIC_ROLE_LIKE_GAMMA', False)
|
||||
|
||||
# set gamma permissions
|
||||
for perm in perms:
|
||||
if (
|
||||
perm.view_menu and
|
||||
perm.view_menu.name not in ADMIN_ONLY_VIEW_MENUES and
|
||||
perm.permission and
|
||||
perm.permission.name not in ADMIN_ONLY_PERMISSIONS and
|
||||
perm.permission.name not in ALPHA_ONLY_PERMISSIONS):
|
||||
sm.add_permission_role(gamma, perm)
|
||||
if public_role_like_gamma:
|
||||
sm.add_permission_role(public_role, perm)
|
||||
session = db.session()
|
||||
table_perms = [
|
||||
table.perm for table in session.query(models.SqlaTable).all()]
|
||||
table_perms += [
|
||||
table.perm for table in session.query(models.DruidDatasource).all()]
|
||||
for table_perm in table_perms:
|
||||
merge_perm(sm, 'datasource_access', table_perm)
|
||||
|
||||
db_perms = [db.perm for db in session.query(models.Database).all()]
|
||||
for db_perm in db_perms:
|
||||
merge_perm(sm, 'database_access', db_perm)
|
||||
init_metrics_perm(superset)
|
||||
|
||||
|
||||
def init_metrics_perm(superset, metrics=None):
|
||||
"""Create permissions for restricted metrics
|
||||
|
||||
:param metrics: a list of metrics to be processed, if not specified,
|
||||
all metrics are processed
|
||||
:type metrics: models.SqlMetric or models.DruidMetric
|
||||
"""
|
||||
db = superset.db
|
||||
models = superset.models
|
||||
sm = superset.appbuilder.sm
|
||||
|
||||
if not metrics:
|
||||
metrics = []
|
||||
for model in [models.SqlMetric, models.DruidMetric]:
|
||||
metrics += list(db.session.query(model).all())
|
||||
|
||||
for metric in metrics:
|
||||
if metric.is_restricted and metric.perm:
|
||||
merge_perm(sm, 'metric_access', metric.perm)
|
||||
|
||||
|
||||
def datetime_f(dttm):
|
||||
"""Formats datetime to take less room when it is recent"""
|
||||
if dttm:
|
||||
|
||||
Reference in New Issue
Block a user