From 4bfad26614ef8b8df66027f17de91e2bff5ec30d Mon Sep 17 00:00:00 2001 From: Christopher Poile Date: Fri, 26 Jun 2020 10:15:04 -0400 Subject: [PATCH] MM-26441 - fix for doPluginRequest (#14897) * merge rawQuery params with provided values * tests for doPluginRequest Co-authored-by: Mattermod --- app/integration_action.go | 15 ++++- app/integration_action_test.go | 108 +++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/app/integration_action.go b/app/integration_action.go index 060ca35732..cf4e027d52 100644 --- a/app/integration_action.go +++ b/app/integration_action.go @@ -353,9 +353,23 @@ func (a *App) doPluginRequest(method, rawURL string, values url.Values, body []b if err != nil { return nil, model.NewAppError("doPluginRequest", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest) } + + // merge the rawQuery params (if any) with the function's provided values + rawValues := inURL.Query() + if len(rawValues) != 0 { + if values == nil { + values = make(url.Values) + } + for k, vs := range rawValues { + for _, v := range vs { + values.Add(k, v) + } + } + } if values != nil { base.RawQuery = values.Encode() } + w := &LocalResponseWriter{} r, err := http.NewRequest(method, base.String(), bytes.NewReader(body)) if err != nil { @@ -366,7 +380,6 @@ func (a *App) doPluginRequest(method, rawURL string, values url.Values, body []b params := make(map[string]string) params["plugin_id"] = pluginId r = mux.SetURLVars(r, params) - r.URL.RawQuery = inURL.Query().Encode() a.ServePluginRequest(w, r) diff --git a/app/integration_action_test.go b/app/integration_action_test.go index e3bf337236..dafb9a0149 100644 --- a/app/integration_action_test.go +++ b/app/integration_action_test.go @@ -6,8 +6,10 @@ package app import ( "encoding/json" "fmt" + "io/ioutil" "net/http" "net/http/httptest" + "net/url" "strings" "testing" @@ -952,3 +954,109 @@ func TestPostActionRelativePluginURL(t *testing.T) { require.Nil(t, err) }) } + +func TestDoPluginRequest(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1" + }) + + setupPluginApiTest(t, + ` + package main + + import ( + "net/http" + "reflect" + "sort" + + "github.com/mattermost/mattermost-server/v5/plugin" + ) + + type MyPlugin struct { + plugin.MattermostPlugin + } + + func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) { + q := r.URL.Query() + if q.Get("abc") != "xyz" { + w.WriteHeader(http.StatusInternalServerError) + _, _ = w.Write([]byte("could not find param abc=xyz")) + return + } + + multiple := q["multiple"] + if len(multiple) != 3 { + w.WriteHeader(http.StatusInternalServerError) + _, _ = w.Write([]byte("param multiple should have 3 values")) + return + } + sort.Strings(multiple) + if !reflect.DeepEqual(multiple, []string{"1 first", "2 second", "3 third"}) { + w.WriteHeader(http.StatusInternalServerError) + _, _ = w.Write([]byte("param multiple not correct")) + return + } + + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("OK")) + } + + func main() { + plugin.ClientMain(&MyPlugin{}) + } + `, `{"id": "myplugin", "backend": {"executable": "backend.exe"}}`, "myplugin", th.App) + + hooks, err2 := th.App.GetPluginsEnvironment().HooksForPlugin("myplugin") + require.Nil(t, err2) + require.NotNil(t, hooks) + + resp, err := th.App.doPluginRequest("GET", "/plugins/myplugin", nil, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ := ioutil.ReadAll(resp.Body) + assert.Equal(t, "could not find param abc=xyz", string(body)) + + resp, err = th.App.doPluginRequest("GET", "/plugins/myplugin?abc=xyz", nil, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ = ioutil.ReadAll(resp.Body) + assert.Equal(t, "param multiple should have 3 values", string(body)) + + resp, err = th.App.doPluginRequest("GET", "/plugins/myplugin", + url.Values{"abc": []string{"xyz"}, "multiple": []string{"1 first", "2 second", "3 third"}}, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ = ioutil.ReadAll(resp.Body) + assert.Equal(t, "OK", string(body)) + + resp, err = th.App.doPluginRequest("GET", "/plugins/myplugin?abc=xyz&multiple=1%20first", + url.Values{"multiple": []string{"2 second", "3 third"}}, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ = ioutil.ReadAll(resp.Body) + assert.Equal(t, "OK", string(body)) + + resp, err = th.App.doPluginRequest("GET", "/plugins/myplugin?abc=xyz&multiple=1%20first&multiple=3%20third", + url.Values{"multiple": []string{"2 second"}}, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ = ioutil.ReadAll(resp.Body) + assert.Equal(t, "OK", string(body)) + + resp, err = th.App.doPluginRequest("GET", "/plugins/myplugin?multiple=1%20first&multiple=3%20third", + url.Values{"multiple": []string{"2 second"}, "abc": []string{"xyz"}}, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ = ioutil.ReadAll(resp.Body) + assert.Equal(t, "OK", string(body)) + + resp, err = th.App.doPluginRequest("GET", "/plugins/myplugin?multiple=1%20first&multiple=3%20third", + url.Values{"multiple": []string{"4 fourth"}, "abc": []string{"xyz"}}, nil) + assert.Nil(t, err) + require.NotNil(t, resp) + body, _ = ioutil.ReadAll(resp.Body) + assert.Equal(t, "param multiple not correct", string(body)) +}