mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PublicDashboards: add recipients to the public dashboards retrieval (#63149)
This commit is contained in:
parent
91dd5b0e0d
commit
8520a8614c
@ -385,7 +385,6 @@ var wireTestSet = wire.NewSet(
|
|||||||
ProvideTestEnv,
|
ProvideTestEnv,
|
||||||
sqlstore.ProvideServiceForTests,
|
sqlstore.ProvideServiceForTests,
|
||||||
ngmetrics.ProvideServiceForTest,
|
ngmetrics.ProvideServiceForTest,
|
||||||
|
|
||||||
notifications.MockNotificationService,
|
notifications.MockNotificationService,
|
||||||
wire.Bind(new(notifications.Service), new(*notifications.NotificationServiceMock)),
|
wire.Bind(new(notifications.Service), new(*notifications.NotificationServiceMock)),
|
||||||
wire.Bind(new(notifications.WebhookSender), new(*notifications.NotificationServiceMock)),
|
wire.Bind(new(notifications.WebhookSender), new(*notifications.NotificationServiceMock)),
|
||||||
|
@ -28,6 +28,8 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration"
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning"
|
"github.com/grafana/grafana/pkg/services/provisioning"
|
||||||
|
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||||
|
publicdashboardsService "github.com/grafana/grafana/pkg/services/publicdashboards/service"
|
||||||
"github.com/grafana/grafana/pkg/services/searchusers"
|
"github.com/grafana/grafana/pkg/services/searchusers"
|
||||||
"github.com/grafana/grafana/pkg/services/searchusers/filters"
|
"github.com/grafana/grafana/pkg/services/searchusers/filters"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrations"
|
"github.com/grafana/grafana/pkg/services/sqlstore/migrations"
|
||||||
@ -80,6 +82,8 @@ var wireExtsBasicSet = wire.NewSet(
|
|||||||
ossaccesscontrol.ProvideDatasourcePermissionsService,
|
ossaccesscontrol.ProvideDatasourcePermissionsService,
|
||||||
wire.Bind(new(accesscontrol.DatasourcePermissionsService), new(*ossaccesscontrol.DatasourcePermissionsService)),
|
wire.Bind(new(accesscontrol.DatasourcePermissionsService), new(*ossaccesscontrol.DatasourcePermissionsService)),
|
||||||
pluginsintegration.WireExtensionSet,
|
pluginsintegration.WireExtensionSet,
|
||||||
|
publicdashboardsService.ProvideServiceWrapper,
|
||||||
|
wire.Bind(new(publicdashboards.ServiceWrapper), new(*publicdashboardsService.PublicDashboardServiceWrapperImpl)),
|
||||||
)
|
)
|
||||||
|
|
||||||
var wireExtsSet = wire.NewSet(
|
var wireExtsSet = wire.NewSet(
|
||||||
|
@ -324,8 +324,9 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T)
|
|||||||
store := publicdashboardsStore.ProvideStore(db)
|
store := publicdashboardsStore.ProvideStore(db)
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
ac := acmock.New()
|
ac := acmock.New()
|
||||||
|
ws := &publicdashboards.FakePublicDashboardServiceWrapper{}
|
||||||
cfg.RBACEnabled = false
|
cfg.RBACEnabled = false
|
||||||
service := publicdashboardsService.ProvideService(cfg, store, qds, annotationsService, ac)
|
service := publicdashboardsService.ProvideService(cfg, store, qds, annotationsService, ac, ws)
|
||||||
pubdash, err := service.Create(context.Background(), &user.SignedInUser{}, savePubDashboardCmd)
|
pubdash, err := service.Create(context.Background(), &user.SignedInUser{}, savePubDashboardCmd)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ type PublicDashboard struct {
|
|||||||
AnnotationsEnabled bool `json:"annotationsEnabled" xorm:"annotations_enabled"`
|
AnnotationsEnabled bool `json:"annotationsEnabled" xorm:"annotations_enabled"`
|
||||||
TimeSelectionEnabled bool `json:"timeSelectionEnabled" xorm:"time_selection_enabled"`
|
TimeSelectionEnabled bool `json:"timeSelectionEnabled" xorm:"time_selection_enabled"`
|
||||||
Share ShareType `json:"share" xorm:"share"`
|
Share ShareType `json:"share" xorm:"share"`
|
||||||
|
Recipients []string `json:"recipients,omitempty" xorm:"-"`
|
||||||
CreatedBy int64 `json:"createdBy" xorm:"created_by"`
|
CreatedBy int64 `json:"createdBy" xorm:"created_by"`
|
||||||
UpdatedBy int64 `json:"updatedBy" xorm:"updated_by"`
|
UpdatedBy int64 `json:"updatedBy" xorm:"updated_by"`
|
||||||
CreatedAt time.Time `json:"createdAt" xorm:"created_at"`
|
CreatedAt time.Time `json:"createdAt" xorm:"created_at"`
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package publicdashboards
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
|
||||||
|
models "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FakePublicDashboardServiceWrapper is an autogenerated mock type for the ServiceWrapper type
|
||||||
|
type FakePublicDashboardServiceWrapper struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindByDashboardUid provides a mock function with given fields: ctx, orgId, dashboardUid
|
||||||
|
func (_m *FakePublicDashboardServiceWrapper) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
|
||||||
|
ret := _m.Called(ctx, orgId, dashboardUid)
|
||||||
|
|
||||||
|
var r0 *models.PublicDashboard
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *models.PublicDashboard); ok {
|
||||||
|
r0 = rf(ctx, orgId, dashboardUid)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*models.PublicDashboard)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
|
||||||
|
r1 = rf(ctx, orgId, dashboardUid)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockConstructorTestingTNewFakePublicDashboardServiceWrapper interface {
|
||||||
|
mock.TestingT
|
||||||
|
Cleanup(func())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFakePublicDashboardServiceWrapper creates a new instance of FakePublicDashboardServiceWrapper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||||
|
func NewFakePublicDashboardServiceWrapper(t mockConstructorTestingTNewFakePublicDashboardServiceWrapper) *FakePublicDashboardServiceWrapper {
|
||||||
|
mock := &FakePublicDashboardServiceWrapper{}
|
||||||
|
mock.Mock.Test(t)
|
||||||
|
|
||||||
|
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||||
|
|
||||||
|
return mock
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Code generated by mockery v2.16.0. DO NOT EDIT.
|
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||||
|
|
||||||
package publicdashboards
|
package publicdashboards
|
||||||
|
|
||||||
|
@ -36,6 +36,13 @@ type Service interface {
|
|||||||
ExistsEnabledByDashboardUid(ctx context.Context, dashboardUid string) (bool, error)
|
ExistsEnabledByDashboardUid(ctx context.Context, dashboardUid string) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceWrapper these methods have different behavior between OSS and Enterprise. The latter would call the OSS service first
|
||||||
|
//
|
||||||
|
//go:generate mockery --name ServiceWrapper --structname FakePublicDashboardServiceWrapper --inpackage --filename public_dashboard_service_wrapper_mock.go
|
||||||
|
type ServiceWrapper interface {
|
||||||
|
FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error)
|
||||||
|
}
|
||||||
|
|
||||||
//go:generate mockery --name Store --structname FakePublicDashboardStore --inpackage --filename public_dashboard_store_mock.go
|
//go:generate mockery --name Store --structname FakePublicDashboardStore --inpackage --filename public_dashboard_store_mock.go
|
||||||
type Store interface {
|
type Store interface {
|
||||||
Find(ctx context.Context, uid string) (*PublicDashboard, error)
|
Find(ctx context.Context, uid string) (*PublicDashboard, error)
|
||||||
|
@ -33,6 +33,7 @@ type PublicDashboardServiceImpl struct {
|
|||||||
QueryDataService *query.Service
|
QueryDataService *query.Service
|
||||||
AnnotationsRepo annotations.Repository
|
AnnotationsRepo annotations.Repository
|
||||||
ac accesscontrol.AccessControl
|
ac accesscontrol.AccessControl
|
||||||
|
serviceWrapper publicdashboards.ServiceWrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
var LogPrefix = "publicdashboards.service"
|
var LogPrefix = "publicdashboards.service"
|
||||||
@ -49,6 +50,7 @@ func ProvideService(
|
|||||||
qds *query.Service,
|
qds *query.Service,
|
||||||
anno annotations.Repository,
|
anno annotations.Repository,
|
||||||
ac accesscontrol.AccessControl,
|
ac accesscontrol.AccessControl,
|
||||||
|
serviceWrapper publicdashboards.ServiceWrapper,
|
||||||
) *PublicDashboardServiceImpl {
|
) *PublicDashboardServiceImpl {
|
||||||
return &PublicDashboardServiceImpl{
|
return &PublicDashboardServiceImpl{
|
||||||
log: log.New(LogPrefix),
|
log: log.New(LogPrefix),
|
||||||
@ -58,9 +60,15 @@ func ProvideService(
|
|||||||
QueryDataService: qds,
|
QueryDataService: qds,
|
||||||
AnnotationsRepo: anno,
|
AnnotationsRepo: anno,
|
||||||
ac: ac,
|
ac: ac,
|
||||||
|
serviceWrapper: serviceWrapper,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByDashboardUid this method would be replaced by another implementation for Enterprise version
|
||||||
|
func (pd *PublicDashboardServiceImpl) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error) {
|
||||||
|
return pd.serviceWrapper.FindByDashboardUid(ctx, orgId, dashboardUid)
|
||||||
|
}
|
||||||
|
|
||||||
func (pd *PublicDashboardServiceImpl) Find(ctx context.Context, uid string) (*PublicDashboard, error) {
|
func (pd *PublicDashboardServiceImpl) Find(ctx context.Context, uid string) (*PublicDashboard, error) {
|
||||||
pubdash, err := pd.store.Find(ctx, uid)
|
pubdash, err := pd.store.Find(ctx, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -120,20 +128,6 @@ func (pd *PublicDashboardServiceImpl) FindPublicDashboardAndDashboardByAccessTok
|
|||||||
return pubdash, dash, nil
|
return pubdash, dash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindByDashboardUid is a helper method to retrieve the public dashboard configuration for a given dashboard from the database
|
|
||||||
func (pd *PublicDashboardServiceImpl) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error) {
|
|
||||||
pubdash, err := pd.store.FindByDashboardUid(ctx, orgId, dashboardUid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrInternalServerError.Errorf("FindByDashboardUid: failed to find a public dashboard by orgId: %d and dashboardUid: %s: %w", orgId, dashboardUid, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if pubdash == nil {
|
|
||||||
return nil, ErrPublicDashboardNotFound.Errorf("FindByDashboardUid: Public dashboard not found by orgId: %d and dashboardUid: %s", orgId, dashboardUid)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pubdash, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates and validates the public dashboard and saves it to the database
|
// Creates and validates the public dashboard and saves it to the database
|
||||||
func (pd *PublicDashboardServiceImpl) Create(ctx context.Context, u *user.SignedInUser, dto *SavePublicDashboardDTO) (*PublicDashboard, error) {
|
func (pd *PublicDashboardServiceImpl) Create(ctx context.Context, u *user.SignedInUser, dto *SavePublicDashboardDTO) (*PublicDashboard, error) {
|
||||||
// ensure dashboard exists
|
// ensure dashboard exists
|
||||||
|
@ -131,10 +131,12 @@ func TestCreatePublicDashboard(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
publicdashboardStore := database.ProvideStore(sqlStore)
|
publicdashboardStore := database.ProvideStore(sqlStore)
|
||||||
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}, nil)
|
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}, nil)
|
||||||
|
serviceWrapper := ProvideServiceWrapper(publicdashboardStore)
|
||||||
|
|
||||||
service := &PublicDashboardServiceImpl{
|
service := &PublicDashboardServiceImpl{
|
||||||
log: log.New("test.logger"),
|
log: log.New("test.logger"),
|
||||||
store: publicdashboardStore,
|
store: publicdashboardStore,
|
||||||
|
serviceWrapper: serviceWrapper,
|
||||||
}
|
}
|
||||||
|
|
||||||
dto := &SavePublicDashboardDTO{
|
dto := &SavePublicDashboardDTO{
|
||||||
@ -183,10 +185,12 @@ func TestCreatePublicDashboard(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
publicdashboardStore := database.ProvideStore(sqlStore)
|
publicdashboardStore := database.ProvideStore(sqlStore)
|
||||||
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}, nil)
|
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}, nil)
|
||||||
|
serviceWrapper := ProvideServiceWrapper(publicdashboardStore)
|
||||||
|
|
||||||
service := &PublicDashboardServiceImpl{
|
service := &PublicDashboardServiceImpl{
|
||||||
log: log.New("test.logger"),
|
log: log.New("test.logger"),
|
||||||
store: publicdashboardStore,
|
store: publicdashboardStore,
|
||||||
|
serviceWrapper: serviceWrapper,
|
||||||
}
|
}
|
||||||
|
|
||||||
dto := &SavePublicDashboardDTO{
|
dto := &SavePublicDashboardDTO{
|
||||||
@ -331,10 +335,12 @@ func TestCreatePublicDashboard(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
publicdashboardStore := database.ProvideStore(sqlStore)
|
publicdashboardStore := database.ProvideStore(sqlStore)
|
||||||
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}, nil)
|
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}, nil)
|
||||||
|
serviceWrapper := ProvideServiceWrapper(publicdashboardStore)
|
||||||
|
|
||||||
service := &PublicDashboardServiceImpl{
|
service := &PublicDashboardServiceImpl{
|
||||||
log: log.New("test.logger"),
|
log: log.New("test.logger"),
|
||||||
store: publicdashboardStore,
|
store: publicdashboardStore,
|
||||||
|
serviceWrapper: serviceWrapper,
|
||||||
}
|
}
|
||||||
|
|
||||||
dto := &SavePublicDashboardDTO{
|
dto := &SavePublicDashboardDTO{
|
||||||
|
45
pkg/services/publicdashboards/service/service_wapper.go
Normal file
45
pkg/services/publicdashboards/service/service_wapper.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||||
|
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicDashboardServiceWrapperImpl Define the Service Implementation. We're generating mock implementation
|
||||||
|
// automatically
|
||||||
|
type PublicDashboardServiceWrapperImpl struct {
|
||||||
|
log log.Logger
|
||||||
|
store publicdashboards.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gives us compile time error if the service does not adhere to the contract of
|
||||||
|
// the interface
|
||||||
|
var _ publicdashboards.ServiceWrapper = (*PublicDashboardServiceWrapperImpl)(nil)
|
||||||
|
|
||||||
|
// ProvideServiceWrapper Factory for method used by wire to inject dependencies.
|
||||||
|
// builds the service, and api, and configures routes
|
||||||
|
func ProvideServiceWrapper(
|
||||||
|
store publicdashboards.Store,
|
||||||
|
) *PublicDashboardServiceWrapperImpl {
|
||||||
|
return &PublicDashboardServiceWrapperImpl{
|
||||||
|
log: log.New(LogPrefix),
|
||||||
|
store: store,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindByDashboardUid is a helper method to retrieve the public dashboard configuration for a given dashboard from the database
|
||||||
|
func (pd *PublicDashboardServiceWrapperImpl) FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error) {
|
||||||
|
pubdash, err := pd.store.FindByDashboardUid(ctx, orgId, dashboardUid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrInternalServerError.Errorf("FindByDashboardUid: failed to find a public dashboard by orgId: %d and dashboardUid: %s: %w", orgId, dashboardUid, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pubdash == nil {
|
||||||
|
return nil, ErrPublicDashboardNotFound.Errorf("FindByDashboardUid: Public dashboard not found by orgId: %d and dashboardUid: %s", orgId, dashboardUid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pubdash, nil
|
||||||
|
}
|
@ -51,6 +51,7 @@ export const supportedDatasources = new Set<string>([
|
|||||||
'marcusolsson-ynab-datasource',
|
'marcusolsson-ynab-datasource',
|
||||||
'mssql',
|
'mssql',
|
||||||
'mysql',
|
'mysql',
|
||||||
|
'nagasudhirpulla-api-datasource',
|
||||||
'opentsdb',
|
'opentsdb',
|
||||||
'postgres',
|
'postgres',
|
||||||
'prometheus',
|
'prometheus',
|
||||||
|
Loading…
Reference in New Issue
Block a user