github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/services/marketplace/client.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package marketplace 5 6 import ( 7 "fmt" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "net/url" 12 "strings" 13 14 "github.com/mattermost/mattermost-server/v5/model" 15 "github.com/mattermost/mattermost-server/v5/services/httpservice" 16 "github.com/pkg/errors" 17 ) 18 19 // Client is the programmatic interface to the marketplace server API. 20 type Client struct { 21 address string 22 httpClient *http.Client 23 } 24 25 // NewClient creates a client to the marketplace server at the given address. 26 func NewClient(address string, httpService httpservice.HTTPService) (*Client, error) { 27 var httpClient *http.Client 28 addressUrl, err := url.Parse(address) 29 if err != nil { 30 return nil, errors.Wrap(err, "failed to parse marketplace address") 31 } 32 if addressUrl.Hostname() == "localhost" || addressUrl.Hostname() == "127.0.0.1" { 33 httpClient = httpService.MakeClient(true) 34 } else { 35 httpClient = httpService.MakeClient(false) 36 } 37 38 return &Client{ 39 address: address, 40 httpClient: httpClient, 41 }, nil 42 } 43 44 // GetPlugins fetches the list of plugins from the configured server. 45 func (c *Client) GetPlugins(request *model.MarketplacePluginFilter) ([]*model.BaseMarketplacePlugin, error) { 46 u, err := url.Parse(c.buildURL("/api/v1/plugins")) 47 if err != nil { 48 return nil, err 49 } 50 51 request.ApplyToURL(u) 52 53 resp, err := c.doGet(u.String()) 54 if err != nil { 55 return nil, err 56 } 57 defer closeBody(resp) 58 59 switch resp.StatusCode { 60 case http.StatusOK: 61 return model.BaseMarketplacePluginsFromReader(resp.Body) 62 default: 63 return nil, errors.Errorf("failed with status code %d", resp.StatusCode) 64 } 65 } 66 67 func (c *Client) GetPlugin(filter *model.MarketplacePluginFilter, pluginVersion string) (*model.BaseMarketplacePlugin, error) { 68 plugins, err := c.GetPlugins(filter) 69 if err != nil { 70 return nil, err 71 } 72 for _, plugin := range plugins { 73 if plugin.Manifest.Version == pluginVersion { 74 return plugin, nil 75 } 76 } 77 return nil, errors.New("plugin not found") 78 } 79 80 // closeBody ensures the Body of an http.Response is properly closed. 81 func closeBody(r *http.Response) { 82 if r.Body != nil { 83 _, _ = io.Copy(ioutil.Discard, r.Body) 84 _ = r.Body.Close() 85 } 86 } 87 88 func (c *Client) buildURL(urlPath string, args ...interface{}) string { 89 return fmt.Sprintf("%s/%s", strings.TrimRight(c.address, "/"), strings.TrimLeft(fmt.Sprintf(urlPath, args...), "/")) 90 } 91 92 func (c *Client) doGet(u string) (*http.Response, error) { 93 return c.httpClient.Get(u) 94 }