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 }