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:
Torkel Ödegaard
2023-08-25 20:56:02 +02:00
committed by GitHub
parent 2245a3d0d1
commit 3ee26df41e
37 changed files with 147 additions and 204 deletions

View File

@@ -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,

View File

@@ -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"`

View File

@@ -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"`

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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)),
) {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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

View File

@@ -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)
})
}

View File

@@ -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}

View File

@@ -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)