github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/sqlstore/compliance_store.go (about)

     1  // Copyright (c) 2016-present Xenia, 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/xzl8028/xenia-server/model"
    12  	"github.com/xzl8028/xenia-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) (*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 (us 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 := us.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 (us SqlComplianceStore) Get(id string) (*model.Compliance, *model.AppError) {
    73  	obj, err := us.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, err.Error(), 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  			if index >= 1 {
    94  				keywordQuery += " OR LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index)
    95  			} else {
    96  				keywordQuery += "LOWER(Posts.Message) LIKE :Keyword" + strconv.Itoa(index)
    97  			}
    98  
    99  			props["Keyword"+strconv.Itoa(index)] = "%" + keyword + "%"
   100  		}
   101  
   102  		keywordQuery += ")"
   103  	}
   104  
   105  	emailQuery := ""
   106  	emails := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(job.Emails, ",", " ", -1))))
   107  	if len(emails) > 0 {
   108  
   109  		emailQuery = "AND ("
   110  
   111  		for index, email := range emails {
   112  			if index >= 1 {
   113  				emailQuery += " OR Users.Email = :Email" + strconv.Itoa(index)
   114  			} else {
   115  				emailQuery += "Users.Email = :Email" + strconv.Itoa(index)
   116  			}
   117  
   118  			props["Email"+strconv.Itoa(index)] = email
   119  		}
   120  
   121  		emailQuery += ")"
   122  	}
   123  
   124  	query :=
   125  		`(SELECT
   126  			Teams.Name AS TeamName,
   127  			Teams.DisplayName AS TeamDisplayName,
   128  			Channels.Name AS ChannelName,
   129  			Channels.DisplayName AS ChannelDisplayName,
   130  			Channels.Type AS ChannelType,
   131  			Users.Username AS UserUsername,
   132  			Users.Email AS UserEmail,
   133  			Users.Nickname AS UserNickname,
   134  			Posts.Id AS PostId,
   135  			Posts.CreateAt AS PostCreateAt,
   136  			Posts.UpdateAt AS PostUpdateAt,
   137  			Posts.DeleteAt AS PostDeleteAt,
   138  			Posts.RootId AS PostRootId,
   139  			Posts.ParentId AS PostParentId,
   140  			Posts.OriginalId AS PostOriginalId,
   141  			Posts.Message AS PostMessage,
   142  			Posts.Type AS PostType,
   143  			Posts.Props AS PostProps,
   144  			Posts.Hashtags AS PostHashtags,
   145  			Posts.FileIds AS PostFileIds,
   146  			Bots.UserId IS NOT NULL AS IsBot
   147  		FROM
   148  			Teams,
   149  			Channels,
   150  			Users,
   151  			Posts
   152          LEFT JOIN Bots ON Bots.UserId = Posts.UserId
   153  		WHERE
   154  			Teams.Id = Channels.TeamId
   155  				AND Posts.ChannelId = Channels.Id
   156  				AND Posts.UserId = Users.Id
   157  				AND Posts.CreateAt > :StartTime
   158  				AND Posts.CreateAt <= :EndTime
   159  				` + emailQuery + `
   160  				` + keywordQuery + `)
   161  		UNION ALL
   162  		(SELECT
   163  			'direct-messages' AS TeamName,
   164  			'Direct Messages' AS TeamDisplayName,
   165  			Channels.Name AS ChannelName,
   166  			Channels.DisplayName AS ChannelDisplayName,
   167  			Channels.Type AS ChannelType,
   168  			Users.Username AS UserUsername,
   169  			Users.Email AS UserEmail,
   170  			Users.Nickname AS UserNickname,
   171  			Posts.Id AS PostId,
   172  			Posts.CreateAt AS PostCreateAt,
   173  			Posts.UpdateAt AS PostUpdateAt,
   174  			Posts.DeleteAt AS PostDeleteAt,
   175  			Posts.RootId AS PostRootId,
   176  			Posts.ParentId AS PostParentId,
   177  			Posts.OriginalId AS PostOriginalId,
   178  			Posts.Message AS PostMessage,
   179  			Posts.Type AS PostType,
   180  			Posts.Props AS PostProps,
   181  			Posts.Hashtags AS PostHashtags,
   182  			Posts.FileIds AS PostFileIds,
   183  			Bots.UserId IS NOT NULL AS IsBot
   184  		FROM
   185  			Channels,
   186  			Users,
   187  			Posts
   188  		LEFT JOIN Bots ON Bots.UserId = Posts.UserId
   189  		WHERE
   190  			Channels.TeamId = ''
   191  				AND Posts.ChannelId = Channels.Id
   192  				AND Posts.UserId = Users.Id
   193  				AND Posts.CreateAt > :StartTime
   194  				AND Posts.CreateAt <= :EndTime
   195  				` + emailQuery + `
   196  				` + keywordQuery + `)
   197  		ORDER BY PostCreateAt
   198  		LIMIT 30000`
   199  
   200  	var cposts []*model.CompliancePost
   201  
   202  	if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
   203  		return nil, model.NewAppError("SqlPostStore.ComplianceExport", "store.sql_post.compliance_export.app_error", nil, err.Error(), http.StatusInternalServerError)
   204  	}
   205  	return cposts, nil
   206  }
   207  
   208  func (s SqlComplianceStore) MessageExport(after int64, limit int) ([]*model.MessageExport, *model.AppError) {
   209  	props := map[string]interface{}{"StartTime": after, "Limit": limit}
   210  	query :=
   211  		`SELECT
   212  			Posts.Id AS PostId,
   213  			Posts.CreateAt AS PostCreateAt,
   214  			Posts.Message AS PostMessage,
   215  			Posts.Type AS PostType,
   216  			Posts.OriginalId AS PostOriginalId,
   217  			Posts.RootId AS PostRootId,
   218  			Posts.Props AS PostProps,
   219  			Posts.FileIds AS PostFileIds,
   220  			Teams.Id AS TeamId,
   221  			Teams.Name AS TeamName,
   222  			Teams.DisplayName AS TeamDisplayName,
   223  			Channels.Id AS ChannelId,
   224  			CASE
   225  				WHEN Channels.Type = 'D' THEN 'Direct Message'
   226  				WHEN Channels.Type = 'G' THEN 'Group Message'
   227  				ELSE Channels.DisplayName
   228  			END AS ChannelDisplayName,
   229  			Channels.Name AS ChannelName,
   230  			Channels.Type AS ChannelType,
   231  			Users.Id AS UserId,
   232  			Users.Email AS UserEmail,
   233  			Users.Username,
   234  			Bots.UserId IS NOT NULL AS IsBot
   235  		FROM
   236  			Posts
   237  		LEFT OUTER JOIN Channels ON Posts.ChannelId = Channels.Id
   238  		LEFT OUTER JOIN Teams ON Channels.TeamId = Teams.Id
   239  		LEFT OUTER JOIN Users ON Posts.UserId = Users.Id
   240  		LEFT JOIN Bots ON Bots.UserId = Posts.UserId
   241  		WHERE
   242  			Posts.CreateAt > :StartTime AND
   243  			Posts.Type = ''
   244  		ORDER BY PostCreateAt
   245  		LIMIT :Limit`
   246  
   247  	var cposts []*model.MessageExport
   248  	if _, err := s.GetReplica().Select(&cposts, query, props); err != nil {
   249  		return nil, model.NewAppError("SqlComplianceStore.MessageExport", "store.sql_compliance.message_export.app_error", nil, err.Error(), http.StatusInternalServerError)
   250  	}
   251  	return cposts, nil
   252  }