diff --git a/superset/common/query_context.py b/superset/common/query_context.py index 7cd00fceb1..7cb82a43c0 100644 --- a/superset/common/query_context.py +++ b/superset/common/query_context.py @@ -196,6 +196,7 @@ class QueryContext: extra_cache_keys=extra_cache_keys, rls=security_manager.get_rls_ids(self.datasource) if config["ENABLE_ROW_LEVEL_SECURITY"] + and self.datasource.is_rls_supported else [], changed_on=self.datasource.changed_on, **kwargs diff --git a/superset/connectors/base/models.py b/superset/connectors/base/models.py index eb0d3e234a..5ba28e8c6f 100644 --- a/superset/connectors/base/models.py +++ b/superset/connectors/base/models.py @@ -84,6 +84,9 @@ class BaseDatasource( # Used to do code highlighting when displaying the query in the UI query_language: Optional[str] = None + # Only some datasources support Row Level Security + is_rls_supported: bool = False + @property def name(self) -> str: # can be a Column or a property pointing to one diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 9fb6e4f7c6..be6df5219e 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -16,7 +16,6 @@ # under the License. # pylint: disable=C,R,W import logging -import re from collections import OrderedDict from datetime import datetime, timedelta from typing import Any, Dict, Hashable, List, NamedTuple, Optional, Tuple, Union @@ -394,6 +393,7 @@ class SqlaTable(Model, BaseDatasource): type = "table" query_language = "sql" + is_rls_supported = True metric_class = SqlMetric column_class = TableColumn owner_class = security_manager.user_model diff --git a/superset/views/annotations.py b/superset/views/annotations.py index 84428770d3..a8c26c7c00 100644 --- a/superset/views/annotations.py +++ b/superset/views/annotations.py @@ -103,7 +103,7 @@ class AnnotationLayerModelView(SupersetModelView): # pylint: disable=too-many-a add_title = _("Add Annotation Layer") edit_title = _("Edit Annotation Layer") - list_columns = ["name", "descr"] + list_columns = ["id", "name", "descr"] edit_columns = ["name", "descr"] add_columns = edit_columns diff --git a/superset/viz.py b/superset/viz.py index a8b1abc251..93e840cbf7 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -43,10 +43,9 @@ from dateutil import relativedelta as rdelta from flask import request from flask_babel import lazy_gettext as _ from geopy.point import Point -from markdown import markdown from pandas.tseries.frequencies import to_offset -from superset import app, cache, get_manifest_files, security_manager +from superset import app, cache, security_manager from superset.constants import NULL_STRING from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.exceptions import ( @@ -405,7 +404,7 @@ class BaseViz: cache_dict["extra_cache_keys"] = self.datasource.get_extra_cache_keys(query_obj) cache_dict["rls"] = ( security_manager.get_rls_ids(self.datasource) - if config["ENABLE_ROW_LEVEL_SECURITY"] + if config["ENABLE_ROW_LEVEL_SECURITY"] and self.datasource.is_rls_supported else [] ) cache_dict["changed_on"] = self.datasource.changed_on diff --git a/tests/core_tests.py b/tests/core_tests.py index 7ea85c7320..4e43d49d0c 100644 --- a/tests/core_tests.py +++ b/tests/core_tests.py @@ -177,12 +177,18 @@ class CoreTests(SupersetTestCase): db.session.add(annotation) db.session.commit() - resp = self.get_resp( + resp_annotations = json.loads( + self.get_resp("annotationlayermodelview/api/read") + ) + # the UI needs id and name to function + self.assertIn("id", resp_annotations["result"][0]) + self.assertIn("name", resp_annotations["result"][0]) + + layer = self.get_resp( f"/superset/annotation_json/{layer.id}?form_data=" + quote(json.dumps({"time_range": "100 years ago : now"})) ) - - assert "my_annotation" in resp + self.assertIn("my_annotation", layer) def test_admin_only_permissions(self): def assert_admin_permission_in(role_name, assert_func):