Skip to content

Commit

Permalink
Reimplement has_access. (#2028)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkyryliuk authored Jan 26, 2017
1 parent a8c29c4 commit 1ac2273
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
40 changes: 39 additions & 1 deletion superset/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.utils import formatdate
from flask import flash, Markup, render_template
from flask import flash, Markup, render_template, url_for, redirect, request
from flask_appbuilder.const import (
LOGMSG_ERR_SEC_ACCESS_DENIED,
FLAMSG_ERR_SEC_ACCESS_DENIED,
PERMISSION_PREFIX
)
from flask_appbuilder._compat import as_unicode
from flask_babel import gettext as __
from past.builtins import basestring
from pydruid.utils.having import Having
Expand Down Expand Up @@ -513,3 +519,35 @@ def get_email_address_list(address_string):
else:
address_string = [address_string]
return address_string


# Forked from the flask_appbuilder.security.decorators
# TODO(bkyryliuk): contribute it back to FAB
def has_access(f):
"""
Use this decorator to enable granular security permissions to your
methods. Permissions will be associated to a role, and roles are
associated to users.
By default the permission's name is the methods name.
"""
if hasattr(f, '_permission_name'):
permission_str = f._permission_name
else:
permission_str = f.__name__

def wraps(self, *args, **kwargs):
permission_str = PERMISSION_PREFIX + f._permission_name
if self.appbuilder.sm.has_access(
permission_str, self.__class__.__name__):
return f(self, *args, **kwargs)
else:
logging.warning(LOGMSG_ERR_SEC_ACCESS_DENIED.format(
permission_str, self.__class__.__name__))
flash(as_unicode(FLAMSG_ERR_SEC_ACCESS_DENIED), "danger")
# adds next arg to forward to the original path once user is logged in.
return redirect(url_for(
self.appbuilder.sm.auth_view.__class__.__name__ + ".login",
next=request.path))
f._permission_name = permission_str
return functools.update_wrapper(wraps, f)
3 changes: 2 additions & 1 deletion superset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from flask_appbuilder import ModelView, CompactCRUDMixin, BaseView, expose
from flask_appbuilder.actions import action
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder.security.decorators import has_access, has_access_api
from flask_appbuilder.security.decorators import has_access_api
from flask_appbuilder.widgets import ListWidget
from flask_appbuilder.models.sqla.filters import BaseFilter
from flask_appbuilder.security.sqla import models as ab_models
Expand All @@ -39,6 +39,7 @@
app, appbuilder, cache, db, models, sm, sql_lab, sql_parse,
results_backend, security, viz, utils,
)
from superset.utils import has_access
from superset.source_registry import SourceRegistry
from superset.models import DatasourceAccessRequest as DAR
from superset.sql_parse import SupersetQuery
Expand Down

0 comments on commit 1ac2273

Please sign in to comment.