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 }