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