mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-53990] Support a global retention time of less than 1 day (#25196)
* adding new MessageRetentionHours config --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
@@ -122,9 +122,9 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li
|
||||
props["AllowCustomThemes"] = "true"
|
||||
props["AllowedThemes"] = ""
|
||||
props["DataRetentionEnableMessageDeletion"] = "false"
|
||||
props["DataRetentionMessageRetentionDays"] = "0"
|
||||
props["DataRetentionMessageRetentionHours"] = "0"
|
||||
props["DataRetentionEnableFileDeletion"] = "false"
|
||||
props["DataRetentionFileRetentionDays"] = "0"
|
||||
props["DataRetentionFileRetentionHours"] = "0"
|
||||
|
||||
props["CustomUrlSchemes"] = strings.Join(c.DisplaySettings.CustomURLSchemes, ",")
|
||||
props["MaxMarkdownNodes"] = strconv.FormatInt(int64(*c.DisplaySettings.MaxMarkdownNodes), 10)
|
||||
@@ -204,9 +204,9 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li
|
||||
|
||||
if *license.Features.DataRetention {
|
||||
props["DataRetentionEnableMessageDeletion"] = strconv.FormatBool(*c.DataRetentionSettings.EnableMessageDeletion)
|
||||
props["DataRetentionMessageRetentionDays"] = strconv.FormatInt(int64(*c.DataRetentionSettings.MessageRetentionDays), 10)
|
||||
props["DataRetentionMessageRetentionHours"] = strconv.FormatInt(int64(c.DataRetentionSettings.GetMessageRetentionHours()), 10)
|
||||
props["DataRetentionEnableFileDeletion"] = strconv.FormatBool(*c.DataRetentionSettings.EnableFileDeletion)
|
||||
props["DataRetentionFileRetentionDays"] = strconv.FormatInt(int64(*c.DataRetentionSettings.FileRetentionDays), 10)
|
||||
props["DataRetentionFileRetentionHours"] = strconv.FormatInt(int64(c.DataRetentionSettings.GetFileRetentionHours()), 10)
|
||||
}
|
||||
|
||||
if license.HasSharedChannels() {
|
||||
|
||||
@@ -8742,13 +8742,37 @@
|
||||
"id": "model.config.is_valid.data_retention.deletion_job_start_time.app_error",
|
||||
"translation": "Data retention job start time must be a 24-hour time stamp in the form HH:MM."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.file_retention_both_zero.app_error",
|
||||
"translation": "File retention days and file retention hours cannot both be 0."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.file_retention_days_too_low.app_error",
|
||||
"translation": "File retention must be one day or longer."
|
||||
"translation": "File retention days cannot be less than 0."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.file_retention_hours_too_low.app_error",
|
||||
"translation": "File retention hours cannot be less than 0"
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.file_retention_misconfiguration.app_error",
|
||||
"translation": "File retention days and file retention hours cannot both be greater than 0."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.message_retention_both_zero.app_error",
|
||||
"translation": "Message retention days and message retention hours cannot both be 0."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.message_retention_days_too_low.app_error",
|
||||
"translation": "Message retention must be one day or longer."
|
||||
"translation": "Message retention days cannot be less than 0."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.message_retention_hours_too_low.app_error",
|
||||
"translation": "Message retention hours cannot be less than 0"
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.data_retention.message_retention_misconfiguration.app_error",
|
||||
"translation": "Message retention days and message retention hours cannot both be greater than 0."
|
||||
},
|
||||
{
|
||||
"id": "model.config.is_valid.directory.app_error",
|
||||
|
||||
@@ -829,7 +829,9 @@ func (ts *TelemetryService) trackConfig() {
|
||||
"enable_message_deletion": *cfg.DataRetentionSettings.EnableMessageDeletion,
|
||||
"enable_file_deletion": *cfg.DataRetentionSettings.EnableFileDeletion,
|
||||
"message_retention_days": *cfg.DataRetentionSettings.MessageRetentionDays,
|
||||
"message_retention_hours": *cfg.DataRetentionSettings.MessageRetentionHours,
|
||||
"file_retention_days": *cfg.DataRetentionSettings.FileRetentionDays,
|
||||
"file_retention_hours": *cfg.DataRetentionSettings.FileRetentionHours,
|
||||
"deletion_job_start_time": *cfg.DataRetentionSettings.DeletionJobStartTime,
|
||||
"batch_size": *cfg.DataRetentionSettings.BatchSize,
|
||||
"time_between_batches": *cfg.DataRetentionSettings.TimeBetweenBatchesMilliseconds,
|
||||
|
||||
@@ -207,7 +207,9 @@ const (
|
||||
BleveSettingsDefaultBatchSize = 10000
|
||||
|
||||
DataRetentionSettingsDefaultMessageRetentionDays = 365
|
||||
DataRetentionSettingsDefaultMessageRetentionHours = 0
|
||||
DataRetentionSettingsDefaultFileRetentionDays = 365
|
||||
DataRetentionSettingsDefaultFileRetentionHours = 0
|
||||
DataRetentionSettingsDefaultBoardsRetentionDays = 365
|
||||
DataRetentionSettingsDefaultDeletionJobStartTime = "02:00"
|
||||
DataRetentionSettingsDefaultBatchSize = 3000
|
||||
@@ -2911,8 +2913,10 @@ type DataRetentionSettings struct {
|
||||
EnableMessageDeletion *bool `access:"compliance_data_retention_policy"`
|
||||
EnableFileDeletion *bool `access:"compliance_data_retention_policy"`
|
||||
EnableBoardsDeletion *bool `access:"compliance_data_retention_policy"`
|
||||
MessageRetentionDays *int `access:"compliance_data_retention_policy"`
|
||||
FileRetentionDays *int `access:"compliance_data_retention_policy"`
|
||||
MessageRetentionDays *int `access:"compliance_data_retention_policy"` // Deprecated: use `MessageRetentionHours`
|
||||
MessageRetentionHours *int `access:"compliance_data_retention_policy"`
|
||||
FileRetentionDays *int `access:"compliance_data_retention_policy"` // Deprecated: use `FileRetentionHours`
|
||||
FileRetentionHours *int `access:"compliance_data_retention_policy"`
|
||||
BoardsRetentionDays *int `access:"compliance_data_retention_policy"`
|
||||
DeletionJobStartTime *string `access:"compliance_data_retention_policy"`
|
||||
BatchSize *int `access:"compliance_data_retention_policy"`
|
||||
@@ -2937,10 +2941,18 @@ func (s *DataRetentionSettings) SetDefaults() {
|
||||
s.MessageRetentionDays = NewInt(DataRetentionSettingsDefaultMessageRetentionDays)
|
||||
}
|
||||
|
||||
if s.MessageRetentionHours == nil {
|
||||
s.MessageRetentionHours = NewInt(DataRetentionSettingsDefaultMessageRetentionHours)
|
||||
}
|
||||
|
||||
if s.FileRetentionDays == nil {
|
||||
s.FileRetentionDays = NewInt(DataRetentionSettingsDefaultFileRetentionDays)
|
||||
}
|
||||
|
||||
if s.FileRetentionHours == nil {
|
||||
s.FileRetentionHours = NewInt(DataRetentionSettingsDefaultFileRetentionHours)
|
||||
}
|
||||
|
||||
if s.BoardsRetentionDays == nil {
|
||||
s.BoardsRetentionDays = NewInt(DataRetentionSettingsDefaultBoardsRetentionDays)
|
||||
}
|
||||
@@ -2961,6 +2973,30 @@ func (s *DataRetentionSettings) SetDefaults() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetMessageRetentionHours returns the message retention time as an int.
|
||||
// MessageRetentionHours takes precedence over the deprecated MessageRetentionDays.
|
||||
func (s *DataRetentionSettings) GetMessageRetentionHours() int {
|
||||
if s.MessageRetentionHours != nil && *s.MessageRetentionHours > 0 {
|
||||
return *s.MessageRetentionHours
|
||||
}
|
||||
if s.MessageRetentionDays != nil && *s.MessageRetentionDays > 0 {
|
||||
return *s.MessageRetentionDays * 24
|
||||
}
|
||||
return DataRetentionSettingsDefaultMessageRetentionDays * 24
|
||||
}
|
||||
|
||||
// GetFileRetentionHours returns the message retention time as an int.
|
||||
// FileRetentionHours takes precedence over the deprecated FileRetentionDays.
|
||||
func (s *DataRetentionSettings) GetFileRetentionHours() int {
|
||||
if s.FileRetentionHours != nil && *s.FileRetentionHours > 0 {
|
||||
return *s.FileRetentionHours
|
||||
}
|
||||
if s.FileRetentionDays != nil && *s.FileRetentionDays > 0 {
|
||||
return *s.FileRetentionDays * 24
|
||||
}
|
||||
return DataRetentionSettingsDefaultFileRetentionDays * 24
|
||||
}
|
||||
|
||||
type JobSettings struct {
|
||||
RunJobs *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
|
||||
RunScheduler *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
|
||||
@@ -4141,14 +4177,38 @@ func (bs *BleveSettings) isValid() *AppError {
|
||||
}
|
||||
|
||||
func (s *DataRetentionSettings) isValid() *AppError {
|
||||
if *s.MessageRetentionDays <= 0 {
|
||||
if s.MessageRetentionDays == nil || *s.MessageRetentionDays < 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.message_retention_days_too_low.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *s.FileRetentionDays <= 0 {
|
||||
if s.MessageRetentionHours == nil || *s.MessageRetentionHours < 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.message_retention_hours_too_low.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if s.FileRetentionDays == nil || *s.FileRetentionDays < 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.file_retention_days_too_low.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if s.FileRetentionHours == nil || *s.FileRetentionHours < 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.file_retention_hours_too_low.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *s.MessageRetentionDays > 0 && *s.MessageRetentionHours > 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.message_retention_misconfiguration.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *s.FileRetentionDays > 0 && *s.FileRetentionHours > 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.file_retention_misconfiguration.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *s.MessageRetentionDays == 0 && *s.MessageRetentionHours == 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.message_retention_both_zero.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *s.FileRetentionDays == 0 && *s.FileRetentionHours == 0 {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.file_retention_both_zero.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if _, err := time.Parse("15:04", *s.DeletionJobStartTime); err != nil {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.deletion_job_start_time.app_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||
}
|
||||
|
||||
@@ -1647,3 +1647,105 @@ func TestConfigDefaultCallsPluginState(t *testing.T) {
|
||||
assert.False(t, c1.PluginSettings.PluginStates["com.mattermost.calls"].Enable)
|
||||
})
|
||||
}
|
||||
|
||||
func TestConfigGetMessageRetentionHours(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config Config
|
||||
value int
|
||||
}{
|
||||
{
|
||||
name: "should return MessageRetentionDays config value in hours by default",
|
||||
config: Config{},
|
||||
value: 8760,
|
||||
},
|
||||
{
|
||||
name: "should return MessageRetentionHours config value",
|
||||
config: Config{
|
||||
DataRetentionSettings: DataRetentionSettings{
|
||||
MessageRetentionHours: NewInt(48),
|
||||
},
|
||||
},
|
||||
value: 48,
|
||||
},
|
||||
{
|
||||
name: "should return MessageRetentionHours config value",
|
||||
config: Config{
|
||||
DataRetentionSettings: DataRetentionSettings{
|
||||
MessageRetentionDays: NewInt(50),
|
||||
MessageRetentionHours: NewInt(48),
|
||||
},
|
||||
},
|
||||
value: 48,
|
||||
},
|
||||
{
|
||||
name: "should return MessageRetentionDays config value in hours",
|
||||
config: Config{
|
||||
DataRetentionSettings: DataRetentionSettings{
|
||||
MessageRetentionDays: NewInt(50),
|
||||
MessageRetentionHours: NewInt(0),
|
||||
},
|
||||
},
|
||||
value: 1200,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.config.SetDefaults()
|
||||
|
||||
require.Equal(t, test.value, test.config.DataRetentionSettings.GetMessageRetentionHours())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigGetFileRetentionHours(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config Config
|
||||
value int
|
||||
}{
|
||||
{
|
||||
name: "should return FileRetentionDays config value in hours by default",
|
||||
config: Config{},
|
||||
value: 8760,
|
||||
},
|
||||
{
|
||||
name: "should return FileRetentionHours config value",
|
||||
config: Config{
|
||||
DataRetentionSettings: DataRetentionSettings{
|
||||
FileRetentionHours: NewInt(48),
|
||||
},
|
||||
},
|
||||
value: 48,
|
||||
},
|
||||
{
|
||||
name: "should return FileRetentionHours config value",
|
||||
config: Config{
|
||||
DataRetentionSettings: DataRetentionSettings{
|
||||
FileRetentionDays: NewInt(50),
|
||||
FileRetentionHours: NewInt(48),
|
||||
},
|
||||
},
|
||||
value: 48,
|
||||
},
|
||||
{
|
||||
name: "should return FileRetentionDays config value in hours",
|
||||
config: Config{
|
||||
DataRetentionSettings: DataRetentionSettings{
|
||||
FileRetentionDays: NewInt(50),
|
||||
FileRetentionHours: NewInt(0),
|
||||
},
|
||||
},
|
||||
value: 1200,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.config.SetDefaults()
|
||||
|
||||
require.Equal(t, test.value, test.config.DataRetentionSettings.GetFileRetentionHours())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user