From 47250c6629416b628a19e5571ac89f7b4646418c Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 14 May 2018 10:24:58 -0400 Subject: Refactor context out of API packages (#8755) * Refactor context out of API packages * Update function names per feedback * Move webhook handlers to web and fix web tests * Move more webhook tests out of api package * Fix static handler --- web/webhook.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 web/webhook.go (limited to 'web/webhook.go') diff --git a/web/webhook.go b/web/webhook.go new file mode 100644 index 000000000..55cdeb9b5 --- /dev/null +++ b/web/webhook.go @@ -0,0 +1,101 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package web + +import ( + "fmt" + "io" + "net/http" + "strings" + + "github.com/gorilla/mux" + "github.com/gorilla/schema" + + "github.com/mattermost/mattermost-server/mlog" + "github.com/mattermost/mattermost-server/model" +) + +func (w *Web) InitWebhooks() { + w.MainRouter.Handle("/hooks/commands/{id:[A-Za-z0-9]+}", w.NewHandler(commandWebhook)).Methods("POST") + w.MainRouter.Handle("/hooks/{id:[A-Za-z0-9]+}", w.NewHandler(incomingWebhook)).Methods("POST") +} + +func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + id := params["id"] + + r.ParseForm() + + var err *model.AppError + incomingWebhookPayload := &model.IncomingWebhookRequest{} + contentType := r.Header.Get("Content-Type") + if strings.Split(contentType, "; ")[0] == "application/x-www-form-urlencoded" { + payload := strings.NewReader(r.FormValue("payload")) + + incomingWebhookPayload, err = decodePayload(payload) + if err != nil { + c.Err = err + return + } + } else if strings.HasPrefix(contentType, "multipart/form-data") { + r.ParseMultipartForm(0) + + decoder := schema.NewDecoder() + err := decoder.Decode(incomingWebhookPayload, r.PostForm) + + if err != nil { + c.Err = model.NewAppError("incomingWebhook", "api.webhook.incoming.error", nil, err.Error(), http.StatusBadRequest) + return + } + } else { + incomingWebhookPayload, err = decodePayload(r.Body) + if err != nil { + c.Err = err + return + } + } + + if c.App.Config().LogSettings.EnableWebhookDebugging { + mlog.Debug(fmt.Sprint("Incoming webhook received. Content=", incomingWebhookPayload.ToJson())) + } + + err = c.App.HandleIncomingWebhook(id, incomingWebhookPayload) + if err != nil { + c.Err = err + return + } + + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("ok")) +} + +func commandWebhook(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + id := params["id"] + + response, err := model.CommandResponseFromHTTPBody(r.Header.Get("Content-Type"), r.Body) + if err != nil { + c.Err = model.NewAppError("commandWebhook", "web.command_webhook.parse.app_error", nil, err.Error(), http.StatusBadRequest) + return + } + + appErr := c.App.HandleCommandWebhook(id, response) + if appErr != nil { + c.Err = appErr + return + } + + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("ok")) +} + +func decodePayload(payload io.Reader) (*model.IncomingWebhookRequest, *model.AppError) { + incomingWebhookPayload, decodeError := model.IncomingWebhookRequestFromJson(payload) + + if decodeError != nil { + return nil, decodeError + } + + return incomingWebhookPayload, nil +} -- cgit v1.2.3-1-g7c22