github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+incompatible/app/plugin_requests.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "net/http" 8 "path" 9 "strings" 10 11 "bytes" 12 "github.com/gorilla/mux" 13 "github.com/mattermost/mattermost-server/mlog" 14 "github.com/mattermost/mattermost-server/model" 15 "github.com/mattermost/mattermost-server/plugin" 16 "github.com/mattermost/mattermost-server/utils" 17 "io/ioutil" 18 ) 19 20 func (a *App) ServePluginRequest(w http.ResponseWriter, r *http.Request) { 21 if a.Plugins == nil || !*a.Config().PluginSettings.Enable { 22 err := model.NewAppError("ServePluginRequest", "app.plugin.disabled.app_error", nil, "Enable plugins to serve plugin requests", http.StatusNotImplemented) 23 a.Log.Error(err.Error()) 24 w.WriteHeader(err.StatusCode) 25 w.Header().Set("Content-Type", "application/json") 26 w.Write([]byte(err.ToJson())) 27 return 28 } 29 30 params := mux.Vars(r) 31 hooks, err := a.Plugins.HooksForPlugin(params["plugin_id"]) 32 if err != nil { 33 a.Log.Error("Access to route for non-existent plugin", mlog.String("missing_plugin_id", params["plugin_id"]), mlog.Err(err)) 34 http.NotFound(w, r) 35 return 36 } 37 38 a.servePluginRequest(w, r, hooks.ServeHTTP) 39 } 40 41 func (a *App) servePluginRequest(w http.ResponseWriter, r *http.Request, handler func(*plugin.Context, http.ResponseWriter, *http.Request)) { 42 token := "" 43 context := &plugin.Context{} 44 cookieAuth := false 45 46 authHeader := r.Header.Get(model.HEADER_AUTH) 47 if strings.HasPrefix(strings.ToUpper(authHeader), model.HEADER_BEARER+" ") { 48 token = authHeader[len(model.HEADER_BEARER)+1:] 49 } else if strings.HasPrefix(strings.ToLower(authHeader), model.HEADER_TOKEN+" ") { 50 token = authHeader[len(model.HEADER_TOKEN)+1:] 51 } else if cookie, _ := r.Cookie(model.SESSION_COOKIE_TOKEN); cookie != nil { 52 token = cookie.Value 53 cookieAuth = true 54 } else { 55 token = r.URL.Query().Get("access_token") 56 } 57 58 r.Header.Del("Mattermost-User-Id") 59 if token != "" { 60 session, err := a.GetSession(token) 61 csrfCheckPassed := true 62 63 if err == nil && cookieAuth && r.Method != "GET" && r.Header.Get(model.HEADER_REQUESTED_WITH) != model.HEADER_REQUESTED_WITH_XML { 64 bodyBytes, _ := ioutil.ReadAll(r.Body) 65 r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) 66 r.ParseForm() 67 sentToken := r.FormValue("csrf") 68 expectedToken := session.GetCSRF() 69 70 if sentToken != expectedToken { 71 csrfCheckPassed = false 72 } 73 74 // Set Request Body again, since otherwise form values aren't accessible in plugin handler 75 r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) 76 } 77 78 if session != nil && err == nil && csrfCheckPassed { 79 r.Header.Set("Mattermost-User-Id", session.UserId) 80 context.SessionId = session.Id 81 } 82 } 83 84 cookies := r.Cookies() 85 r.Header.Del("Cookie") 86 for _, c := range cookies { 87 if c.Name != model.SESSION_COOKIE_TOKEN { 88 r.AddCookie(c) 89 } 90 } 91 r.Header.Del(model.HEADER_AUTH) 92 r.Header.Del("Referer") 93 94 params := mux.Vars(r) 95 96 subpath, _ := utils.GetSubpathFromConfig(a.Config()) 97 98 newQuery := r.URL.Query() 99 newQuery.Del("access_token") 100 r.URL.RawQuery = newQuery.Encode() 101 r.URL.Path = strings.TrimPrefix(r.URL.Path, path.Join(subpath, "plugins", params["plugin_id"])) 102 103 handler(context, w, r) 104 }