From c1c084a59669be1c70c9fcbb413a5dbe9f12f436 Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Tue, 7 Jun 2022 09:12:15 +0300 Subject: [PATCH] app/plugin: add product middleware and enable products register their routers (#20374) --- app/channels.go | 5 +++++ app/plugin.go | 23 +++++++++++++++++++++++ app/plugin_requests.go | 9 ++++++++- app/server.go | 1 + 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/channels.go b/app/channels.go index 4ebb777907..07692fe95d 100644 --- a/app/channels.go +++ b/app/channels.go @@ -51,6 +51,7 @@ type Channels struct { cfgSvc configSvc filestore filestore.FileBackend licenseSvc licenseSvc + routerSvc *routerService postActionCookieSecret []byte @@ -209,6 +210,9 @@ func NewChannels(s *Server, services map[ServiceKey]interface{}) (*Channels, err return nil, errors.Wrap(imgErr, "failed to create image encoder") } + ch.routerSvc = newRouterService() + services[RouterKey] = ch.routerSvc + // Setup routes. pluginsRoute := ch.srv.Router.PathPrefix("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}").Subrouter() pluginsRoute.HandleFunc("", ch.ServePluginRequest) @@ -267,6 +271,7 @@ func (ch *Channels) Start() error { if err := ch.ensurePostActionCookieSecret(); err != nil { return errors.Wrapf(err, "unable to ensure PostAction cookie secret") } + return nil } diff --git a/app/plugin.go b/app/plugin.go index dbe0e61704..9fb043c5b1 100644 --- a/app/plugin.go +++ b/app/plugin.go @@ -17,6 +17,7 @@ import ( "sync" "github.com/blang/semver" + "github.com/gorilla/mux" svg "github.com/h2non/go-is-svg" "github.com/pkg/errors" @@ -37,6 +38,28 @@ type pluginSignaturePath struct { signaturePath string } +type routerService struct { + mu sync.Mutex + routerMap map[string]*mux.Router +} + +func newRouterService() *routerService { + return &routerService{ + routerMap: make(map[string]*mux.Router), + } +} + +func (rs *routerService) RegisterRouter(productID string, sub *mux.Router) { + rs.mu.Lock() + defer rs.mu.Unlock() + rs.routerMap[productID] = sub +} + +func (rs *routerService) getHandler(productID string) (http.Handler, bool) { + handler, ok := rs.routerMap[productID] + return handler, ok +} + // GetPluginsEnvironment returns the plugin environment for use if plugins are enabled and // initialized. // diff --git a/app/plugin_requests.go b/app/plugin_requests.go index 142ec94a14..17301c54ce 100644 --- a/app/plugin_requests.go +++ b/app/plugin_requests.go @@ -21,6 +21,14 @@ import ( ) func (ch *Channels) ServePluginRequest(w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + if handler, ok := ch.routerSvc.getHandler(params["plugin_id"]); ok { + ch.servePluginRequest(w, r, func(*plugin.Context, http.ResponseWriter, *http.Request) { + handler.ServeHTTP(w, r) + }) + return + } + pluginsEnvironment := ch.GetPluginsEnvironment() if pluginsEnvironment == nil { err := model.NewAppError("ServePluginRequest", "app.plugin.disabled.app_error", nil, "Enable plugins to serve plugin requests", http.StatusNotImplemented) @@ -31,7 +39,6 @@ func (ch *Channels) ServePluginRequest(w http.ResponseWriter, r *http.Request) { return } - params := mux.Vars(r) hooks, err := pluginsEnvironment.HooksForPlugin(params["plugin_id"]) if err != nil { mlog.Debug("Access to route for non-existent plugin", diff --git a/app/server.go b/app/server.go index 67daea4b64..185e99546f 100644 --- a/app/server.go +++ b/app/server.go @@ -95,6 +95,7 @@ const ( TeamKey ServiceKey = "team" UserKey ServiceKey = "user" PermissionsKey ServiceKey = "permissions" + RouterKey ServiceKey = "router" ) type Server struct {