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() --- model/client4.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'model/client4.go') diff --git a/model/client4.go b/model/client4.go index 26ea6ee03..badb60a2a 100644 --- a/model/client4.go +++ b/model/client4.go @@ -178,6 +178,14 @@ func (c *Client4) GetFileRoute(fileId string) string { return fmt.Sprintf(c.GetFilesRoute()+"/%v", fileId) } +func (c *Client4) GetPluginsRoute() string { + return fmt.Sprintf("/plugins") +} + +func (c *Client4) GetPluginRoute(pluginId string) string { + return fmt.Sprintf(c.GetPluginsRoute()+"/%v", pluginId) +} + func (c *Client4) GetSystemRoute() string { return fmt.Sprintf("/system") } @@ -3019,3 +3027,64 @@ func (c *Client4) CancelJob(jobId string) (bool, *Response) { return CheckStatusOK(r), BuildResponse(r) } } + +// Plugin Section + +// UploadPlugin takes an io.Reader stream pointing to the contents of a .tar.gz plugin. +// WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. +func (c *Client4) UploadPlugin(file io.Reader) (*Manifest, *Response) { + body := new(bytes.Buffer) + writer := multipart.NewWriter(body) + + if part, err := writer.CreateFormFile("plugin", "plugin.tar.gz"); err != nil { + return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} + } else if _, err = io.Copy(part, file); err != nil { + return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} + } + + if err := writer.Close(); err != nil { + return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} + } + + rq, _ := http.NewRequest("POST", c.ApiUrl+c.GetPluginsRoute(), body) + rq.Header.Set("Content-Type", writer.FormDataContentType()) + rq.Close = true + + if len(c.AuthToken) > 0 { + rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) + } + + if rp, err := c.HttpClient.Do(rq); err != nil || rp == nil { + return nil, BuildErrorResponse(rp, NewAppError("UploadPlugin", "model.client.connecting.app_error", nil, err.Error(), 0)) + } else { + defer closeBody(rp) + + if rp.StatusCode >= 300 { + return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) + } else { + return ManifestFromJson(rp.Body), BuildResponse(rp) + } + } +} + +// GetPlugins will return a list of plugin manifests for currently active plugins. +// WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. +func (c *Client4) GetPlugins() ([]*Manifest, *Response) { + if r, err := c.DoApiGet(c.GetPluginsRoute(), ""); err != nil { + return nil, BuildErrorResponse(r, err) + } else { + defer closeBody(r) + return ManifestListFromJson(r.Body), BuildResponse(r) + } +} + +// RemovePlugin will deactivate and delete a plugin. +// WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. +func (c *Client4) RemovePlugin(id string) (bool, *Response) { + if r, err := c.DoApiDelete(c.GetPluginRoute(id)); err != nil { + return false, BuildErrorResponse(r, err) + } else { + defer closeBody(r) + return CheckStatusOK(r), BuildResponse(r) + } +} -- cgit v1.2.3-1-g7c22