github.com/nmintoh/dserver@v5.11.1+incompatible/app/plugin_test.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "bytes" 8 "crypto/sha256" 9 "encoding/base64" 10 "io/ioutil" 11 "net/http" 12 "net/http/httptest" 13 "testing" 14 15 "github.com/gorilla/mux" 16 "github.com/mattermost/mattermost-server/model" 17 "github.com/mattermost/mattermost-server/plugin" 18 "github.com/stretchr/testify/assert" 19 "github.com/stretchr/testify/require" 20 ) 21 22 func getHashedKey(key string) string { 23 hash := sha256.New() 24 hash.Write([]byte(key)) 25 return base64.StdEncoding.EncodeToString(hash.Sum(nil)) 26 } 27 28 func TestPluginKeyValueStore(t *testing.T) { 29 th := Setup(t).InitBasic() 30 defer th.TearDown() 31 32 pluginId := "testpluginid" 33 34 defer func() { 35 assert.Nil(t, th.App.DeletePluginKey(pluginId, "key")) 36 assert.Nil(t, th.App.DeletePluginKey(pluginId, "key2")) 37 assert.Nil(t, th.App.DeletePluginKey(pluginId, "key3")) 38 assert.Nil(t, th.App.DeletePluginKey(pluginId, "key4")) 39 }() 40 41 assert.Nil(t, th.App.SetPluginKey(pluginId, "key", []byte("test"))) 42 ret, err := th.App.GetPluginKey(pluginId, "key") 43 assert.Nil(t, err) 44 assert.Equal(t, []byte("test"), ret) 45 46 // Test inserting over existing entries 47 assert.Nil(t, th.App.SetPluginKey(pluginId, "key", []byte("test2"))) 48 ret, err = th.App.GetPluginKey(pluginId, "key") 49 assert.Nil(t, err) 50 assert.Equal(t, []byte("test2"), ret) 51 52 // Test getting non-existent key 53 ret, err = th.App.GetPluginKey(pluginId, "notakey") 54 assert.Nil(t, err) 55 assert.Nil(t, ret) 56 57 // Test deleting non-existent keys. 58 assert.Nil(t, th.App.DeletePluginKey(pluginId, "notrealkey")) 59 60 // Verify behaviour for the old approach that involved storing the hashed keys. 61 hashedKey2 := getHashedKey("key2") 62 kv := &model.PluginKeyValue{ 63 PluginId: pluginId, 64 Key: hashedKey2, 65 Value: []byte("test"), 66 ExpireAt: 0, 67 } 68 69 result := <-th.App.Srv.Store.Plugin().SaveOrUpdate(kv) 70 assert.Nil(t, result.Err) 71 72 // Test fetch by keyname (this key does not exist but hashed key will be used for lookup) 73 ret, err = th.App.GetPluginKey(pluginId, "key2") 74 assert.Nil(t, err) 75 assert.Equal(t, kv.Value, ret) 76 77 // Test fetch by hashed keyname 78 ret, err = th.App.GetPluginKey(pluginId, hashedKey2) 79 assert.Nil(t, err) 80 assert.Equal(t, kv.Value, ret) 81 82 // Test ListKeys 83 assert.Nil(t, th.App.SetPluginKey(pluginId, "key3", []byte("test3"))) 84 assert.Nil(t, th.App.SetPluginKey(pluginId, "key4", []byte("test4"))) 85 86 list, err := th.App.ListPluginKeys(pluginId, 0, 1) 87 assert.Nil(t, err) 88 assert.Equal(t, []string{"key"}, list) 89 90 list, err = th.App.ListPluginKeys(pluginId, 1, 1) 91 assert.Nil(t, err) 92 assert.Equal(t, []string{"key3"}, list) 93 94 list, err = th.App.ListPluginKeys(pluginId, 0, 4) 95 assert.Nil(t, err) 96 assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list) 97 98 list, err = th.App.ListPluginKeys(pluginId, 0, 2) 99 assert.Nil(t, err) 100 assert.Equal(t, []string{"key", "key3"}, list) 101 102 list, err = th.App.ListPluginKeys(pluginId, 1, 2) 103 assert.Nil(t, err) 104 assert.Equal(t, []string{"key4", hashedKey2}, list) 105 106 list, err = th.App.ListPluginKeys(pluginId, 2, 2) 107 assert.Nil(t, err) 108 assert.Equal(t, []string{}, list) 109 110 // List Keys bad input 111 list, err = th.App.ListPluginKeys(pluginId, 0, 0) 112 assert.Nil(t, err) 113 assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list) 114 115 list, err = th.App.ListPluginKeys(pluginId, 0, -1) 116 assert.Nil(t, err) 117 assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list) 118 119 list, err = th.App.ListPluginKeys(pluginId, -1, 1) 120 assert.Nil(t, err) 121 assert.Equal(t, []string{"key"}, list) 122 123 list, err = th.App.ListPluginKeys(pluginId, -1, 0) 124 assert.Nil(t, err) 125 assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list) 126 } 127 128 func TestServePluginRequest(t *testing.T) { 129 th := Setup(t).InitBasic() 130 defer th.TearDown() 131 132 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PluginSettings.Enable = false }) 133 134 w := httptest.NewRecorder() 135 r := httptest.NewRequest("GET", "/plugins/foo/bar", nil) 136 th.App.ServePluginRequest(w, r) 137 assert.Equal(t, http.StatusNotImplemented, w.Result().StatusCode) 138 } 139 140 func TestPrivateServePluginRequest(t *testing.T) { 141 th := Setup(t).InitBasic() 142 defer th.TearDown() 143 144 testCases := []struct { 145 Description string 146 ConfigFunc func(cfg *model.Config) 147 URL string 148 ExpectedURL string 149 }{ 150 { 151 "no subpath", 152 func(cfg *model.Config) {}, 153 "/plugins/id/endpoint", 154 "/endpoint", 155 }, 156 { 157 "subpath", 158 func(cfg *model.Config) { *cfg.ServiceSettings.SiteURL += "/subpath" }, 159 "/subpath/plugins/id/endpoint", 160 "/endpoint", 161 }, 162 } 163 164 for _, testCase := range testCases { 165 t.Run(testCase.Description, func(t *testing.T) { 166 th.App.UpdateConfig(testCase.ConfigFunc) 167 expectedBody := []byte("body") 168 request := httptest.NewRequest(http.MethodGet, testCase.URL, bytes.NewReader(expectedBody)) 169 recorder := httptest.NewRecorder() 170 171 handler := func(context *plugin.Context, w http.ResponseWriter, r *http.Request) { 172 assert.Equal(t, testCase.ExpectedURL, r.URL.Path) 173 174 body, _ := ioutil.ReadAll(r.Body) 175 assert.Equal(t, expectedBody, body) 176 } 177 178 request = mux.SetURLVars(request, map[string]string{"plugin_id": "id"}) 179 180 th.App.servePluginRequest(recorder, request, handler) 181 }) 182 } 183 184 } 185 186 func TestHandlePluginRequest(t *testing.T) { 187 th := Setup(t).InitBasic() 188 defer th.TearDown() 189 190 th.App.UpdateConfig(func(cfg *model.Config) { 191 *cfg.PluginSettings.Enable = false 192 *cfg.ServiceSettings.EnableUserAccessTokens = true 193 }) 194 195 token, err := th.App.CreateUserAccessToken(&model.UserAccessToken{ 196 UserId: th.BasicUser.Id, 197 }) 198 require.Nil(t, err) 199 200 var assertions func(*http.Request) 201 router := mux.NewRouter() 202 router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}/{anything:.*}", func(_ http.ResponseWriter, r *http.Request) { 203 th.App.servePluginRequest(nil, r, func(_ *plugin.Context, _ http.ResponseWriter, r *http.Request) { 204 assertions(r) 205 }) 206 }) 207 208 r := httptest.NewRequest("GET", "/plugins/foo/bar", nil) 209 r.Header.Add("Authorization", "Bearer "+token.Token) 210 assertions = func(r *http.Request) { 211 assert.Equal(t, "/bar", r.URL.Path) 212 assert.Equal(t, th.BasicUser.Id, r.Header.Get("Mattermost-User-Id")) 213 } 214 router.ServeHTTP(nil, r) 215 216 r = httptest.NewRequest("GET", "/plugins/foo/bar?a=b&access_token="+token.Token+"&c=d", nil) 217 assertions = func(r *http.Request) { 218 assert.Equal(t, "/bar", r.URL.Path) 219 assert.Equal(t, "a=b&c=d", r.URL.RawQuery) 220 assert.Equal(t, th.BasicUser.Id, r.Header.Get("Mattermost-User-Id")) 221 } 222 router.ServeHTTP(nil, r) 223 224 r = httptest.NewRequest("GET", "/plugins/foo/bar?a=b&access_token=asdf&c=d", nil) 225 assertions = func(r *http.Request) { 226 assert.Equal(t, "/bar", r.URL.Path) 227 assert.Equal(t, "a=b&c=d", r.URL.RawQuery) 228 assert.Empty(t, r.Header.Get("Mattermost-User-Id")) 229 } 230 router.ServeHTTP(nil, r) 231 } 232 233 func TestGetPluginStatusesDisabled(t *testing.T) { 234 th := Setup(t).InitBasic() 235 defer th.TearDown() 236 237 th.App.UpdateConfig(func(cfg *model.Config) { 238 *cfg.PluginSettings.Enable = false 239 }) 240 241 _, err := th.App.GetPluginStatuses() 242 require.NotNil(t, err) 243 require.EqualError(t, err, "GetPluginStatuses: Plugins have been disabled. Please check your logs for details., ") 244 } 245 246 func TestGetPluginStatuses(t *testing.T) { 247 th := Setup(t).InitBasic() 248 defer th.TearDown() 249 250 th.App.UpdateConfig(func(cfg *model.Config) { 251 *cfg.PluginSettings.Enable = true 252 }) 253 254 pluginStatuses, err := th.App.GetPluginStatuses() 255 require.Nil(t, err) 256 require.NotNil(t, pluginStatuses) 257 }