FS: Fix rendering of public dashboards in MT frontend service (#115162)
* pass publicDashboardAccessToken to ST backend via bootdata * slightly cleaner * slightly tidy up go templating * add HandleView middleware
This commit is contained in:
@@ -187,6 +187,15 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
publicdashboardsapi.CountPublicDashboardRequest(),
|
||||
hs.Index,
|
||||
)
|
||||
|
||||
r.Get("/bootdata/:accessToken",
|
||||
reqNoAuth,
|
||||
hs.PublicDashboardsApi.Middleware.HandleView,
|
||||
publicdashboardsapi.SetPublicDashboardAccessToken,
|
||||
publicdashboardsapi.SetPublicDashboardOrgIdOnContext(hs.PublicDashboardsApi.PublicDashboardService),
|
||||
publicdashboardsapi.CountPublicDashboardRequest(),
|
||||
hs.GetBootdata,
|
||||
)
|
||||
}
|
||||
|
||||
r.Get("/explore", authorize(ac.EvalPermission(ac.ActionDatasourcesExplore)), hs.Index)
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
fswebassets "github.com/grafana/grafana/pkg/services/frontend/webassets"
|
||||
"github.com/grafana/grafana/pkg/services/hooks"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
publicdashboardsapi "github.com/grafana/grafana/pkg/services/publicdashboards/api"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
@@ -164,6 +165,11 @@ func (s *frontendService) registerRoutes(m *web.Mux) {
|
||||
// uses cache busting to ensure requests aren't cached.
|
||||
s.routeGet(m, "/-/fe-boot-error", s.handleBootError)
|
||||
|
||||
s.routeGet(m, "/public-dashboards/:accessToken",
|
||||
publicdashboardsapi.SetPublicDashboardAccessToken,
|
||||
s.index.HandleRequest,
|
||||
)
|
||||
|
||||
// All other requests return index.html
|
||||
s.routeGet(m, "/*", s.index.HandleRequest)
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ type IndexViewData struct {
|
||||
|
||||
// Nonce is a cryptographic identifier for use with Content Security Policy.
|
||||
Nonce string
|
||||
|
||||
PublicDashboardAccessToken string
|
||||
}
|
||||
|
||||
// Templates setup.
|
||||
@@ -138,9 +140,12 @@ func (p *IndexProvider) HandleRequest(writer http.ResponseWriter, request *http.
|
||||
return
|
||||
}
|
||||
|
||||
reqCtx := contexthandler.FromContext(ctx)
|
||||
|
||||
// TODO -- restructure so the static stuff is under one variable and the rest is dynamic
|
||||
data := p.data // copy everything
|
||||
data.Nonce = nonce
|
||||
data.PublicDashboardAccessToken = reqCtx.PublicDashboardAccessToken
|
||||
|
||||
if data.CSPEnabled {
|
||||
data.CSPContent = middleware.ReplacePolicyVariables(p.data.CSPContent, p.data.AppSubUrl, data.Nonce)
|
||||
@@ -150,7 +155,6 @@ func (p *IndexProvider) HandleRequest(writer http.ResponseWriter, request *http.
|
||||
writer.Header().Set("Content-Security-Policy-Report-Only", policy)
|
||||
}
|
||||
|
||||
reqCtx := contexthandler.FromContext(ctx)
|
||||
p.runIndexDataHooks(reqCtx, &data)
|
||||
|
||||
writer.Header().Set("Content-Type", "text/html; charset=UTF-8")
|
||||
|
||||
@@ -188,6 +188,7 @@
|
||||
// Wrap in an IIFE to avoid polluting the global scope. Intentionally global-scope properties
|
||||
// are explicitly assigned to the `window` object.
|
||||
(() => {
|
||||
const publicDashboardAccessToken = [[.PublicDashboardAccessToken]]
|
||||
// Grafana can only fail to load once
|
||||
// However, it can fail to load in multiple different places
|
||||
// To avoid double reporting the error, we use this boolean to check if we've already failed
|
||||
@@ -271,9 +272,15 @@
|
||||
async function fetchBootData() {
|
||||
const queryParams = new URLSearchParams(window.location.search);
|
||||
|
||||
let path = '/bootdata';
|
||||
// call a special bootdata url with the public access token
|
||||
// this is needed to set the access token and correct org for public dashboards on the ST backend
|
||||
if (publicDashboardAccessToken) {
|
||||
path += `/${publicDashboardAccessToken}`;
|
||||
}
|
||||
// pass the search params through to the bootdata request
|
||||
// this allows for overriding the theme/language etc
|
||||
const bootDataUrl = new URL('/bootdata', window.location.origin);
|
||||
const bootDataUrl = new URL(path, window.location.origin);
|
||||
for (const [key, value] of queryParams.entries()) {
|
||||
bootDataUrl.searchParams.append(key, value);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ export const getPublicDashboardRoutes = (): RouteDescriptor[] => {
|
||||
{
|
||||
path: '/public-dashboards/:accessToken',
|
||||
pageClass: 'page-dashboard',
|
||||
allowAnonymous: true,
|
||||
routeName: DashboardRoutes.Public,
|
||||
chromeless: true,
|
||||
component: SafeDynamicImport(
|
||||
|
||||
Reference in New Issue
Block a user