[MM-64347] Enable System Console UI for AuditSettings by default (#31118)
Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
f980a538c5
Коммит
b69412d23f
@@ -9296,6 +9296,30 @@
|
|||||||
"id": "model.config.is_valid.encrypt_sql.app_error",
|
"id": "model.config.is_valid.encrypt_sql.app_error",
|
||||||
"translation": "Invalid at rest encrypt key for SQL settings. Must be 32 chars or more."
|
"translation": "Invalid at rest encrypt key for SQL settings. Must be 32 chars or more."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.experimental_audit_settings.file_max_age_invalid",
|
||||||
|
"translation": "Max File Age of audit logs config must not be negative."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.experimental_audit_settings.file_max_backups_invalid",
|
||||||
|
"translation": "Maximum File Backups of audit logs config must not be negative."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.experimental_audit_settings.file_max_queue_size_invalid",
|
||||||
|
"translation": "Maximum File Queue of audit logs config must be greater than zero."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.experimental_audit_settings.file_max_size_invalid",
|
||||||
|
"translation": "Maximum File Size of audit logs config must be greater than zero."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.experimental_audit_settings.file_name_empty",
|
||||||
|
"translation": "When audit file logging is enabled, a file name must be specified."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.experimental_audit_settings.file_name_is_directory",
|
||||||
|
"translation": "The file name must not be a directory."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "model.config.is_valid.export.directory.app_error",
|
"id": "model.config.is_valid.export.directory.app_error",
|
||||||
"translation": "Value for Directory should not be empty."
|
"translation": "Value for Directory should not be empty."
|
||||||
|
|||||||
@@ -1568,6 +1568,47 @@ type ExperimentalAuditSettings struct {
|
|||||||
Certificate *string `access:"experimental_features"` // telemetry: none
|
Certificate *string `access:"experimental_features"` // telemetry: none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ExperimentalAuditSettings) isValid() *AppError {
|
||||||
|
if *s.FileEnabled {
|
||||||
|
if *s.FileName == "" {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.experimental_audit_settings.file_name_empty", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(*s.FileName, `\`) {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.experimental_audit_settings.file_name_is_directory", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *s.FileMaxSizeMB <= 0 {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.experimental_audit_settings.file_max_size_invalid", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *s.FileMaxAgeDays < 0 {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.experimental_audit_settings.file_max_age_invalid", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *s.FileMaxBackups < 0 {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.experimental_audit_settings.file_max_backups_invalid", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *s.FileMaxQueueSize <= 0 {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.experimental_audit_settings.file_max_queue_size_invalid", nil, "", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := make(mlog.LoggerConfiguration)
|
||||||
|
err := json.Unmarshal(s.AdvancedLoggingJSON, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.log.advanced_logging.json", map[string]any{"Error": err}, "", http.StatusBadRequest).Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cfg.IsValid()
|
||||||
|
if err != nil {
|
||||||
|
return NewAppError("ExperimentalAuditSettings.isValid", "model.config.is_valid.log.advanced_logging.parse", map[string]any{"Error": err}, "", http.StatusBadRequest).Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ExperimentalAuditSettings) SetDefaults() {
|
func (s *ExperimentalAuditSettings) SetDefaults() {
|
||||||
if s.FileEnabled == nil {
|
if s.FileEnabled == nil {
|
||||||
s.FileEnabled = NewPointer(false)
|
s.FileEnabled = NewPointer(false)
|
||||||
@@ -4040,6 +4081,10 @@ func (o *Config) IsValid() *AppError {
|
|||||||
return appErr
|
return appErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if appErr := o.ExperimentalAuditSettings.isValid(); appErr != nil {
|
||||||
|
return appErr
|
||||||
|
}
|
||||||
|
|
||||||
if appErr := o.LocalizationSettings.isValid(); appErr != nil {
|
if appErr := o.LocalizationSettings.isValid(); appErr != nil {
|
||||||
return appErr
|
return appErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1402,6 +1402,8 @@ func TestLdapSettingsIsValid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLogSettingsIsValid(t *testing.T) {
|
func TestLogSettingsIsValid(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
for name, test := range map[string]struct {
|
for name, test := range map[string]struct {
|
||||||
LogSettings LogSettings
|
LogSettings LogSettings
|
||||||
ExpectError bool
|
ExpectError bool
|
||||||
@@ -2163,6 +2165,115 @@ func TestConfigDefaultConnectedWorkspacesSettings(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExperimentalAuditSettingsIsValid(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for name, test := range map[string]struct {
|
||||||
|
ExperimentalAuditSettings ExperimentalAuditSettings
|
||||||
|
ExpectError bool
|
||||||
|
}{
|
||||||
|
"empty settings": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{},
|
||||||
|
ExpectError: false,
|
||||||
|
},
|
||||||
|
"file enabled with empty filename": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer(""),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"file enabled with valid filename": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(100),
|
||||||
|
FileMaxAgeDays: NewPointer(5),
|
||||||
|
FileMaxBackups: NewPointer(10),
|
||||||
|
FileMaxQueueSize: NewPointer(1000),
|
||||||
|
},
|
||||||
|
ExpectError: false,
|
||||||
|
},
|
||||||
|
"invalid file max size": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(0),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"negative file max size": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(-10),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"negative file max age": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(100),
|
||||||
|
FileMaxAgeDays: NewPointer(-5),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"negative file max backups": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(100),
|
||||||
|
FileMaxAgeDays: NewPointer(5),
|
||||||
|
FileMaxBackups: NewPointer(-10),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"zero file max queue size": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(100),
|
||||||
|
FileMaxAgeDays: NewPointer(5),
|
||||||
|
FileMaxBackups: NewPointer(10),
|
||||||
|
FileMaxQueueSize: NewPointer(0),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"negative file max queue size": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
FileEnabled: NewPointer(true),
|
||||||
|
FileName: NewPointer("audit.log"),
|
||||||
|
FileMaxSizeMB: NewPointer(100),
|
||||||
|
FileMaxAgeDays: NewPointer(5),
|
||||||
|
FileMaxBackups: NewPointer(10),
|
||||||
|
FileMaxQueueSize: NewPointer(-1000),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
"AdvancedLoggingJSON has JSON error ": {
|
||||||
|
ExperimentalAuditSettings: ExperimentalAuditSettings{
|
||||||
|
AdvancedLoggingJSON: json.RawMessage(`
|
||||||
|
{
|
||||||
|
"foo": "bar",
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
ExpectError: true,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
test.ExperimentalAuditSettings.SetDefaults()
|
||||||
|
|
||||||
|
appErr := test.ExperimentalAuditSettings.isValid()
|
||||||
|
if test.ExpectError {
|
||||||
|
require.NotNil(t, appErr)
|
||||||
|
} else {
|
||||||
|
require.Nil(t, appErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFilterConfig(t *testing.T) {
|
func TestFilterConfig(t *testing.T) {
|
||||||
t.Run("should clear default values", func(t *testing.T) {
|
t.Run("should clear default values", func(t *testing.T) {
|
||||||
cfg := &Config{}
|
cfg := &Config{}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func (f *FeatureFlags) SetDefaults() {
|
|||||||
f.ChannelBookmarks = true
|
f.ChannelBookmarks = true
|
||||||
f.WebSocketEventScope = true
|
f.WebSocketEventScope = true
|
||||||
f.NotificationMonitoring = true
|
f.NotificationMonitoring = true
|
||||||
f.ExperimentalAuditSettingsSystemConsoleUI = false
|
f.ExperimentalAuditSettingsSystemConsoleUI = true
|
||||||
f.CustomProfileAttributes = true
|
f.CustomProfileAttributes = true
|
||||||
f.AttributeBasedAccessControl = true
|
f.AttributeBasedAccessControl = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5613,6 +5613,149 @@ const AdminDefinition: AdminDefinitionType = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
audit_logging: {
|
||||||
|
url: 'compliance/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.minLicenseTier(LicenseSkus.Enterprise)),
|
||||||
|
),
|
||||||
|
schema: {
|
||||||
|
id: 'ExperimentalAuditSettings',
|
||||||
|
name: 'Audit logging (Beta)',
|
||||||
|
settings: [
|
||||||
|
{
|
||||||
|
type: 'banner',
|
||||||
|
label: defineMessage({id: 'admin.rate.noteDescription', defaultMessage: 'Changing properties in this section will require a server restart before taking effect.'}),
|
||||||
|
banner_type: 'info',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.'}),
|
||||||
|
isDisabled: it.any(
|
||||||
|
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
it.stateIsFalse('ExperimentalAuditSettings.FileEnabled'),
|
||||||
|
),
|
||||||
|
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: 'Maximum size, in megabytes (MB), the log file can grow before it gets rotated.'}),
|
||||||
|
isDisabled: it.any(
|
||||||
|
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
it.stateIsFalse('ExperimentalAuditSettings.FileEnabled'),
|
||||||
|
),
|
||||||
|
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: 'Maximum number of days to retain old log files. 0 disables the removal of old log files.'}),
|
||||||
|
isDisabled: it.any(
|
||||||
|
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
it.stateIsFalse('ExperimentalAuditSettings.FileEnabled'),
|
||||||
|
),
|
||||||
|
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: 'Maximum number of old log files to retain. 0 retains all old log files. Note: Configuring Max File Age can result in old log files being deleted regardless of this configuration value.'}),
|
||||||
|
isDisabled: it.any(
|
||||||
|
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
it.stateIsFalse('ExperimentalAuditSettings.FileEnabled'),
|
||||||
|
),
|
||||||
|
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.any(
|
||||||
|
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
it.stateIsFalse('ExperimentalAuditSettings.FileEnabled'),
|
||||||
|
),
|
||||||
|
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.any(
|
||||||
|
it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
it.stateIsFalse('ExperimentalAuditSettings.FileEnabled'),
|
||||||
|
),
|
||||||
|
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 <link>documentation</link> to learn more about Advanced Logging and the JSON format it uses.'}),
|
||||||
|
help_text_markdown: false,
|
||||||
|
help_text_values: {
|
||||||
|
link: (msg: string) => (
|
||||||
|
<ExternalLink
|
||||||
|
location='admin_console.experimental_audit_settings'
|
||||||
|
href={DocLinks.ADVANCED_LOGGING}
|
||||||
|
>
|
||||||
|
{msg}
|
||||||
|
</ExternalLink>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
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);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'custom',
|
||||||
|
component: AuditLoggingCertificateUploadSetting,
|
||||||
|
label: defineMessage({id: 'admin.audit_logging_experimental.certificate.title', defaultMessage: 'Certificate'}),
|
||||||
|
key: 'ExperimentalAuditSettings.Certificate',
|
||||||
|
help_text: defineMessage({id: 'admin.audit_logging_experimental.certificate.help_text', defaultMessage: 'The certificate file used for audit logging encryption.'}),
|
||||||
|
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
||||||
|
isHidden: it.not(it.licensedForFeature('Cloud')),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
custom_terms_of_service: {
|
custom_terms_of_service: {
|
||||||
url: 'compliance/custom_terms_of_service',
|
url: 'compliance/custom_terms_of_service',
|
||||||
title: defineMessage({id: 'admin.sidebar.customTermsOfService', defaultMessage: 'Custom Terms of Service'}),
|
title: defineMessage({id: 'admin.sidebar.customTermsOfService', defaultMessage: 'Custom Terms of Service'}),
|
||||||
@@ -6086,126 +6229,6 @@ const AdminDefinition: AdminDefinitionType = {
|
|||||||
component: BleveSettings,
|
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.minLicenseTier(LicenseSkus.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 <link>documentation</link> to learn more about Advanced Logging and the JSON format it uses.'}),
|
|
||||||
help_text_markdown: false,
|
|
||||||
help_text_values: {
|
|
||||||
link: (msg: string) => (
|
|
||||||
<ExternalLink
|
|
||||||
location='admin_console.experimental_audit_settings'
|
|
||||||
href={DocLinks.ADVANCED_LOGGING}
|
|
||||||
>
|
|
||||||
{msg}
|
|
||||||
</ExternalLink>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'custom',
|
|
||||||
component: AuditLoggingCertificateUploadSetting,
|
|
||||||
label: defineMessage({id: 'admin.audit_logging_experimental.certificate.title', defaultMessage: 'Certificate'}),
|
|
||||||
key: 'ExperimentalAuditSettings.Certificate',
|
|
||||||
help_text: defineMessage({id: 'admin.audit_logging_experimental.certificate.help_text', defaultMessage: 'The certificate file used for audit logging encryption.'}),
|
|
||||||
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)),
|
|
||||||
isHidden: it.not(it.licensedForFeature('Cloud')),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1871,6 +1871,17 @@ exports[`components/AdminSidebar should match snapshot with license with enterpr
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<AdminSidebarSection
|
||||||
|
definitionKey="compliance.audit_logging"
|
||||||
|
key="compliance.audit_logging"
|
||||||
|
name="compliance/audit_logging"
|
||||||
|
title={
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Audit Logging"
|
||||||
|
id="admin.sidebar.audit_logging_experimental"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<AdminSidebarSection
|
<AdminSidebarSection
|
||||||
definitionKey="compliance.custom_terms_of_service_feature_discovery"
|
definitionKey="compliance.custom_terms_of_service_feature_discovery"
|
||||||
key="compliance.custom_terms_of_service_feature_discovery"
|
key="compliance.custom_terms_of_service_feature_discovery"
|
||||||
@@ -1947,17 +1958,6 @@ exports[`components/AdminSidebar should match snapshot with license with enterpr
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<AdminSidebarSection
|
|
||||||
definitionKey="experimental.audit_logging"
|
|
||||||
key="experimental.audit_logging"
|
|
||||||
name="experimental/audit_logging"
|
|
||||||
title={
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Audit Logging"
|
|
||||||
id="admin.sidebar.audit_logging_experimental"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</AdminSidebarCategory>
|
</AdminSidebarCategory>
|
||||||
</ul>
|
</ul>
|
||||||
</SearchKeywordMarking>
|
</SearchKeywordMarking>
|
||||||
@@ -2948,6 +2948,17 @@ exports[`components/AdminSidebar should match snapshot with license with enterpr
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<AdminSidebarSection
|
||||||
|
definitionKey="compliance.audit_logging"
|
||||||
|
key="compliance.audit_logging"
|
||||||
|
name="compliance/audit_logging"
|
||||||
|
title={
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Audit Logging"
|
||||||
|
id="admin.sidebar.audit_logging_experimental"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<AdminSidebarSection
|
<AdminSidebarSection
|
||||||
definitionKey="compliance.custom_terms_of_service_feature_discovery"
|
definitionKey="compliance.custom_terms_of_service_feature_discovery"
|
||||||
key="compliance.custom_terms_of_service_feature_discovery"
|
key="compliance.custom_terms_of_service_feature_discovery"
|
||||||
@@ -3024,17 +3035,6 @@ exports[`components/AdminSidebar should match snapshot with license with enterpr
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<AdminSidebarSection
|
|
||||||
definitionKey="experimental.audit_logging"
|
|
||||||
key="experimental.audit_logging"
|
|
||||||
name="experimental/audit_logging"
|
|
||||||
title={
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Audit Logging"
|
|
||||||
id="admin.sidebar.audit_logging_experimental"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</AdminSidebarCategory>
|
</AdminSidebarCategory>
|
||||||
</ul>
|
</ul>
|
||||||
</SearchKeywordMarking>
|
</SearchKeywordMarking>
|
||||||
|
|||||||
@@ -362,15 +362,15 @@
|
|||||||
"admin.audit_logging_experimental.file_compress.title": "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.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_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.help_text": "Maximum number of days to retain old log files. 0 disables the removal of old log files.",
|
||||||
"admin.audit_logging_experimental.file_max_age.title": "Max File Age (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.help_text": "Maximum number of old log files to retain. 0 retains all old log files. Note: Configuring Max File Age can result in old log files being deleted regardless of this configuration value.",
|
||||||
"admin.audit_logging_experimental.file_max_backups.title": "Maximum File Backups",
|
"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.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_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.help_text": "Maximum size, in megabytes (MB), the log file can grow before it gets rotated.",
|
||||||
"admin.audit_logging_experimental.file_max_size.title": "Max File Size (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.help_text": "The name of the file to write to.",
|
||||||
"admin.audit_logging_experimental.file_name.title": "File Name",
|
"admin.audit_logging_experimental.file_name.title": "File Name",
|
||||||
"admin.audits.reload": "Reload User Activity Logs",
|
"admin.audits.reload": "Reload User Activity Logs",
|
||||||
"admin.authentication.email": "Email Authentication",
|
"admin.authentication.email": "Email Authentication",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user