From 91b0cdc8712e3f23055d0f8ece836da53eb63c05 Mon Sep 17 00:00:00 2001 From: Will Browne Date: Thu, 8 Jun 2023 18:36:41 +0200 Subject: [PATCH] Plugins: Account for nil user when constructing plugin context (#69811) cater for nil user --- pkg/api/plugin_resource.go | 2 +- pkg/api/plugins.go | 2 +- pkg/services/live/liveplugin/plugin.go | 2 +- .../plugincontext/plugincontext.go | 36 ++++++++++++------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/pkg/api/plugin_resource.go b/pkg/api/plugin_resource.go index 8ca1a20dbf3..6f94a627ad2 100644 --- a/pkg/api/plugin_resource.go +++ b/pkg/api/plugin_resource.go @@ -26,7 +26,7 @@ func (hs *HTTPServer) CallResource(c *contextmodel.ReqContext) { } func (hs *HTTPServer) callPluginResource(c *contextmodel.ReqContext, pluginID string) { - pCtx, err := hs.pluginContextProvider.Get(c.Req.Context(), pluginID, c.SignedInUser) + pCtx, err := hs.pluginContextProvider.Get(c.Req.Context(), pluginID, c.SignedInUser, c.OrgID) if err != nil { if errors.Is(err, plugincontext.ErrPluginNotFound) { c.JsonApiErr(404, "Plugin not found", nil) diff --git a/pkg/api/plugins.go b/pkg/api/plugins.go index 19bfd231472..55c7395620a 100644 --- a/pkg/api/plugins.go +++ b/pkg/api/plugins.go @@ -393,7 +393,7 @@ func (hs *HTTPServer) redirectCDNPluginAsset(c *contextmodel.ReqContext, plugin // /api/plugins/:pluginId/health func (hs *HTTPServer) CheckHealth(c *contextmodel.ReqContext) response.Response { pluginID := web.Params(c.Req)[":pluginId"] - pCtx, err := hs.pluginContextProvider.Get(c.Req.Context(), pluginID, c.SignedInUser) + pCtx, err := hs.pluginContextProvider.Get(c.Req.Context(), pluginID, c.SignedInUser, c.OrgID) if err != nil { if errors.Is(err, plugincontext.ErrPluginNotFound) { return response.Error(404, "Plugin not found", nil) diff --git a/pkg/services/live/liveplugin/plugin.go b/pkg/services/live/liveplugin/plugin.go index cda9e012b30..8a9a9a35c99 100644 --- a/pkg/services/live/liveplugin/plugin.go +++ b/pkg/services/live/liveplugin/plugin.go @@ -74,7 +74,7 @@ func NewContextGetter(pluginContextProvider *plugincontext.Provider, dataSourceC func (g *ContextGetter) GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, error) { if datasourceUID == "" { - return g.pluginContextProvider.Get(ctx, pluginID, user) + return g.pluginContextProvider.Get(ctx, pluginID, user, user.OrgID) } ds, err := g.dataSourceCache.GetDatasourceByUID(ctx, datasourceUID, user, skipCache) diff --git a/pkg/services/pluginsintegration/plugincontext/plugincontext.go b/pkg/services/pluginsintegration/plugincontext/plugincontext.go index 1dea0e6af6b..34b9be7056c 100644 --- a/pkg/services/pluginsintegration/plugincontext/plugincontext.go +++ b/pkg/services/pluginsintegration/plugincontext/plugincontext.go @@ -39,20 +39,23 @@ type Provider struct { // Get allows getting plugin context by its ID. If datasourceUID is not empty string // then PluginContext.DataSourceInstanceSettings will be resolved and appended to // returned context. -func (p *Provider) Get(ctx context.Context, pluginID string, user *user.SignedInUser) (backend.PluginContext, error) { +// Note: *user.SignedInUser can be nil. +func (p *Provider) Get(ctx context.Context, pluginID string, user *user.SignedInUser, orgID int64) (backend.PluginContext, error) { plugin, exists := p.pluginStore.Plugin(ctx, pluginID) if !exists { return backend.PluginContext{}, ErrPluginNotFound } pCtx := backend.PluginContext{ - OrgID: user.OrgID, PluginID: pluginID, - User: adapters.BackendUserFromSignedInUser(user), + } + if user != nil { + pCtx.OrgID = user.OrgID + pCtx.User = adapters.BackendUserFromSignedInUser(user) } if plugin.IsApp() { - appSettings, err := p.appInstanceSettings(ctx, pluginID, user) + appSettings, err := p.appInstanceSettings(ctx, pluginID, orgID) if err != nil { return backend.PluginContext{}, err } @@ -64,10 +67,19 @@ func (p *Provider) Get(ctx context.Context, pluginID string, user *user.SignedIn // GetWithDataSource allows getting plugin context by its ID and PluginContext.DataSourceInstanceSettings will be // resolved and appended to the returned context. +// Note: *user.SignedInUser can be nil. func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user *user.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, error) { - pCtx, err := p.Get(ctx, pluginID, user) - if err != nil { - return backend.PluginContext{}, err + _, exists := p.pluginStore.Plugin(ctx, pluginID) + if !exists { + return backend.PluginContext{}, ErrPluginNotFound + } + + pCtx := backend.PluginContext{ + PluginID: pluginID, + } + if user != nil { + pCtx.OrgID = user.OrgID + pCtx.User = adapters.BackendUserFromSignedInUser(user) } datasourceSettings, err := adapters.ModelToInstanceSettings(ds, p.decryptSecureJsonDataFn(ctx)) @@ -82,12 +94,12 @@ func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user const pluginSettingsCacheTTL = 5 * time.Second const pluginSettingsCachePrefix = "plugin-setting-" -func (p *Provider) appInstanceSettings(ctx context.Context, pluginID string, user *user.SignedInUser) (*backend.AppInstanceSettings, error) { +func (p *Provider) appInstanceSettings(ctx context.Context, pluginID string, orgID int64) (*backend.AppInstanceSettings, error) { jsonData := json.RawMessage{} decryptedSecureJSONData := map[string]string{} var updated time.Time - ps, err := p.getCachedPluginSettings(ctx, pluginID, user) + ps, err := p.getCachedPluginSettings(ctx, pluginID, orgID) if err != nil { // pluginsettings.ErrPluginSettingNotFound is expected if there's no row found for plugin setting in database (if non-app plugin). // Otherwise, something is wrong with cache or database, and we return the error to the client. @@ -114,19 +126,19 @@ func (p *Provider) InvalidateSettingsCache(_ context.Context, pluginID string) { p.cacheService.Delete(getCacheKey(pluginID)) } -func (p *Provider) getCachedPluginSettings(ctx context.Context, pluginID string, user *user.SignedInUser) (*pluginsettings.DTO, error) { +func (p *Provider) getCachedPluginSettings(ctx context.Context, pluginID string, orgID int64) (*pluginsettings.DTO, error) { cacheKey := getCacheKey(pluginID) if cached, found := p.cacheService.Get(cacheKey); found { ps := cached.(*pluginsettings.DTO) - if ps.OrgID == user.OrgID { + if ps.OrgID == orgID { return ps, nil } } ps, err := p.pluginSettingsService.GetPluginSettingByPluginID(ctx, &pluginsettings.GetByPluginIDArgs{ PluginID: pluginID, - OrgID: user.OrgID, + OrgID: orgID, }) if err != nil { return nil, err