Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement has_access decorator. #2028

Merged
merged 1 commit into from
Jan 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this? seems like it could bite us in the future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mistercrunch - I just copied existing implementation:
https://github.com/dpgaspar/Flask-AppBuilder/blob/af095ac4094d068fa2dd467bd01fa8b95d697fc1/flask_appbuilder/security/decorators.py#L5

I plan to create another PR to path FAB is possible, there is a TODO for it.

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 @@ -21,7 +21,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 @@ -38,6 +38,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