Skip to content

Commit 5901320

Browse files
feat(database): Adding per-user caching option in Security tab (#34842)
1 parent 23bb4f8 commit 5901320

File tree

4 files changed

+71
-42
lines changed

4 files changed

+71
-42
lines changed

superset-frontend/src/features/databases/DatabaseModal/ExtraOptions.tsx

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -460,48 +460,26 @@ const ExtraOptions = ({
460460
),
461461
children: (
462462
<>
463-
<StyledInputContainer>
464-
<div className="control-label">{t('Secure extra')}</div>
463+
<StyledInputContainer
464+
css={!isFileUploadSupportedByEngine ? no_margin_bottom : {}}
465+
>
465466
<div className="input-container">
466-
<StyledJsonEditor
467-
name="masked_encrypted_extra"
468-
value={db?.masked_encrypted_extra || ''}
469-
placeholder={t('Secure extra')}
470-
onChange={(json: string) =>
471-
onEditorChange({ json, name: 'masked_encrypted_extra' })
472-
}
473-
width="100%"
474-
height="160px"
475-
annotations={secureExtraAnnotations}
476-
/>
477-
</div>
478-
<div className="helper">
479-
<div>
480-
{t(
481-
'JSON string containing additional connection configuration. ' +
482-
'This is used to provide connection information for systems ' +
483-
'like Hive, Presto and BigQuery which do not conform to the ' +
484-
'username:password syntax normally used by SQLAlchemy.',
467+
<Checkbox
468+
id="per_user_caching"
469+
name="per_user_caching"
470+
indeterminate={false}
471+
checked={!!extraJson?.per_user_caching}
472+
onChange={onExtraInputChange}
473+
>
474+
{t('Per user caching')}
475+
</Checkbox>
476+
<InfoTooltip
477+
tooltip={t(
478+
'Cache data separately for each user based on their data access roles and permissions. ' +
479+
'When disabled, a single cache will be used for all users.',
485480
)}
486-
</div>
487-
</div>
488-
</StyledInputContainer>
489-
<StyledInputContainer>
490-
<div className="control-label">{t('Root certificate')}</div>
491-
<div className="input-container">
492-
<Input.TextArea
493-
name="server_cert"
494-
value={db?.server_cert || ''}
495-
placeholder={t('Enter CA_BUNDLE')}
496-
onChange={onTextChange}
497481
/>
498482
</div>
499-
<div className="helper">
500-
{t(
501-
'Optional CA_BUNDLE contents to validate HTTPS requests. Only ' +
502-
'available on certain database engines.',
503-
)}
504-
</div>
505483
</StyledInputContainer>
506484
<StyledInputContainer
507485
css={!isFileUploadSupportedByEngine ? no_margin_bottom : {}}
@@ -569,6 +547,49 @@ const ExtraOptions = ({
569547
</div>
570548
</StyledInputContainer>
571549
)}
550+
<StyledInputContainer>
551+
<div className="control-label">{t('Secure extra')}</div>
552+
<div className="input-container">
553+
<StyledJsonEditor
554+
name="masked_encrypted_extra"
555+
value={db?.masked_encrypted_extra || ''}
556+
placeholder={t('Secure extra')}
557+
onChange={(json: string) =>
558+
onEditorChange({ json, name: 'masked_encrypted_extra' })
559+
}
560+
width="100%"
561+
height="160px"
562+
annotations={secureExtraAnnotations}
563+
/>
564+
</div>
565+
<div className="helper">
566+
<div>
567+
{t(
568+
'JSON string containing additional connection configuration. ' +
569+
'This is used to provide connection information for systems ' +
570+
'like Hive, Presto and BigQuery which do not conform to the ' +
571+
'username:password syntax normally used by SQLAlchemy.',
572+
)}
573+
</div>
574+
</div>
575+
</StyledInputContainer>
576+
<StyledInputContainer>
577+
<div className="control-label">{t('Root certificate')}</div>
578+
<div className="input-container">
579+
<Input.TextArea
580+
name="server_cert"
581+
value={db?.server_cert || ''}
582+
placeholder={t('Enter CA_BUNDLE')}
583+
onChange={onTextChange}
584+
/>
585+
</div>
586+
<div className="helper">
587+
{t(
588+
'Optional CA_BUNDLE contents to validate HTTPS requests. Only ' +
589+
'available on certain database engines.',
590+
)}
591+
</div>
592+
</StyledInputContainer>
572593
</>
573594
),
574595
},

superset-frontend/src/features/databases/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ export interface ExtraJson {
246246
disable_data_preview?: boolean; // in SQL Lab
247247
disable_drill_to_detail?: boolean;
248248
allow_multi_catalog?: boolean;
249+
per_user_caching?: boolean; // in Security
249250
engine_params?: {
250251
catalog?: Record<string, string>;
251252
connect_args?: {

superset/common/query_object.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,19 @@ def cache_key(self, **extra: Any) -> str: # noqa: C901
454454
cache_dict["annotation_layers"] = annotation_layers
455455

456456
# Add an impersonation key to cache if impersonation is enabled on the db
457-
# or if the CACHE_QUERY_BY_USER flag is on
457+
# or if the CACHE_QUERY_BY_USER flag is on or per_user_caching is enabled on
458+
# the database
458459
try:
459460
database = self.datasource.database # type: ignore
461+
extra = json.loads(database.extra or "{}")
460462
if (
461-
feature_flag_manager.is_feature_enabled("CACHE_IMPERSONATION")
462-
and database.impersonate_user
463-
) or feature_flag_manager.is_feature_enabled("CACHE_QUERY_BY_USER"):
463+
(
464+
feature_flag_manager.is_feature_enabled("CACHE_IMPERSONATION")
465+
and database.impersonate_user
466+
)
467+
or feature_flag_manager.is_feature_enabled("CACHE_QUERY_BY_USER")
468+
or extra.get("per_user_caching", False)
469+
):
464470
if key := database.db_engine_spec.get_impersonation_key(
465471
getattr(g, "user", None)
466472
):

superset/databases/schemas.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ def fix_schemas_allowed_for_csv_upload( # pylint: disable=invalid-name
831831
disable_data_preview = fields.Boolean(required=False)
832832
disable_drill_to_detail = fields.Boolean(required=False)
833833
allow_multi_catalog = fields.Boolean(required=False)
834+
per_user_caching = fields.Boolean(required=False)
834835
version = fields.String(required=False, allow_none=True)
835836
schema_options = fields.Dict(keys=fields.Str(), values=fields.Raw())
836837

0 commit comments

Comments
 (0)