github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/api4/webhook.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package api4 5 6 import ( 7 "net/http" 8 9 "github.com/mattermost/mattermost-server/model" 10 ) 11 12 func (api *API) InitWebhook() { 13 api.BaseRoutes.IncomingHooks.Handle("", api.ApiSessionRequired(createIncomingHook)).Methods("POST") 14 api.BaseRoutes.IncomingHooks.Handle("", api.ApiSessionRequired(getIncomingHooks)).Methods("GET") 15 api.BaseRoutes.IncomingHook.Handle("", api.ApiSessionRequired(getIncomingHook)).Methods("GET") 16 api.BaseRoutes.IncomingHook.Handle("", api.ApiSessionRequired(updateIncomingHook)).Methods("PUT") 17 api.BaseRoutes.IncomingHook.Handle("", api.ApiSessionRequired(deleteIncomingHook)).Methods("DELETE") 18 19 api.BaseRoutes.OutgoingHooks.Handle("", api.ApiSessionRequired(createOutgoingHook)).Methods("POST") 20 api.BaseRoutes.OutgoingHooks.Handle("", api.ApiSessionRequired(getOutgoingHooks)).Methods("GET") 21 api.BaseRoutes.OutgoingHook.Handle("", api.ApiSessionRequired(getOutgoingHook)).Methods("GET") 22 api.BaseRoutes.OutgoingHook.Handle("", api.ApiSessionRequired(updateOutgoingHook)).Methods("PUT") 23 api.BaseRoutes.OutgoingHook.Handle("", api.ApiSessionRequired(deleteOutgoingHook)).Methods("DELETE") 24 api.BaseRoutes.OutgoingHook.Handle("/regen_token", api.ApiSessionRequired(regenOutgoingHookToken)).Methods("POST") 25 } 26 27 func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { 28 hook := model.IncomingWebhookFromJson(r.Body) 29 if hook == nil { 30 c.SetInvalidParam("incoming_webhook") 31 return 32 } 33 34 channel, err := c.App.GetChannel(hook.ChannelId) 35 if err != nil { 36 c.Err = err 37 return 38 } 39 40 c.LogAudit("attempt") 41 42 if !c.App.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 43 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 44 return 45 } 46 47 if channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) { 48 c.LogAudit("fail - bad channel permissions") 49 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 50 return 51 } 52 53 incomingHook, err := c.App.CreateIncomingWebhookForChannel(c.Session.UserId, channel, hook) 54 if err != nil { 55 c.Err = err 56 return 57 } 58 59 c.LogAudit("success") 60 w.WriteHeader(http.StatusCreated) 61 w.Write([]byte(incomingHook.ToJson())) 62 } 63 64 func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { 65 c.RequireHookId() 66 if c.Err != nil { 67 return 68 } 69 70 updatedHook := model.IncomingWebhookFromJson(r.Body) 71 if updatedHook == nil { 72 c.SetInvalidParam("incoming_webhook") 73 return 74 } 75 76 // The hook being updated in the payload must be the same one as indicated in the URL. 77 if updatedHook.Id != c.Params.HookId { 78 c.SetInvalidParam("hook_id") 79 return 80 } 81 82 c.LogAudit("attempt") 83 84 oldHook, err := c.App.GetIncomingWebhook(c.Params.HookId) 85 if err != nil { 86 c.Err = err 87 return 88 } 89 90 if updatedHook.TeamId == "" { 91 updatedHook.TeamId = oldHook.TeamId 92 } 93 94 if updatedHook.TeamId != oldHook.TeamId { 95 c.Err = model.NewAppError("updateIncomingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest) 96 return 97 } 98 99 if !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 100 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 101 return 102 } 103 104 if c.Session.UserId != oldHook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 105 c.LogAudit("fail - inappropriate permissions") 106 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 107 return 108 } 109 110 channel, err := c.App.GetChannel(updatedHook.ChannelId) 111 if err != nil { 112 c.Err = err 113 return 114 } 115 116 if channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) { 117 c.LogAudit("fail - bad channel permissions") 118 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 119 return 120 } 121 122 incomingHook, err := c.App.UpdateIncomingWebhook(oldHook, updatedHook) 123 if err != nil { 124 c.Err = err 125 return 126 } 127 128 c.LogAudit("success") 129 w.WriteHeader(http.StatusCreated) 130 w.Write([]byte(incomingHook.ToJson())) 131 } 132 133 func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) { 134 teamId := r.URL.Query().Get("team_id") 135 136 var hooks []*model.IncomingWebhook 137 var err *model.AppError 138 139 if len(teamId) > 0 { 140 if !c.App.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_WEBHOOKS) { 141 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 142 return 143 } 144 145 hooks, err = c.App.GetIncomingWebhooksForTeamPage(teamId, c.Params.Page, c.Params.PerPage) 146 } else { 147 if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_WEBHOOKS) { 148 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 149 return 150 } 151 152 hooks, err = c.App.GetIncomingWebhooksPage(c.Params.Page, c.Params.PerPage) 153 } 154 155 if err != nil { 156 c.Err = err 157 return 158 } 159 160 w.Write([]byte(model.IncomingWebhookListToJson(hooks))) 161 } 162 163 func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { 164 c.RequireHookId() 165 if c.Err != nil { 166 return 167 } 168 169 hookId := c.Params.HookId 170 171 var err *model.AppError 172 var hook *model.IncomingWebhook 173 var channel *model.Channel 174 175 hook, err = c.App.GetIncomingWebhook(hookId) 176 if err != nil { 177 c.Err = err 178 return 179 } 180 181 channel, err = c.App.GetChannel(hook.ChannelId) 182 if err != nil { 183 c.Err = err 184 return 185 } 186 187 if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) || 188 (channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, hook.ChannelId, model.PERMISSION_READ_CHANNEL)) { 189 c.LogAudit("fail - bad permissions") 190 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 191 return 192 } 193 194 if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 195 c.LogAudit("fail - inappropriate permissions") 196 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 197 return 198 } 199 200 w.Write([]byte(hook.ToJson())) 201 } 202 203 func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { 204 c.RequireHookId() 205 if c.Err != nil { 206 return 207 } 208 209 hookId := c.Params.HookId 210 211 var err *model.AppError 212 var hook *model.IncomingWebhook 213 var channel *model.Channel 214 215 hook, err = c.App.GetIncomingWebhook(hookId) 216 if err != nil { 217 c.Err = err 218 return 219 } 220 221 channel, err = c.App.GetChannel(hook.ChannelId) 222 if err != nil { 223 c.Err = err 224 return 225 } 226 227 if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) || 228 (channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, hook.ChannelId, model.PERMISSION_READ_CHANNEL)) { 229 c.LogAudit("fail - bad permissions") 230 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 231 return 232 } 233 234 if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 235 c.LogAudit("fail - inappropriate permissions") 236 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 237 return 238 } 239 240 if err = c.App.DeleteIncomingWebhook(hookId); err != nil { 241 c.Err = err 242 return 243 } 244 245 ReturnStatusOK(w) 246 } 247 248 func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { 249 c.RequireHookId() 250 if c.Err != nil { 251 return 252 } 253 254 updatedHook := model.OutgoingWebhookFromJson(r.Body) 255 if updatedHook == nil { 256 c.SetInvalidParam("outgoing_webhook") 257 return 258 } 259 260 // The hook being updated in the payload must be the same one as indicated in the URL. 261 if updatedHook.Id != c.Params.HookId { 262 c.SetInvalidParam("hook_id") 263 return 264 } 265 266 c.LogAudit("attempt") 267 268 oldHook, err := c.App.GetOutgoingWebhook(c.Params.HookId) 269 if err != nil { 270 c.Err = err 271 return 272 } 273 274 if updatedHook.TeamId == "" { 275 updatedHook.TeamId = oldHook.TeamId 276 } 277 278 if updatedHook.TeamId != oldHook.TeamId { 279 c.Err = model.NewAppError("updateOutgoingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest) 280 return 281 } 282 283 if !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 284 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 285 return 286 } 287 288 if c.Session.UserId != oldHook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 289 c.LogAudit("fail - inappropriate permissions") 290 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 291 return 292 } 293 294 updatedHook.CreatorId = c.Session.UserId 295 296 rhook, err := c.App.UpdateOutgoingWebhook(oldHook, updatedHook) 297 if err != nil { 298 c.Err = err 299 return 300 } 301 302 c.LogAudit("success") 303 w.Write([]byte(rhook.ToJson())) 304 } 305 306 func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { 307 hook := model.OutgoingWebhookFromJson(r.Body) 308 if hook == nil { 309 c.SetInvalidParam("outgoing_webhook") 310 return 311 } 312 313 c.LogAudit("attempt") 314 315 hook.CreatorId = c.Session.UserId 316 317 if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 318 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 319 return 320 } 321 322 rhook, err := c.App.CreateOutgoingWebhook(hook) 323 if err != nil { 324 c.LogAudit("fail") 325 c.Err = err 326 return 327 } 328 329 c.LogAudit("success") 330 w.WriteHeader(http.StatusCreated) 331 w.Write([]byte(rhook.ToJson())) 332 } 333 334 func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) { 335 channelId := r.URL.Query().Get("channel_id") 336 teamId := r.URL.Query().Get("team_id") 337 338 var hooks []*model.OutgoingWebhook 339 var err *model.AppError 340 341 if len(channelId) > 0 { 342 if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_MANAGE_WEBHOOKS) { 343 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 344 return 345 } 346 347 hooks, err = c.App.GetOutgoingWebhooksForChannelPage(channelId, c.Params.Page, c.Params.PerPage) 348 } else if len(teamId) > 0 { 349 if !c.App.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_WEBHOOKS) { 350 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 351 return 352 } 353 354 hooks, err = c.App.GetOutgoingWebhooksForTeamPage(teamId, c.Params.Page, c.Params.PerPage) 355 } else { 356 if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_WEBHOOKS) { 357 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 358 return 359 } 360 361 hooks, err = c.App.GetOutgoingWebhooksPage(c.Params.Page, c.Params.PerPage) 362 } 363 364 if err != nil { 365 c.Err = err 366 return 367 } 368 369 w.Write([]byte(model.OutgoingWebhookListToJson(hooks))) 370 } 371 372 func getOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { 373 c.RequireHookId() 374 if c.Err != nil { 375 return 376 } 377 378 hook, err := c.App.GetOutgoingWebhook(c.Params.HookId) 379 if err != nil { 380 c.Err = err 381 return 382 } 383 384 c.LogAudit("attempt") 385 386 if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 387 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 388 return 389 } 390 391 if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 392 c.LogAudit("fail - inappropriate permissions") 393 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 394 return 395 } 396 397 c.LogAudit("success") 398 w.Write([]byte(hook.ToJson())) 399 } 400 401 func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) { 402 c.RequireHookId() 403 if c.Err != nil { 404 return 405 } 406 407 hook, err := c.App.GetOutgoingWebhook(c.Params.HookId) 408 if err != nil { 409 c.Err = err 410 return 411 } 412 413 c.LogAudit("attempt") 414 415 if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 416 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 417 return 418 } 419 420 if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 421 c.LogAudit("fail - inappropriate permissions") 422 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 423 return 424 } 425 426 rhook, err := c.App.RegenOutgoingWebhookToken(hook) 427 if err != nil { 428 c.Err = err 429 return 430 } 431 432 w.Write([]byte(rhook.ToJson())) 433 } 434 435 func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { 436 c.RequireHookId() 437 if c.Err != nil { 438 return 439 } 440 441 hook, err := c.App.GetOutgoingWebhook(c.Params.HookId) 442 if err != nil { 443 c.Err = err 444 return 445 } 446 447 c.LogAudit("attempt") 448 449 if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) { 450 c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS) 451 return 452 } 453 454 if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) { 455 c.LogAudit("fail - inappropriate permissions") 456 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) 457 return 458 } 459 460 if err := c.App.DeleteOutgoingWebhook(hook.Id); err != nil { 461 c.LogAudit("fail") 462 c.Err = err 463 return 464 } 465 466 c.LogAudit("success") 467 ReturnStatusOK(w) 468 }