webhook.go 9.16 KB
Newer Older
1
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
JoramWilander's avatar
JoramWilander committed
2
3
4
5
6
// See License.txt for license information.

package api

import (
Christopher Speller's avatar
Christopher Speller committed
7
8
	"net/http"

=Corey Hulen's avatar
=Corey Hulen committed
9
	l4g "github.com/alecthomas/log4go"
Christopher Speller's avatar
Christopher Speller committed
10
11
	"github.com/mattermost/mattermost-server/model"
	"github.com/mattermost/mattermost-server/utils"
JoramWilander's avatar
JoramWilander committed
12
13
)

14
func (api *API) InitWebhook() {
15
	l4g.Debug(utils.T("api.webhook.init.debug"))
JoramWilander's avatar
JoramWilander committed
16

17
18
19
20
	api.BaseRoutes.Hooks.Handle("/incoming/create", api.ApiUserRequired(createIncomingHook)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/incoming/update", api.ApiUserRequired(updateIncomingHook)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/incoming/delete", api.ApiUserRequired(deleteIncomingHook)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/incoming/list", api.ApiUserRequired(getIncomingHooks)).Methods("GET")
JoramWilander's avatar
JoramWilander committed
21

22
23
24
25
26
	api.BaseRoutes.Hooks.Handle("/outgoing/create", api.ApiUserRequired(createOutgoingHook)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/outgoing/update", api.ApiUserRequired(updateOutgoingHook)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/outgoing/regen_token", api.ApiUserRequired(regenOutgoingHookToken)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/outgoing/delete", api.ApiUserRequired(deleteOutgoingHook)).Methods("POST")
	api.BaseRoutes.Hooks.Handle("/outgoing/list", api.ApiUserRequired(getOutgoingHooks)).Methods("GET")
JoramWilander's avatar
JoramWilander committed
27
28
29
30
31
32
33
34
35
}

func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
	hook := model.IncomingWebhookFromJson(r.Body)
	if hook == nil {
		c.SetInvalidParam("createIncomingHook", "webhook")
		return
	}

Chris's avatar
Chris committed
36
	channel, err := c.App.GetChannel(hook.ChannelId)
37
38
39
40
	if err != nil {
		c.Err = err
		return
	}
JoramWilander's avatar
JoramWilander committed
41

42
	c.LogAudit("attempt")
JoramWilander's avatar
JoramWilander committed
43

44
	if !c.App.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
45
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
46
47
48
		return
	}

Chris's avatar
Chris committed
49
	if channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
50
		c.LogAudit("fail - bad channel permissions")
51
		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
52
		return
JoramWilander's avatar
JoramWilander committed
53
54
	}

Chris's avatar
Chris committed
55
	if incomingHook, err := c.App.CreateIncomingWebhookForChannel(c.Session.UserId, channel, hook); err != nil {
56
		c.Err = err
JoramWilander's avatar
JoramWilander committed
57
58
59
		return
	} else {
		c.LogAudit("success")
60
		w.Write([]byte(incomingHook.ToJson()))
JoramWilander's avatar
JoramWilander committed
61
62
63
	}
}

64
65
66
67
68
69
70
71
72
func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {

	hook := model.IncomingWebhookFromJson(r.Body)

	if hook == nil {
		c.SetInvalidParam("updateIncomingHook", "webhook")
		return
	}

73
	c.LogAudit("attempt")
74

Chris's avatar
Chris committed
75
	oldHook, err := c.App.GetIncomingWebhook(hook.Id)
76
77
	if err != nil {
		c.Err = err
78
79
80
		return
	}

81
82
	if c.TeamId != oldHook.TeamId {
		c.Err = model.NewAppError("updateIncomingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest)
83
84
85
		return
	}

86
	if !c.App.SessionHasPermissionToTeam(c.Session, oldHook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
87
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
88
89
90
		return
	}

Chris's avatar
Chris committed
91
	if c.Session.UserId != oldHook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, oldHook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
92
		c.LogAudit("fail - inappropriate permissions")
93
		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
94
95
96
		return
	}

Chris's avatar
Chris committed
97
	channel, err := c.App.GetChannel(hook.ChannelId)
98
99
	if err != nil {
		c.Err = err
100
101
102
		return
	}

Chris's avatar
Chris committed
103
	if channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
104
105
106
107
		c.LogAudit("fail - bad channel permissions")
		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
		return
	}
108

Chris's avatar
Chris committed
109
	rhook, err := c.App.UpdateIncomingWebhook(oldHook, hook)
110
111
	if err != nil {
		c.Err = err
112
113
114
115
116
117
118
		return
	}

	c.LogAudit("success")
	w.Write([]byte(rhook.ToJson()))
}

JoramWilander's avatar
JoramWilander committed
119
func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
120
121
122
123
124
	props := model.MapFromJson(r.Body)

	id := props["id"]
	if len(id) == 0 {
		c.SetInvalidParam("deleteIncomingHook", "id")
JoramWilander's avatar
JoramWilander committed
125
126
127
		return
	}

Chris's avatar
Chris committed
128
	hook, err := c.App.GetIncomingWebhook(id)
129
	if err != nil {
130
		c.Err = err
131
		return
=Corey Hulen's avatar
=Corey Hulen committed
132
133
	}

134
	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
135
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
136
137
138
		return
	}

139
140
	c.LogAudit("attempt")

141
	if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
142
143
		c.LogAudit("fail - inappropriate permissions")
		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
144
145
146
		return
	}

Chris's avatar
Chris committed
147
	if err := c.App.DeleteIncomingWebhook(id); err != nil {
148
		c.LogAudit("fail")
JoramWilander's avatar
JoramWilander committed
149
150
151
152
153
154
155
156
157
		c.Err = err
		return
	}

	c.LogAudit("success")
	w.Write([]byte(model.MapToJson(props)))
}

func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
158
	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
159
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
160
		return
=Corey Hulen's avatar
=Corey Hulen committed
161
162
	}

Chris's avatar
Chris committed
163
	if hooks, err := c.App.GetIncomingWebhooksForTeamPage(c.TeamId, 0, 100); err != nil {
164
		c.Err = err
JoramWilander's avatar
JoramWilander committed
165
166
167
168
169
		return
	} else {
		w.Write([]byte(model.IncomingWebhookListToJson(hooks)))
	}
}
JoramWilander's avatar
JoramWilander committed
170

171
172
173
174
175
176
177
func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
	hook := model.OutgoingWebhookFromJson(r.Body)
	if hook == nil {
		c.SetInvalidParam("createOutgoingHook", "webhook")
		return
	}

178
179
	c.LogAudit("attempt")

180
	hook.TeamId = c.TeamId
181
	hook.CreatorId = c.Session.UserId
182

183
	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
184
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
185
186
187
		return
	}

Chris's avatar
Chris committed
188
	if rhook, err := c.App.CreateOutgoingWebhook(hook); err != nil {
189
190
		c.LogAudit("fail")
		c.Err = err
JoramWilander's avatar
JoramWilander committed
191
192
193
194
195
196
197
198
		return
	} else {
		c.LogAudit("success")
		w.Write([]byte(rhook.ToJson()))
	}
}

func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
199
	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
200
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
201
202
203
		return
	}

Chris's avatar
Chris committed
204
	if hooks, err := c.App.GetOutgoingWebhooksForTeamPage(c.TeamId, 0, 100); err != nil {
205
		c.Err = err
206
		return
JoramWilander's avatar
JoramWilander committed
207
208
209
210
211
	} else {
		w.Write([]byte(model.OutgoingWebhookListToJson(hooks)))
	}
}

212
213
214
215
216
217
218
219
220
221
func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
	c.LogAudit("attempt")

	hook := model.OutgoingWebhookFromJson(r.Body)

	if hook == nil {
		c.SetInvalidParam("updateOutgoingHook", "webhook")
		return
	}

Chris's avatar
Chris committed
222
	oldHook, err := c.App.GetOutgoingWebhook(hook.Id)
223
	if err != nil {
224
225
226
227
		c.Err = err
		return
	}

228
229
	if c.TeamId != oldHook.TeamId {
		c.Err = model.NewAppError("updateOutgoingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusForbidden)
230
231
232
		return
	}

233
	if !c.App.SessionHasPermissionToTeam(c.Session, oldHook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
234
235
		c.LogAudit("fail - inappropriate permissions")
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
236
237
238
		return
	}

239
	if c.Session.UserId != oldHook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, oldHook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
240
241
		c.LogAudit("fail - inappropriate permissions")
		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
242
243
244
		return
	}

Chris's avatar
Chris committed
245
	rhook, err := c.App.UpdateOutgoingWebhook(oldHook, hook)
246
247
	if err != nil {
		c.Err = err
248
249
250
251
252
253
254
		return
	}

	c.LogAudit("success")
	w.Write([]byte(rhook.ToJson()))
}

JoramWilander's avatar
JoramWilander committed
255
func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
256
	props := model.MapFromJson(r.Body)
JoramWilander's avatar
JoramWilander committed
257

258
259
260
	id := props["id"]
	if len(id) == 0 {
		c.SetInvalidParam("deleteIncomingHook", "id")
261
		return
=Corey Hulen's avatar
=Corey Hulen committed
262
263
	}

JoramWilander's avatar
JoramWilander committed
264
265
	c.LogAudit("attempt")

266
	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
267
268
269
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
		return
	}
JoramWilander's avatar
JoramWilander committed
270

Chris's avatar
Chris committed
271
	hook, err := c.App.GetOutgoingWebhook(id)
272
273
	if err != nil {
		c.Err = err
JoramWilander's avatar
JoramWilander committed
274
275
276
		return
	}

277
	if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
278
279
		c.LogAudit("fail - inappropriate permissions")
		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
280
281
282
		return
	}

Chris's avatar
Chris committed
283
	if err := c.App.DeleteOutgoingWebhook(id); err != nil {
284
		c.LogAudit("fail")
JoramWilander's avatar
JoramWilander committed
285
286
287
288
289
290
291
292
293
		c.Err = err
		return
	}

	c.LogAudit("success")
	w.Write([]byte(model.MapToJson(props)))
}

func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) {
294
295
296
297
298
	props := model.MapFromJson(r.Body)

	id := props["id"]
	if len(id) == 0 {
		c.SetInvalidParam("regenOutgoingHookToken", "id")
JoramWilander's avatar
JoramWilander committed
299
300
301
		return
	}

Chris's avatar
Chris committed
302
	hook, err := c.App.GetOutgoingWebhook(id)
303
	if err != nil {
304
		c.Err = err
305
		return
=Corey Hulen's avatar
=Corey Hulen committed
306
307
	}

JoramWilander's avatar
JoramWilander committed
308
309
	c.LogAudit("attempt")

310
311
	if c.TeamId != hook.TeamId {
		c.Err = model.NewAppError("regenOutgoingHookToken", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusForbidden)
JoramWilander's avatar
JoramWilander committed
312
313
314
		return
	}

315
	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
316
		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
317
318
319
		return
	}

320
	if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
321
322
		c.LogAudit("fail - inappropriate permissions")
		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
JoramWilander's avatar
JoramWilander committed
323
324
		return
	}
Christopher Speller's avatar
Christopher Speller committed
325

Chris's avatar
Chris committed
326
	if rhook, err := c.App.RegenOutgoingWebhookToken(hook); err != nil {
327
		c.Err = err
Christopher Speller's avatar
Christopher Speller committed
328
		return
329
330
	} else {
		w.Write([]byte(rhook.ToJson()))
Christopher Speller's avatar
Christopher Speller committed
331
	}
332
}