diff options
-rw-r--r-- | api4/api.go | 4 | ||||
-rw-r--r-- | api4/data_retention.go | 30 | ||||
-rw-r--r-- | api4/data_retention_test.go | 16 | ||||
-rw-r--r-- | app/app.go | 21 | ||||
-rw-r--r-- | app/data_retention.go | 18 | ||||
-rw-r--r-- | einterfaces/data_retention.go | 12 | ||||
-rw-r--r-- | einterfaces/jobs/data_retention.go | 2 | ||||
-rw-r--r-- | i18n/en.json | 4 | ||||
-rw-r--r-- | jobs/schedulers.go | 4 | ||||
-rw-r--r-- | jobs/server.go | 2 | ||||
-rw-r--r-- | jobs/workers.go | 4 | ||||
-rw-r--r-- | model/client4.go | 16 | ||||
-rw-r--r-- | model/data_retention_policy.go | 36 |
13 files changed, 157 insertions, 12 deletions
diff --git a/api4/api.go b/api4/api.go index e9cf3054c..c712b67f2 100644 --- a/api4/api.go +++ b/api4/api.go @@ -80,6 +80,8 @@ type Routes struct { Elasticsearch *mux.Router // 'api/v4/elasticsearch' + DataRetention *mux.Router // 'api/v4/data_retention' + Brand *mux.Router // 'api/v4/brand' System *mux.Router // 'api/v4/system' @@ -185,6 +187,7 @@ func Init(a *app.App, root *mux.Router, full bool) *API { api.BaseRoutes.Reactions = api.BaseRoutes.ApiRoot.PathPrefix("/reactions").Subrouter() api.BaseRoutes.Jobs = api.BaseRoutes.ApiRoot.PathPrefix("/jobs").Subrouter() api.BaseRoutes.Elasticsearch = api.BaseRoutes.ApiRoot.PathPrefix("/elasticsearch").Subrouter() + api.BaseRoutes.DataRetention = api.BaseRoutes.ApiRoot.PathPrefix("/data_retention").Subrouter() api.BaseRoutes.Emojis = api.BaseRoutes.ApiRoot.PathPrefix("/emoji").Subrouter() api.BaseRoutes.Emoji = api.BaseRoutes.Emojis.PathPrefix("/{emoji_id:[A-Za-z0-9]+}").Subrouter() @@ -208,6 +211,7 @@ func Init(a *app.App, root *mux.Router, full bool) *API { api.InitCluster() api.InitLdap() api.InitElasticsearch() + api.InitDataRetention() api.InitBrand() api.InitJob() api.InitCommand() diff --git a/api4/data_retention.go b/api4/data_retention.go new file mode 100644 index 000000000..da0d5812e --- /dev/null +++ b/api4/data_retention.go @@ -0,0 +1,30 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package api4 + +import ( + "net/http" + + l4g "github.com/alecthomas/log4go" + + "github.com/mattermost/mattermost-server/utils" +) + +func (api *API) InitDataRetention() { + l4g.Debug(utils.T("api.data_retention.init.debug")) + + api.BaseRoutes.DataRetention.Handle("/policy", api.ApiSessionRequired(getPolicy)).Methods("GET") +} + +func getPolicy(c *Context, w http.ResponseWriter, r *http.Request) { + + // No permission check required. + + if policy, err := c.App.GetDataRetentionPolicy(); err != nil { + c.Err = err + return + } else { + w.Write([]byte(policy.ToJson())) + } +} diff --git a/api4/data_retention_test.go b/api4/data_retention_test.go new file mode 100644 index 000000000..9a0b35ea6 --- /dev/null +++ b/api4/data_retention_test.go @@ -0,0 +1,16 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package api4 + +import ( + "testing" +) + +func TestDataRetentionGetPolicy(t *testing.T) { + th := Setup().InitBasic() + defer TearDown() + + _, resp := th.Client.GetDataRetentionPolicy() + CheckNotImplementedStatus(t, resp) +} diff --git a/app/app.go b/app/app.go index 508c652c1..7974ab44f 100644 --- a/app/app.go +++ b/app/app.go @@ -34,6 +34,7 @@ type App struct { Brand einterfaces.BrandInterface Cluster einterfaces.ClusterInterface Compliance einterfaces.ComplianceInterface + DataRetention einterfaces.DataRetentionInterface Elasticsearch einterfaces.ElasticsearchInterface Ldap einterfaces.LdapInterface Metrics einterfaces.MetricsInterface @@ -103,10 +104,16 @@ func RegisterComplianceInterface(f func(*App) einterfaces.ComplianceInterface) { complianceInterface = f } -var jobsDataRetentionInterface func(*App) ejobs.DataRetentionInterface +var dataRetentionInterface func(*App) einterfaces.DataRetentionInterface -func RegisterJobsDataRetentionInterface(f func(*App) ejobs.DataRetentionInterface) { - jobsDataRetentionInterface = f +func RegisterDataRetentionInterface(f func(*App) einterfaces.DataRetentionInterface) { + dataRetentionInterface = f +} + +var jobsDataRetentionJobInterface func(*App) ejobs.DataRetentionJobInterface + +func RegisterJobsDataRetentionJobInterface(f func(*App) ejobs.DataRetentionJobInterface) { + jobsDataRetentionJobInterface = f } var jobsElasticsearchAggregatorInterface func(*App) ejobs.ElasticsearchAggregatorInterface @@ -183,9 +190,11 @@ func (a *App) initEnterprise() { a.Saml.ConfigureSP() }) } - - if jobsDataRetentionInterface != nil { - a.Jobs.DataRetention = jobsDataRetentionInterface(a) + if dataRetentionInterface != nil { + a.DataRetention = dataRetentionInterface(a) + } + if jobsDataRetentionJobInterface != nil { + a.Jobs.DataRetentionJob = jobsDataRetentionJobInterface(a) } if jobsElasticsearchAggregatorInterface != nil { a.Jobs.ElasticsearchAggregator = jobsElasticsearchAggregatorInterface(a) diff --git a/app/data_retention.go b/app/data_retention.go new file mode 100644 index 000000000..b931ca8b1 --- /dev/null +++ b/app/data_retention.go @@ -0,0 +1,18 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package app + +import ( + "net/http" + + "github.com/mattermost/mattermost-server/model" +) + +func (a *App) GetDataRetentionPolicy() (*model.DataRetentionPolicy, *model.AppError) { + if a.DataRetention == nil { + return nil, model.NewAppError("App.GetDataRetentionPolicy", "ent.data_retention.generic.license.error", nil, "", http.StatusNotImplemented) + } + + return a.DataRetention.GetPolicy() +} diff --git a/einterfaces/data_retention.go b/einterfaces/data_retention.go new file mode 100644 index 000000000..07f7d387d --- /dev/null +++ b/einterfaces/data_retention.go @@ -0,0 +1,12 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package einterfaces + +import ( + "github.com/mattermost/mattermost-server/model" +) + +type DataRetentionInterface interface { + GetPolicy() (*model.DataRetentionPolicy, *model.AppError) +} diff --git a/einterfaces/jobs/data_retention.go b/einterfaces/jobs/data_retention.go index 5910d6120..73f78e4fe 100644 --- a/einterfaces/jobs/data_retention.go +++ b/einterfaces/jobs/data_retention.go @@ -7,7 +7,7 @@ import ( "github.com/mattermost/mattermost-server/model" ) -type DataRetentionInterface interface { +type DataRetentionJobInterface interface { MakeWorker() model.Worker MakeScheduler() model.Scheduler } diff --git a/i18n/en.json b/i18n/en.json index bfbb18ea9..456727d9b 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -3688,6 +3688,10 @@ "translation": "Compliance export started for job '{{.JobName}}' at '{{.FilePath}}'" }, { + "id": "ent.data_retention.generic.license.error", + "translation": "License does not support Data Retention." + }, + { "id": "ent.elasticsearch.aggregator_worker.create_index_job.error", "translation": "Elasticsearch aggregator worker failed to create the indexing job" }, diff --git a/jobs/schedulers.go b/jobs/schedulers.go index 2f1ae394f..3d52c969a 100644 --- a/jobs/schedulers.go +++ b/jobs/schedulers.go @@ -35,8 +35,8 @@ func (srv *JobServer) InitSchedulers() *Schedulers { jobs: srv, } - if dataRetentionInterface := srv.DataRetention; dataRetentionInterface != nil { - schedulers.schedulers = append(schedulers.schedulers, dataRetentionInterface.MakeScheduler()) + if srv.DataRetentionJob != nil { + schedulers.schedulers = append(schedulers.schedulers, srv.DataRetentionJob.MakeScheduler()) } if elasticsearchAggregatorInterface := srv.ElasticsearchAggregator; elasticsearchAggregatorInterface != nil { diff --git a/jobs/server.go b/jobs/server.go index 667d6c075..8c5ee807d 100644 --- a/jobs/server.go +++ b/jobs/server.go @@ -17,7 +17,7 @@ type JobServer struct { Workers *Workers Schedulers *Schedulers - DataRetention ejobs.DataRetentionInterface + DataRetentionJob ejobs.DataRetentionJobInterface ElasticsearchAggregator ejobs.ElasticsearchAggregatorInterface ElasticsearchIndexer ejobs.ElasticsearchIndexerInterface LdapSync ejobs.LdapSyncInterface diff --git a/jobs/workers.go b/jobs/workers.go index dfa150ff6..c984a43b8 100644 --- a/jobs/workers.go +++ b/jobs/workers.go @@ -27,8 +27,8 @@ func (srv *JobServer) InitWorkers() *Workers { workers := &Workers{} workers.Watcher = srv.MakeWatcher(workers, DEFAULT_WATCHER_POLLING_INTERVAL) - if dataRetentionInterface := srv.DataRetention; dataRetentionInterface != nil { - workers.DataRetention = dataRetentionInterface.MakeWorker() + if srv.DataRetentionJob != nil { + workers.DataRetention = srv.DataRetentionJob.MakeWorker() } if elasticsearchIndexerInterface := srv.ElasticsearchIndexer; elasticsearchIndexerInterface != nil { diff --git a/model/client4.go b/model/client4.go index eb8568a5e..3bd3b2125 100644 --- a/model/client4.go +++ b/model/client4.go @@ -254,6 +254,10 @@ func (c *Client4) GetBrandRoute() string { return fmt.Sprintf("/brand") } +func (c *Client4) GetDataRetentionRoute() string { + return fmt.Sprintf("/data_retention") +} + func (c *Client4) GetElasticsearchRoute() string { return fmt.Sprintf("/elasticsearch") } @@ -2747,6 +2751,18 @@ func (c *Client4) PurgeElasticsearchIndexes() (bool, *Response) { } } +// Data Retention Section + +// GetDataRetentionPolicy will get the current server data retention policy details. +func (c *Client4) GetDataRetentionPolicy() (*DataRetentionPolicy, *Response) { + if r, err := c.DoApiGet(c.GetDataRetentionRoute()+"/policy", ""); err != nil { + return nil, BuildErrorResponse(r, err) + } else { + defer closeBody(r) + return DataRetentionPolicyFromJson(r.Body), BuildResponse(r) + } +} + // Commands Section // CreateCommand will create a new command if the user have the right permissions. diff --git a/model/data_retention_policy.go b/model/data_retention_policy.go new file mode 100644 index 000000000..7284477e5 --- /dev/null +++ b/model/data_retention_policy.go @@ -0,0 +1,36 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "encoding/json" + "io" +) + +type DataRetentionPolicy struct { + MessageDeletionEnabled bool `json:"message_deletion_enabled"` + FileDeletionEnabled bool `json:"file_deletion_enabled"` + MessageRetentionCutoff int64 `json:"message_retention_cutoff"` + FileRetentionCutoff int64 `json:"file_retention_cutoff"` +} + +func (me *DataRetentionPolicy) ToJson() string { + b, err := json.Marshal(me) + if err != nil { + return "" + } else { + return string(b) + } +} + +func DataRetentionPolicyFromJson(data io.Reader) *DataRetentionPolicy { + decoder := json.NewDecoder(data) + var me DataRetentionPolicy + err := decoder.Decode(&me) + if err == nil { + return &me + } else { + return nil + } +} |