diff options
author | Corey Hulen <corey@hulen.com> | 2016-03-17 13:16:10 -0700 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2016-03-17 13:16:10 -0700 |
commit | 53d7718e57d4225eb5c020324d32cbe5b5eca7ad (patch) | |
tree | 9e549812c250513d56dd631c65c49402ea549ff7 /model | |
parent | 8d571ee498c97128bd797f8ac1cb4c3c995fb875 (diff) | |
parent | 2e5cc29738340c7330d1b2606ceba40865872e4c (diff) | |
download | chat-53d7718e57d4225eb5c020324d32cbe5b5eca7ad.tar.gz chat-53d7718e57d4225eb5c020324d32cbe5b5eca7ad.tar.bz2 chat-53d7718e57d4225eb5c020324d32cbe5b5eca7ad.zip |
Merge pull request #2442 from mattermost/PLT-2115
PLT-2115 adding compliance feature
Diffstat (limited to 'model')
-rw-r--r-- | model/client.go | 36 | ||||
-rw-r--r-- | model/compliance.go | 132 | ||||
-rw-r--r-- | model/compliance_post.go | 104 | ||||
-rw-r--r-- | model/compliance_post_test.go | 27 | ||||
-rw-r--r-- | model/compliance_test.go | 19 | ||||
-rw-r--r-- | model/config.go | 46 | ||||
-rw-r--r-- | model/license.go | 12 | ||||
-rw-r--r-- | model/system.go | 9 |
8 files changed, 366 insertions, 19 deletions
diff --git a/model/client.go b/model/client.go index 14c175fc1..68cf11414 100644 --- a/model/client.go +++ b/model/client.go @@ -474,6 +474,42 @@ func (c *Client) TestEmail(config *Config) (*Result, *AppError) { } } +func (c *Client) GetComplianceReports() (*Result, *AppError) { + if r, err := c.DoApiGet("/admin/compliance_reports", "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), CompliancesFromJson(r.Body)}, nil + } +} + +func (c *Client) SaveComplianceReport(job *Compliance) (*Result, *AppError) { + if r, err := c.DoApiPost("/admin/save_compliance_report", job.ToJson()); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), ComplianceFromJson(r.Body)}, nil + } +} + +func (c *Client) DownloadComplianceReport(id string) (*Result, *AppError) { + var rq *http.Request + rq, _ = http.NewRequest("GET", c.ApiUrl+"/admin/download_compliance_report/"+id, nil) + + if len(c.AuthToken) > 0 { + rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) + } + + if rp, err := c.HttpClient.Do(rq); err != nil { + return nil, NewLocAppError("/admin/download_compliance_report", "model.client.connecting.app_error", nil, err.Error()) + } else if rp.StatusCode >= 300 { + return nil, AppErrorFromJson(rp.Body) + } else { + return &Result{rp.Header.Get(HEADER_REQUEST_ID), + rp.Header.Get(HEADER_ETAG_SERVER), rp.Body}, nil + } +} + func (c *Client) GetTeamAnalytics(teamId, name string) (*Result, *AppError) { if r, err := c.DoApiGet("/admin/analytics/"+teamId+"/"+name, "", ""); err != nil { return nil, err diff --git a/model/compliance.go b/model/compliance.go new file mode 100644 index 000000000..4a96a597a --- /dev/null +++ b/model/compliance.go @@ -0,0 +1,132 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "encoding/json" + "io" + "strings" +) + +const ( + COMPLIANCE_STATUS_CREATED = "created" + COMPLIANCE_STATUS_RUNNING = "running" + COMPLIANCE_STATUS_FINISHED = "finished" + COMPLIANCE_STATUS_FAILED = "failed" + COMPLIANCE_STATUS_REMOVED = "removed" + + COMPLIANCE_TYPE_DAILY = "daily" + COMPLIANCE_TYPE_ADHOC = "adhoc" +) + +type Compliance struct { + Id string `json:"id"` + CreateAt int64 `json:"create_at"` + UserId string `json:"user_id"` + Status string `json:"status"` + Count int `json:"count"` + Desc string `json:"desc"` + Type string `json:"type"` + StartAt int64 `json:"start_at"` + EndAt int64 `json:"end_at"` + Keywords string `json:"keywords"` + Emails string `json:"emails"` +} + +type Compliances []Compliance + +func (o *Compliance) ToJson() string { + b, err := json.Marshal(o) + if err != nil { + return "" + } else { + return string(b) + } +} + +func (me *Compliance) PreSave() { + if me.Id == "" { + me.Id = NewId() + } + + if me.Status == "" { + me.Status = COMPLIANCE_STATUS_CREATED + } + + me.Count = 0 + me.Emails = strings.ToLower(me.Emails) + me.Keywords = strings.ToLower(me.Keywords) + + me.CreateAt = GetMillis() +} + +func (me *Compliance) JobName() string { + jobName := me.Type + if me.Type == COMPLIANCE_TYPE_DAILY { + jobName += "-" + me.Desc + } + + jobName += "-" + me.Id + + return jobName +} + +func (me *Compliance) IsValid() *AppError { + + if len(me.Id) != 26 { + return NewLocAppError("Compliance.IsValid", "model.compliance.is_valid.id.app_error", nil, "") + } + + if me.CreateAt == 0 { + return NewLocAppError("Compliance.IsValid", "model.compliance.is_valid.create_at.app_error", nil, "") + } + + if len(me.Desc) > 512 || len(me.Desc) == 0 { + return NewLocAppError("Compliance.IsValid", "model.compliance.is_valid.desc.app_error", nil, "") + } + + if me.StartAt == 0 { + return NewLocAppError("Compliance.IsValid", "model.compliance.is_valid.start_at.app_error", nil, "") + } + + if me.EndAt == 0 { + return NewLocAppError("Compliance.IsValid", "model.compliance.is_valid.end_at.app_error", nil, "") + } + + if me.EndAt <= me.StartAt { + return NewLocAppError("Compliance.IsValid", "model.compliance.is_valid.start_end_at.app_error", nil, "") + } + + return nil +} + +func ComplianceFromJson(data io.Reader) *Compliance { + decoder := json.NewDecoder(data) + var o Compliance + err := decoder.Decode(&o) + if err == nil { + return &o + } else { + return nil + } +} + +func (o Compliances) ToJson() string { + if b, err := json.Marshal(o); err != nil { + return "[]" + } else { + return string(b) + } +} + +func CompliancesFromJson(data io.Reader) Compliances { + decoder := json.NewDecoder(data) + var o Compliances + err := decoder.Decode(&o) + if err == nil { + return o + } else { + return nil + } +} diff --git a/model/compliance_post.go b/model/compliance_post.go new file mode 100644 index 000000000..ce26a3660 --- /dev/null +++ b/model/compliance_post.go @@ -0,0 +1,104 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "time" +) + +type CompliancePost struct { + + // From Team + TeamName string + TeamDisplayName string + + // From Channel + ChannelName string + ChannelDisplayName string + + // From User + UserUsername string + UserEmail string + UserNickname string + + // From Post + PostId string + PostCreateAt int64 + PostUpdateAt int64 + PostDeleteAt int64 + PostRootId string + PostParentId string + PostOriginalId string + PostMessage string + PostType string + PostProps string + PostHashtags string + PostFilenames string +} + +func CompliancePostHeader() []string { + return []string{ + "TeamName", + "TeamDisplayName", + + "ChannelName", + "ChannelDisplayName", + + "UserUsername", + "UserEmail", + "UserNickname", + + "PostId", + "PostCreateAt", + "PostUpdateAt", + "PostDeleteAt", + "PostRootId", + "PostParentId", + "PostOriginalId", + "PostMessage", + "PostType", + "PostProps", + "PostHashtags", + "PostFilenames", + } +} + +func (me *CompliancePost) Row() []string { + + postDeleteAt := "" + if me.PostDeleteAt > 0 { + postDeleteAt = time.Unix(0, me.PostDeleteAt*int64(1000*1000)).Format(time.RFC3339) + } + + postUpdateAt := "" + if me.PostUpdateAt != me.PostCreateAt { + postUpdateAt = time.Unix(0, me.PostUpdateAt*int64(1000*1000)).Format(time.RFC3339) + } + + return []string{ + me.TeamName, + me.TeamDisplayName, + + me.ChannelName, + me.ChannelDisplayName, + + me.UserUsername, + me.UserEmail, + me.UserNickname, + + me.PostId, + time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339), + postUpdateAt, + postDeleteAt, + + me.PostRootId, + me.PostParentId, + me.PostOriginalId, + me.PostMessage, + me.PostType, + me.PostProps, + me.PostHashtags, + me.PostFilenames, + } +} diff --git a/model/compliance_post_test.go b/model/compliance_post_test.go new file mode 100644 index 000000000..28e20ba4b --- /dev/null +++ b/model/compliance_post_test.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "testing" +) + +func TestCompliancePostHeader(t *testing.T) { + if CompliancePostHeader()[0] != "TeamName" { + t.Fatal() + } +} + +func TestCompliancePost(t *testing.T) { + o := CompliancePost{TeamName: "test", PostFilenames: "files", PostCreateAt: GetMillis()} + r := o.Row() + + if r[0] != "test" { + t.Fatal() + } + + if r[len(r)-1] != "files" { + t.Fatal() + } +} diff --git a/model/compliance_test.go b/model/compliance_test.go new file mode 100644 index 000000000..6acc5a882 --- /dev/null +++ b/model/compliance_test.go @@ -0,0 +1,19 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "strings" + "testing" +) + +func TestCompliance(t *testing.T) { + o := Compliance{Desc: "test", CreateAt: GetMillis()} + json := o.ToJson() + result := ComplianceFromJson(strings.NewReader(json)) + + if o.Desc != result.Desc { + t.Fatal("JobName do not match") + } +} diff --git a/model/config.go b/model/config.go index d684c72b2..3ca241275 100644 --- a/model/config.go +++ b/model/config.go @@ -179,19 +179,26 @@ type LdapSettings struct { QueryTimeout *int } +type ComplianceSettings struct { + Enable *bool + Directory *string + EnableDaily *bool +} + type Config struct { - ServiceSettings ServiceSettings - TeamSettings TeamSettings - SqlSettings SqlSettings - LogSettings LogSettings - FileSettings FileSettings - EmailSettings EmailSettings - RateLimitSettings RateLimitSettings - PrivacySettings PrivacySettings - SupportSettings SupportSettings - GitLabSettings SSOSettings - GoogleSettings SSOSettings - LdapSettings LdapSettings + ServiceSettings ServiceSettings + TeamSettings TeamSettings + SqlSettings SqlSettings + LogSettings LogSettings + FileSettings FileSettings + EmailSettings EmailSettings + RateLimitSettings RateLimitSettings + PrivacySettings PrivacySettings + SupportSettings SupportSettings + GitLabSettings SSOSettings + GoogleSettings SSOSettings + LdapSettings LdapSettings + ComplianceSettings ComplianceSettings } func (o *Config) ToJson() string { @@ -402,6 +409,21 @@ func (o *Config) SetDefaults() { o.ServiceSettings.WebserverMode = new(string) *o.ServiceSettings.WebserverMode = "regular" } + + if o.ComplianceSettings.Enable == nil { + o.ComplianceSettings.Enable = new(bool) + *o.ComplianceSettings.Enable = false + } + + if o.ComplianceSettings.Directory == nil { + o.ComplianceSettings.Directory = new(string) + *o.ComplianceSettings.Directory = "./data/" + } + + if o.ComplianceSettings.EnableDaily == nil { + o.ComplianceSettings.EnableDaily = new(bool) + *o.ComplianceSettings.EnableDaily = false + } } func (o *Config) IsValid() *AppError { diff --git a/model/license.go b/model/license.go index ea66fef0d..8461c9f76 100644 --- a/model/license.go +++ b/model/license.go @@ -32,9 +32,10 @@ type Customer struct { } type Features struct { - Users *int `json:"users"` - LDAP *bool `json:"ldap"` - GoogleSSO *bool `json:"google_sso"` + Users *int `json:"users"` + LDAP *bool `json:"ldap"` + GoogleSSO *bool `json:"google_sso"` + Compliance *bool `json:"compliance"` } func (f *Features) SetDefaults() { @@ -52,6 +53,11 @@ func (f *Features) SetDefaults() { f.GoogleSSO = new(bool) *f.GoogleSSO = true } + + if f.Compliance == nil { + f.Compliance = new(bool) + *f.Compliance = true + } } func (l *License) IsExpired() bool { diff --git a/model/system.go b/model/system.go index b387749f6..68d542c15 100644 --- a/model/system.go +++ b/model/system.go @@ -9,10 +9,11 @@ import ( ) const ( - SYSTEM_DIAGNOSTIC_ID = "DiagnosticId" - SYSTEM_RAN_UNIT_TESTS = "RanUnitTests" - SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime" - SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId" + SYSTEM_DIAGNOSTIC_ID = "DiagnosticId" + SYSTEM_RAN_UNIT_TESTS = "RanUnitTests" + SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime" + SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId" + SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime" ) type System struct { |