github.com/teloshs/mattermost-server@v5.11.1+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  			    Channels.Type AS ChannelType,
   142  			    Users.Username AS UserUsername,
   143  			    Users.Email AS UserEmail,
   144  			    Users.Nickname AS UserNickname,
   145  			    Posts.Id AS PostId,
   146  			    Posts.CreateAt AS PostCreateAt,
   147  			    Posts.UpdateAt AS PostUpdateAt,
   148  			    Posts.DeleteAt AS PostDeleteAt,
   149  			    Posts.RootId AS PostRootId,
   150  			    Posts.ParentId AS PostParentId,
   151  			    Posts.OriginalId AS PostOriginalId,
   152  			    Posts.Message AS PostMessage,
   153  			    Posts.Type AS PostType,
   154  			    Posts.Props AS PostProps,
   155  			    Posts.Hashtags AS PostHashtags,
   156  			    Posts.FileIds AS PostFileIds
   157  			FROM
   158  			    Teams,
   159  			    Channels,
   160  			    Users,
   161  			    Posts
   162  			WHERE
   163  			    Teams.Id = Channels.TeamId
   164  			        AND Posts.ChannelId = Channels.Id
   165  			        AND Posts.UserId = Users.Id
   166  			        AND Posts.CreateAt > :StartTime
   167  			        AND Posts.CreateAt <= :EndTime
   168  			        ` + emailQuery + `
   169  			        ` + keywordQuery + `)
   170  			UNION ALL
   171  			(SELECT
   172  			    'direct-messages' AS TeamName,
   173  			    'Direct Messages' AS TeamDisplayName,
   174  			    Channels.Name AS ChannelName,
   175  			    Channels.DisplayName AS ChannelDisplayName,
   176  			    Channels.Type AS ChannelType,
   177  			    Users.Username AS UserUsername,
   178  			    Users.Email AS UserEmail,
   179  			    Users.Nickname AS UserNickname,
   180  			    Posts.Id AS PostId,
   181  			    Posts.CreateAt AS PostCreateAt,
   182  			    Posts.UpdateAt AS PostUpdateAt,
   183  			    Posts.DeleteAt AS PostDeleteAt,
   184  			    Posts.RootId AS PostRootId,
   185  			    Posts.ParentId AS PostParentId,
   186  			    Posts.OriginalId AS PostOriginalId,
   187  			    Posts.Message AS PostMessage,
   188  			    Posts.Type AS PostType,
   189  			    Posts.Props AS PostProps,
   190  			    Posts.Hashtags AS PostHashtags,
   191  			    Posts.FileIds AS PostFileIds
   192  			FROM
   193  			    Channels,
   194  			    Users,
   195  			    Posts
   196  			WHERE
   197  			    Channels.TeamId = ''
   198  			        AND Posts.ChannelId = Channels.Id
   199  			        AND Posts.UserId = Users.Id
   200  			        AND Posts.CreateAt > :StartTime
   201  			        AND Posts.CreateAt <= :EndTime
   202  			        ` + emailQuery + `
   203  			        ` + keywordQuery + `)
   204  			ORDER BY PostCreateAt
   205  			LIMIT 30000`
   206  
   207  		var cposts []*model.CompliancePost
   208  
   209  		if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
   210  			result.Err = model.NewAppError("SqlPostStore.ComplianceExport", "store.sql_post.compliance_export.app_error", nil, err.Error(), http.StatusInternalServerError)
   211  		} else {
   212  			result.Data = cposts
   213  		}
   214  	})
   215  }
   216  
   217  func (s SqlComplianceStore) MessageExport(after int64, limit int) store.StoreChannel {
   218  	return store.Do(func(result *store.StoreResult) {
   219  		props := map[string]interface{}{"StartTime": after, "Limit": limit}
   220  		query :=
   221  			`SELECT
   222  				Posts.Id AS PostId,
   223  				Posts.CreateAt AS PostCreateAt,
   224  				Posts.Message AS PostMessage,
   225  				Posts.Type AS PostType,
   226  				Posts.OriginalId AS PostOriginalId,
   227  				Posts.RootId AS PostRootId,
   228  				Posts.FileIds AS PostFileIds,
   229  				Teams.Id AS TeamId,
   230  				Teams.Name AS TeamName,
   231  				Teams.DisplayName AS TeamDisplayName,
   232  				Channels.Id AS ChannelId,
   233  				CASE
   234  					WHEN Channels.Type = 'D' THEN 'Direct Message'
   235  					WHEN Channels.Type = 'G' THEN 'Group Message'
   236  					ELSE Channels.DisplayName
   237  				END AS ChannelDisplayName,
   238  				Channels.Name AS ChannelName,
   239  				Channels.Type AS ChannelType,
   240  				Users.Id AS UserId,
   241  				Users.Email AS UserEmail,
   242  				Users.Username
   243  			FROM
   244  				Posts
   245  				LEFT OUTER JOIN Channels ON Posts.ChannelId = Channels.Id
   246  				LEFT OUTER JOIN Teams ON Channels.TeamId = Teams.Id
   247  				LEFT OUTER JOIN Users ON Posts.UserId = Users.Id
   248  			WHERE
   249  				Posts.CreateAt > :StartTime AND
   250  				Posts.Type = ''
   251  			ORDER BY PostCreateAt
   252  			LIMIT :Limit`
   253  
   254  		var cposts []*model.MessageExport
   255  		if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
   256  			result.Err = model.NewAppError("SqlComplianceStore.MessageExport", "store.sql_compliance.message_export.app_error", nil, err.Error(), http.StatusInternalServerError)
   257  		} else {
   258  			result.Data = cposts
   259  		}
   260  	})
   261  }