diff --git a/superset-frontend/src/features/databases/DatabaseModal/ExtraOptions.tsx b/superset-frontend/src/features/databases/DatabaseModal/ExtraOptions.tsx index 33d8d2d904e..48cdccdb55e 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/ExtraOptions.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/ExtraOptions.tsx @@ -460,48 +460,26 @@ const ExtraOptions = ({ ), children: ( <> - -
{t('Secure extra')}
+
- - onEditorChange({ json, name: 'masked_encrypted_extra' }) - } - width="100%" - height="160px" - annotations={secureExtraAnnotations} - /> -
-
-
- {t( - 'JSON string containing additional connection configuration. ' + - 'This is used to provide connection information for systems ' + - 'like Hive, Presto and BigQuery which do not conform to the ' + - 'username:password syntax normally used by SQLAlchemy.', + + {t('Per user caching')} + + -
- - -
{t('Root certificate')}
-
-
-
- {t( - 'Optional CA_BUNDLE contents to validate HTTPS requests. Only ' + - 'available on certain database engines.', - )} -
)} + +
{t('Secure extra')}
+
+ + onEditorChange({ json, name: 'masked_encrypted_extra' }) + } + width="100%" + height="160px" + annotations={secureExtraAnnotations} + /> +
+
+
+ {t( + 'JSON string containing additional connection configuration. ' + + 'This is used to provide connection information for systems ' + + 'like Hive, Presto and BigQuery which do not conform to the ' + + 'username:password syntax normally used by SQLAlchemy.', + )} +
+
+
+ +
{t('Root certificate')}
+
+ +
+
+ {t( + 'Optional CA_BUNDLE contents to validate HTTPS requests. Only ' + + 'available on certain database engines.', + )} +
+
), }, diff --git a/superset-frontend/src/features/databases/types.ts b/superset-frontend/src/features/databases/types.ts index 96f0db390da..57c76c987e7 100644 --- a/superset-frontend/src/features/databases/types.ts +++ b/superset-frontend/src/features/databases/types.ts @@ -246,6 +246,7 @@ export interface ExtraJson { disable_data_preview?: boolean; // in SQL Lab disable_drill_to_detail?: boolean; allow_multi_catalog?: boolean; + per_user_caching?: boolean; // in Security engine_params?: { catalog?: Record; connect_args?: { diff --git a/superset/common/query_object.py b/superset/common/query_object.py index 188aeaae0c7..0740ca889da 100644 --- a/superset/common/query_object.py +++ b/superset/common/query_object.py @@ -454,13 +454,19 @@ class QueryObject: # pylint: disable=too-many-instance-attributes cache_dict["annotation_layers"] = annotation_layers # Add an impersonation key to cache if impersonation is enabled on the db - # or if the CACHE_QUERY_BY_USER flag is on + # or if the CACHE_QUERY_BY_USER flag is on or per_user_caching is enabled on + # the database try: database = self.datasource.database # type: ignore + extra = json.loads(database.extra or "{}") if ( - feature_flag_manager.is_feature_enabled("CACHE_IMPERSONATION") - and database.impersonate_user - ) or feature_flag_manager.is_feature_enabled("CACHE_QUERY_BY_USER"): + ( + feature_flag_manager.is_feature_enabled("CACHE_IMPERSONATION") + and database.impersonate_user + ) + or feature_flag_manager.is_feature_enabled("CACHE_QUERY_BY_USER") + or extra.get("per_user_caching", False) + ): if key := database.db_engine_spec.get_impersonation_key( getattr(g, "user", None) ): diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py index b91dbd25d5d..ea24ba219b6 100644 --- a/superset/databases/schemas.py +++ b/superset/databases/schemas.py @@ -831,6 +831,7 @@ class ImportV1DatabaseExtraSchema(Schema): disable_data_preview = fields.Boolean(required=False) disable_drill_to_detail = fields.Boolean(required=False) allow_multi_catalog = fields.Boolean(required=False) + per_user_caching = fields.Boolean(required=False) version = fields.String(required=False, allow_none=True) schema_options = fields.Dict(keys=fields.Str(), values=fields.Raw())