Files
mattermost/app/plugin_test.go

926 lines
28 KiB
Go
Raw Normal View History

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
import (
"bytes"
"crypto/sha256"
"encoding/base64"
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
"fmt"
"io/ioutil"
2017-12-01 09:07:32 -06:00
"net/http"
"net/http/httptest"
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
"os"
"path/filepath"
"testing"
"time"
2017-12-01 09:07:32 -06:00
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/plugin"
"github.com/mattermost/mattermost-server/v5/testlib"
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
"github.com/mattermost/mattermost-server/v5/utils"
"github.com/mattermost/mattermost-server/v5/utils/fileutils"
)
func getHashedKey(key string) string {
hash := sha256.New()
hash.Write([]byte(key))
return base64.StdEncoding.EncodeToString(hash.Sum(nil))
}
func TestPluginKeyValueStore(t *testing.T) {
th := Setup(t)
defer th.TearDown()
pluginId := "testpluginid"
defer func() {
assert.Nil(t, th.App.DeletePluginKey(pluginId, "key"))
assert.Nil(t, th.App.DeletePluginKey(pluginId, "key2"))
assert.Nil(t, th.App.DeletePluginKey(pluginId, "key3"))
assert.Nil(t, th.App.DeletePluginKey(pluginId, "key4"))
}()
assert.Nil(t, th.App.SetPluginKey(pluginId, "key", []byte("test")))
ret, err := th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte("test"), ret)
// Test inserting over existing entries
assert.Nil(t, th.App.SetPluginKey(pluginId, "key", []byte("test2")))
ret, err = th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte("test2"), ret)
// Test getting non-existent key
ret, err = th.App.GetPluginKey(pluginId, "notakey")
assert.Nil(t, err)
assert.Nil(t, ret)
// Test deleting non-existent keys.
assert.Nil(t, th.App.DeletePluginKey(pluginId, "notrealkey"))
// Verify behaviour for the old approach that involved storing the hashed keys.
hashedKey2 := getHashedKey("key2")
kv := &model.PluginKeyValue{
PluginId: pluginId,
Key: hashedKey2,
Value: []byte("test"),
ExpireAt: 0,
}
_, nErr := th.App.Srv().Store.Plugin().SaveOrUpdate(kv)
assert.Nil(t, nErr)
// Test fetch by keyname (this key does not exist but hashed key will be used for lookup)
ret, err = th.App.GetPluginKey(pluginId, "key2")
assert.Nil(t, err)
assert.Equal(t, kv.Value, ret)
// Test fetch by hashed keyname
ret, err = th.App.GetPluginKey(pluginId, hashedKey2)
assert.Nil(t, err)
assert.Equal(t, kv.Value, ret)
// Test ListKeys
assert.Nil(t, th.App.SetPluginKey(pluginId, "key3", []byte("test3")))
assert.Nil(t, th.App.SetPluginKey(pluginId, "key4", []byte("test4")))
list, err := th.App.ListPluginKeys(pluginId, 0, 1)
assert.Nil(t, err)
assert.Equal(t, []string{"key"}, list)
list, err = th.App.ListPluginKeys(pluginId, 1, 1)
assert.Nil(t, err)
assert.Equal(t, []string{"key3"}, list)
list, err = th.App.ListPluginKeys(pluginId, 0, 4)
assert.Nil(t, err)
assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list)
list, err = th.App.ListPluginKeys(pluginId, 0, 2)
assert.Nil(t, err)
assert.Equal(t, []string{"key", "key3"}, list)
list, err = th.App.ListPluginKeys(pluginId, 1, 2)
assert.Nil(t, err)
assert.Equal(t, []string{"key4", hashedKey2}, list)
list, err = th.App.ListPluginKeys(pluginId, 2, 2)
assert.Nil(t, err)
assert.Equal(t, []string{}, list)
// List Keys bad input
list, err = th.App.ListPluginKeys(pluginId, 0, 0)
assert.Nil(t, err)
assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list)
list, err = th.App.ListPluginKeys(pluginId, 0, -1)
assert.Nil(t, err)
assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list)
list, err = th.App.ListPluginKeys(pluginId, -1, 1)
assert.Nil(t, err)
assert.Equal(t, []string{"key"}, list)
list, err = th.App.ListPluginKeys(pluginId, -1, 0)
assert.Nil(t, err)
assert.Equal(t, []string{"key", "key3", "key4", hashedKey2}, list)
}
2017-12-01 09:07:32 -06:00
func TestPluginKeyValueStoreCompareAndSet(t *testing.T) {
th := Setup(t)
defer th.TearDown()
pluginId := "testpluginid"
defer func() {
assert.Nil(t, th.App.DeletePluginKey(pluginId, "key"))
}()
// Set using Set api for key2
assert.Nil(t, th.App.SetPluginKey(pluginId, "key2", []byte("test")))
ret, err := th.App.GetPluginKey(pluginId, "key2")
assert.Nil(t, err)
assert.Equal(t, []byte("test"), ret)
// Attempt to insert value for key2
updated, err := th.App.CompareAndSetPluginKey(pluginId, "key2", nil, []byte("test2"))
assert.Nil(t, err)
assert.False(t, updated)
ret, err = th.App.GetPluginKey(pluginId, "key2")
assert.Nil(t, err)
assert.Equal(t, []byte("test"), ret)
// Insert new value for key
updated, err = th.App.CompareAndSetPluginKey(pluginId, "key", nil, []byte("test"))
assert.Nil(t, err)
assert.True(t, updated)
ret, err = th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte("test"), ret)
// Should fail to insert again
updated, err = th.App.CompareAndSetPluginKey(pluginId, "key", nil, []byte("test3"))
assert.Nil(t, err)
assert.False(t, updated)
ret, err = th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte("test"), ret)
// Test updating using incorrect old value
updated, err = th.App.CompareAndSetPluginKey(pluginId, "key", []byte("oldvalue"), []byte("test3"))
assert.Nil(t, err)
assert.False(t, updated)
ret, err = th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte("test"), ret)
// Test updating using correct old value
updated, err = th.App.CompareAndSetPluginKey(pluginId, "key", []byte("test"), []byte("test2"))
assert.Nil(t, err)
assert.True(t, updated)
ret, err = th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte("test2"), ret)
}
func TestPluginKeyValueStoreSetWithOptionsJSON(t *testing.T) {
pluginId := "testpluginid"
t.Run("storing a value without providing options works", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
result, err := th.App.SetPluginKeyWithOptions(pluginId, "key", []byte("value-1"), model.PluginKVSetOptions{})
assert.True(t, result)
assert.Nil(t, err)
// and I can get it back!
ret, err := th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte(`value-1`), ret)
})
t.Run("test that setting it atomic when it doesn't match doesn't change anything", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
err := th.App.SetPluginKey(pluginId, "key", []byte("value-1"))
require.Nil(t, err)
result, err := th.App.SetPluginKeyWithOptions(pluginId, "key", []byte("value-3"), model.PluginKVSetOptions{
Atomic: true,
OldValue: []byte("value-2"),
})
assert.False(t, result)
assert.Nil(t, err)
// test that the value didn't change
ret, err := th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte(`value-1`), ret)
})
t.Run("test the atomic change with the proper old value", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
err := th.App.SetPluginKey(pluginId, "key", []byte("value-2"))
require.Nil(t, err)
result, err := th.App.SetPluginKeyWithOptions(pluginId, "key", []byte("value-3"), model.PluginKVSetOptions{
Atomic: true,
OldValue: []byte("value-2"),
})
assert.True(t, result)
assert.Nil(t, err)
// test that the value did change
ret, err := th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte(`value-3`), ret)
})
t.Run("when new value is nil and old value matches with the current, it should delete the currently set value", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
// first set a value.
result, err := th.App.SetPluginKeyWithOptions(pluginId, "nil-test-key-2", []byte("value-1"), model.PluginKVSetOptions{})
require.Nil(t, err)
require.True(t, result)
// now it should delete the set value.
result, err = th.App.SetPluginKeyWithOptions(pluginId, "nil-test-key-2", nil, model.PluginKVSetOptions{
Atomic: true,
OldValue: []byte("value-1"),
})
assert.Nil(t, err)
assert.True(t, result)
ret, err := th.App.GetPluginKey(pluginId, "nil-test-key-2")
assert.Nil(t, err)
assert.Nil(t, ret)
})
t.Run("when new value is nil and there is a value set for the key already, it should delete the currently set value", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
// first set a value.
result, err := th.App.SetPluginKeyWithOptions(pluginId, "nil-test-key-3", []byte("value-1"), model.PluginKVSetOptions{})
require.Nil(t, err)
require.True(t, result)
// now it should delete the set value.
result, err = th.App.SetPluginKeyWithOptions(pluginId, "nil-test-key-3", nil, model.PluginKVSetOptions{})
assert.Nil(t, err)
assert.True(t, result)
// verify a nil value is returned
ret, err := th.App.GetPluginKey(pluginId, "nil-test-key-3")
assert.Nil(t, err)
assert.Nil(t, ret)
// verify the row is actually gone
list, err := th.App.ListPluginKeys(pluginId, 0, 1)
assert.Nil(t, err)
assert.Empty(t, list)
})
t.Run("when old value is nil and there is no value set for the key before, it should set the new value", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
result, err := th.App.SetPluginKeyWithOptions(pluginId, "nil-test-key-4", []byte("value-1"), model.PluginKVSetOptions{
Atomic: true,
OldValue: nil,
})
assert.Nil(t, err)
assert.True(t, result)
ret, err := th.App.GetPluginKey(pluginId, "nil-test-key-4")
assert.Nil(t, err)
assert.Equal(t, []byte("value-1"), ret)
})
t.Run("test that value is set and unset with ExpireInSeconds", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
result, err := th.App.SetPluginKeyWithOptions(pluginId, "key", []byte("value-1"), model.PluginKVSetOptions{
ExpireInSeconds: 1,
})
assert.True(t, result)
assert.Nil(t, err)
// test that the value is set
ret, err := th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Equal(t, []byte(`value-1`), ret)
// test that the value is not longer
time.Sleep(1500 * time.Millisecond)
ret, err = th.App.GetPluginKey(pluginId, "key")
assert.Nil(t, err)
assert.Nil(t, ret)
})
}
2017-12-01 09:07:32 -06:00
func TestServePluginRequest(t *testing.T) {
th := Setup(t)
2017-12-01 09:07:32 -06:00
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PluginSettings.Enable = false })
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/plugins/foo/bar", nil)
th.App.ServePluginRequest(w, r)
assert.Equal(t, http.StatusNotImplemented, w.Result().StatusCode)
}
func TestPrivateServePluginRequest(t *testing.T) {
th := Setup(t)
defer th.TearDown()
testCases := []struct {
Description string
ConfigFunc func(cfg *model.Config)
URL string
ExpectedURL string
}{
{
"no subpath",
func(cfg *model.Config) {},
"/plugins/id/endpoint",
"/endpoint",
},
{
"subpath",
func(cfg *model.Config) { *cfg.ServiceSettings.SiteURL += "/subpath" },
"/subpath/plugins/id/endpoint",
"/endpoint",
},
}
for _, testCase := range testCases {
t.Run(testCase.Description, func(t *testing.T) {
th.App.UpdateConfig(testCase.ConfigFunc)
expectedBody := []byte("body")
request := httptest.NewRequest(http.MethodGet, testCase.URL, bytes.NewReader(expectedBody))
recorder := httptest.NewRecorder()
handler := func(context *plugin.Context, w http.ResponseWriter, r *http.Request) {
assert.Equal(t, testCase.ExpectedURL, r.URL.Path)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, expectedBody, body)
}
request = mux.SetURLVars(request, map[string]string{"plugin_id": "id"})
th.App.servePluginRequest(recorder, request, handler)
})
}
}
2017-12-01 09:07:32 -06:00
func TestHandlePluginRequest(t *testing.T) {
th := Setup(t).InitBasic()
2017-12-01 09:07:32 -06:00
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = false
*cfg.ServiceSettings.EnableUserAccessTokens = true
})
token, err := th.App.CreateUserAccessToken(&model.UserAccessToken{
UserId: th.BasicUser.Id,
})
require.Nil(t, err)
var assertions func(*http.Request)
router := mux.NewRouter()
router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}/{anything:.*}", func(_ http.ResponseWriter, r *http.Request) {
th.App.servePluginRequest(nil, r, func(_ *plugin.Context, _ http.ResponseWriter, r *http.Request) {
2017-12-01 09:07:32 -06:00
assertions(r)
})
})
r := httptest.NewRequest("GET", "/plugins/foo/bar", nil)
r.Header.Add("Authorization", "Bearer "+token.Token)
assertions = func(r *http.Request) {
assert.Equal(t, "/bar", r.URL.Path)
assert.Equal(t, th.BasicUser.Id, r.Header.Get("Mattermost-User-Id"))
}
router.ServeHTTP(nil, r)
r = httptest.NewRequest("GET", "/plugins/foo/bar?a=b&access_token="+token.Token+"&c=d", nil)
assertions = func(r *http.Request) {
assert.Equal(t, "/bar", r.URL.Path)
assert.Equal(t, "a=b&c=d", r.URL.RawQuery)
assert.Equal(t, th.BasicUser.Id, r.Header.Get("Mattermost-User-Id"))
}
router.ServeHTTP(nil, r)
r = httptest.NewRequest("GET", "/plugins/foo/bar?a=b&access_token=asdf&c=d", nil)
assertions = func(r *http.Request) {
assert.Equal(t, "/bar", r.URL.Path)
assert.Equal(t, "a=b&c=d", r.URL.RawQuery)
assert.Empty(t, r.Header.Get("Mattermost-User-Id"))
}
router.ServeHTTP(nil, r)
}
MM-8622: Improved plugin error reporting (#8737) * allow `Wait()`ing on the supervisor In the event the plugin supervisor shuts down a plugin for crashing too many times, the new `Wait()` interface allows the `ActivatePlugin` to accept a callback function to trigger when `supervisor.Wait()` returns. If the supervisor shuts down normally, this callback is invoked with a nil error, otherwise any error reported by the supervisor is passed along. * improve plugin activation/deactivation logic Avoid triggering activation of previously failed-to-start plugins just becase something in the configuration changed. Now, intelligently compare the global enable bit as well as the each individual plugin's enabled bit. * expose store to manipulate PluginStatuses * expose API to fetch plugin statuses * keep track of whether or not plugin sandboxing is supported * transition plugin statuses * restore error on plugin activation if already active * don't initialize test plugins until successfully loaded * emit websocket events when plugin statuses change * skip pruning if already initialized * MM-8622: maintain plugin statuses in memory Switch away from persisting plugin statuses to the database, and maintain in memory instead. This will be followed by a cluster interface to query the in-memory status of plugin statuses from all cluster nodes. At the same time, rename `cluster_discovery_id` on the `PluginStatus` model object to `cluster_id`. * MM-8622: aggregate plugin statuses across cluster * fetch cluster plugin statuses when emitting websocket notification * address unit test fixes after rebasing * relax (poor) racey unit test re: supervisor.Wait() * make store-mocks
2018-05-23 14:26:35 -04:00
func TestGetPluginStatusesDisabled(t *testing.T) {
th := Setup(t)
MM-8622: Improved plugin error reporting (#8737) * allow `Wait()`ing on the supervisor In the event the plugin supervisor shuts down a plugin for crashing too many times, the new `Wait()` interface allows the `ActivatePlugin` to accept a callback function to trigger when `supervisor.Wait()` returns. If the supervisor shuts down normally, this callback is invoked with a nil error, otherwise any error reported by the supervisor is passed along. * improve plugin activation/deactivation logic Avoid triggering activation of previously failed-to-start plugins just becase something in the configuration changed. Now, intelligently compare the global enable bit as well as the each individual plugin's enabled bit. * expose store to manipulate PluginStatuses * expose API to fetch plugin statuses * keep track of whether or not plugin sandboxing is supported * transition plugin statuses * restore error on plugin activation if already active * don't initialize test plugins until successfully loaded * emit websocket events when plugin statuses change * skip pruning if already initialized * MM-8622: maintain plugin statuses in memory Switch away from persisting plugin statuses to the database, and maintain in memory instead. This will be followed by a cluster interface to query the in-memory status of plugin statuses from all cluster nodes. At the same time, rename `cluster_discovery_id` on the `PluginStatus` model object to `cluster_id`. * MM-8622: aggregate plugin statuses across cluster * fetch cluster plugin statuses when emitting websocket notification * address unit test fixes after rebasing * relax (poor) racey unit test re: supervisor.Wait() * make store-mocks
2018-05-23 14:26:35 -04:00
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = false
})
MM-8622: Improved plugin error reporting (#8737) * allow `Wait()`ing on the supervisor In the event the plugin supervisor shuts down a plugin for crashing too many times, the new `Wait()` interface allows the `ActivatePlugin` to accept a callback function to trigger when `supervisor.Wait()` returns. If the supervisor shuts down normally, this callback is invoked with a nil error, otherwise any error reported by the supervisor is passed along. * improve plugin activation/deactivation logic Avoid triggering activation of previously failed-to-start plugins just becase something in the configuration changed. Now, intelligently compare the global enable bit as well as the each individual plugin's enabled bit. * expose store to manipulate PluginStatuses * expose API to fetch plugin statuses * keep track of whether or not plugin sandboxing is supported * transition plugin statuses * restore error on plugin activation if already active * don't initialize test plugins until successfully loaded * emit websocket events when plugin statuses change * skip pruning if already initialized * MM-8622: maintain plugin statuses in memory Switch away from persisting plugin statuses to the database, and maintain in memory instead. This will be followed by a cluster interface to query the in-memory status of plugin statuses from all cluster nodes. At the same time, rename `cluster_discovery_id` on the `PluginStatus` model object to `cluster_id`. * MM-8622: aggregate plugin statuses across cluster * fetch cluster plugin statuses when emitting websocket notification * address unit test fixes after rebasing * relax (poor) racey unit test re: supervisor.Wait() * make store-mocks
2018-05-23 14:26:35 -04:00
_, err := th.App.GetPluginStatuses()
require.NotNil(t, err)
MM-8622: Improved plugin error reporting (#8737) * allow `Wait()`ing on the supervisor In the event the plugin supervisor shuts down a plugin for crashing too many times, the new `Wait()` interface allows the `ActivatePlugin` to accept a callback function to trigger when `supervisor.Wait()` returns. If the supervisor shuts down normally, this callback is invoked with a nil error, otherwise any error reported by the supervisor is passed along. * improve plugin activation/deactivation logic Avoid triggering activation of previously failed-to-start plugins just becase something in the configuration changed. Now, intelligently compare the global enable bit as well as the each individual plugin's enabled bit. * expose store to manipulate PluginStatuses * expose API to fetch plugin statuses * keep track of whether or not plugin sandboxing is supported * transition plugin statuses * restore error on plugin activation if already active * don't initialize test plugins until successfully loaded * emit websocket events when plugin statuses change * skip pruning if already initialized * MM-8622: maintain plugin statuses in memory Switch away from persisting plugin statuses to the database, and maintain in memory instead. This will be followed by a cluster interface to query the in-memory status of plugin statuses from all cluster nodes. At the same time, rename `cluster_discovery_id` on the `PluginStatus` model object to `cluster_id`. * MM-8622: aggregate plugin statuses across cluster * fetch cluster plugin statuses when emitting websocket notification * address unit test fixes after rebasing * relax (poor) racey unit test re: supervisor.Wait() * make store-mocks
2018-05-23 14:26:35 -04:00
require.EqualError(t, err, "GetPluginStatuses: Plugins have been disabled. Please check your logs for details., ")
}
func TestGetPluginStatuses(t *testing.T) {
th := Setup(t)
MM-8622: Improved plugin error reporting (#8737) * allow `Wait()`ing on the supervisor In the event the plugin supervisor shuts down a plugin for crashing too many times, the new `Wait()` interface allows the `ActivatePlugin` to accept a callback function to trigger when `supervisor.Wait()` returns. If the supervisor shuts down normally, this callback is invoked with a nil error, otherwise any error reported by the supervisor is passed along. * improve plugin activation/deactivation logic Avoid triggering activation of previously failed-to-start plugins just becase something in the configuration changed. Now, intelligently compare the global enable bit as well as the each individual plugin's enabled bit. * expose store to manipulate PluginStatuses * expose API to fetch plugin statuses * keep track of whether or not plugin sandboxing is supported * transition plugin statuses * restore error on plugin activation if already active * don't initialize test plugins until successfully loaded * emit websocket events when plugin statuses change * skip pruning if already initialized * MM-8622: maintain plugin statuses in memory Switch away from persisting plugin statuses to the database, and maintain in memory instead. This will be followed by a cluster interface to query the in-memory status of plugin statuses from all cluster nodes. At the same time, rename `cluster_discovery_id` on the `PluginStatus` model object to `cluster_id`. * MM-8622: aggregate plugin statuses across cluster * fetch cluster plugin statuses when emitting websocket notification * address unit test fixes after rebasing * relax (poor) racey unit test re: supervisor.Wait() * make store-mocks
2018-05-23 14:26:35 -04:00
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
})
pluginStatuses, err := th.App.GetPluginStatuses()
require.Nil(t, err)
require.NotNil(t, pluginStatuses)
}
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
func TestPluginSync(t *testing.T) {
th := Setup(t)
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
defer th.TearDown()
testCases := []struct {
Description string
ConfigFunc func(cfg *model.Config)
}{
{
"local",
func(cfg *model.Config) {
cfg.FileSettings.DriverName = model.NewString(model.IMAGE_DRIVER_LOCAL)
},
},
{
"s3",
func(cfg *model.Config) {
s3Host := os.Getenv("CI_MINIO_HOST")
if s3Host == "" {
s3Host = "localhost"
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
}
s3Port := os.Getenv("CI_MINIO_PORT")
if s3Port == "" {
s3Port = "9000"
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
}
s3Endpoint := fmt.Sprintf("%s:%s", s3Host, s3Port)
cfg.FileSettings.DriverName = model.NewString(model.IMAGE_DRIVER_S3)
cfg.FileSettings.AmazonS3AccessKeyId = model.NewString(model.MINIO_ACCESS_KEY)
cfg.FileSettings.AmazonS3SecretAccessKey = model.NewString(model.MINIO_SECRET_KEY)
cfg.FileSettings.AmazonS3Bucket = model.NewString(model.MINIO_BUCKET)
cfg.FileSettings.AmazonS3PathPrefix = model.NewString("")
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
cfg.FileSettings.AmazonS3Endpoint = model.NewString(s3Endpoint)
cfg.FileSettings.AmazonS3Region = model.NewString("")
cfg.FileSettings.AmazonS3SSL = model.NewBool(false)
},
},
}
for _, testCase := range testCases {
t.Run(testCase.Description, func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
testCase.ConfigFunc(cfg)
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
})
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
env := th.App.GetPluginsEnvironment()
require.NotNil(t, env)
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
path, _ := fileutils.FindDir("tests")
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
t.Run("new bundle in the file store", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.RequirePluginSignature = false
})
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
fileReader, err := os.Open(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)
defer fileReader.Close()
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
_, appErr := th.App.WriteFile(fileReader, th.App.getBundleStorePath("testplugin"))
checkNoError(t, appErr)
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
appErr = th.App.SyncPlugins()
checkNoError(t, appErr)
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
// Check if installed
pluginStatus, err := env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
})
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
t.Run("bundle removed from the file store", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.RequirePluginSignature = false
})
MM-16368 - Plugin Signing (#13017) * [MM-18757] POST handler for `/plugins/marketplace` (#12372) * Implement installMarketplacePlugin * Add InstallMarketplacePlugin endpoint * Fix go.mod * merge with master * Fix go.mod * Fix plugin tests * Move get plugin to marketplace client * Fix stylistic concerns * Add trailing newline to the go.mod * [MM-16586] Add plugin signature settings (#12390) * MM-17149 - Extend config.json for marketplace settings (#11933) * MM-17149 - Extend config.json for marketplace settings * Renamed MarketplaceUrl, tracking default marketplace url * Added EnableMarketplace to the client config * Revert "Added EnableMarketplace to the client config" This reverts commit 0f982c4c661c2cd9bb96264e9a01a2363c40d9c5. * MM-17149 - Added EnableMarketplace to the client config (#11958) * Added EnableMarketplace to the client config * Moved EnableMarketplace setting out of limited client configuration * Add public key settings to the config.json * Rename PublicKeys to SignaturePublicKeyFiles * Change filepath.Split to Base * Remove additional prints * Force extention of a public key file * Remove config validation * Remove error on delete * Remove config cloning * Add error messages * Add plugin public key tests * Rename extension to PluginSignaturePublicKeyFileExtention * Remove EnforceVerification * Change []*PublicKeyDescription to []string * Change .asc extension to .plugin.asc * Change ordering of public methods * Change plugin key commands * Update examples in the plugin key commands * Remove forcing extention * Add verify signature in settings * Fix tabbing * Fix naming * Remove unused text * Remove unused text * Update command examples * Fix unit tests * Change errors.New to errors.Wrap * Fix verbose flag * Change .asc to .gpg * Fix } * Change AddPublicKey signature * Change public.key extension * Add plugin public key command tests * Update en.json * Bootstrap the public keys * Update en.json * Fix en.json * Fix en.json * Bootstrap hard-coded public key * Remove unused texts in en.json * Change file to name * Add license header * Update development public key * Remove writeFile method * Remove .plugin.asc extension * Rename publiKey to mattermostPublicKey * Remove init_public_keys string * GolangCI * Closing file handlers * Fixed test that was installing nps plugin * [MM-19798] Implement plugin signature verification (#12768) * MM-17149 - Extend config.json for marketplace settings (#11933) * MM-17149 - Extend config.json for marketplace settings * Renamed MarketplaceUrl, tracking default marketplace url * Added EnableMarketplace to the client config * Revert "Added EnableMarketplace to the client config" This reverts commit 0f982c4c661c2cd9bb96264e9a01a2363c40d9c5. * MM-17149 - Added EnableMarketplace to the client config (#11958) * Added EnableMarketplace to the client config * Moved EnableMarketplace setting out of limited client configuration * Add public key settings to the config.json * Rename PublicKeys to SignaturePublicKeyFiles * Change filepath.Split to Base * Remove additional prints * Force extention of a public key file * Remove config validation * Remove error on delete * Remove config cloning * Add error messages * Add plugin public key tests * Rename extension to PluginSignaturePublicKeyFileExtention * Remove EnforceVerification * Change []*PublicKeyDescription to []string * Change .asc extension to .plugin.asc * Change ordering of public methods * Change plugin key commands * Update examples in the plugin key commands * Remove forcing extention * Add verify signature in settings * Fix tabbing * Fix naming * Remove unused text * Remove unused text * Update command examples * Fix unit tests * Change errors.New to errors.Wrap * Fix verbose flag * Change .asc to .gpg * Fix } * Change AddPublicKey signature * Change public.key extension * Add plugin public key command tests * Update en.json * Bootstrap the public keys * Update en.json * Fix en.json * Fix en.json * Bootstrap hard-coded public key * Remove unused texts in en.json * Change file to name * Add license header * Implement plugin signature verification * Remove benburker openpgp * Update en.json * Update development public key * Add support of multiple signatures in filestore * Update en.json * Run go mod vendor * Fix style * Remove writeFile method * Remove .plugin.asc extension * Rename publiKey to mattermostPublicKey * Verify plugin with mattermost public key * Remove init_public_keys string * Add InstallPluginWithSignature method and Refactor * Add signature verification on claster notification * Remove armored signature headers * Add error strings * Fix en.json * Change signatureStorePath * Implement minor fixes * Refactor plugin install methods * Add installPlugin method to uploadPlugin * Update en.json * Refactor installPlugin * Limit number of signatures * Close signatures * Fix helper function * Fix fromReadCloseSeekerToReadSeeker * Cleaned up ReadCloseSeeker for signatures * Remove signature truncation on FS * GolangCI * Add tests for armored signatures and plugin uploads * Fix nil slice issue * Fix TestPluginSync * Fixed tests * Return io.ReadSeeker from downloadFromUrl * Add log for the found plugins in the file store * Remove logging plugin detection info * [MM-20134] Consume and store single-signature for each plugin (#13081) * Consume and store single-signature for each plugin * Fix en.json * Remove saveSignature method * Remove public key hash * PR Feedback * refactored config * PR feedback
2019-11-18 19:02:41 -05:00
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
appErr := th.App.RemoveFile(th.App.getBundleStorePath("testplugin"))
checkNoError(t, appErr)
appErr = th.App.SyncPlugins()
checkNoError(t, appErr)
// Check if removed
pluginStatus, err := env.Statuses()
require.Nil(t, err)
require.Empty(t, pluginStatus)
})
t.Run("plugin signatures required, no signature", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.RequirePluginSignature = true
})
pluginFileReader, err := os.Open(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)
defer pluginFileReader.Close()
_, appErr := th.App.WriteFile(pluginFileReader, th.App.getBundleStorePath("testplugin"))
checkNoError(t, appErr)
appErr = th.App.SyncPlugins()
checkNoError(t, appErr)
pluginStatus, err := env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 0)
})
t.Run("plugin signatures required, wrong signature", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.RequirePluginSignature = true
})
signatureFileReader, err := os.Open(filepath.Join(path, "testplugin2.tar.gz.sig"))
require.NoError(t, err)
defer signatureFileReader.Close()
_, appErr := th.App.WriteFile(signatureFileReader, th.App.getSignatureStorePath("testplugin"))
checkNoError(t, appErr)
appErr = th.App.SyncPlugins()
checkNoError(t, appErr)
pluginStatus, err := env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 0)
})
t.Run("plugin signatures required, correct signature", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.RequirePluginSignature = true
})
key, err := os.Open(filepath.Join(path, "development-private-key.asc"))
require.NoError(t, err)
appErr := th.App.AddPublicKey("pub_key", key)
checkNoError(t, appErr)
signatureFileReader, err := os.Open(filepath.Join(path, "testplugin.tar.gz.sig"))
require.NoError(t, err)
defer signatureFileReader.Close()
_, appErr = th.App.WriteFile(signatureFileReader, th.App.getSignatureStorePath("testplugin"))
checkNoError(t, appErr)
appErr = th.App.SyncPlugins()
checkNoError(t, appErr)
pluginStatus, err := env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
appErr = th.App.DeletePublicKey("pub_key")
checkNoError(t, appErr)
appErr = th.App.RemovePlugin("testplugin")
checkNoError(t, appErr)
MM-16368 - Plugin Signing (#13017) * [MM-18757] POST handler for `/plugins/marketplace` (#12372) * Implement installMarketplacePlugin * Add InstallMarketplacePlugin endpoint * Fix go.mod * merge with master * Fix go.mod * Fix plugin tests * Move get plugin to marketplace client * Fix stylistic concerns * Add trailing newline to the go.mod * [MM-16586] Add plugin signature settings (#12390) * MM-17149 - Extend config.json for marketplace settings (#11933) * MM-17149 - Extend config.json for marketplace settings * Renamed MarketplaceUrl, tracking default marketplace url * Added EnableMarketplace to the client config * Revert "Added EnableMarketplace to the client config" This reverts commit 0f982c4c661c2cd9bb96264e9a01a2363c40d9c5. * MM-17149 - Added EnableMarketplace to the client config (#11958) * Added EnableMarketplace to the client config * Moved EnableMarketplace setting out of limited client configuration * Add public key settings to the config.json * Rename PublicKeys to SignaturePublicKeyFiles * Change filepath.Split to Base * Remove additional prints * Force extention of a public key file * Remove config validation * Remove error on delete * Remove config cloning * Add error messages * Add plugin public key tests * Rename extension to PluginSignaturePublicKeyFileExtention * Remove EnforceVerification * Change []*PublicKeyDescription to []string * Change .asc extension to .plugin.asc * Change ordering of public methods * Change plugin key commands * Update examples in the plugin key commands * Remove forcing extention * Add verify signature in settings * Fix tabbing * Fix naming * Remove unused text * Remove unused text * Update command examples * Fix unit tests * Change errors.New to errors.Wrap * Fix verbose flag * Change .asc to .gpg * Fix } * Change AddPublicKey signature * Change public.key extension * Add plugin public key command tests * Update en.json * Bootstrap the public keys * Update en.json * Fix en.json * Fix en.json * Bootstrap hard-coded public key * Remove unused texts in en.json * Change file to name * Add license header * Update development public key * Remove writeFile method * Remove .plugin.asc extension * Rename publiKey to mattermostPublicKey * Remove init_public_keys string * GolangCI * Closing file handlers * Fixed test that was installing nps plugin * [MM-19798] Implement plugin signature verification (#12768) * MM-17149 - Extend config.json for marketplace settings (#11933) * MM-17149 - Extend config.json for marketplace settings * Renamed MarketplaceUrl, tracking default marketplace url * Added EnableMarketplace to the client config * Revert "Added EnableMarketplace to the client config" This reverts commit 0f982c4c661c2cd9bb96264e9a01a2363c40d9c5. * MM-17149 - Added EnableMarketplace to the client config (#11958) * Added EnableMarketplace to the client config * Moved EnableMarketplace setting out of limited client configuration * Add public key settings to the config.json * Rename PublicKeys to SignaturePublicKeyFiles * Change filepath.Split to Base * Remove additional prints * Force extention of a public key file * Remove config validation * Remove error on delete * Remove config cloning * Add error messages * Add plugin public key tests * Rename extension to PluginSignaturePublicKeyFileExtention * Remove EnforceVerification * Change []*PublicKeyDescription to []string * Change .asc extension to .plugin.asc * Change ordering of public methods * Change plugin key commands * Update examples in the plugin key commands * Remove forcing extention * Add verify signature in settings * Fix tabbing * Fix naming * Remove unused text * Remove unused text * Update command examples * Fix unit tests * Change errors.New to errors.Wrap * Fix verbose flag * Change .asc to .gpg * Fix } * Change AddPublicKey signature * Change public.key extension * Add plugin public key command tests * Update en.json * Bootstrap the public keys * Update en.json * Fix en.json * Fix en.json * Bootstrap hard-coded public key * Remove unused texts in en.json * Change file to name * Add license header * Implement plugin signature verification * Remove benburker openpgp * Update en.json * Update development public key * Add support of multiple signatures in filestore * Update en.json * Run go mod vendor * Fix style * Remove writeFile method * Remove .plugin.asc extension * Rename publiKey to mattermostPublicKey * Verify plugin with mattermost public key * Remove init_public_keys string * Add InstallPluginWithSignature method and Refactor * Add signature verification on claster notification * Remove armored signature headers * Add error strings * Fix en.json * Change signatureStorePath * Implement minor fixes * Refactor plugin install methods * Add installPlugin method to uploadPlugin * Update en.json * Refactor installPlugin * Limit number of signatures * Close signatures * Fix helper function * Fix fromReadCloseSeekerToReadSeeker * Cleaned up ReadCloseSeeker for signatures * Remove signature truncation on FS * GolangCI * Add tests for armored signatures and plugin uploads * Fix nil slice issue * Fix TestPluginSync * Fixed tests * Return io.ReadSeeker from downloadFromUrl * Add log for the found plugins in the file store * Remove logging plugin detection info * [MM-20134] Consume and store single-signature for each plugin (#13081) * Consume and store single-signature for each plugin * Fix en.json * Remove saveSignature method * Remove public key hash * PR Feedback * refactored config * PR feedback
2019-11-18 19:02:41 -05:00
})
MM-16261: Synchronize plugins in HA (#11657) * MM-16272 - Synchronize plugins across cluster (#11611) * MM-16272 - Synchronize plugins across cluster * Adding a test * MM-16272 - Fixed tests * MM-16272 - PR feedback * MM-16270 - Plugin Sync (#11615) * Initial implementation for plugin synch with file store. WIP * Removed ListAll implementation. Used ListDirectory and change localstore to be consistent and return all items (files and folders) from directory * Refactored plugin filestore operations out of main install/remove plugin * Fixing error handling details * Changes to use structured logging * More logging fixes * Wording and comments improvements * Error handling and control flow improvements * Changed managed flag check to use os.stat * Added file store plugin dir and filename consts * Replaced FileRead to use a the FileReader in PluginSync * Minor styling and PR feedback changes * Minor error handling improvements * Added unit test for SyncPlugins. Changed SyncPlugins to use plugins environment to list available plugins * PR Feedback improvements * Minor err handling fix * Removing FileStorePath from PluginEventData (#11644) * Fix plugin path (#11654) * tweak path, logging Fix an issue not finding the plugins folder in S3. Tweak logging messages to add additional clarity. * Removing FileExists check when Syncing plugins. Updated localstore to not return an error when directory does not exist * PR Feedback * Install prepackaged plugins locally only (#11656) * s/uninstall/remove * Updated ClusterMessage comment * Updated PluginSync to test against s3 + local storage
2019-07-18 15:05:53 -03:00
})
}
}
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
func TestSyncPluginsActiveState(t *testing.T) {
th := Setup(t)
defer th.TearDown()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
})
env := th.App.GetPluginsEnvironment()
require.NotNil(t, env)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.RequirePluginSignature = false
})
path, _ := fileutils.FindDir("tests")
fileReader, err := os.Open(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)
defer fileReader.Close()
_, appErr := th.App.WriteFile(fileReader, th.App.getBundleStorePath("testplugin"))
checkNoError(t, appErr)
// Sync with file store so the plugin environment has access to this plugin.
appErr = th.App.SyncPlugins()
checkNoError(t, appErr)
// Verify the plugin was installed and set to deactivated.
pluginStatus, err := env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
require.Equal(t, pluginStatus[0].State, model.PluginStateNotRunning)
// Enable plugin by setting setting config. This implicitly calls SyncPluginsActiveState through a config listener.
th.App.UpdateConfig(func(cfg *model.Config) {
cfg.PluginSettings.PluginStates["testplugin"] = &model.PluginState{Enable: true}
})
// Verify the plugin was activated due to config change.
pluginStatus, err = env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
require.Equal(t, pluginStatus[0].State, model.PluginStateRunning)
// Disable plugin by setting config. This implicitly calls SyncPluginsActiveState through a config listener.
th.App.UpdateConfig(func(cfg *model.Config) {
cfg.PluginSettings.PluginStates["testplugin"] = &model.PluginState{Enable: false}
})
// Verify the plugin was deactivated due to config change.
pluginStatus, err = env.Statuses()
require.Nil(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
require.Equal(t, pluginStatus[0].State, model.PluginStateNotRunning)
}
func TestPluginPanicLogs(t *testing.T) {
t.Run("should panic", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
tearDown, _, _ := SetAppEnvironmentWithPlugins(t, []string{
`
package main
import (
"github.com/mattermost/mattermost-server/v5/plugin"
"github.com/mattermost/mattermost-server/v5/model"
)
type MyPlugin struct {
plugin.MattermostPlugin
}
func (p *MyPlugin) MessageWillBePosted(c *plugin.Context, post *model.Post) (*model.Post, string) {
panic("some text from panic")
return nil, ""
}
func main() {
plugin.ClientMain(&MyPlugin{})
}
`,
}, th.App, th.App.NewPluginAPI)
defer tearDown()
post := &model.Post{
UserId: th.BasicUser.Id,
ChannelId: th.BasicChannel.Id,
Message: "message_",
CreateAt: model.GetMillis() - 10000,
}
_, err := th.App.CreatePost(post, th.BasicChannel, false, true)
assert.Nil(t, err)
testlib.AssertLog(t, th.LogBuffer, mlog.LevelDebug, "panic: some text from panic")
})
}
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
func TestProcessPrepackagedPlugins(t *testing.T) {
th := Setup(t)
MM-19606- Rework Prepackaged Plugins (#13449) * MM-19609 - Add new prepackage configuration settings (#13062) * Add signatures to the prepackaged plugins (#13138) * MM-19612 - Support querying local plugin marketplace when upst… (#13250) * MM-19612 - Support querying local plugin marketplace when upstream unavailable or disabled * Update translations file * Fixed comment * Updated to check EnableRemoteMarketplace setting and LocalOnly to get marketplace plugins * Fixed unit tests * Tests cleanup code * Removed unused error message * Updated tests * MM-19614- Updated Marketplace Service error id (#13388) * [MM-19610] Consume prepackaged plugins (#13005) * consume prepackaged plugins into memory * missing i18n * remove spurious .gitignore changes * return on failure to install prepackged plugins * cleanup * s/plugins/availablePlugins * whitespace * don't return extractDir when not needed * s/plug/plugin * error on icon, cleanup * update armored version of testplugin signature * honour AutomaticPrepackagedPlugins * document getPrepackagedPlugin * MM-19613 - Include prepackaged plugins in marketplace results (#13433) * Added prepackaged plugins to marketplace results * PR Feedback * PR Feedback * Update error where definition * Removing unnecessary var declaration * Updated comments * MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438) * MM-21263 - Use EnableRemoteMarketplace in marketplace install endpoint * Call updateConfig before calling NewServer in TestHelper * Added translations * PR feedback * Translations * Feedback * s/helpers.go/download.go * Converging env.PrepackagedPlugins * Initial PR feedback * Ordered imports properly * Updated DownloadURL to return slice of bytes * Fixed method typo * Fixed logging * Added read lock for prepackaged plugins list * PR Feedback * Added condition to only install prepackaged plugin if it was previously enabled * Linting * Updated to check plugin state in config * Closing filereader * Only add local label if remote marketplace is enabled * Updated local tag description * Fixed tests Co-authored-by: Ali Farooq <ali.farooq0@pm.me> Co-authored-by: Shota Gvinepadze <wineson@gmail.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2020-01-15 13:38:55 -05:00
defer th.TearDown()
testsPath, _ := fileutils.FindDir("tests")
prepackagedPluginsPath := filepath.Join(testsPath, prepackagedPluginsDir)
fileErr := os.Mkdir(prepackagedPluginsPath, os.ModePerm)
require.NoError(t, fileErr)
defer os.RemoveAll(prepackagedPluginsPath)
prepackagedPluginsDir, found := fileutils.FindDir(prepackagedPluginsPath)
require.True(t, found, "failed to find prepackaged plugins directory")
testPluginPath := filepath.Join(testsPath, "testplugin.tar.gz")
fileErr = utils.CopyFile(testPluginPath, filepath.Join(prepackagedPluginsDir, "testplugin.tar.gz"))
require.NoError(t, fileErr)
t.Run("automatic, enabled plugin, no signature", func(t *testing.T) {
// Install the plugin and enable
pluginBytes, err := ioutil.ReadFile(testPluginPath)
require.NoError(t, err)
require.NotNil(t, pluginBytes)
manifest, appErr := th.App.installPluginLocally(bytes.NewReader(pluginBytes), nil, installPluginLocallyAlways)
require.Nil(t, appErr)
require.Equal(t, "testplugin", manifest.Id)
env := th.App.GetPluginsEnvironment()
activatedManifest, activated, err := env.Activate(manifest.Id)
require.NoError(t, err)
require.True(t, activated)
require.Equal(t, manifest, activatedManifest)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.AutomaticPrepackagedPlugins = true
})
plugins := th.App.processPrepackagedPlugins(prepackagedPluginsDir)
require.Len(t, plugins, 1)
require.Equal(t, plugins[0].Manifest.Id, "testplugin")
require.Empty(t, plugins[0].Signature, 0)
pluginStatus, err := env.Statuses()
require.NoError(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
appErr = th.App.RemovePlugin("testplugin")
checkNoError(t, appErr)
pluginStatus, err = env.Statuses()
require.NoError(t, err)
require.Len(t, pluginStatus, 0)
})
t.Run("automatic, not enabled plugin", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.AutomaticPrepackagedPlugins = true
})
env := th.App.GetPluginsEnvironment()
plugins := th.App.processPrepackagedPlugins(prepackagedPluginsDir)
require.Len(t, plugins, 1)
require.Equal(t, plugins[0].Manifest.Id, "testplugin")
require.Empty(t, plugins[0].Signature, 0)
pluginStatus, err := env.Statuses()
require.NoError(t, err)
require.Empty(t, pluginStatus, 0)
})
t.Run("automatic, multiple plugins with signatures, not enabled", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.AutomaticPrepackagedPlugins = true
})
env := th.App.GetPluginsEnvironment()
// Add signature
testPluginSignaturePath := filepath.Join(testsPath, "testplugin.tar.gz.sig")
err := utils.CopyFile(testPluginSignaturePath, filepath.Join(prepackagedPluginsDir, "testplugin.tar.gz.sig"))
require.NoError(t, err)
// Add second plugin
testPlugin2Path := filepath.Join(testsPath, "testplugin2.tar.gz")
err = utils.CopyFile(testPlugin2Path, filepath.Join(prepackagedPluginsDir, "testplugin2.tar.gz"))
require.NoError(t, err)
testPlugin2SignaturePath := filepath.Join(testsPath, "testplugin2.tar.gz.sig")
err = utils.CopyFile(testPlugin2SignaturePath, filepath.Join(prepackagedPluginsDir, "testplugin2.tar.gz.sig"))
require.NoError(t, err)
plugins := th.App.processPrepackagedPlugins(prepackagedPluginsDir)
require.Len(t, plugins, 2)
require.Contains(t, []string{"testplugin", "testplugin2"}, plugins[0].Manifest.Id)
require.NotEmpty(t, plugins[0].Signature)
require.Contains(t, []string{"testplugin", "testplugin2"}, plugins[1].Manifest.Id)
require.NotEmpty(t, plugins[1].Signature)
pluginStatus, err := env.Statuses()
require.NoError(t, err)
require.Len(t, pluginStatus, 0)
})
t.Run("automatic, multiple plugins with signatures, one enabled", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.AutomaticPrepackagedPlugins = true
})
env := th.App.GetPluginsEnvironment()
// Add signature
testPluginSignaturePath := filepath.Join(testsPath, "testplugin.tar.gz.sig")
err := utils.CopyFile(testPluginSignaturePath, filepath.Join(prepackagedPluginsDir, "testplugin.tar.gz.sig"))
require.NoError(t, err)
// Install first plugin and enable
pluginBytes, err := ioutil.ReadFile(testPluginPath)
require.NoError(t, err)
require.NotNil(t, pluginBytes)
manifest, appErr := th.App.installPluginLocally(bytes.NewReader(pluginBytes), nil, installPluginLocallyAlways)
require.Nil(t, appErr)
require.Equal(t, "testplugin", manifest.Id)
activatedManifest, activated, err := env.Activate(manifest.Id)
require.NoError(t, err)
require.True(t, activated)
require.Equal(t, manifest, activatedManifest)
// Add second plugin
testPlugin2Path := filepath.Join(testsPath, "testplugin2.tar.gz")
err = utils.CopyFile(testPlugin2Path, filepath.Join(prepackagedPluginsDir, "testplugin2.tar.gz"))
require.NoError(t, err)
testPlugin2SignaturePath := filepath.Join(testsPath, "testplugin2.tar.gz.sig")
err = utils.CopyFile(testPlugin2SignaturePath, filepath.Join(prepackagedPluginsDir, "testplugin2.tar.gz.sig"))
require.NoError(t, err)
plugins := th.App.processPrepackagedPlugins(prepackagedPluginsDir)
require.Len(t, plugins, 2)
require.Contains(t, []string{"testplugin", "testplugin2"}, plugins[0].Manifest.Id)
require.NotEmpty(t, plugins[0].Signature)
require.Contains(t, []string{"testplugin", "testplugin2"}, plugins[1].Manifest.Id)
require.NotEmpty(t, plugins[1].Signature)
pluginStatus, err := env.Statuses()
require.NoError(t, err)
require.Len(t, pluginStatus, 1)
require.Equal(t, pluginStatus[0].PluginId, "testplugin")
appErr = th.App.RemovePlugin("testplugin")
checkNoError(t, appErr)
pluginStatus, err = env.Statuses()
require.NoError(t, err)
require.Len(t, pluginStatus, 0)
})
t.Run("non-automatic, multiple plugins", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.AutomaticPrepackagedPlugins = false
})
env := th.App.GetPluginsEnvironment()
testPlugin2Path := filepath.Join(testsPath, "testplugin2.tar.gz")
err := utils.CopyFile(testPlugin2Path, filepath.Join(prepackagedPluginsDir, "testplugin2.tar.gz"))
require.NoError(t, err)
testPlugin2SignaturePath := filepath.Join(testsPath, "testplugin2.tar.gz.sig")
err = utils.CopyFile(testPlugin2SignaturePath, filepath.Join(prepackagedPluginsDir, "testplugin2.tar.gz.sig"))
require.NoError(t, err)
plugins := th.App.processPrepackagedPlugins(prepackagedPluginsDir)
require.Len(t, plugins, 2)
require.Contains(t, []string{"testplugin", "testplugin2"}, plugins[0].Manifest.Id)
require.NotEmpty(t, plugins[0].Signature)
require.Contains(t, []string{"testplugin", "testplugin2"}, plugins[1].Manifest.Id)
require.NotEmpty(t, plugins[1].Signature)
pluginStatus, err := env.Statuses()
require.NoError(t, err)
require.Len(t, pluginStatus, 0)
})
}