mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PublicDashboards: Variables refactor (#73476)
Co-authored-by: Juan Cabanas <juan.cabanas@grafana.com> Co-authored-by: Ezequiel Victorero <ezequiel.victorero@grafana.com> Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
@@ -165,7 +165,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
|
||||
// anonymous view public dashboard
|
||||
r.Get("/public-dashboards/:accessToken",
|
||||
publicdashboardsapi.SetPublicDashboardFlag,
|
||||
publicdashboardsapi.SetPublicDashboardAccessToken,
|
||||
publicdashboardsapi.SetPublicDashboardOrgIdOnContext(hs.PublicDashboardsApi.PublicDashboardService),
|
||||
publicdashboardsapi.CountPublicDashboardRequest(),
|
||||
hs.Index,
|
||||
|
||||
@@ -7,34 +7,33 @@ import (
|
||||
)
|
||||
|
||||
type DashboardMeta struct {
|
||||
IsStarred bool `json:"isStarred,omitempty"`
|
||||
IsSnapshot bool `json:"isSnapshot,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
CanSave bool `json:"canSave"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAdmin bool `json:"canAdmin"`
|
||||
CanStar bool `json:"canStar"`
|
||||
CanDelete bool `json:"canDelete"`
|
||||
Slug string `json:"slug"`
|
||||
Url string `json:"url"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Version int `json:"version"`
|
||||
HasACL bool `json:"hasAcl" xorm:"has_acl"`
|
||||
IsFolder bool `json:"isFolder"`
|
||||
FolderId int64 `json:"folderId"`
|
||||
FolderUid string `json:"folderUid"`
|
||||
FolderTitle string `json:"folderTitle"`
|
||||
FolderUrl string `json:"folderUrl"`
|
||||
Provisioned bool `json:"provisioned"`
|
||||
ProvisionedExternalId string `json:"provisionedExternalId"`
|
||||
AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"`
|
||||
PublicDashboardAccessToken string `json:"publicDashboardAccessToken"`
|
||||
PublicDashboardUID string `json:"publicDashboardUid"`
|
||||
PublicDashboardEnabled bool `json:"publicDashboardEnabled"`
|
||||
IsStarred bool `json:"isStarred,omitempty"`
|
||||
IsSnapshot bool `json:"isSnapshot,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
CanSave bool `json:"canSave"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAdmin bool `json:"canAdmin"`
|
||||
CanStar bool `json:"canStar"`
|
||||
CanDelete bool `json:"canDelete"`
|
||||
Slug string `json:"slug"`
|
||||
Url string `json:"url"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Version int `json:"version"`
|
||||
HasACL bool `json:"hasAcl" xorm:"has_acl"`
|
||||
IsFolder bool `json:"isFolder"`
|
||||
FolderId int64 `json:"folderId"`
|
||||
FolderUid string `json:"folderUid"`
|
||||
FolderTitle string `json:"folderTitle"`
|
||||
FolderUrl string `json:"folderUrl"`
|
||||
Provisioned bool `json:"provisioned"`
|
||||
ProvisionedExternalId string `json:"provisionedExternalId"`
|
||||
AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"`
|
||||
PublicDashboardUID string `json:"publicDashboardUid,omitempty"`
|
||||
PublicDashboardEnabled bool `json:"publicDashboardEnabled,omitempty"`
|
||||
}
|
||||
type AnnotationPermission struct {
|
||||
Dashboard AnnotationActions `json:"dashboard"`
|
||||
|
||||
@@ -217,7 +217,7 @@ type FrontendSettingsDTO struct {
|
||||
GeomapDefaultBaseLayerConfig *map[string]interface{} `json:"geomapDefaultBaseLayerConfig,omitempty"`
|
||||
GeomapDisableCustomBaseLayer bool `json:"geomapDisableCustomBaseLayer"`
|
||||
|
||||
IsPublicDashboardView bool `json:"isPublicDashboardView"`
|
||||
PublicDashboardAccessToken string `json:"publicDashboardAccessToken"`
|
||||
|
||||
DateFormats setting.DateFormats `json:"dateFormats,omitempty"`
|
||||
|
||||
|
||||
@@ -77,8 +77,6 @@ type MetricRequest struct {
|
||||
Queries []*simplejson.Json `json:"queries"`
|
||||
// required: false
|
||||
Debug bool `json:"debug"`
|
||||
|
||||
PublicDashboardAccessToken string `json:"publicDashboardAccessToken"`
|
||||
}
|
||||
|
||||
func (mr *MetricRequest) GetUniqueDatasourceTypes() []string {
|
||||
|
||||
@@ -152,6 +152,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
DateFormats: hs.Cfg.DateFormats,
|
||||
SecureSocksDSProxyEnabled: hs.Cfg.SecureSocksDSProxy.Enabled && hs.Cfg.SecureSocksDSProxy.ShowUI,
|
||||
DisableFrontendSandboxForPlugins: hs.Cfg.DisableFrontendSandboxForPlugins,
|
||||
PublicDashboardAccessToken: c.PublicDashboardAccessToken,
|
||||
|
||||
Auth: dtos.FrontendSettingsAuthDTO{
|
||||
OAuthSkipOrgRoleUpdateSync: hs.Cfg.OAuthSkipOrgRoleUpdateSync,
|
||||
@@ -282,7 +283,7 @@ func (hs *HTTPServer) getFSDataSources(c *contextmodel.ReqContext, availablePlug
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.IsPublicDashboardView {
|
||||
if c.IsPublicDashboardView() {
|
||||
// If RBAC is enabled, it will filter out all datasources for a public user, so we need to skip it
|
||||
orgDataSources = dataSources
|
||||
} else {
|
||||
|
||||
@@ -29,8 +29,6 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
return nil, err
|
||||
}
|
||||
|
||||
settings.IsPublicDashboardView = c.IsPublicDashboardView
|
||||
|
||||
prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: c.UserID, OrgID: c.OrgID, Teams: c.Teams}
|
||||
prefs, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery)
|
||||
if err != nil {
|
||||
|
||||
@@ -61,19 +61,19 @@ func CopyWithReqContext(ctx context.Context) context.Context {
|
||||
Resp: web.NewResponseWriter(origReqCtx.Req.Method, response.CreateNormalResponse(http.Header{}, []byte{}, 0)),
|
||||
}
|
||||
reqCtx := &contextmodel.ReqContext{
|
||||
Context: webCtx,
|
||||
SignedInUser: origReqCtx.SignedInUser,
|
||||
UserToken: origReqCtx.UserToken,
|
||||
IsSignedIn: origReqCtx.IsSignedIn,
|
||||
IsRenderCall: origReqCtx.IsRenderCall,
|
||||
AllowAnonymous: origReqCtx.AllowAnonymous,
|
||||
SkipDSCache: origReqCtx.SkipDSCache,
|
||||
SkipQueryCache: origReqCtx.SkipQueryCache,
|
||||
Logger: origReqCtx.Logger,
|
||||
Error: origReqCtx.Error,
|
||||
RequestNonce: origReqCtx.RequestNonce,
|
||||
IsPublicDashboardView: origReqCtx.IsPublicDashboardView,
|
||||
LookupTokenErr: origReqCtx.LookupTokenErr,
|
||||
Context: webCtx,
|
||||
SignedInUser: origReqCtx.SignedInUser,
|
||||
UserToken: origReqCtx.UserToken,
|
||||
IsSignedIn: origReqCtx.IsSignedIn,
|
||||
IsRenderCall: origReqCtx.IsRenderCall,
|
||||
AllowAnonymous: origReqCtx.AllowAnonymous,
|
||||
SkipDSCache: origReqCtx.SkipDSCache,
|
||||
SkipQueryCache: origReqCtx.SkipQueryCache,
|
||||
Logger: origReqCtx.Logger,
|
||||
Error: origReqCtx.Error,
|
||||
RequestNonce: origReqCtx.RequestNonce,
|
||||
PublicDashboardAccessToken: origReqCtx.PublicDashboardAccessToken,
|
||||
LookupTokenErr: origReqCtx.LookupTokenErr,
|
||||
}
|
||||
return context.WithValue(ctx, reqContextKey{}, reqCtx)
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ type ReqContext struct {
|
||||
Logger log.Logger
|
||||
Error error
|
||||
// RequestNonce is a cryptographic request identifier for use with Content Security Policy.
|
||||
RequestNonce string
|
||||
IsPublicDashboardView bool
|
||||
RequestNonce string
|
||||
PublicDashboardAccessToken string
|
||||
|
||||
PerfmonTimer prometheus.Summary
|
||||
LookupTokenErr error
|
||||
@@ -60,6 +60,10 @@ func (ctx *ReqContext) IsApiRequest() bool {
|
||||
return strings.HasPrefix(ctx.Req.URL.Path, "/api")
|
||||
}
|
||||
|
||||
func (ctx *ReqContext) IsPublicDashboardView() bool {
|
||||
return ctx.PublicDashboardAccessToken != ""
|
||||
}
|
||||
|
||||
func (ctx *ReqContext) JsonApiErr(status int, message string, err error) {
|
||||
resp := make(map[string]interface{})
|
||||
traceID := tracing.TraceIDFromContext(ctx.Req.Context(), false)
|
||||
|
||||
@@ -95,7 +95,7 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Prefere
|
||||
})
|
||||
}
|
||||
|
||||
if c.IsPublicDashboardView || hasAccess(ac.EvalAny(
|
||||
if c.IsPublicDashboardView() || hasAccess(ac.EvalAny(
|
||||
ac.EvalPermission(dashboards.ActionFoldersRead), ac.EvalPermission(dashboards.ActionFoldersCreate),
|
||||
ac.EvalPermission(dashboards.ActionDashboardsRead), ac.EvalPermission(dashboards.ActionDashboardsCreate)),
|
||||
) {
|
||||
|
||||
@@ -46,16 +46,16 @@ func TestAlertingProxy_createProxyContext(t *testing.T) {
|
||||
Context: &web.Context{
|
||||
Req: &http.Request{},
|
||||
},
|
||||
SignedInUser: &user.SignedInUser{},
|
||||
UserToken: &auth.UserToken{},
|
||||
IsSignedIn: rand.Int63()%2 == 1,
|
||||
IsRenderCall: rand.Int63()%2 == 1,
|
||||
AllowAnonymous: rand.Int63()%2 == 1,
|
||||
SkipDSCache: rand.Int63()%2 == 1,
|
||||
SkipQueryCache: rand.Int63()%2 == 1,
|
||||
Logger: log.New("test"),
|
||||
RequestNonce: util.GenerateShortUID(),
|
||||
IsPublicDashboardView: rand.Int63()%2 == 1,
|
||||
SignedInUser: &user.SignedInUser{},
|
||||
UserToken: &auth.UserToken{},
|
||||
IsSignedIn: rand.Int63()%2 == 1,
|
||||
IsRenderCall: rand.Int63()%2 == 1,
|
||||
AllowAnonymous: rand.Int63()%2 == 1,
|
||||
SkipDSCache: rand.Int63()%2 == 1,
|
||||
SkipQueryCache: rand.Int63()%2 == 1,
|
||||
Logger: log.New("test"),
|
||||
RequestNonce: util.GenerateShortUID(),
|
||||
PublicDashboardAccessToken: util.GenerateShortUID(),
|
||||
}
|
||||
|
||||
t.Run("should create a copy of request context", func(t *testing.T) {
|
||||
@@ -81,7 +81,7 @@ func TestAlertingProxy_createProxyContext(t *testing.T) {
|
||||
require.Equal(t, ctx.SkipQueryCache, newCtx.SkipQueryCache)
|
||||
require.Equal(t, ctx.Logger, newCtx.Logger)
|
||||
require.Equal(t, ctx.RequestNonce, newCtx.RequestNonce)
|
||||
require.Equal(t, ctx.IsPublicDashboardView, newCtx.IsPublicDashboardView)
|
||||
require.Equal(t, ctx.PublicDashboardAccessToken, newCtx.PublicDashboardAccessToken)
|
||||
}
|
||||
})
|
||||
t.Run("should overwrite response writer", func(t *testing.T) {
|
||||
|
||||
@@ -36,7 +36,7 @@ var ResourceCachingRequestHistogram = prometheus.NewHistogramVec(prometheus.Hist
|
||||
}, []string{"plugin_id", "cache"})
|
||||
|
||||
func getQueryType(req *contextmodel.ReqContext) string {
|
||||
if req.IsPublicDashboardView {
|
||||
if req.IsPublicDashboardView() {
|
||||
return QueryPubdash
|
||||
}
|
||||
return QueryDashboard
|
||||
|
||||
@@ -28,9 +28,9 @@ func SetPublicDashboardOrgIdOnContext(publicDashboardService publicdashboards.Se
|
||||
}
|
||||
}
|
||||
|
||||
// SetPublicDashboardFlag Adds public dashboard flag on context
|
||||
func SetPublicDashboardFlag(c *contextmodel.ReqContext) {
|
||||
c.IsPublicDashboardView = true
|
||||
// SetPublicDashboardAccessToken Adds public dashboard flag on context
|
||||
func SetPublicDashboardAccessToken(c *contextmodel.ReqContext) {
|
||||
c.PublicDashboardAccessToken = web.Params(c.Req)[":accessToken"]
|
||||
}
|
||||
|
||||
// RequiresExistingAccessToken Middleware to enforce that a public dashboards exists before continuing to handler. This
|
||||
|
||||
@@ -145,10 +145,10 @@ func TestSetPublicDashboardOrgIdOnContext(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetPublicDashboardFlag(t *testing.T) {
|
||||
t.Run("Adds context.IsPublicDashboardView=true to request", func(t *testing.T) {
|
||||
ctx := &contextmodel.ReqContext{}
|
||||
SetPublicDashboardFlag(ctx)
|
||||
assert.True(t, ctx.IsPublicDashboardView)
|
||||
t.Run("Adds context.PublicDashboardAccessToken to request", func(t *testing.T) {
|
||||
ctx := &contextmodel.ReqContext{Context: &web.Context{Req: web.SetURLParams(&http.Request{}, map[string]string{":accessToken": "asdfasdfasdfsadfasdfsfd"})}}
|
||||
SetPublicDashboardAccessToken(ctx)
|
||||
assert.NotEmpty(t, ctx.PublicDashboardAccessToken)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -30,21 +30,21 @@ func (api *Api) ViewPublicDashboard(c *contextmodel.ReqContext) response.Respons
|
||||
}
|
||||
|
||||
meta := dtos.DashboardMeta{
|
||||
Slug: dash.Slug,
|
||||
Type: dashboards.DashTypeDB,
|
||||
CanStar: false,
|
||||
CanSave: false,
|
||||
CanEdit: false,
|
||||
CanAdmin: false,
|
||||
CanDelete: false,
|
||||
Created: dash.Created,
|
||||
Updated: dash.Updated,
|
||||
Version: dash.Version,
|
||||
IsFolder: false,
|
||||
FolderId: dash.FolderID,
|
||||
PublicDashboardAccessToken: pubdash.AccessToken,
|
||||
PublicDashboardEnabled: pubdash.IsEnabled,
|
||||
Slug: dash.Slug,
|
||||
Type: dashboards.DashTypeDB,
|
||||
CanStar: false,
|
||||
CanSave: false,
|
||||
CanEdit: false,
|
||||
CanAdmin: false,
|
||||
CanDelete: false,
|
||||
Created: dash.Created,
|
||||
Updated: dash.Updated,
|
||||
Version: dash.Version,
|
||||
IsFolder: false,
|
||||
FolderId: dash.FolderID,
|
||||
PublicDashboardEnabled: pubdash.IsEnabled,
|
||||
}
|
||||
|
||||
dash.Data.Get("timepicker").Set("hidden", !pubdash.TimeSelectionEnabled)
|
||||
|
||||
dto := dtos.DashboardFullWithMeta{Meta: meta, Dashboard: dash.Data}
|
||||
|
||||
@@ -287,11 +287,10 @@ func TestQueryDataMultipleSources(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
queries := []*simplejson.Json{query1, query2}
|
||||
reqDTO := dtos.MetricRequest{
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
PublicDashboardAccessToken: "abc123",
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", "http://localhost:3000", nil)
|
||||
@@ -351,11 +350,10 @@ func TestQueryDataMultipleSources(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
queries := []*simplejson.Json{query1, query2, query3}
|
||||
reqDTO := dtos.MetricRequest{
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
PublicDashboardAccessToken: "abc123",
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
}
|
||||
|
||||
// without query parameter
|
||||
@@ -406,11 +404,10 @@ func TestQueryDataMultipleSources(t *testing.T) {
|
||||
queries := []*simplejson.Json{query1, query2}
|
||||
|
||||
reqDTO := dtos.MetricRequest{
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
PublicDashboardAccessToken: "abc123",
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
}
|
||||
|
||||
res, err := tc.queryService.QueryData(context.Background(), tc.signedInUser, true, reqDTO)
|
||||
@@ -436,11 +433,10 @@ func TestQueryDataMultipleSources(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
queries := []*simplejson.Json{query1}
|
||||
reqDTO := dtos.MetricRequest{
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
PublicDashboardAccessToken: "abc123",
|
||||
From: "2022-01-01",
|
||||
To: "2022-01-02",
|
||||
Queries: queries,
|
||||
Debug: false,
|
||||
}
|
||||
|
||||
_, err = tc.queryService.QueryData(context.Background(), tc.signedInUser, true, reqDTO)
|
||||
|
||||
Reference in New Issue
Block a user