chore(rls): move to feature flag and disable related view (#11575)
* chore(rls): move to feature flag and disable related view * rename feature flag
This commit is contained in:
parent
52145f8683
commit
600a6fa92a
|
|
@ -23,6 +23,8 @@ assists people when migrating to a new version.
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
|
* [11575](https://github.com/apache/incubator-superset/pull/11575) The Row Level Security (RLS) config flag has been moved to a feature flag. To migrate, add `ROW_LEVEL_SECURITY: True` to the `FEATURE_FLAGS` dict in `superset_config.py`.
|
||||||
|
|
||||||
* NOTICE: config flag ENABLE_REACT_CRUD_VIEWS has been set to `True` by default, set to `False` if
|
* NOTICE: config flag ENABLE_REACT_CRUD_VIEWS has been set to `True` by default, set to `False` if
|
||||||
you prefer to vintage look and feel :)
|
you prefer to vintage look and feel :)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ class SupersetAppInitializer:
|
||||||
category_label=__("Manage"),
|
category_label=__("Manage"),
|
||||||
category_icon="",
|
category_icon="",
|
||||||
)
|
)
|
||||||
if self.config["ENABLE_ROW_LEVEL_SECURITY"]:
|
if feature_flag_manager.is_feature_enabled("ROW_LEVEL_SECURITY"):
|
||||||
appbuilder.add_view(
|
appbuilder.add_view(
|
||||||
RowLevelSecurityFiltersModelView,
|
RowLevelSecurityFiltersModelView,
|
||||||
"Row Level Security",
|
"Row Level Security",
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from flask_babel import gettext as _
|
from flask_babel import gettext as _
|
||||||
|
|
||||||
from superset import app, cache, db, security_manager
|
from superset import app, cache, db, is_feature_enabled, security_manager
|
||||||
from superset.common.query_object import QueryObject
|
from superset.common.query_object import QueryObject
|
||||||
from superset.connectors.base.models import BaseDatasource
|
from superset.connectors.base.models import BaseDatasource
|
||||||
from superset.connectors.connector_registry import ConnectorRegistry
|
from superset.connectors.connector_registry import ConnectorRegistry
|
||||||
|
|
@ -207,7 +207,7 @@ class QueryContext:
|
||||||
datasource=self.datasource.uid,
|
datasource=self.datasource.uid,
|
||||||
extra_cache_keys=extra_cache_keys,
|
extra_cache_keys=extra_cache_keys,
|
||||||
rls=security_manager.get_rls_ids(self.datasource)
|
rls=security_manager.get_rls_ids(self.datasource)
|
||||||
if config["ENABLE_ROW_LEVEL_SECURITY"]
|
if is_feature_enabled("ROW_LEVEL_SECURITY")
|
||||||
and self.datasource.is_rls_supported
|
and self.datasource.is_rls_supported
|
||||||
else [],
|
else [],
|
||||||
changed_on=self.datasource.changed_on,
|
changed_on=self.datasource.changed_on,
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,14 @@ DEFAULT_FEATURE_FLAGS: Dict[str, bool] = {
|
||||||
"ESCAPE_MARKDOWN_HTML": False,
|
"ESCAPE_MARKDOWN_HTML": False,
|
||||||
"SIP_34_ANNOTATIONS_UI": False,
|
"SIP_34_ANNOTATIONS_UI": False,
|
||||||
"VERSIONED_EXPORT": False,
|
"VERSIONED_EXPORT": False,
|
||||||
|
# Note that: RowLevelSecurityFilter is only given by default to the Admin role
|
||||||
|
# and the Admin Role does have the all_datasources security permission.
|
||||||
|
# But, if users create a specific role with access to RowLevelSecurityFilter MVC
|
||||||
|
# and a custom datasource access, the table dropdown will not be correctly filtered
|
||||||
|
# by that custom datasource access. So we are assuming a default security config,
|
||||||
|
# a custom security config could potentially give access to setting filters on
|
||||||
|
# tables that users do not have access to.
|
||||||
|
"ROW_LEVEL_SECURITY": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set the default view to card/grid view if thumbnail support is enabled.
|
# Set the default view to card/grid view if thumbnail support is enabled.
|
||||||
|
|
@ -876,14 +884,6 @@ TALISMAN_CONFIG = {
|
||||||
"force_https_permanent": False,
|
"force_https_permanent": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Note that: RowLevelSecurityFilter is only given by default to the Admin role
|
|
||||||
# and the Admin Role does have the all_datasources security permission.
|
|
||||||
# But, if users create a specific role with access to RowLevelSecurityFilter MVC
|
|
||||||
# and a custom datasource access, the table dropdown will not be correctly filtered
|
|
||||||
# by that custom datasource access. So we are assuming a default security config,
|
|
||||||
# a custom security config could potentially give access to setting filters on
|
|
||||||
# tables that users do not have access to.
|
|
||||||
ENABLE_ROW_LEVEL_SECURITY = False
|
|
||||||
# It is possible to customize which tables and roles are featured in the RLS
|
# It is possible to customize which tables and roles are featured in the RLS
|
||||||
# dropdown. When set, this dict is assigned to `add_form_query_rel_fields` and
|
# dropdown. When set, this dict is assigned to `add_form_query_rel_fields` and
|
||||||
# `edit_form_query_rel_fields` on `RowLevelSecurityFiltersModelView`. Example:
|
# `edit_form_query_rel_fields` on `RowLevelSecurityFiltersModelView`. Example:
|
||||||
|
|
|
||||||
|
|
@ -1112,7 +1112,7 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
||||||
raise QueryObjectValidationError(
|
raise QueryObjectValidationError(
|
||||||
_("Invalid filter operation type: %(op)s", op=op)
|
_("Invalid filter operation type: %(op)s", op=op)
|
||||||
)
|
)
|
||||||
if config["ENABLE_ROW_LEVEL_SECURITY"]:
|
if is_feature_enabled("ROW_LEVEL_SECURITY"):
|
||||||
where_clause_and += self._get_sqla_row_level_filters(template_processor)
|
where_clause_and += self._get_sqla_row_level_filters(template_processor)
|
||||||
if extras:
|
if extras:
|
||||||
where = extras.get("where")
|
where = extras.get("where")
|
||||||
|
|
@ -1508,7 +1508,7 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
||||||
templatable_statements.append(extras["where"])
|
templatable_statements.append(extras["where"])
|
||||||
if "having" in extras:
|
if "having" in extras:
|
||||||
templatable_statements.append(extras["having"])
|
templatable_statements.append(extras["having"])
|
||||||
if config["ENABLE_ROW_LEVEL_SECURITY"] and self.is_rls_supported:
|
if is_feature_enabled("ROW_LEVEL_SECURITY") and self.is_rls_supported:
|
||||||
templatable_statements += [
|
templatable_statements += [
|
||||||
f.clause for f in security_manager.get_rls_filters(self)
|
f.clause for f in security_manager.get_rls_filters(self)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,6 @@ class TableModelView( # pylint: disable=too-many-ancestors
|
||||||
related_views = [
|
related_views = [
|
||||||
TableColumnInlineView,
|
TableColumnInlineView,
|
||||||
SqlMetricInlineView,
|
SqlMetricInlineView,
|
||||||
RowLevelSecurityFiltersModelView,
|
|
||||||
]
|
]
|
||||||
base_order = ("changed_on", "desc")
|
base_order = ("changed_on", "desc")
|
||||||
search_columns = ("database", "schema", "table_name", "owners", "is_sqllab_view")
|
search_columns = ("database", "schema", "table_name", "owners", "is_sqllab_view")
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,8 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
|
||||||
"RoleModelView",
|
"RoleModelView",
|
||||||
"LogModelView",
|
"LogModelView",
|
||||||
"Security",
|
"Security",
|
||||||
|
"Row Level Security",
|
||||||
|
"Row Level Security Filters",
|
||||||
"RowLevelSecurityFiltersModelView",
|
"RowLevelSecurityFiltersModelView",
|
||||||
} | USER_MODEL_VIEWS
|
} | USER_MODEL_VIEWS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ from flask_babel import lazy_gettext as _
|
||||||
from geopy.point import Point
|
from geopy.point import Point
|
||||||
from pandas.tseries.frequencies import to_offset
|
from pandas.tseries.frequencies import to_offset
|
||||||
|
|
||||||
from superset import app, cache, db, security_manager
|
from superset import app, cache, db, is_feature_enabled, security_manager
|
||||||
from superset.constants import NULL_STRING
|
from superset.constants import NULL_STRING
|
||||||
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
|
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
|
||||||
from superset.exceptions import (
|
from superset.exceptions import (
|
||||||
|
|
@ -462,7 +462,8 @@ class BaseViz:
|
||||||
cache_dict["extra_cache_keys"] = self.datasource.get_extra_cache_keys(query_obj)
|
cache_dict["extra_cache_keys"] = self.datasource.get_extra_cache_keys(query_obj)
|
||||||
cache_dict["rls"] = (
|
cache_dict["rls"] = (
|
||||||
security_manager.get_rls_ids(self.datasource)
|
security_manager.get_rls_ids(self.datasource)
|
||||||
if config["ENABLE_ROW_LEVEL_SECURITY"] and self.datasource.is_rls_supported
|
if is_feature_enabled("ROW_LEVEL_SECURITY")
|
||||||
|
and self.datasource.is_rls_supported
|
||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
cache_dict["changed_on"] = self.datasource.changed_on
|
cache_dict["changed_on"] = self.datasource.changed_on
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ class BaseViz:
|
||||||
cache_dict["extra_cache_keys"] = self.datasource.get_extra_cache_keys(query_obj)
|
cache_dict["extra_cache_keys"] = self.datasource.get_extra_cache_keys(query_obj)
|
||||||
cache_dict["rls"] = (
|
cache_dict["rls"] = (
|
||||||
security_manager.get_rls_ids(self.datasource)
|
security_manager.get_rls_ids(self.datasource)
|
||||||
if config["ENABLE_ROW_LEVEL_SECURITY"]
|
if config["ROW_LEVEL_SECURITY"]
|
||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
cache_dict["changed_on"] = self.datasource.changed_on
|
cache_dict["changed_on"] = self.datasource.changed_on
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ FEATURE_FLAGS = {
|
||||||
"SHARE_QUERIES_VIA_KV_STORE": True,
|
"SHARE_QUERIES_VIA_KV_STORE": True,
|
||||||
"ENABLE_TEMPLATE_PROCESSING": True,
|
"ENABLE_TEMPLATE_PROCESSING": True,
|
||||||
"ENABLE_REACT_CRUD_VIEWS": os.environ.get("ENABLE_REACT_CRUD_VIEWS", False),
|
"ENABLE_REACT_CRUD_VIEWS": os.environ.get("ENABLE_REACT_CRUD_VIEWS", False),
|
||||||
|
"ROW_LEVEL_SECURITY": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -73,7 +74,6 @@ FAB_ROLES = {"TestRole": [["Security", "menu_access"], ["List Users", "menu_acce
|
||||||
PUBLIC_ROLE_LIKE = "Gamma"
|
PUBLIC_ROLE_LIKE = "Gamma"
|
||||||
AUTH_ROLE_PUBLIC = "Public"
|
AUTH_ROLE_PUBLIC = "Public"
|
||||||
EMAIL_NOTIFICATIONS = False
|
EMAIL_NOTIFICATIONS = False
|
||||||
ENABLE_ROW_LEVEL_SECURITY = True
|
|
||||||
CACHE_CONFIG = {"CACHE_TYPE": "simple"}
|
CACHE_CONFIG = {"CACHE_TYPE": "simple"}
|
||||||
REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
|
REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
|
||||||
REDIS_PORT = os.environ.get("REDIS_PORT", "6379")
|
REDIS_PORT = os.environ.get("REDIS_PORT", "6379")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue