PublicDashboards: Middleware creation (#77941)

This commit is contained in:
Juan Cabanas 2023-11-21 17:56:36 -03:00 committed by GitHub
parent a3576fc8cf
commit 9c5daed336
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 81 additions and 8 deletions

View File

@ -166,6 +166,7 @@ func (hs *HTTPServer) registerRoutes() {
// anonymous view public dashboard
r.Get("/public-dashboards/:accessToken",
hs.PublicDashboardsApi.Middleware.HandleView,
publicdashboardsapi.SetPublicDashboardAccessToken,
publicdashboardsapi.SetPublicDashboardOrgIdOnContext(hs.PublicDashboardsApi.PublicDashboardService),
publicdashboardsapi.CountPublicDashboardRequest(),

View File

@ -273,7 +273,8 @@ func TestHTTPServer_DeleteDashboardByUID_AccessControl(t *testing.T) {
pubDashService := publicdashboards.NewFakePublicDashboardService(t)
pubDashService.On("DeleteByDashboard", mock.Anything, mock.Anything).Return(nil).Maybe()
hs.PublicDashboardsApi = api.ProvideApi(pubDashService, nil, hs.AccessControl, featuremgmt.WithFeatures())
middleware := publicdashboards.NewFakePublicDashboardMiddleware(t)
hs.PublicDashboardsApi = api.ProvideApi(pubDashService, nil, hs.AccessControl, featuremgmt.WithFeatures(), middleware)
guardian.InitAccessControlGuardian(hs.Cfg, hs.AccessControl, hs.DashboardService)
})

View File

@ -35,6 +35,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration"
"github.com/grafana/grafana/pkg/services/provisioning"
"github.com/grafana/grafana/pkg/services/publicdashboards"
publicdashboardsApi "github.com/grafana/grafana/pkg/services/publicdashboards/api"
publicdashboardsService "github.com/grafana/grafana/pkg/services/publicdashboards/service"
"github.com/grafana/grafana/pkg/services/searchusers"
"github.com/grafana/grafana/pkg/services/searchusers/filters"
@ -87,6 +88,8 @@ var wireExtsBasicSet = wire.NewSet(
ossaccesscontrol.ProvideDatasourcePermissionsService,
wire.Bind(new(accesscontrol.DatasourcePermissionsService), new(*ossaccesscontrol.DatasourcePermissionsService)),
pluginsintegration.WireExtensionSet,
publicdashboardsApi.ProvideMiddleware,
wire.Bind(new(publicdashboards.Middleware), new(*publicdashboardsApi.Middleware)),
publicdashboardsService.ProvideServiceWrapper,
wire.Bind(new(publicdashboards.ServiceWrapper), new(*publicdashboardsService.PublicDashboardServiceWrapperImpl)),
caching.ProvideCachingService,

View File

@ -26,6 +26,7 @@ type Api struct {
AccessControl accesscontrol.AccessControl
Features *featuremgmt.FeatureManager
Log log.Logger
Middleware publicdashboards.Middleware
}
func ProvideApi(
@ -33,6 +34,7 @@ func ProvideApi(
rr routing.RouteRegister,
ac accesscontrol.AccessControl,
features *featuremgmt.FeatureManager,
md publicdashboards.Middleware,
) *Api {
api := &Api{
PublicDashboardService: pd,
@ -40,6 +42,7 @@ func ProvideApi(
AccessControl: ac,
Features: features,
Log: log.New("publicdashboards.api"),
Middleware: md,
}
// attach api if PublicDashboards feature flag is enabled
@ -56,11 +59,11 @@ func (api *Api) RegisterAPIEndpoints() {
// Anonymous access to public dashboard route is configured in pkg/api/api.go
// because it is deeply dependent on the HTTPServer.Index() method and would result in a
// circular dependency
api.RouteRegister.Get("/api/public/dashboards/:accessToken", routing.Wrap(api.ViewPublicDashboard))
api.RouteRegister.Get("/api/public/dashboards/:accessToken/annotations", routing.Wrap(api.GetPublicAnnotations))
api.RouteRegister.Post("/api/public/dashboards/:accessToken/panels/:panelId/query", routing.Wrap(api.QueryPublicDashboard))
api.RouteRegister.Group("/api/public/dashboards/:accessToken", func(apiRoute routing.RouteRegister) {
apiRoute.Get("/", routing.Wrap(api.ViewPublicDashboard))
apiRoute.Get("/annotations", routing.Wrap(api.GetPublicAnnotations))
apiRoute.Post("/panels/:panelId/query", routing.Wrap(api.QueryPublicDashboard))
}, api.Middleware.HandleApi)
// Auth endpoints
auth := accesscontrol.Middleware(api.AccessControl)
@ -68,7 +71,6 @@ func (api *Api) RegisterAPIEndpoints() {
// List public dashboards for org
api.RouteRegister.Get("/api/dashboards/public-dashboards", middleware.ReqSignedIn, routing.Wrap(api.ListPublicDashboards))
// Get public dashboard
api.RouteRegister.Get("/api/dashboards/uid/:dashboardUid/public-dashboards",
auth(accesscontrol.EvalPermission(dashboards.ActionDashboardsRead, uidScope)),

View File

@ -58,7 +58,7 @@ func setupTestServer(
// build api, this will mount the routes at the same time if
// featuremgmt.FlagPublicDashboard is enabled
ProvideApi(service, rr, ac, features)
ProvideApi(service, rr, ac, features, &Middleware{})
// connect routes to mux
rr.Register(m.Router)

View File

@ -67,3 +67,19 @@ func CountPublicDashboardRequest() func(c *contextmodel.ReqContext) {
metrics.MPublicDashboardRequestCount.Inc()
}
}
// Empty middleware created in order to bind the enterprise one
type Middleware struct {
}
var _ publicdashboards.Middleware = (*Middleware)(nil)
func ProvideMiddleware() *Middleware {
return &Middleware{}
}
func (m *Middleware) HandleApi(c *contextmodel.ReqContext) {
}
func (m *Middleware) HandleView(c *contextmodel.ReqContext) {
}
func (m *Middleware) HandleAccessView(c *contextmodel.ReqContext) {
}

View File

@ -0,0 +1,42 @@
// Code generated by mockery v2.36.1. DO NOT EDIT.
package publicdashboards
import (
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
mock "github.com/stretchr/testify/mock"
)
// FakePublicDashboardMiddleware is an autogenerated mock type for the Middleware type
type FakePublicDashboardMiddleware struct {
mock.Mock
}
// HandleApi provides a mock function with given fields: c
func (_m *FakePublicDashboardMiddleware) HandleApi(c *contextmodel.ReqContext) {
_m.Called(c)
}
// HandleGet provides a mock function with given fields: c
func (_m *FakePublicDashboardMiddleware) HandleView(c *contextmodel.ReqContext) {
_m.Called(c)
}
// HandleRequestOrConfirmAccess provides a mock function with given fields: c
func (_m *FakePublicDashboardMiddleware) HandleAccessView(c *contextmodel.ReqContext) {
_m.Called(c)
}
// NewFakePublicDashboardMiddleware creates a new instance of FakePublicDashboardMiddleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewFakePublicDashboardMiddleware(t interface {
mock.TestingT
Cleanup(func())
}) *FakePublicDashboardMiddleware {
mock := &FakePublicDashboardMiddleware{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -5,6 +5,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/api/dtos"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/dashboards"
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
"github.com/grafana/grafana/pkg/services/user"
@ -64,3 +65,10 @@ type Store interface {
ExistsEnabledByDashboardUid(ctx context.Context, dashboardUid string) (bool, error)
GetMetrics(ctx context.Context) (*Metrics, error)
}
//go:generate mockery --name Middleware --structname FakePublicDashboardMiddleware --inpackage --filename public_dashboard_middleware_mock.go
type Middleware interface {
HandleApi(c *contextmodel.ReqContext)
HandleView(c *contextmodel.ReqContext)
HandleAccessView(c *contextmodel.ReqContext)
}