From 36b17bf99ddd35c0c223722f8b6f4f1c71b2235e Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Mon, 14 Mar 2016 16:07:58 -0700 Subject: PLT-2115 Adding compliance --- model/client.go | 36 +++++++++++++ model/compliance.go | 132 +++++++++++++++++++++++++++++++++++++++++++++++ model/compliance_post.go | 18 +++++-- model/compliance_test.go | 19 +++++++ model/config.go | 46 ++++++++++++----- model/license.go | 12 +++-- 6 files changed, 245 insertions(+), 18 deletions(-) create mode 100644 model/compliance.go create mode 100644 model/compliance_test.go (limited to 'model') diff --git a/model/client.go b/model/client.go index 3adcb980d..f5c8ad641 100644 --- a/model/client.go +++ b/model/client.go @@ -471,6 +471,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 index 636be8f17..ce26a3660 100644 --- a/model/compliance_post.go +++ b/model/compliance_post.go @@ -65,6 +65,17 @@ func CompliancePostHeader() []string { } 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, @@ -77,9 +88,10 @@ func (me *CompliancePost) Row() []string { me.UserNickname, me.PostId, - time.Unix(0, me.PostCreateAt*1000).Format(time.RFC3339), - time.Unix(0, me.PostUpdateAt*1000).Format(time.RFC3339), - time.Unix(0, me.PostDeleteAt*1000).Format(time.RFC3339), + time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339), + postUpdateAt, + postDeleteAt, + me.PostRootId, me.PostParentId, me.PostOriginalId, 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 82c51224e..8f5865f28 100644 --- a/model/config.go +++ b/model/config.go @@ -170,19 +170,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 { @@ -383,6 +390,21 @@ func (o *Config) SetDefaults() { o.ServiceSettings.AllowCorsFrom = new(string) *o.ServiceSettings.AllowCorsFrom = "" } + + 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 { -- cgit v1.2.3-1-g7c22