[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:
Maxime Beauchemin
2016-11-17 11:58:33 -08:00
committed by GitHub
parent aad9744d85
commit bce02e3f51
19 changed files with 765 additions and 543 deletions

View File

@@ -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: