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