From 5d4e92b6c5751b66a2490515f6d8a33516448512 Mon Sep 17 00:00:00 2001 From: Nick Misasi Date: Tue, 7 May 2024 13:36:07 -0400 Subject: [PATCH] [CLD-7549] Expose System Console UI for ExperimentalAuditSettings (#26840) * Expose experimental audit log settings to sys console * Add the rest of the config * Add check for enterprise sku * Update string to include a note about being required given another setting * gofmt --------- Co-authored-by: Mattermost Build --- server/public/model/config.go | 2 +- server/public/model/feature_flags.go | 3 + .../admin_console/admin_definition.tsx | 107 ++++++++++++++++++ webapp/channels/src/i18n/en.json | 15 +++ 4 files changed, 126 insertions(+), 1 deletion(-) diff --git a/server/public/model/config.go b/server/public/model/config.go index 61e01ec570..df27045548 100644 --- a/server/public/model/config.go +++ b/server/public/model/config.go @@ -1400,7 +1400,7 @@ type ExperimentalAuditSettings struct { FileMaxBackups *int `access:"experimental_features,write_restrictable,cloud_restrictable"` FileCompress *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` FileMaxQueueSize *int `access:"experimental_features,write_restrictable,cloud_restrictable"` - AdvancedLoggingJSON json.RawMessage `access:"experimental_features,write_restrictable,cloud_restrictable"` + AdvancedLoggingJSON json.RawMessage `access:"experimental_features,write_restrictable"` AdvancedLoggingConfig *string `access:"experimental_features,write_restrictable,cloud_restrictable"` // Deprecated: use `AdvancedLoggingJSON` } diff --git a/server/public/model/feature_flags.go b/server/public/model/feature_flags.go index 7fc70c4f8c..faa8c34a5b 100644 --- a/server/public/model/feature_flags.go +++ b/server/public/model/feature_flags.go @@ -56,6 +56,8 @@ type FeatureFlags struct { NotificationMonitoring bool + ExperimentalAuditSettingsSystemConsoleUI bool + ClientMetrics bool } @@ -80,6 +82,7 @@ func (f *FeatureFlags) SetDefaults() { f.ChannelBookmarks = false f.WebSocketEventScope = false f.NotificationMonitoring = true + f.ExperimentalAuditSettingsSystemConsoleUI = false f.ClientMetrics = false } diff --git a/webapp/channels/src/components/admin_console/admin_definition.tsx b/webapp/channels/src/components/admin_console/admin_definition.tsx index a5706460a1..8ef006f27c 100644 --- a/webapp/channels/src/components/admin_console/admin_definition.tsx +++ b/webapp/channels/src/components/admin_console/admin_definition.tsx @@ -6264,6 +6264,113 @@ const AdminDefinition: AdminDefinitionType = { component: BleveSettings, }, }, + audit_logging: { + url: 'experimental/audit_logging', + title: defineMessage({id: 'admin.sidebar.audit_logging_experimental', defaultMessage: 'Audit Logging'}), + isHidden: it.any(it.not(it.userHasReadPermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), it.configIsFalse('FeatureFlags', 'ExperimentalAuditSettingsSystemConsoleUI'), it.not(it.licensedForSku('enterprise'))), + schema: { + id: 'ExperimentalAuditSettings', + name: 'Audit Log Settings (Experimental)', + settings: [ + { + type: 'bool', + key: 'ExperimentalAuditSettings.FileEnabled', + label: defineMessage({id: 'admin.audit_logging_experimental.file_enabled.title', defaultMessage: 'File Enabled'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_enabled.help_text', defaultMessage: 'Choose whether audit logs are written locally to a file or not.'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'text', + key: 'ExperimentalAuditSettings.FileName', + label: defineMessage({id: 'admin.audit_logging_experimental.file_name.title', defaultMessage: 'File Name'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_name.help_text', defaultMessage: 'The name of the file to write to. NOTE: If ExperimentalAuditSettings.FileEnabled is set to TRUE, this field is required.'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'number', + key: 'ExperimentalAuditSettings.FileMaxSizeMB', + label: defineMessage({id: 'admin.audit_logging_experimental.file_max_size.title', defaultMessage: 'Max File Size (MB)'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_max_size.help_text', defaultMessage: 'The maximum size of a single exported file, in MB.'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'number', + key: 'ExperimentalAuditSettings.FileMaxAgeDays', + label: defineMessage({id: 'admin.audit_logging_experimental.file_max_age.title', defaultMessage: 'Max File Age (Days)'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_max_age.help_text', defaultMessage: 'The maximum age of an exported file, in days.'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'number', + key: 'ExperimentalAuditSettings.FileMaxBackups', + label: defineMessage({id: 'admin.audit_logging_experimental.file_max_backups.title', defaultMessage: 'Maximum File Backups'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_max_backups.help_text', defaultMessage: 'The maximum number of backup files to retain'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'bool', + key: 'ExperimentalAuditSettings.FileCompress', + label: defineMessage({id: 'admin.audit_logging_experimental.file_compress.title', defaultMessage: 'File Compression'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_compress.help_text', defaultMessage: 'Choose whether enable or disable file compression.'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'number', + key: 'ExperimentalAuditSettings.FileMaxQueueSize', + label: defineMessage({id: 'admin.audit_logging_experimental.file_max_queue_size.title', defaultMessage: 'Maximum File Queue'}), + help_text: defineMessage({id: 'admin.audit_logging_experimental.file_max_queue_size.help_text', defaultMessage: 'The maximum number of files to be retained in the queue.'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + isHidden: it.licensedForFeature('Cloud'), + }, + { + type: 'longtext', + key: 'ExperimentalAuditSettings.AdvancedLoggingJSON', + label: defineMessage({id: 'admin.log.AdvancedLoggingJSONTitle', defaultMessage: 'Advanced Logging:'}), + help_text: defineMessage({id: 'admin.log.AdvancedLoggingJSONDescription', defaultMessage: 'The JSON configuration for Advanced Audit Logging. Please see documentation to learn more about Advanced Logging and the JSON format it uses.'}), + help_text_markdown: false, + help_text_values: { + link: (msg: string) => ( + + {msg} + + ), + }, + placeholder: defineMessage({id: 'admin.log.AdvancedLoggingJSONPlaceholder', defaultMessage: 'Enter your JSON configuration'}), + isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), + validate: (value) => { + const valid = new ValidationResult(true, ''); + if (!value) { + return valid; + } + try { + JSON.parse(value); + return valid; + } catch (error) { + return new ValidationResult(false, error.message); + } + }, + onConfigLoad: (configVal) => JSON.stringify(configVal, null, ' '), + onConfigSave: (displayVal) => { + // Handle case where field is empty + if (!displayVal) { + return {undefined}; + } + + return JSON.parse(displayVal); + }, + }, + ], + }, + }, }, }, }; diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 0c8716e4d2..af26d9afa4 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -256,6 +256,20 @@ "admin.advance.metrics": "Performance Monitoring", "admin.announcement_banner_feature_discovery.copy": "Create announcement banners to notify all members of important information.", "admin.announcement_banner_feature_discovery.title": "Create custom announcement banners with Mattermost Professional", + "admin.audit_logging_experimental.file_compress.help_text": "Choose whether enable or disable file compression.", + "admin.audit_logging_experimental.file_compress.title": "File Compression", + "admin.audit_logging_experimental.file_enabled.help_text": "Choose whether audit logs are written locally to a file or not.", + "admin.audit_logging_experimental.file_enabled.title": "File Enabled", + "admin.audit_logging_experimental.file_max_age.help_text": "The maximum age of an exported file, in days.", + "admin.audit_logging_experimental.file_max_age.title": "Max File Age (Days)", + "admin.audit_logging_experimental.file_max_backups.help_text": "The maximum number of backup files to retain", + "admin.audit_logging_experimental.file_max_backups.title": "Maximum File Backups", + "admin.audit_logging_experimental.file_max_queue_size.help_text": "The maximum number of files to be retained in the queue.", + "admin.audit_logging_experimental.file_max_queue_size.title": "Maximum File Queue", + "admin.audit_logging_experimental.file_max_size.help_text": "The maximum size of a single exported file, in MB.", + "admin.audit_logging_experimental.file_max_size.title": "Max File Size (MB)", + "admin.audit_logging_experimental.file_name.help_text": "The name of the file to write to. NOTE: If ExperimentalAuditSettings.FileEnabled is set to TRUE, this field is required.", + "admin.audit_logging_experimental.file_name.title": "File Name", "admin.audits.reload": "Reload User Activity Logs", "admin.authentication.email": "Email Authentication", "admin.authentication.gitlab": "GitLab", @@ -2290,6 +2304,7 @@ "admin.set_by_env": "This setting has been set through an environment variable. It cannot be changed through the System Console.", "admin.sidebar.about": "About", "admin.sidebar.announcement": "Announcement Banner", + "admin.sidebar.audit_logging_experimental": "Audit Logging", "admin.sidebar.authentication": "Authentication", "admin.sidebar.billing": "Billing & Account", "admin.sidebar.billing_history": "Billing History",