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  }