mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866)
* PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
10
pkg/api/acl.go
Normal file
10
pkg/api/acl.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package api
|
||||
|
||||
import "github.com/grafana/grafana/pkg/models"
|
||||
|
||||
// updateDashboardACL updates a dashboard's ACL items.
|
||||
//
|
||||
// Stubbable by tests.
|
||||
var updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
return hs.SQLStore.UpdateDashboardACL(dashID, items)
|
||||
}
|
||||
@@ -266,7 +266,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
apiRoute.Get("/datasources/id/:name", routing.Wrap(GetDataSourceIdByName), reqSignedIn)
|
||||
|
||||
apiRoute.Get("/plugins", routing.Wrap(hs.GetPluginList))
|
||||
apiRoute.Get("/plugins/:pluginId/settings", routing.Wrap(GetPluginSettingByID))
|
||||
apiRoute.Get("/plugins/:pluginId/settings", routing.Wrap(hs.GetPluginSettingByID))
|
||||
apiRoute.Get("/plugins/:pluginId/markdown/:name", routing.Wrap(hs.GetPluginMarkdown))
|
||||
apiRoute.Get("/plugins/:pluginId/health", routing.Wrap(hs.CheckHealth))
|
||||
apiRoute.Any("/plugins/:pluginId/resources", hs.CallResource)
|
||||
@@ -288,13 +288,13 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
|
||||
// Folders
|
||||
apiRoute.Group("/folders", func(folderRoute routing.RouteRegister) {
|
||||
folderRoute.Get("/", routing.Wrap(GetFolders))
|
||||
folderRoute.Get("/id/:id", routing.Wrap(GetFolderByID))
|
||||
folderRoute.Get("/", routing.Wrap(hs.GetFolders))
|
||||
folderRoute.Get("/id/:id", routing.Wrap(hs.GetFolderByID))
|
||||
folderRoute.Post("/", bind(models.CreateFolderCommand{}), routing.Wrap(hs.CreateFolder))
|
||||
|
||||
folderRoute.Group("/:uid", func(folderUidRoute routing.RouteRegister) {
|
||||
folderUidRoute.Get("/", routing.Wrap(GetFolderByUID))
|
||||
folderUidRoute.Put("/", bind(models.UpdateFolderCommand{}), routing.Wrap(UpdateFolder))
|
||||
folderUidRoute.Get("/", routing.Wrap(hs.GetFolderByUID))
|
||||
folderUidRoute.Put("/", bind(models.UpdateFolderCommand{}), routing.Wrap(hs.UpdateFolder))
|
||||
folderUidRoute.Delete("/", routing.Wrap(hs.DeleteFolder))
|
||||
|
||||
folderUidRoute.Group("/permissions", func(folderPermissionRoute routing.RouteRegister) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
|
||||
@@ -122,7 +121,7 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
meta.FolderUrl = query.Result.GetUrl()
|
||||
}
|
||||
|
||||
svc := dashboards.NewProvisioningService()
|
||||
svc := dashboards.NewProvisioningService(hs.SQLStore)
|
||||
provisioningData, err := svc.GetProvisionedDashboardDataByDashboardID(dash.Id)
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking if dashboard is provisioned", err)
|
||||
@@ -227,7 +226,7 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
}
|
||||
}
|
||||
|
||||
svc := dashboards.NewService()
|
||||
svc := dashboards.NewService(hs.SQLStore)
|
||||
err := svc.DeleteDashboard(dash.Id, c.OrgId)
|
||||
if err != nil {
|
||||
var dashboardErr models.DashboardErr
|
||||
@@ -264,7 +263,7 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
}
|
||||
}
|
||||
|
||||
svc := dashboards.NewProvisioningService()
|
||||
svc := dashboards.NewProvisioningService(hs.SQLStore)
|
||||
provisioningData, err := svc.GetProvisionedDashboardDataByDashboardID(dash.Id)
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking if dashboard is provisioned", err)
|
||||
@@ -291,15 +290,15 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
Overwrite: cmd.Overwrite,
|
||||
}
|
||||
|
||||
dashSvc := dashboards.NewService()
|
||||
dashSvc := dashboards.NewService(hs.SQLStore)
|
||||
dashboard, err := dashSvc.SaveDashboard(dashItem, allowUiUpdate)
|
||||
if err != nil {
|
||||
return dashboardSaveErrorToApiResponse(err)
|
||||
return hs.dashboardSaveErrorToApiResponse(err)
|
||||
}
|
||||
|
||||
if hs.Cfg.EditorsCanAdmin && newDashboard {
|
||||
inFolder := cmd.FolderId > 0
|
||||
err := dashboards.MakeUserAdmin(hs.Bus, cmd.OrgId, cmd.UserId, dashboard.Id, !inFolder)
|
||||
err := dashSvc.MakeUserAdmin(cmd.OrgId, cmd.UserId, dashboard.Id, !inFolder)
|
||||
if err != nil {
|
||||
hs.log.Error("Could not make user admin", "dashboard", dashboard.Title, "user", c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
@@ -335,7 +334,7 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
})
|
||||
}
|
||||
|
||||
func dashboardSaveErrorToApiResponse(err error) response.Response {
|
||||
func (hs *HTTPServer) dashboardSaveErrorToApiResponse(err error) response.Response {
|
||||
var dashboardErr models.DashboardErr
|
||||
if ok := errors.As(err, &dashboardErr); ok {
|
||||
if body := dashboardErr.Body(); body != nil {
|
||||
@@ -360,7 +359,7 @@ func dashboardSaveErrorToApiResponse(err error) response.Response {
|
||||
if ok := errors.As(err, &pluginErr); ok {
|
||||
message := fmt.Sprintf("The dashboard belongs to plugin %s.", pluginErr.PluginId)
|
||||
// look up plugin name
|
||||
if pluginDef, exist := manager.Plugins[pluginErr.PluginId]; exist {
|
||||
if pluginDef := hs.PluginManager.GetPlugin(pluginErr.PluginId); pluginDef != nil {
|
||||
message = fmt.Sprintf("The dashboard belongs to plugin %s.", pluginDef.Name)
|
||||
}
|
||||
return response.JSON(412, util.DynMap{"status": "plugin-dashboard", "message": message})
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
)
|
||||
@@ -68,11 +67,9 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext, apiCmd dt
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
|
||||
cmd := models.UpdateDashboardAclCommand{}
|
||||
cmd.DashboardID = dashID
|
||||
|
||||
var items []*models.DashboardAcl
|
||||
for _, item := range apiCmd.Items {
|
||||
cmd.Items = append(cmd.Items, &models.DashboardAcl{
|
||||
items = append(items, &models.DashboardAcl{
|
||||
OrgID: c.OrgId,
|
||||
DashboardID: dashID,
|
||||
UserID: item.UserID,
|
||||
@@ -88,9 +85,9 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext, apiCmd dt
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while retrieving hidden permissions", err)
|
||||
}
|
||||
cmd.Items = append(cmd.Items, hiddenACL...)
|
||||
items = append(items, hiddenACL...)
|
||||
|
||||
if okToUpdate, err := g.CheckPermissionBeforeUpdate(models.PERMISSION_ADMIN, cmd.Items); err != nil || !okToUpdate {
|
||||
if okToUpdate, err := g.CheckPermissionBeforeUpdate(models.PERMISSION_ADMIN, items); err != nil || !okToUpdate {
|
||||
if err != nil {
|
||||
if errors.Is(err, guardian.ErrGuardianPermissionExists) || errors.Is(err, guardian.ErrGuardianOverride) {
|
||||
return response.Error(400, err.Error(), err)
|
||||
@@ -102,7 +99,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext, apiCmd dt
|
||||
return response.Error(403, "Cannot remove own admin permission for a folder", nil)
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil {
|
||||
if err := updateDashboardACL(hs, dashID, items); err != nil {
|
||||
if errors.Is(err, models.ErrDashboardAclInfoMissing) ||
|
||||
errors.Is(err, models.ErrDashboardPermissionDashboardEmpty) {
|
||||
return response.Error(409, err.Error(), err)
|
||||
|
||||
@@ -48,7 +48,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(sc)
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -91,7 +91,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(sc)
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -151,7 +151,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(sc)
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -189,7 +189,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(sc)
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -217,7 +217,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/dashboards/id/:id/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateDashboardPermissions(sc)
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
respJSON, err := jsonMap(sc.resp.Body.Bytes())
|
||||
require.NoError(t, err)
|
||||
@@ -260,7 +260,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
callUpdateDashboardPermissions(sc)
|
||||
callUpdateDashboardPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -335,13 +335,20 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
setUp()
|
||||
bus.AddHandler("test", func(cmd *models.UpdateDashboardAclCommand) error {
|
||||
assert.Len(t, cmd.Items, 4)
|
||||
return nil
|
||||
// TODO: Replace this fake with a fake SQLStore instead (once we can use an interface in its stead)
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
var gotItems []*models.DashboardAcl
|
||||
updateDashboardACL = func(hs *HTTPServer, folderID int64, items []*models.DashboardAcl) error {
|
||||
gotItems = items
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Len(t, gotItems, 4)
|
||||
},
|
||||
}, hs)
|
||||
})
|
||||
@@ -353,10 +360,16 @@ func callGetDashboardPermissions(sc *scenarioContext, hs *HTTPServer) {
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func callUpdateDashboardPermissions(sc *scenarioContext) {
|
||||
bus.AddHandler("test", func(cmd *models.UpdateDashboardAclCommand) error {
|
||||
return nil
|
||||
func callUpdateDashboardPermissions(t *testing.T, sc *scenarioContext) {
|
||||
t.Helper()
|
||||
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
dboards "github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
@@ -28,7 +29,10 @@ func TestGetHomeDashboard(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.StaticRootPath = "../../public/"
|
||||
|
||||
hs := &HTTPServer{Cfg: cfg, Bus: bus.New()}
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg, Bus: bus.New(),
|
||||
PluginManager: &fakePluginManager{},
|
||||
}
|
||||
hs.Bus.AddHandler(func(query *models.GetPreferencesWithDefaultsQuery) error {
|
||||
query.Result = &models.Preferences{
|
||||
HomeDashboardId: 0,
|
||||
@@ -102,11 +106,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetProvisionedDashboardDataByIdQuery) error {
|
||||
query.Result = nil
|
||||
return nil
|
||||
})
|
||||
|
||||
viewerRole := models.ROLE_VIEWER
|
||||
editorRole := models.ROLE_EDITOR
|
||||
|
||||
@@ -165,7 +164,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
@@ -175,7 +174,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardByUID(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
callDeleteDashboardByUID(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
@@ -230,7 +229,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -239,7 +238,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardByUID(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
callDeleteDashboardByUID(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -281,11 +280,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
setting.ViewersCanEdit = false
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetProvisionedDashboardDataByIdQuery) error {
|
||||
query.Result = nil
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetDashboardsBySlugQuery) error {
|
||||
dashboards := []*models.Dashboard{fakeDash}
|
||||
query.Result = dashboards
|
||||
@@ -354,7 +348,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, hs)
|
||||
callDeleteDashboardBySlug(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -363,7 +357,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardByUID(sc, hs)
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -414,7 +408,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, hs)
|
||||
callDeleteDashboardBySlug(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -423,7 +417,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUp()
|
||||
|
||||
CallDeleteDashboardByUID(sc, hs)
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -492,7 +486,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, hs)
|
||||
callDeleteDashboardBySlug(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -500,7 +494,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardByUID(sc, hs)
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -570,7 +564,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, hs)
|
||||
callDeleteDashboardBySlug(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -578,7 +572,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardByUID(sc, hs)
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -624,7 +618,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, hs)
|
||||
callDeleteDashboardBySlug(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -632,7 +626,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardByUID(sc, hs)
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -690,7 +684,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/child-dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, hs)
|
||||
callDeleteDashboardBySlug(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "child-dash", state.dashQueries[0].Slug)
|
||||
})
|
||||
@@ -698,7 +692,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/uid/abcdefghi", "/api/dashboards/uid/:uid", role, func(sc *scenarioContext) {
|
||||
state := setUpInner()
|
||||
|
||||
CallDeleteDashboardByUID(sc, hs)
|
||||
callDeleteDashboardByUID(sc, hs)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
assert.Equal(t, "abcdefghi", state.dashQueries[0].Uid)
|
||||
})
|
||||
@@ -730,11 +724,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
dashTwo.FolderId = 3
|
||||
dashTwo.HasAcl = false
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetProvisionedDashboardDataByIdQuery) error {
|
||||
query.Result = nil
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetDashboardsBySlugQuery) error {
|
||||
dashboards := []*models.Dashboard{dashOne, dashTwo}
|
||||
query.Result = dashboards
|
||||
@@ -743,14 +732,15 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
role := models.ROLE_EDITOR
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/dash", "/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
CallDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/dash",
|
||||
"/api/dashboards/db/:slug", role, func(sc *scenarioContext) {
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
|
||||
assert.Equal(t, 412, sc.resp.Code)
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, "multiple-slugs-exists", result.Get("status").MustString())
|
||||
assert.Equal(t, models.ErrDashboardsWithSameSlugExists.Error(), result.Get("message").MustString())
|
||||
})
|
||||
assert.Equal(t, 412, sc.resp.Code)
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, "multiple-slugs-exists", result.Get("status").MustString())
|
||||
assert.Equal(t, models.ErrDashboardsWithSameSlugExists.Error(), result.Get("message").MustString())
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Post dashboard response tests", func(t *testing.T) {
|
||||
@@ -856,11 +846,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetProvisionedDashboardDataByIdQuery) error {
|
||||
query.Result = nil
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetDashboardVersionQuery) error {
|
||||
query.Result = &models.DashboardVersion{
|
||||
Data: simplejson.NewFromAny(map[string]interface{}{
|
||||
@@ -1017,10 +1002,13 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetProvisionedDashboardDataByIdQuery) error {
|
||||
query.Result = &models.DashboardProvisioning{ExternalId: "/tmp/grafana/dashboards/test/dashboard1.json"}
|
||||
return nil
|
||||
origGetProvisionedData := dashboards.GetProvisionedData
|
||||
t.Cleanup(func() {
|
||||
dashboards.GetProvisionedData = origGetProvisionedData
|
||||
})
|
||||
dashboards.GetProvisionedData = func(dboards.Store, int64) (*models.DashboardProvisioning, error) {
|
||||
return &models.DashboardProvisioning{ExternalId: "/tmp/grafana/dashboards/test/dashboard1.json"}, nil
|
||||
}
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = []*models.DashboardAclInfoDTO{
|
||||
@@ -1030,20 +1018,21 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/dash", "/api/dashboards/db/:slug", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/dash",
|
||||
"/api/dashboards/db/:slug", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
CallDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
callDeleteDashboardBySlug(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, models.ErrDashboardCannotDeleteProvisionedDashboard.Error(), result.Get("error").MustString())
|
||||
})
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
result := sc.ToJSON()
|
||||
assert.Equal(t, models.ErrDashboardCannotDeleteProvisionedDashboard.Error(), result.Get("error").MustString())
|
||||
})
|
||||
|
||||
loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/dashboards/db/abcdefghi", "/api/dashboards/db/:uid", models.ROLE_EDITOR, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
CallDeleteDashboardByUID(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
callDeleteDashboardByUID(sc, &HTTPServer{Cfg: setting.NewCfg()})
|
||||
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
result := sc.ToJSON()
|
||||
@@ -1141,7 +1130,7 @@ func callGetDashboardVersions(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func CallDeleteDashboardBySlug(sc *scenarioContext, hs *HTTPServer) {
|
||||
func callDeleteDashboardBySlug(sc *scenarioContext, hs *HTTPServer) {
|
||||
bus.AddHandler("test", func(cmd *models.DeleteDashboardCommand) error {
|
||||
return nil
|
||||
})
|
||||
@@ -1150,7 +1139,7 @@ func CallDeleteDashboardBySlug(sc *scenarioContext, hs *HTTPServer) {
|
||||
sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func CallDeleteDashboardByUID(sc *scenarioContext, hs *HTTPServer) {
|
||||
func callDeleteDashboardByUID(sc *scenarioContext, hs *HTTPServer) {
|
||||
bus.AddHandler("test", func(cmd *models.DeleteDashboardCommand) error {
|
||||
return nil
|
||||
})
|
||||
@@ -1187,6 +1176,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
||||
QuotaService: "a.QuotaService{
|
||||
Cfg: cfg,
|
||||
},
|
||||
PluginManager: &fakePluginManager{},
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
@@ -1204,7 +1194,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
||||
dashboards.NewProvisioningService = origProvisioningService
|
||||
})
|
||||
dashboards.MockDashboardService(mock)
|
||||
dashboards.NewProvisioningService = func() dashboards.DashboardProvisioningService {
|
||||
dashboards.NewProvisioningService = func(dboards.Store) dashboards.DashboardProvisioningService {
|
||||
return mockDashboardProvisioningService{}
|
||||
}
|
||||
|
||||
@@ -1268,7 +1258,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
|
||||
dashboards.NewService = origNewDashboardService
|
||||
dashboards.NewProvisioningService = origProvisioningService
|
||||
})
|
||||
dashboards.NewProvisioningService = func() dashboards.DashboardProvisioningService {
|
||||
dashboards.NewProvisioningService = func(dboards.Store) dashboards.DashboardProvisioningService {
|
||||
return mockDashboardProvisioningService{}
|
||||
}
|
||||
dashboards.MockDashboardService(mock)
|
||||
@@ -1290,6 +1280,7 @@ type mockDashboardProvisioningService struct {
|
||||
dashboards.DashboardProvisioningService
|
||||
}
|
||||
|
||||
func (m mockDashboardProvisioningService) GetProvisionedDashboardDataByDashboardID(dashboardId int64) (*models.DashboardProvisioning, error) {
|
||||
return &models.DashboardProvisioning{}, nil
|
||||
func (s mockDashboardProvisioningService) GetProvisionedDashboardDataByDashboardID(dashboardID int64) (
|
||||
*models.DashboardProvisioning, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/pluginproxy"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
)
|
||||
|
||||
// ProxyDataSourceRequest proxies datasource requests
|
||||
@@ -35,8 +34,8 @@ func (hs *HTTPServer) ProxyDataSourceRequest(c *models.ReqContext) {
|
||||
}
|
||||
|
||||
// find plugin
|
||||
plugin, ok := manager.DataSources[ds.Type]
|
||||
if !ok {
|
||||
plugin := hs.PluginManager.GetDataSource(ds.Type)
|
||||
if plugin == nil {
|
||||
c.JsonApiErr(http.StatusInternalServerError, "Unable to find datasource plugin", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins/adapters"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
@@ -47,7 +46,7 @@ func (hs *HTTPServer) GetDataSources(c *models.ReqContext) response.Response {
|
||||
ReadOnly: ds.ReadOnly,
|
||||
}
|
||||
|
||||
if plugin, exists := manager.DataSources[ds.Type]; exists {
|
||||
if plugin := hs.PluginManager.GetDataSource(ds.Type); plugin != nil {
|
||||
dsItem.TypeLogoUrl = plugin.Info.Logos.Small
|
||||
dsItem.TypeName = plugin.Name
|
||||
} else {
|
||||
@@ -363,8 +362,8 @@ func (hs *HTTPServer) CallDatasourceResource(c *models.ReqContext) {
|
||||
}
|
||||
|
||||
// find plugin
|
||||
plugin, ok := manager.DataSources[ds.Type]
|
||||
if !ok {
|
||||
plugin := hs.PluginManager.GetDataSource(ds.Type)
|
||||
if plugin == nil {
|
||||
c.JsonApiErr(500, "Unable to find datasource plugin", err)
|
||||
return
|
||||
}
|
||||
@@ -428,8 +427,8 @@ func (hs *HTTPServer) CheckDatasourceHealth(c *models.ReqContext) response.Respo
|
||||
return response.Error(500, "Unable to load datasource metadata", err)
|
||||
}
|
||||
|
||||
plugin, ok := hs.PluginManager.GetDatasource(ds.Type)
|
||||
if !ok {
|
||||
plugin := hs.PluginManager.GetDataSource(ds.Type)
|
||||
if plugin == nil {
|
||||
return response.Error(500, "Unable to find datasource plugin", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,11 @@ func TestDataSourcesProxy_userLoggedIn(t *testing.T) {
|
||||
})
|
||||
|
||||
// handler func being tested
|
||||
hs := &HTTPServer{Bus: bus.GetBus(), Cfg: setting.NewCfg()}
|
||||
hs := &HTTPServer{
|
||||
Bus: bus.GetBus(),
|
||||
Cfg: setting.NewCfg(),
|
||||
PluginManager: &fakePluginManager{},
|
||||
}
|
||||
sc.handlerFunc = hs.GetDataSources
|
||||
sc.fakeReq("GET", "/api/datasources").exec()
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package dtos
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
)
|
||||
|
||||
type PluginSetting struct {
|
||||
@@ -64,6 +63,6 @@ type ImportDashboardCommand struct {
|
||||
Path string `json:"path"`
|
||||
Overwrite bool `json:"overwrite"`
|
||||
Dashboard *simplejson.Json `json:"dashboard"`
|
||||
Inputs []manager.ImportDashboardInput `json:"inputs"`
|
||||
Inputs []plugins.ImportDashboardInput `json:"inputs"`
|
||||
FolderId int64 `json:"folderId"`
|
||||
}
|
||||
|
||||
19
pkg/api/fakes.go
Normal file
19
pkg/api/fakes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package api
|
||||
|
||||
import "github.com/grafana/grafana/pkg/plugins"
|
||||
|
||||
type fakePluginManager struct {
|
||||
plugins.Manager
|
||||
}
|
||||
|
||||
func (pm *fakePluginManager) GetPlugin(id string) *plugins.PluginBase {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pm *fakePluginManager) GetDataSource(id string) *plugins.DataSourcePlugin {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pm *fakePluginManager) Renderer() *plugins.RendererPlugin {
|
||||
return nil
|
||||
}
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func GetFolders(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
func (hs *HTTPServer) GetFolders(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folders, err := s.GetFolders(c.QueryInt64("limit"))
|
||||
|
||||
if err != nil {
|
||||
@@ -35,10 +35,9 @@ func GetFolders(c *models.ReqContext) response.Response {
|
||||
return response.JSON(200, result)
|
||||
}
|
||||
|
||||
func GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Params(":uid"))
|
||||
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
}
|
||||
@@ -47,8 +46,8 @@ func GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
return response.JSON(200, toFolderDto(g, folder))
|
||||
}
|
||||
|
||||
func GetFolderByID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByID(c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
@@ -59,24 +58,25 @@ func GetFolderByID(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) CreateFolder(c *models.ReqContext, cmd models.CreateFolderCommand) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
err := s.CreateFolder(&cmd)
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.CreateFolder(cmd.Title, cmd.Uid)
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
}
|
||||
|
||||
if hs.Cfg.EditorsCanAdmin {
|
||||
if err := dashboards.MakeUserAdmin(hs.Bus, c.OrgId, c.SignedInUser.UserId, cmd.Result.Id, true); err != nil {
|
||||
hs.log.Error("Could not make user admin", "folder", cmd.Result.Title, "user", c.SignedInUser.UserId, "error", err)
|
||||
if err := s.MakeUserAdmin(c.OrgId, c.SignedInUser.UserId, folder.Id, true); err != nil {
|
||||
hs.log.Error("Could not make user admin", "folder", folder.Title, "user",
|
||||
c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
g := guardian.New(cmd.Result.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(g, cmd.Result))
|
||||
g := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(g, folder))
|
||||
}
|
||||
|
||||
func UpdateFolder(c *models.ReqContext, cmd models.UpdateFolderCommand) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext, cmd models.UpdateFolderCommand) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
err := s.UpdateFolder(c.Params(":uid"), &cmd)
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
@@ -87,7 +87,7 @@ func UpdateFolder(c *models.ReqContext, cmd models.UpdateFolderCommand) response
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // temporarily adding this function to HTTPServer, will be removed from HTTPServer when librarypanels featuretoggle is removed
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
if hs.Cfg.IsPanelLibraryEnabled() {
|
||||
err := hs.LibraryPanelService.DeleteLibraryPanelsInFolder(c, c.Params(":uid"))
|
||||
if err != nil {
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
@@ -14,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) GetFolderPermissionList(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Params(":uid"))
|
||||
|
||||
if err != nil {
|
||||
@@ -62,9 +61,8 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
return response.Error(400, err.Error(), err)
|
||||
}
|
||||
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser)
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Params(":uid"))
|
||||
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
}
|
||||
@@ -79,11 +77,9 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
return toFolderError(models.ErrFolderAccessDenied)
|
||||
}
|
||||
|
||||
cmd := models.UpdateDashboardAclCommand{}
|
||||
cmd.DashboardID = folder.Id
|
||||
|
||||
var items []*models.DashboardAcl
|
||||
for _, item := range apiCmd.Items {
|
||||
cmd.Items = append(cmd.Items, &models.DashboardAcl{
|
||||
items = append(items, &models.DashboardAcl{
|
||||
OrgID: c.OrgId,
|
||||
DashboardID: folder.Id,
|
||||
UserID: item.UserID,
|
||||
@@ -99,9 +95,9 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while retrieving hidden permissions", err)
|
||||
}
|
||||
cmd.Items = append(cmd.Items, hiddenACL...)
|
||||
items = append(items, hiddenACL...)
|
||||
|
||||
if okToUpdate, err := g.CheckPermissionBeforeUpdate(models.PERMISSION_ADMIN, cmd.Items); err != nil || !okToUpdate {
|
||||
if okToUpdate, err := g.CheckPermissionBeforeUpdate(models.PERMISSION_ADMIN, items); err != nil || !okToUpdate {
|
||||
if err != nil {
|
||||
if errors.Is(err, guardian.ErrGuardianPermissionExists) ||
|
||||
errors.Is(err, guardian.ErrGuardianOverride) {
|
||||
@@ -114,7 +110,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
return response.Error(403, "Cannot remove own admin permission for a folder", nil)
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil {
|
||||
if err := updateDashboardACL(hs, folder.Id, items); err != nil {
|
||||
if errors.Is(err, models.ErrDashboardAclInfoMissing) {
|
||||
err = models.ErrFolderAclInfoMissing
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateFolderPermissions(sc)
|
||||
callUpdateFolderPermissions(t, sc)
|
||||
assert.Equal(t, 404, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -92,7 +92,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateFolderPermissions(sc)
|
||||
callUpdateFolderPermissions(t, sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -153,7 +153,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateFolderPermissions(sc)
|
||||
callUpdateFolderPermissions(t, sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
|
||||
var resp struct {
|
||||
@@ -205,7 +205,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateFolderPermissions(sc)
|
||||
callUpdateFolderPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -233,7 +233,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateFolderPermissions(sc)
|
||||
callUpdateFolderPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
respJSON, err := jsonMap(sc.resp.Body.Bytes())
|
||||
require.NoError(t, err)
|
||||
@@ -279,7 +279,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
callUpdateFolderPermissions(sc)
|
||||
callUpdateFolderPermissions(t, sc)
|
||||
assert.Equal(t, 400, sc.resp.Code)
|
||||
},
|
||||
}, hs)
|
||||
@@ -355,13 +355,19 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
routePattern: "/api/folders/:uid/permissions",
|
||||
cmd: cmd,
|
||||
fn: func(sc *scenarioContext) {
|
||||
bus.AddHandler("test", func(cmd *models.UpdateDashboardAclCommand) error {
|
||||
assert.Len(t, cmd.Items, 4)
|
||||
return nil
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
var gotItems []*models.DashboardAcl
|
||||
updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
gotItems = items
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
assert.Len(t, gotItems, 4)
|
||||
},
|
||||
}, hs)
|
||||
})
|
||||
@@ -372,10 +378,16 @@ func callGetFolderPermissions(sc *scenarioContext, hs *HTTPServer) {
|
||||
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func callUpdateFolderPermissions(sc *scenarioContext) {
|
||||
bus.AddHandler("test", func(cmd *models.UpdateDashboardAclCommand) error {
|
||||
return nil
|
||||
func callUpdateFolderPermissions(t *testing.T, sc *scenarioContext) {
|
||||
t.Helper()
|
||||
|
||||
origUpdateDashboardACL := updateDashboardACL
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
dboards "github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@@ -174,12 +175,16 @@ func updateFolderScenario(t *testing.T, desc string, url string, routePattern st
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
defer bus.ClearBusHandlers()
|
||||
|
||||
hs := HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
sc.context = c
|
||||
sc.context.SignedInUser = &models.SignedInUser{OrgId: testOrgID, UserId: testUserID}
|
||||
|
||||
return UpdateFolder(c, cmd)
|
||||
return hs.UpdateFolder(c, cmd)
|
||||
})
|
||||
|
||||
origNewFolderService := dashboards.NewFolderService
|
||||
@@ -195,6 +200,8 @@ func updateFolderScenario(t *testing.T, desc string, url string, routePattern st
|
||||
}
|
||||
|
||||
type fakeFolderService struct {
|
||||
dashboards.FolderService
|
||||
|
||||
GetFoldersResult []*models.Folder
|
||||
GetFoldersError error
|
||||
GetFolderByUIDResult *models.Folder
|
||||
@@ -222,9 +229,8 @@ func (s *fakeFolderService) GetFolderByUID(uid string) (*models.Folder, error) {
|
||||
return s.GetFolderByUIDResult, s.GetFolderByUIDError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) CreateFolder(cmd *models.CreateFolderCommand) error {
|
||||
cmd.Result = s.CreateFolderResult
|
||||
return s.CreateFolderError
|
||||
func (s *fakeFolderService) CreateFolder(title, uid string) (*models.Folder, error) {
|
||||
return s.CreateFolderResult, s.CreateFolderError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) UpdateFolder(existingUID string, cmd *models.UpdateFolderCommand) error {
|
||||
@@ -238,7 +244,8 @@ func (s *fakeFolderService) DeleteFolder(uid string) (*models.Folder, error) {
|
||||
}
|
||||
|
||||
func mockFolderService(mock *fakeFolderService) {
|
||||
dashboards.NewFolderService = func(orgId int64, user *models.SignedInUser) dashboards.FolderService {
|
||||
dashboards.NewFolderService = func(orgId int64, user *models.SignedInUser,
|
||||
dashboardStore dboards.Store) dashboards.FolderService {
|
||||
return mock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ func ReadSourceMapFromFS(dir string, path string) ([]byte, error) {
|
||||
}
|
||||
|
||||
type SourceMapStore struct {
|
||||
sync.Mutex
|
||||
cache map[string]*sourceMap
|
||||
cfg *setting.Cfg
|
||||
readSourceMap ReadSourceMapFn
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func NewSourceMapStore(cfg *setting.Cfg, readSourceMap ReadSourceMapFn) *SourceMapStore {
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
@@ -110,12 +109,12 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins *plu
|
||||
|
||||
// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
|
||||
// the datasource table)
|
||||
for _, ds := range manager.DataSources {
|
||||
for _, ds := range hs.PluginManager.DataSources() {
|
||||
if ds.BuiltIn {
|
||||
dataSources[ds.Name] = map[string]interface{}{
|
||||
"type": ds.Type,
|
||||
"name": ds.Name,
|
||||
"meta": manager.DataSources[ds.Id],
|
||||
"meta": hs.PluginManager.GetDataSource(ds.Id),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,8 +225,8 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
||||
"commit": commit,
|
||||
"buildstamp": buildstamp,
|
||||
"edition": hs.License.Edition(),
|
||||
"latestVersion": hs.PluginManager.GrafanaLatestVersion,
|
||||
"hasUpdate": hs.PluginManager.GrafanaHasUpdate,
|
||||
"latestVersion": hs.PluginManager.GrafanaLatestVersion(),
|
||||
"hasUpdate": hs.PluginManager.GrafanaHasUpdate(),
|
||||
"env": setting.Env,
|
||||
"isEnterprise": hs.License.HasValidLicense(),
|
||||
},
|
||||
|
||||
@@ -39,18 +39,21 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg) (*macaron.Macaron, *HT
|
||||
})
|
||||
}
|
||||
|
||||
bus.ClearBusHandlers()
|
||||
bus.AddHandler("sql", sqlstore.GetPluginSettings)
|
||||
t.Cleanup(bus.ClearBusHandlers)
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
pm := &manager.PluginManager{Cfg: cfg, SQLStore: sqlStore}
|
||||
|
||||
r := &rendering.RenderingService{Cfg: cfg}
|
||||
r := &rendering.RenderingService{
|
||||
Cfg: cfg,
|
||||
PluginManager: pm,
|
||||
}
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
Bus: bus.GetBus(),
|
||||
License: &licensing.OSSLicensingService{Cfg: cfg},
|
||||
RenderService: r,
|
||||
PluginManager: &manager.PluginManager{Cfg: cfg},
|
||||
SQLStore: sqlStore,
|
||||
PluginManager: pm,
|
||||
}
|
||||
|
||||
m := macaron.New()
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/live"
|
||||
"github.com/grafana/grafana/pkg/services/search"
|
||||
@@ -79,7 +80,7 @@ type HTTPServer struct {
|
||||
License models.Licensing `inject:""`
|
||||
BackendPluginManager backendplugin.Manager `inject:""`
|
||||
PluginRequestValidator models.PluginRequestValidator `inject:""`
|
||||
PluginManager *manager.PluginManager `inject:""`
|
||||
PluginManager plugins.Manager `inject:""`
|
||||
SearchService *search.SearchService `inject:""`
|
||||
ShortURLService *shorturls.ShortURLService `inject:""`
|
||||
Live *live.GrafanaLive `inject:""`
|
||||
|
||||
@@ -400,8 +400,8 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
|
||||
GoogleTagManagerId: setting.GoogleTagManagerId,
|
||||
BuildVersion: setting.BuildVersion,
|
||||
BuildCommit: setting.BuildCommit,
|
||||
NewGrafanaVersion: hs.PluginManager.GrafanaLatestVersion,
|
||||
NewGrafanaVersionExists: hs.PluginManager.GrafanaHasUpdate,
|
||||
NewGrafanaVersion: hs.PluginManager.GrafanaLatestVersion(),
|
||||
NewGrafanaVersionExists: hs.PluginManager.GrafanaHasUpdate(),
|
||||
AppName: setting.ApplicationName,
|
||||
AppNameBodyClass: getAppNameBodyClass(hs.License.HasValidLicense()),
|
||||
FavIcon: "public/img/fav32.png",
|
||||
|
||||
@@ -25,8 +25,8 @@ var ErrPluginNotFound error = errors.New("plugin not found, no installed plugin
|
||||
|
||||
func (hs *HTTPServer) getPluginContext(pluginID string, user *models.SignedInUser) (backend.PluginContext, error) {
|
||||
pc := backend.PluginContext{}
|
||||
plugin, exists := manager.Plugins[pluginID]
|
||||
if !exists {
|
||||
plugin := hs.PluginManager.GetPlugin(pluginID)
|
||||
if plugin == nil {
|
||||
return pc, ErrPluginNotFound
|
||||
}
|
||||
|
||||
@@ -74,13 +74,12 @@ func (hs *HTTPServer) GetPluginList(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
pluginSettingsMap, err := hs.PluginManager.GetPluginSettings(c.OrgId)
|
||||
|
||||
if err != nil {
|
||||
return response.Error(500, "Failed to get list of plugins", err)
|
||||
}
|
||||
|
||||
result := make(dtos.PluginList, 0)
|
||||
for _, pluginDef := range manager.Plugins {
|
||||
for _, pluginDef := range hs.PluginManager.Plugins() {
|
||||
// filter out app sub plugins
|
||||
if embeddedFilter == "0" && pluginDef.IncludedInAppId != "" {
|
||||
continue
|
||||
@@ -130,7 +129,7 @@ func (hs *HTTPServer) GetPluginList(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
// filter out built in data sources
|
||||
if ds, exists := manager.DataSources[pluginDef.Id]; exists {
|
||||
if ds := hs.PluginManager.GetDataSource(pluginDef.Id); ds != nil {
|
||||
if ds.BuiltIn {
|
||||
continue
|
||||
}
|
||||
@@ -143,11 +142,11 @@ func (hs *HTTPServer) GetPluginList(c *models.ReqContext) response.Response {
|
||||
return response.JSON(200, result)
|
||||
}
|
||||
|
||||
func GetPluginSettingByID(c *models.ReqContext) response.Response {
|
||||
func (hs *HTTPServer) GetPluginSettingByID(c *models.ReqContext) response.Response {
|
||||
pluginID := c.Params(":pluginId")
|
||||
|
||||
def, exists := manager.Plugins[pluginID]
|
||||
if !exists {
|
||||
def := hs.PluginManager.GetPlugin(pluginID)
|
||||
if def == nil {
|
||||
return response.Error(404, "Plugin not found, no installed plugin with that id", nil)
|
||||
}
|
||||
|
||||
@@ -256,7 +255,7 @@ func (hs *HTTPServer) ImportDashboard(c *models.ReqContext, apiCmd dtos.ImportDa
|
||||
dashInfo, err := hs.PluginManager.ImportDashboard(apiCmd.PluginId, apiCmd.Path, c.OrgId, apiCmd.FolderId,
|
||||
apiCmd.Dashboard, apiCmd.Overwrite, apiCmd.Inputs, c.SignedInUser, hs.DataService)
|
||||
if err != nil {
|
||||
return dashboardSaveErrorToApiResponse(err)
|
||||
return hs.dashboardSaveErrorToApiResponse(err)
|
||||
}
|
||||
|
||||
return response.JSON(200, dashInfo)
|
||||
@@ -267,8 +266,8 @@ func (hs *HTTPServer) ImportDashboard(c *models.ReqContext, apiCmd dtos.ImportDa
|
||||
// /api/plugins/:pluginId/metrics
|
||||
func (hs *HTTPServer) CollectPluginMetrics(c *models.ReqContext) response.Response {
|
||||
pluginID := c.Params("pluginId")
|
||||
plugin, exists := manager.Plugins[pluginID]
|
||||
if !exists {
|
||||
plugin := hs.PluginManager.GetPlugin(pluginID)
|
||||
if plugin == nil {
|
||||
return response.Error(404, "Plugin not found", nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,19 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/teamguardian"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
// POST /api/teams
|
||||
func (hs *HTTPServer) CreateTeam(c *models.ReqContext, cmd models.CreateTeamCommand) response.Response {
|
||||
cmd.OrgId = c.OrgId
|
||||
|
||||
if c.OrgRole == models.ROLE_VIEWER {
|
||||
return response.Error(403, "Not allowed to create team.", nil)
|
||||
}
|
||||
|
||||
if err := hs.Bus.Dispatch(&cmd); err != nil {
|
||||
team, err := createTeam(hs.SQLStore, cmd.Name, cmd.Email, c.OrgId)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrTeamNameTaken) {
|
||||
return response.Error(409, "Team name taken", err)
|
||||
}
|
||||
@@ -31,23 +31,17 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext, cmd models.CreateTeamComm
|
||||
// the SignedInUser is an empty struct therefore
|
||||
// an additional check whether it is an actual user is required
|
||||
if c.SignedInUser.IsRealUser() {
|
||||
addMemberCmd := models.AddTeamMemberCommand{
|
||||
UserId: c.SignedInUser.UserId,
|
||||
OrgId: cmd.OrgId,
|
||||
TeamId: cmd.Result.Id,
|
||||
Permission: models.PERMISSION_ADMIN,
|
||||
}
|
||||
|
||||
if err := hs.Bus.Dispatch(&addMemberCmd); err != nil {
|
||||
c.Logger.Error("Could not add creator to team.", "error", err)
|
||||
if err := addTeamMember(hs.SQLStore, c.SignedInUser.UserId, c.OrgId, team.Id, false,
|
||||
models.PERMISSION_ADMIN); err != nil {
|
||||
c.Logger.Error("Could not add creator to team", "error", err)
|
||||
}
|
||||
} else {
|
||||
c.Logger.Warn("Could not add creator to team because is not a real user.")
|
||||
c.Logger.Warn("Could not add creator to team because is not a real user")
|
||||
}
|
||||
}
|
||||
|
||||
return response.JSON(200, &util.DynMap{
|
||||
"teamId": cmd.Result.Id,
|
||||
"teamId": team.Id,
|
||||
"message": "Team created",
|
||||
})
|
||||
}
|
||||
@@ -175,3 +169,18 @@ func (hs *HTTPServer) UpdateTeamPreferences(c *models.ReqContext, dtoCmd dtos.Up
|
||||
|
||||
return updatePreferencesFor(orgId, 0, teamId, &dtoCmd)
|
||||
}
|
||||
|
||||
// createTeam creates a team.
|
||||
//
|
||||
// Stubbable by tests.
|
||||
var createTeam = func(sqlStore *sqlstore.SQLStore, name, email string, orgID int64) (models.Team, error) {
|
||||
return sqlStore.CreateTeam(name, email, orgID)
|
||||
}
|
||||
|
||||
// addTeamMember adds a team member.
|
||||
//
|
||||
// Stubbable by tests.
|
||||
var addTeamMember = func(sqlStore *sqlstore.SQLStore, userID, orgID, teamID int64, isExternal bool,
|
||||
permission models.PermissionType) error {
|
||||
return sqlStore.AddTeamMember(userID, orgID, teamID, isExternal, permission)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
|
||||
@@ -98,20 +99,29 @@ func TestTeamAPIEndpoint(t *testing.T) {
|
||||
|
||||
teamName := "team foo"
|
||||
|
||||
createTeamCalled := 0
|
||||
bus.AddHandler("test", func(cmd *models.CreateTeamCommand) error {
|
||||
createTeamCalled += 1
|
||||
cmd.Result = models.Team{Name: teamName, Id: 42}
|
||||
return nil
|
||||
// TODO: Use a fake SQLStore when it's represented by an interface
|
||||
origCreateTeam := createTeam
|
||||
origAddTeamMember := addTeamMember
|
||||
t.Cleanup(func() {
|
||||
createTeam = origCreateTeam
|
||||
addTeamMember = origAddTeamMember
|
||||
})
|
||||
|
||||
createTeamCalled := 0
|
||||
createTeam = func(sqlStore *sqlstore.SQLStore, name, email string, orgID int64) (models.Team, error) {
|
||||
createTeamCalled++
|
||||
return models.Team{Name: teamName, Id: 42}, nil
|
||||
}
|
||||
|
||||
addTeamMemberCalled := 0
|
||||
bus.AddHandler("test", func(cmd *models.AddTeamMemberCommand) error {
|
||||
addTeamMemberCalled += 1
|
||||
addTeamMember = func(sqlStore *sqlstore.SQLStore, userID, orgID, teamID int64, isExternal bool,
|
||||
permission models.PermissionType) error {
|
||||
addTeamMemberCalled++
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/teams", nil)
|
||||
req, err := http.NewRequest("POST", "/api/teams", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("with no real signed in user", func(t *testing.T) {
|
||||
stub := &testLogger{}
|
||||
@@ -128,7 +138,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
|
||||
assert.Equal(t, createTeamCalled, 1)
|
||||
assert.Equal(t, addTeamMemberCalled, 0)
|
||||
assert.True(t, stub.warnCalled)
|
||||
assert.Equal(t, stub.warnMessage, "Could not add creator to team because is not a real user.")
|
||||
assert.Equal(t, stub.warnMessage, "Could not add creator to team because is not a real user")
|
||||
})
|
||||
|
||||
t.Run("with real signed in user", func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user