github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/sqlstore/webhook_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  	"database/sql"
     8  
     9  	"github.com/pkg/errors"
    10  
    11  	sq "github.com/Masterminds/squirrel"
    12  	"github.com/mattermost/mattermost-server/v5/einterfaces"
    13  	"github.com/mattermost/mattermost-server/v5/model"
    14  	"github.com/mattermost/mattermost-server/v5/store"
    15  )
    16  
    17  type SqlWebhookStore struct {
    18  	SqlStore
    19  	metrics einterfaces.MetricsInterface
    20  }
    21  
    22  func (s SqlWebhookStore) ClearCaches() {
    23  }
    24  
    25  func newSqlWebhookStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.WebhookStore {
    26  	s := &SqlWebhookStore{
    27  		SqlStore: sqlStore,
    28  		metrics:  metrics,
    29  	}
    30  
    31  	for _, db := range sqlStore.GetAllConns() {
    32  		table := db.AddTableWithName(model.IncomingWebhook{}, "IncomingWebhooks").SetKeys(false, "Id")
    33  		table.ColMap("Id").SetMaxSize(26)
    34  		table.ColMap("UserId").SetMaxSize(26)
    35  		table.ColMap("ChannelId").SetMaxSize(26)
    36  		table.ColMap("TeamId").SetMaxSize(26)
    37  		table.ColMap("DisplayName").SetMaxSize(64)
    38  		table.ColMap("Description").SetMaxSize(500)
    39  
    40  		tableo := db.AddTableWithName(model.OutgoingWebhook{}, "OutgoingWebhooks").SetKeys(false, "Id")
    41  		tableo.ColMap("Id").SetMaxSize(26)
    42  		tableo.ColMap("Token").SetMaxSize(26)
    43  		tableo.ColMap("CreatorId").SetMaxSize(26)
    44  		tableo.ColMap("ChannelId").SetMaxSize(26)
    45  		tableo.ColMap("TeamId").SetMaxSize(26)
    46  		tableo.ColMap("TriggerWords").SetMaxSize(1024)
    47  		tableo.ColMap("CallbackURLs").SetMaxSize(1024)
    48  		tableo.ColMap("DisplayName").SetMaxSize(64)
    49  		tableo.ColMap("Description").SetMaxSize(500)
    50  		tableo.ColMap("ContentType").SetMaxSize(128)
    51  		tableo.ColMap("TriggerWhen").SetMaxSize(1)
    52  		tableo.ColMap("Username").SetMaxSize(64)
    53  		tableo.ColMap("IconURL").SetMaxSize(1024)
    54  	}
    55  
    56  	return s
    57  }
    58  
    59  func (s SqlWebhookStore) createIndexesIfNotExists() {
    60  	s.CreateIndexIfNotExists("idx_incoming_webhook_user_id", "IncomingWebhooks", "UserId")
    61  	s.CreateIndexIfNotExists("idx_incoming_webhook_team_id", "IncomingWebhooks", "TeamId")
    62  	s.CreateIndexIfNotExists("idx_outgoing_webhook_team_id", "OutgoingWebhooks", "TeamId")
    63  
    64  	s.CreateIndexIfNotExists("idx_incoming_webhook_update_at", "IncomingWebhooks", "UpdateAt")
    65  	s.CreateIndexIfNotExists("idx_incoming_webhook_create_at", "IncomingWebhooks", "CreateAt")
    66  	s.CreateIndexIfNotExists("idx_incoming_webhook_delete_at", "IncomingWebhooks", "DeleteAt")
    67  
    68  	s.CreateIndexIfNotExists("idx_outgoing_webhook_update_at", "OutgoingWebhooks", "UpdateAt")
    69  	s.CreateIndexIfNotExists("idx_outgoing_webhook_create_at", "OutgoingWebhooks", "CreateAt")
    70  	s.CreateIndexIfNotExists("idx_outgoing_webhook_delete_at", "OutgoingWebhooks", "DeleteAt")
    71  }
    72  
    73  func (s SqlWebhookStore) InvalidateWebhookCache(webhookId string) {
    74  }
    75  
    76  func (s SqlWebhookStore) SaveIncoming(webhook *model.IncomingWebhook) (*model.IncomingWebhook, error) {
    77  
    78  	if len(webhook.Id) > 0 {
    79  		return nil, store.NewErrInvalidInput("IncomingWebhook", "id", webhook.Id)
    80  	}
    81  
    82  	webhook.PreSave()
    83  	if err := webhook.IsValid(); err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	if err := s.GetMaster().Insert(webhook); err != nil {
    88  		return nil, errors.Wrapf(err, "failed to save IncomingWebhook with id=%s", webhook.Id)
    89  	}
    90  
    91  	return webhook, nil
    92  
    93  }
    94  
    95  func (s SqlWebhookStore) UpdateIncoming(hook *model.IncomingWebhook) (*model.IncomingWebhook, error) {
    96  	hook.UpdateAt = model.GetMillis()
    97  
    98  	if _, err := s.GetMaster().Update(hook); err != nil {
    99  		return nil, errors.Wrapf(err, "failed to update IncomingWebhook with id=%s", hook.Id)
   100  	}
   101  	return hook, nil
   102  }
   103  
   104  func (s SqlWebhookStore) GetIncoming(id string, allowFromCache bool) (*model.IncomingWebhook, error) {
   105  	var webhook model.IncomingWebhook
   106  	if err := s.GetReplica().SelectOne(&webhook, "SELECT * FROM IncomingWebhooks WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id}); err != nil {
   107  		if err == sql.ErrNoRows {
   108  			return nil, store.NewErrNotFound("IncomingWebhook", id)
   109  		}
   110  		return nil, errors.Wrapf(err, "failed to get IncomingWebhook with id=%s", id)
   111  	}
   112  
   113  	return &webhook, nil
   114  }
   115  
   116  func (s SqlWebhookStore) DeleteIncoming(webhookId string, time int64) error {
   117  	_, err := s.GetMaster().Exec("Update IncomingWebhooks SET DeleteAt = :DeleteAt, UpdateAt = :UpdateAt WHERE Id = :Id", map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": webhookId})
   118  	if err != nil {
   119  		return errors.Wrapf(err, "failed to update IncomingWebhook with id=%s", webhookId)
   120  	}
   121  
   122  	return nil
   123  }
   124  
   125  func (s SqlWebhookStore) PermanentDeleteIncomingByUser(userId string) error {
   126  	_, err := s.GetMaster().Exec("DELETE FROM IncomingWebhooks WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
   127  	if err != nil {
   128  		return errors.Wrapf(err, "failed to delete IncomingWebhook with userId=%s", userId)
   129  	}
   130  
   131  	return nil
   132  }
   133  
   134  func (s SqlWebhookStore) PermanentDeleteIncomingByChannel(channelId string) error {
   135  	_, err := s.GetMaster().Exec("DELETE FROM IncomingWebhooks WHERE ChannelId = :ChannelId", map[string]interface{}{"ChannelId": channelId})
   136  	if err != nil {
   137  		return errors.Wrapf(err, "failed to delete IncomingWebhook with channelId=%s", channelId)
   138  	}
   139  
   140  	return nil
   141  }
   142  
   143  func (s SqlWebhookStore) GetIncomingList(offset, limit int) ([]*model.IncomingWebhook, error) {
   144  	return s.GetIncomingListByUser("", offset, limit)
   145  }
   146  
   147  func (s SqlWebhookStore) GetIncomingListByUser(userId string, offset, limit int) ([]*model.IncomingWebhook, error) {
   148  	var webhooks []*model.IncomingWebhook
   149  
   150  	query := s.getQueryBuilder().
   151  		Select("*").
   152  		From("IncomingWebhooks").
   153  		Where(sq.Eq{"DeleteAt": int(0)}).Limit(uint64(limit)).Offset(uint64(offset))
   154  
   155  	if len(userId) > 0 {
   156  		query = query.Where(sq.Eq{"UserId": userId})
   157  	}
   158  
   159  	queryString, args, err := query.ToSql()
   160  	if err != nil {
   161  		return nil, errors.Wrap(err, "incoming_webhook_tosql")
   162  	}
   163  
   164  	if _, err := s.GetReplica().Select(&webhooks, queryString, args...); err != nil {
   165  		return nil, errors.Wrap(err, "failed to find IncomingWebhooks")
   166  	}
   167  
   168  	return webhooks, nil
   169  
   170  }
   171  
   172  func (s SqlWebhookStore) GetIncomingByTeamByUser(teamId string, userId string, offset, limit int) ([]*model.IncomingWebhook, error) {
   173  	var webhooks []*model.IncomingWebhook
   174  
   175  	query := s.getQueryBuilder().
   176  		Select("*").
   177  		From("IncomingWebhooks").
   178  		Where(sq.And{
   179  			sq.Eq{"TeamId": teamId},
   180  			sq.Eq{"DeleteAt": int(0)},
   181  		}).Limit(uint64(limit)).Offset(uint64(offset))
   182  
   183  	if len(userId) > 0 {
   184  		query = query.Where(sq.Eq{"UserId": userId})
   185  	}
   186  
   187  	queryString, args, err := query.ToSql()
   188  	if err != nil {
   189  		return nil, errors.Wrap(err, "incoming_webhook_tosql")
   190  	}
   191  
   192  	if _, err := s.GetReplica().Select(&webhooks, queryString, args...); err != nil {
   193  		return nil, errors.Wrapf(err, "failed to find IncomingWebhoook with teamId=%s", teamId)
   194  	}
   195  
   196  	return webhooks, nil
   197  }
   198  
   199  func (s SqlWebhookStore) GetIncomingByTeam(teamId string, offset, limit int) ([]*model.IncomingWebhook, error) {
   200  	return s.GetIncomingByTeamByUser(teamId, "", offset, limit)
   201  }
   202  
   203  func (s SqlWebhookStore) GetIncomingByChannel(channelId string) ([]*model.IncomingWebhook, error) {
   204  	var webhooks []*model.IncomingWebhook
   205  
   206  	if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE ChannelId = :ChannelId AND DeleteAt = 0", map[string]interface{}{"ChannelId": channelId}); err != nil {
   207  		return nil, errors.Wrapf(err, "failed to find IncomingWebhooks with channelId=%s", channelId)
   208  	}
   209  
   210  	return webhooks, nil
   211  }
   212  
   213  func (s SqlWebhookStore) SaveOutgoing(webhook *model.OutgoingWebhook) (*model.OutgoingWebhook, error) {
   214  	if len(webhook.Id) > 0 {
   215  		return nil, store.NewErrInvalidInput("OutgoingWebhook", "id", webhook.Id)
   216  	}
   217  
   218  	webhook.PreSave()
   219  	if err := webhook.IsValid(); err != nil {
   220  		return nil, err
   221  	}
   222  
   223  	if err := s.GetMaster().Insert(webhook); err != nil {
   224  		return nil, errors.Wrapf(err, "failed to save OutgoingWebhook with id=%s", webhook.Id)
   225  	}
   226  
   227  	return webhook, nil
   228  }
   229  
   230  func (s SqlWebhookStore) GetOutgoing(id string) (*model.OutgoingWebhook, error) {
   231  
   232  	var webhook model.OutgoingWebhook
   233  
   234  	if err := s.GetReplica().SelectOne(&webhook, "SELECT * FROM OutgoingWebhooks WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id}); err != nil {
   235  		if err == sql.ErrNoRows {
   236  			return nil, store.NewErrNotFound("OutgoingWebhook", id)
   237  		}
   238  
   239  		return nil, errors.Wrapf(err, "failed to get OutgoingWebhook with id=%s", id)
   240  	}
   241  
   242  	return &webhook, nil
   243  }
   244  
   245  func (s SqlWebhookStore) GetOutgoingListByUser(userId string, offset, limit int) ([]*model.OutgoingWebhook, error) {
   246  	var webhooks []*model.OutgoingWebhook
   247  
   248  	query := s.getQueryBuilder().
   249  		Select("*").
   250  		From("OutgoingWebhooks").
   251  		Where(sq.And{
   252  			sq.Eq{"DeleteAt": int(0)},
   253  		}).Limit(uint64(limit)).Offset(uint64(offset))
   254  
   255  	if len(userId) > 0 {
   256  		query = query.Where(sq.Eq{"CreatorId": userId})
   257  	}
   258  
   259  	queryString, args, err := query.ToSql()
   260  	if err != nil {
   261  		return nil, errors.Wrap(err, "outgoing_webhook_tosql")
   262  	}
   263  
   264  	if _, err := s.GetReplica().Select(&webhooks, queryString, args...); err != nil {
   265  		return nil, errors.Wrap(err, "failed to find OutgoingWebhooks")
   266  	}
   267  
   268  	return webhooks, nil
   269  }
   270  
   271  func (s SqlWebhookStore) GetOutgoingList(offset, limit int) ([]*model.OutgoingWebhook, error) {
   272  	return s.GetOutgoingListByUser("", offset, limit)
   273  
   274  }
   275  
   276  func (s SqlWebhookStore) GetOutgoingByChannelByUser(channelId string, userId string, offset, limit int) ([]*model.OutgoingWebhook, error) {
   277  	var webhooks []*model.OutgoingWebhook
   278  
   279  	query := s.getQueryBuilder().
   280  		Select("*").
   281  		From("OutgoingWebhooks").
   282  		Where(sq.And{
   283  			sq.Eq{"ChannelId": channelId},
   284  			sq.Eq{"DeleteAt": int(0)},
   285  		})
   286  
   287  	if len(userId) > 0 {
   288  		query = query.Where(sq.Eq{"CreatorId": userId})
   289  	}
   290  	if limit >= 0 && offset >= 0 {
   291  		query = query.Limit(uint64(limit)).Offset(uint64(offset))
   292  	}
   293  
   294  	queryString, args, err := query.ToSql()
   295  	if err != nil {
   296  		return nil, errors.Wrap(err, "outgoing_webhook_tosql")
   297  	}
   298  
   299  	if _, err := s.GetReplica().Select(&webhooks, queryString, args...); err != nil {
   300  		return nil, errors.Wrap(err, "failed to find OutgoingWebhooks")
   301  	}
   302  
   303  	return webhooks, nil
   304  }
   305  
   306  func (s SqlWebhookStore) GetOutgoingByChannel(channelId string, offset, limit int) ([]*model.OutgoingWebhook, error) {
   307  	return s.GetOutgoingByChannelByUser(channelId, "", offset, limit)
   308  }
   309  
   310  func (s SqlWebhookStore) GetOutgoingByTeamByUser(teamId string, userId string, offset, limit int) ([]*model.OutgoingWebhook, error) {
   311  	var webhooks []*model.OutgoingWebhook
   312  
   313  	query := s.getQueryBuilder().
   314  		Select("*").
   315  		From("OutgoingWebhooks").
   316  		Where(sq.And{
   317  			sq.Eq{"TeamId": teamId},
   318  			sq.Eq{"DeleteAt": int(0)},
   319  		})
   320  
   321  	if len(userId) > 0 {
   322  		query = query.Where(sq.Eq{"CreatorId": userId})
   323  	}
   324  	if limit >= 0 && offset >= 0 {
   325  		query = query.Limit(uint64(limit)).Offset(uint64(offset))
   326  	}
   327  
   328  	queryString, args, err := query.ToSql()
   329  	if err != nil {
   330  		return nil, errors.Wrap(err, "outgoing_webhook_tosql")
   331  	}
   332  
   333  	if _, err := s.GetReplica().Select(&webhooks, queryString, args...); err != nil {
   334  		return nil, errors.Wrap(err, "failed to find OutgoingWebhooks")
   335  	}
   336  
   337  	return webhooks, nil
   338  }
   339  
   340  func (s SqlWebhookStore) GetOutgoingByTeam(teamId string, offset, limit int) ([]*model.OutgoingWebhook, error) {
   341  	return s.GetOutgoingByTeamByUser(teamId, "", offset, limit)
   342  }
   343  
   344  func (s SqlWebhookStore) DeleteOutgoing(webhookId string, time int64) error {
   345  	_, err := s.GetMaster().Exec("Update OutgoingWebhooks SET DeleteAt = :DeleteAt, UpdateAt = :UpdateAt WHERE Id = :Id", map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": webhookId})
   346  	if err != nil {
   347  		return errors.Wrapf(err, "failed to update OutgoingWebhook with id=%s", webhookId)
   348  	}
   349  
   350  	return nil
   351  }
   352  
   353  func (s SqlWebhookStore) PermanentDeleteOutgoingByUser(userId string) error {
   354  	_, err := s.GetMaster().Exec("DELETE FROM OutgoingWebhooks WHERE CreatorId = :UserId", map[string]interface{}{"UserId": userId})
   355  	if err != nil {
   356  		return errors.Wrapf(err, "failed to delete OutgoingWebhook with creatorId=%s", userId)
   357  	}
   358  
   359  	return nil
   360  }
   361  
   362  func (s SqlWebhookStore) PermanentDeleteOutgoingByChannel(channelId string) error {
   363  	_, err := s.GetMaster().Exec("DELETE FROM OutgoingWebhooks WHERE ChannelId = :ChannelId", map[string]interface{}{"ChannelId": channelId})
   364  	if err != nil {
   365  		return errors.Wrapf(err, "failed to delete OutgoingWebhook with channelId=%s", channelId)
   366  	}
   367  
   368  	s.ClearCaches()
   369  
   370  	return nil
   371  }
   372  
   373  func (s SqlWebhookStore) UpdateOutgoing(hook *model.OutgoingWebhook) (*model.OutgoingWebhook, error) {
   374  	hook.UpdateAt = model.GetMillis()
   375  
   376  	if _, err := s.GetMaster().Update(hook); err != nil {
   377  		return nil, errors.Wrapf(err, "failed to update OutgoingWebhook with id=%s", hook.Id)
   378  	}
   379  
   380  	return hook, nil
   381  }
   382  
   383  func (s SqlWebhookStore) AnalyticsIncomingCount(teamId string) (int64, error) {
   384  	query :=
   385  		`SELECT
   386  			COUNT(*)
   387  		FROM
   388  			IncomingWebhooks
   389  		WHERE
   390  			DeleteAt = 0`
   391  
   392  	if len(teamId) > 0 {
   393  		query += " AND TeamId = :TeamId"
   394  	}
   395  
   396  	v, err := s.GetReplica().SelectInt(query, map[string]interface{}{"TeamId": teamId})
   397  	if err != nil {
   398  		return 0, errors.Wrap(err, "failed to count IncomingWebhooks")
   399  	}
   400  
   401  	return v, nil
   402  }
   403  
   404  func (s SqlWebhookStore) AnalyticsOutgoingCount(teamId string) (int64, error) {
   405  	query :=
   406  		`SELECT
   407  			COUNT(*)
   408  		FROM
   409  			OutgoingWebhooks
   410  		WHERE
   411  			DeleteAt = 0`
   412  
   413  	if len(teamId) > 0 {
   414  		query += " AND TeamId = :TeamId"
   415  	}
   416  
   417  	v, err := s.GetReplica().SelectInt(query, map[string]interface{}{"TeamId": teamId})
   418  	if err != nil {
   419  		return 0, errors.Wrap(err, "failed to count OutgoingWebhooks")
   420  	}
   421  
   422  	return v, nil
   423  }