github.com/wgh-/mattermost-server@v4.8.0-rc2+incompatible/store/sqlstore/compliance_store.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "net/http" 8 "strconv" 9 "strings" 10 11 "github.com/mattermost/mattermost-server/model" 12 "github.com/mattermost/mattermost-server/store" 13 ) 14 15 type SqlComplianceStore struct { 16 SqlStore 17 } 18 19 func NewSqlComplianceStore(sqlStore SqlStore) store.ComplianceStore { 20 s := &SqlComplianceStore{sqlStore} 21 22 for _, db := range sqlStore.GetAllConns() { 23 table := db.AddTableWithName(model.Compliance{}, "Compliances").SetKeys(false, "Id") 24 table.ColMap("Id").SetMaxSize(26) 25 table.ColMap("UserId").SetMaxSize(26) 26 table.ColMap("Status").SetMaxSize(64) 27 table.ColMap("Desc").SetMaxSize(512) 28 table.ColMap("Type").SetMaxSize(64) 29 table.ColMap("Keywords").SetMaxSize(512) 30 table.ColMap("Emails").SetMaxSize(1024) 31 } 32 33 return s 34 } 35 36 func (s SqlComplianceStore) CreateIndexesIfNotExists() { 37 } 38 39 func (s SqlComplianceStore) Save(compliance *model.Compliance) store.StoreChannel { 40 return store.Do(func(result *store.StoreResult) { 41 compliance.PreSave() 42 if result.Err = compliance.IsValid(); result.Err != nil { 43 return 44 } 45 46 if err := s.GetMaster().Insert(compliance); err != nil { 47 result.Err = model.NewAppError("SqlComplianceStore.Save", "store.sql_compliance.save.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 48 } else { 49 result.Data = compliance 50 } 51 }) 52 } 53 54 func (us SqlComplianceStore) Update(compliance *model.Compliance) store.StoreChannel { 55 return store.Do(func(result *store.StoreResult) { 56 if result.Err = compliance.IsValid(); result.Err != nil { 57 return 58 } 59 60 if _, err := us.GetMaster().Update(compliance); err != nil { 61 result.Err = model.NewAppError("SqlComplianceStore.Update", "store.sql_compliance.save.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 62 } else { 63 result.Data = compliance 64 } 65 }) 66 } 67 68 func (s SqlComplianceStore) GetAll(offset, limit int) store.StoreChannel { 69 return store.Do(func(result *store.StoreResult) { 70 query := "SELECT * FROM Compliances ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset" 71 72 var compliances model.Compliances 73 if _, err := s.GetReplica().Select(&compliances, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 74 result.Err = model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusInternalServerError) 75 } else { 76 result.Data = compliances 77 } 78 }) 79 } 80 81 func (us SqlComplianceStore) Get(id string) store.StoreChannel { 82 return store.Do(func(result *store.StoreResult) { 83 if obj, err := us.GetReplica().Get(model.Compliance{}, id); err != nil { 84 result.Err = model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusInternalServerError) 85 } else if obj == nil { 86 result.Err = model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusNotFound) 87 } else { 88 result.Data = obj.(*model.Compliance) 89 } 90 }) 91 } 92 93 func (s SqlComplianceStore) ComplianceExport(job *model.Compliance) store.StoreChannel { 94 return store.Do(func(result *store.StoreResult) { 95 props := map[string]interface{}{"StartTime": job.StartAt, "EndTime": job.EndAt} 96 97 keywordQuery := "" 98 keywords := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Keywords, ",", " ", -1)))) 99 if len(keywords) > 0 { 100 101 keywordQuery = "AND (" 102 103 for index, keyword := range keywords { 104 if index >= 1 { 105 keywordQuery += " OR LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index) 106 } else { 107 keywordQuery += "LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index) 108 } 109 110 props["Keyword"+strconv.Itoa(index)] = "%" + keyword + "%" 111 } 112 113 keywordQuery += ")" 114 } 115 116 emailQuery := "" 117 emails := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Emails, ",", " ", -1)))) 118 if len(emails) > 0 { 119 120 emailQuery = "AND (" 121 122 for index, email := range emails { 123 if index >= 1 { 124 emailQuery += " OR Users.Email = :Email" + strconv.Itoa(index) 125 } else { 126 emailQuery += "Users.Email = :Email" + strconv.Itoa(index) 127 } 128 129 props["Email"+strconv.Itoa(index)] = email 130 } 131 132 emailQuery += ")" 133 } 134 135 query := 136 `(SELECT 137 Teams.Name AS TeamName, 138 Teams.DisplayName AS TeamDisplayName, 139 Channels.Name AS ChannelName, 140 Channels.DisplayName AS ChannelDisplayName, 141 Users.Username AS UserUsername, 142 Users.Email AS UserEmail, 143 Users.Nickname AS UserNickname, 144 Posts.Id AS PostId, 145 Posts.CreateAt AS PostCreateAt, 146 Posts.UpdateAt AS PostUpdateAt, 147 Posts.DeleteAt AS PostDeleteAt, 148 Posts.RootId AS PostRootId, 149 Posts.ParentId AS PostParentId, 150 Posts.OriginalId AS PostOriginalId, 151 Posts.Message AS PostMessage, 152 Posts.Type AS PostType, 153 Posts.Props AS PostProps, 154 Posts.Hashtags AS PostHashtags, 155 Posts.FileIds AS PostFileIds 156 FROM 157 Teams, 158 Channels, 159 Users, 160 Posts 161 WHERE 162 Teams.Id = Channels.TeamId 163 AND Posts.ChannelId = Channels.Id 164 AND Posts.UserId = Users.Id 165 AND Posts.CreateAt > :StartTime 166 AND Posts.CreateAt <= :EndTime 167 ` + emailQuery + ` 168 ` + keywordQuery + `) 169 UNION ALL 170 (SELECT 171 'direct-messages' AS TeamName, 172 'Direct Messages' AS TeamDisplayName, 173 Channels.Name AS ChannelName, 174 Channels.DisplayName AS ChannelDisplayName, 175 Users.Username AS UserUsername, 176 Users.Email AS UserEmail, 177 Users.Nickname AS UserNickname, 178 Posts.Id AS PostId, 179 Posts.CreateAt AS PostCreateAt, 180 Posts.UpdateAt AS PostUpdateAt, 181 Posts.DeleteAt AS PostDeleteAt, 182 Posts.RootId AS PostRootId, 183 Posts.ParentId AS PostParentId, 184 Posts.OriginalId AS PostOriginalId, 185 Posts.Message AS PostMessage, 186 Posts.Type AS PostType, 187 Posts.Props AS PostProps, 188 Posts.Hashtags AS PostHashtags, 189 Posts.FileIds AS PostFileIds 190 FROM 191 Channels, 192 Users, 193 Posts 194 WHERE 195 Channels.TeamId = '' 196 AND Posts.ChannelId = Channels.Id 197 AND Posts.UserId = Users.Id 198 AND Posts.CreateAt > :StartTime 199 AND Posts.CreateAt <= :EndTime 200 ` + emailQuery + ` 201 ` + keywordQuery + `) 202 ORDER BY PostCreateAt 203 LIMIT 30000` 204 205 var cposts []*model.CompliancePost 206 207 if _, err := s.GetReplica().Select(&cposts, query, props); err != nil { 208 result.Err = model.NewAppError("SqlPostStore.ComplianceExport", "store.sql_post.compliance_export.app_error", nil, err.Error(), http.StatusInternalServerError) 209 } else { 210 result.Data = cposts 211 } 212 }) 213 } 214 215 func (s SqlComplianceStore) MessageExport(after int64, limit int) store.StoreChannel { 216 return store.Do(func(result *store.StoreResult) { 217 props := map[string]interface{}{"StartTime": after, "Limit": limit} 218 query := 219 `SELECT 220 Posts.Id AS PostId, 221 Posts.CreateAt AS PostCreateAt, 222 Posts.Message AS PostMessage, 223 Posts.Type AS PostType, 224 Posts.FileIds AS PostFileIds, 225 Channels.Id AS ChannelId, 226 Channels.DisplayName AS ChannelDisplayName, 227 Users.Id AS UserId, 228 Users.Email AS UserEmail, 229 Users.Username 230 FROM 231 Posts 232 LEFT OUTER JOIN Channels ON Posts.ChannelId = Channels.Id 233 LEFT OUTER JOIN Users ON Posts.UserId = Users.Id 234 WHERE 235 Posts.CreateAt > :StartTime AND 236 Posts.Type = '' 237 ORDER BY PostCreateAt 238 LIMIT :Limit` 239 240 var cposts []*model.MessageExport 241 if _, err := s.GetReplica().Select(&cposts, query, props); err != nil { 242 result.Err = model.NewAppError("SqlComplianceStore.MessageExport", "store.sql_compliance.message_export.app_error", nil, err.Error(), http.StatusInternalServerError) 243 } else { 244 result.Data = cposts 245 } 246 }) 247 }