github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/store/sqlstore/compliance_store.go (about)

     1  // Copyright (c) 2015-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/vnforks/kid/v5/model"
    12  	"github.com/vnforks/kid/v5/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) (*model.Compliance, *model.AppError) {
    40  	compliance.PreSave()
    41  	if err := compliance.IsValid(); err != nil {
    42  		return nil, err
    43  	}
    44  
    45  	if err := s.GetMaster().Insert(compliance); err != nil {
    46  		return nil, model.NewAppError("SqlComplianceStore.Save", "store.sql_compliance.save.saving.app_error", nil, err.Error(), http.StatusInternalServerError)
    47  	}
    48  	return compliance, nil
    49  }
    50  
    51  func (s SqlComplianceStore) Update(compliance *model.Compliance) (*model.Compliance, *model.AppError) {
    52  	if err := compliance.IsValid(); err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	if _, err := s.GetMaster().Update(compliance); err != nil {
    57  		return nil, model.NewAppError("SqlComplianceStore.Update", "store.sql_compliance.save.saving.app_error", nil, err.Error(), http.StatusInternalServerError)
    58  	}
    59  	return compliance, nil
    60  }
    61  
    62  func (s SqlComplianceStore) GetAll(offset, limit int) (model.Compliances, *model.AppError) {
    63  	query := "SELECT * FROM Compliances ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset"
    64  
    65  	var compliances model.Compliances
    66  	if _, err := s.GetReplica().Select(&compliances, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
    67  		return nil, model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusInternalServerError)
    68  	}
    69  	return compliances, nil
    70  }
    71  
    72  func (s SqlComplianceStore) Get(id string) (*model.Compliance, *model.AppError) {
    73  	obj, err := s.GetReplica().Get(model.Compliance{}, id)
    74  	if err != nil {
    75  		return nil, model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, err.Error(), http.StatusInternalServerError)
    76  	}
    77  	if obj == nil {
    78  		return nil, model.NewAppError("SqlComplianceStore.Get", "store.sql_compliance.get.finding.app_error", nil, "", http.StatusNotFound)
    79  	}
    80  	return obj.(*model.Compliance), nil
    81  }
    82  
    83  func (s SqlComplianceStore) ComplianceExport(job *model.Compliance) ([]*model.CompliancePost, *model.AppError) {
    84  	props := map[string]interface{}{"StartTime": job.StartAt, "EndTime": job.EndAt}
    85  
    86  	keywordQuery := ""
    87  	keywords := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Keywords, ",", " ", -1))))
    88  	if len(keywords) > 0 {
    89  
    90  		keywordQuery = "AND ("
    91  
    92  		for index, keyword := range keywords {
    93  			keyword = sanitizeSearchTerm(keyword, "\\")
    94  			if index >= 1 {
    95  				keywordQuery += " OR LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index)
    96  			} else {
    97  				keywordQuery += "LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index)
    98  			}
    99  
   100  			props["Keyword"+strconv.Itoa(index)] = "%" + keyword + "%"
   101  		}
   102  
   103  		keywordQuery += ")"
   104  	}
   105  
   106  	emailQuery := ""
   107  	emails := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Emails, ",", " ", -1))))
   108  	if len(emails) > 0 {
   109  
   110  		emailQuery = "AND ("
   111  
   112  		for index, email := range emails {
   113  			if index >= 1 {
   114  				emailQuery += " OR Users.Email = :Email" + strconv.Itoa(index)
   115  			} else {
   116  				emailQuery += "Users.Email = :Email" + strconv.Itoa(index)
   117  			}
   118  
   119  			props["Email"+strconv.Itoa(index)] = email
   120  		}
   121  
   122  		emailQuery += ")"
   123  	}
   124  
   125  	query :=
   126  		`(SELECT
   127  			Branches.Name AS BranchName,
   128  			Branches.DisplayName AS BranchDisplayName,
   129  			Classes.Name AS ClassName,
   130  			Classes.DisplayName AS ClassDisplayName,
   131  			Classes.Type AS ClassType,
   132  			Users.Username AS UserUsername,
   133  			Users.Email AS UserEmail,
   134  			Users.Nickname AS UserNickname,
   135  			Posts.Id AS PostId,
   136  			Posts.CreateAt AS PostCreateAt,
   137  			Posts.UpdateAt AS PostUpdateAt,
   138  			Posts.DeleteAt AS PostDeleteAt,
   139  			Posts.RootId AS PostRootId,
   140  			Posts.ParentId AS PostParentId,
   141  			Posts.OriginalId AS PostOriginalId,
   142  			Posts.Message AS PostMessage,
   143  			Posts.Type AS PostType,
   144  			Posts.Props AS PostProps,
   145  			Posts.Hashtags AS PostHashtags,
   146  			Posts.FileIds AS PostFileIds,
   147  		FROM
   148  			Branches,
   149  			Classes,
   150  			Users,
   151  			Posts
   152  		WHERE
   153  			Branches.Id = Classes.BranchId
   154  				AND Posts.ClassId = Classes.Id
   155  				AND Posts.UserId = Users.Id
   156  				AND Posts.CreateAt > :StartTime
   157  				AND Posts.CreateAt <= :EndTime
   158  				` + emailQuery + `
   159  				` + keywordQuery + `)
   160  		UNION ALL
   161  		(SELECT
   162  			'direct-messages' AS BranchName,
   163  			'Direct Messages' AS BranchDisplayName,
   164  			Classes.Name AS ClassName,
   165  			Classes.DisplayName AS ClassDisplayName,
   166  			Classes.Type AS ClassType,
   167  			Users.Username AS UserUsername,
   168  			Users.Email AS UserEmail,
   169  			Users.Nickname AS UserNickname,
   170  			Posts.Id AS PostId,
   171  			Posts.CreateAt AS PostCreateAt,
   172  			Posts.UpdateAt AS PostUpdateAt,
   173  			Posts.DeleteAt AS PostDeleteAt,
   174  			Posts.RootId AS PostRootId,
   175  			Posts.ParentId AS PostParentId,
   176  			Posts.OriginalId AS PostOriginalId,
   177  			Posts.Message AS PostMessage,
   178  			Posts.Type AS PostType,
   179  			Posts.Props AS PostProps,
   180  			Posts.Hashtags AS PostHashtags,
   181  			Posts.FileIds AS PostFileIds,
   182  		FROM
   183  			Classes,
   184  			Users,
   185  			Posts
   186  		WHERE
   187  			Classes.BranchId = ''
   188  				AND Posts.ClassId = Classes.Id
   189  				AND Posts.UserId = Users.Id
   190  				AND Posts.CreateAt > :StartTime
   191  				AND Posts.CreateAt <= :EndTime
   192  				` + emailQuery + `
   193  				` + keywordQuery + `)
   194  		ORDER BY PostCreateAt
   195  		LIMIT 30000`
   196  
   197  	var cposts []*model.CompliancePost
   198  
   199  	if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
   200  		return nil, model.NewAppError("SqlPostStore.ComplianceExport", "store.sql_post.compliance_export.app_error", nil, err.Error(), http.StatusInternalServerError)
   201  	}
   202  	return cposts, nil
   203  }
   204  
   205  func (s SqlComplianceStore) MessageExport(after int64, limit int) ([]*model.MessageExport, *model.AppError) {
   206  	props := map[string]interface{}{"StartTime": after, "Limit": limit}
   207  	query :=
   208  		`SELECT
   209  			Posts.Id AS PostId,
   210  			Posts.CreateAt AS PostCreateAt,
   211  			Posts.UpdateAt AS PostUpdateAt,
   212  			Posts.DeleteAt AS PostDeleteAt,
   213  			Posts.Message AS PostMessage,
   214  			Posts.Type AS PostType,
   215  			Posts.Props AS PostProps,
   216  			Posts.OriginalId AS PostOriginalId,
   217  			Posts.RootId AS PostRootId,
   218  			Posts.Props AS PostProps,
   219  			Posts.FileIds AS PostFileIds,
   220  			Branches.Id AS BranchId,
   221  			Branches.Name AS BranchName,
   222  			Branches.DisplayName AS BranchDisplayName,
   223  			Classes.Id AS ClassId,
   224  			CASE
   225  				WHEN Classes.Type = 'D' THEN 'Direct Message'
   226  				WHEN Classes.Type = 'G' THEN 'Group Message'
   227  				ELSE Classes.DisplayName
   228  			END AS ClassDisplayName,
   229  			Classes.Name AS ClassName,
   230  			Classes.Type AS ClassType,
   231  			Users.Id AS UserId,
   232  			Users.Email AS UserEmail,
   233  			Users.Username,
   234  		FROM
   235  			Posts
   236  		LEFT OUTER JOIN Classes ON Posts.ClassId = Classes.Id
   237  		LEFT OUTER JOIN Branches ON Classes.BranchId = Branches.Id
   238  		LEFT OUTER JOIN Users ON Posts.UserId = Users.Id
   239  		WHERE
   240  			(Posts.CreateAt > :StartTime OR Posts.UpdateAt > :StartTime OR Posts.DeleteAt > :StartTime) AND
   241  			Posts.Type NOT LIKE 'system_%'
   242  		ORDER BY PostUpdateAt
   243  		LIMIT :Limit`
   244  
   245  	var cposts []*model.MessageExport
   246  	if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
   247  		return nil, model.NewAppError("SqlComplianceStore.MessageExport", "store.sql_compliance.message_export.app_error", nil, err.Error(), http.StatusInternalServerError)
   248  	}
   249  	return cposts, nil
   250  }