From 899ab31fff9b34bc125faf75b79a89e390deb2cf Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Fri, 1 Sep 2017 09:00:27 -0400 Subject: Implement experimental REST API endpoints for plugins (#7279) * Implement experimental REST API endpoints for plugins * Updates per feedback and rebase * Update tests * Further updates * Update extraction of plugins * Use OS temp dir for plugins instead of search path * Fail extraction on paths that attempt to traverse upward * Update pluginenv ActivePlugins() --- api4/plugin.go | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 api4/plugin.go (limited to 'api4/plugin.go') diff --git a/api4/plugin.go b/api4/plugin.go new file mode 100644 index 000000000..109695174 --- /dev/null +++ b/api4/plugin.go @@ -0,0 +1,120 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +// EXPERIMENTAL - SUBJECT TO CHANGE + +package api4 + +import ( + "net/http" + + l4g "github.com/alecthomas/log4go" + "github.com/mattermost/platform/app" + "github.com/mattermost/platform/model" + "github.com/mattermost/platform/utils" +) + +const ( + MAXIMUM_PLUGIN_FILE_SIZE = 50 * 1024 * 1024 +) + +func InitPlugin() { + l4g.Debug("EXPERIMENTAL: Initializing plugin api") + + BaseRoutes.Plugins.Handle("", ApiSessionRequired(uploadPlugin)).Methods("POST") + BaseRoutes.Plugins.Handle("", ApiSessionRequired(getPlugins)).Methods("GET") + BaseRoutes.Plugin.Handle("", ApiSessionRequired(removePlugin)).Methods("DELETE") + +} + +func uploadPlugin(c *Context, w http.ResponseWriter, r *http.Request) { + if !*utils.Cfg.PluginSettings.Enable { + c.Err = model.NewAppError("uploadPlugin", "app.plugin.disabled.app_error", nil, "", http.StatusNotImplemented) + return + } + + if !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { + c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + return + } + + if err := r.ParseMultipartForm(MAXIMUM_PLUGIN_FILE_SIZE); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + m := r.MultipartForm + + pluginArray, ok := m.File["plugin"] + if !ok { + c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.no_file.app_error", nil, "", http.StatusBadRequest) + return + } + + if len(pluginArray) <= 0 { + c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.array.app_error", nil, "", http.StatusBadRequest) + return + } + + file, err := pluginArray[0].Open() + if err != nil { + c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.file.app_error", nil, "", http.StatusBadRequest) + return + } + defer file.Close() + + manifest, unpackErr := app.UnpackAndActivatePlugin(file) + + if unpackErr != nil { + c.Err = unpackErr + return + } + + w.WriteHeader(http.StatusCreated) + w.Write([]byte(manifest.ToJson())) +} + +func getPlugins(c *Context, w http.ResponseWriter, r *http.Request) { + if !*utils.Cfg.PluginSettings.Enable { + c.Err = model.NewAppError("getPlugins", "app.plugin.disabled.app_error", nil, "", http.StatusNotImplemented) + return + } + + if !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { + c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + return + } + + manifests, err := app.GetActivePluginManifests() + if err != nil { + c.Err = err + return + } + + w.Write([]byte(model.ManifestListToJson(manifests))) +} + +func removePlugin(c *Context, w http.ResponseWriter, r *http.Request) { + c.RequirePluginId() + if c.Err != nil { + return + } + + if !*utils.Cfg.PluginSettings.Enable { + c.Err = model.NewAppError("getPlugins", "app.plugin.disabled.app_error", nil, "", http.StatusNotImplemented) + return + } + + if !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { + c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + return + } + + err := app.RemovePlugin(c.Params.PluginId) + if err != nil { + c.Err = err + return + } + + ReturnStatusOK(w) +} -- cgit v1.2.3-1-g7c22