Chore: Remove folders from models pkg (#61853)

This commit is contained in:
idafurjes 2023-01-25 09:14:32 +01:00 committed by GitHub
parent 6bf1d06dba
commit 421976e919
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 184 additions and 190 deletions

View File

@ -169,16 +169,16 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
func (hs *HTTPServer) MoveFolder(c *models.ReqContext) response.Response {
if hs.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
cmd := models.MoveFolderCommand{}
cmd := folder.MoveFolderCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
var theFolder *folder.Folder
var err error
if cmd.ParentUID != nil {
if cmd.NewParentUID != "" {
moveCommand := folder.MoveFolderCommand{
UID: web.Params(c.Req)[":uid"],
NewParentUID: *cmd.ParentUID,
NewParentUID: cmd.NewParentUID,
OrgID: c.OrgID,
}
theFolder, err = hs.folderService.Move(c.Req.Context(), &moveCommand)
@ -280,7 +280,7 @@ func (hs *HTTPServer) newToFolderDto(c *models.ReqContext, g guardian.DashboardG
Id: folder.ID,
Uid: folder.UID,
Title: folder.Title,
Url: folder.Url,
Url: folder.URL,
HasACL: folder.HasACL,
CanSave: canSave,
CanEdit: canEdit,

View File

@ -34,8 +34,8 @@ func TestFoldersAPIEndpoint(t *testing.T) {
folderService := &foldertest.FakeService{}
t.Run("Given a correct request for creating a folder", func(t *testing.T) {
cmd := models.CreateFolderCommand{
Uid: "uid",
cmd := folder.CreateFolderCommand{
UID: "uid",
Title: "Folder",
}
@ -73,8 +73,8 @@ func TestFoldersAPIEndpoint(t *testing.T) {
{Error: dashboards.ErrFolderFailedGenerateUniqueUid, ExpectedStatusCode: 500},
}
cmd := models.CreateFolderCommand{
Uid: "uid",
cmd := folder.CreateFolderCommand{
UID: "uid",
Title: "Folder",
}
@ -235,7 +235,7 @@ func callCreateFolder(sc *scenarioContext) {
}
func createFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService folder.Service,
cmd models.CreateFolderCommand, fn scenarioFunc) {
cmd folder.CreateFolderCommand, fn scenarioFunc) {
setUpRBACGuardian(t)
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
aclMockResp := []*dashboards.DashboardACLInfoDTO{}

View File

@ -10,6 +10,7 @@ import (
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/setting"
)
@ -21,11 +22,12 @@ const (
)
func (hs *HTTPServer) editorInAnyFolder(c *models.ReqContext) bool {
hasEditPermissionInFoldersQuery := models.HasEditPermissionInFoldersQuery{SignedInUser: c.SignedInUser}
if err := hs.DashboardService.HasEditPermissionInFolders(c.Req.Context(), &hasEditPermissionInFoldersQuery); err != nil {
hasEditPermissionInFoldersQuery := folder.HasEditPermissionInFoldersQuery{SignedInUser: c.SignedInUser}
hasEditPermissionInFoldersQueryResult, err := hs.DashboardService.HasEditPermissionInFolders(c.Req.Context(), &hasEditPermissionInFoldersQuery)
if err != nil {
return false
}
return hasEditPermissionInFoldersQuery.Result
return hasEditPermissionInFoldersQueryResult
}
func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewData, error) {

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/setting"
@ -214,12 +215,13 @@ func OrgAdminDashOrFolderAdminOrTeamAdmin(ss db.DB, ds dashboards.DashboardServi
return
}
hasAdminPermissionInDashOrFoldersQuery := models.HasAdminPermissionInDashboardsOrFoldersQuery{SignedInUser: c.SignedInUser}
if err := ds.HasAdminPermissionInDashboardsOrFolders(c.Req.Context(), &hasAdminPermissionInDashOrFoldersQuery); err != nil {
hasAdminPermissionInDashOrFoldersQuery := folder.HasAdminPermissionInDashboardsOrFoldersQuery{SignedInUser: c.SignedInUser}
hasAdminPermissionInDashOrFoldersQueryResult, err := ds.HasAdminPermissionInDashboardsOrFolders(c.Req.Context(), &hasAdminPermissionInDashOrFoldersQuery)
if err != nil {
c.JsonApiErr(500, "Failed to check if user is a folder admin", err)
}
if hasAdminPermissionInDashOrFoldersQuery.Result {
if hasAdminPermissionInDashOrFoldersQueryResult {
return
}

View File

@ -1,60 +0,0 @@
package models
import (
"time"
"github.com/grafana/grafana/pkg/services/user"
)
type Folder struct {
Id int64
Uid string
Title string
Url string
Version int
Created time.Time
Updated time.Time
UpdatedBy int64
CreatedBy int64
HasACL bool
}
// NewFolder creates a new Folder
func NewFolder(title string) *Folder {
folder := &Folder{}
folder.Title = title
folder.Created = time.Now()
folder.Updated = time.Now()
return folder
}
//
// COMMANDS
//
type CreateFolderCommand struct {
Uid string `json:"uid"`
Title string `json:"title"`
Result *Folder `json:"-"`
}
type MoveFolderCommand struct {
ParentUID *string `json:"parentUid"`
}
//
// QUERIES
//
type HasEditPermissionInFoldersQuery struct {
SignedInUser *user.SignedInUser
Result bool
}
type HasAdminPermissionInDashboardsOrFoldersQuery struct {
SignedInUser *user.SignedInUser
Result bool
}

View File

@ -21,8 +21,8 @@ type DashboardService interface {
GetDashboards(ctx context.Context, query *GetDashboardsQuery) error
GetDashboardTags(ctx context.Context, query *GetDashboardTagsQuery) error
GetDashboardUIDByID(ctx context.Context, query *GetDashboardRefByIDQuery) error
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error
HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *folder.HasAdminPermissionInDashboardsOrFoldersQuery) (bool, error)
HasEditPermissionInFolders(ctx context.Context, query *folder.HasEditPermissionInFoldersQuery) (bool, error)
ImportDashboard(ctx context.Context, dto *SaveDashboardDTO) (*Dashboard, error)
MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*Dashboard, error)
@ -68,9 +68,9 @@ type Store interface {
GetProvisionedDashboardData(ctx context.Context, name string) ([]*DashboardProvisioning, error)
GetProvisionedDataByDashboardID(ctx context.Context, dashboardID int64) (*DashboardProvisioning, error)
GetProvisionedDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*DashboardProvisioning, error)
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error
HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error
// SaveAlerts saves dashboard alertmodels.
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *folder.HasAdminPermissionInDashboardsOrFoldersQuery) (bool, error)
HasEditPermissionInFolders(ctx context.Context, query *folder.HasEditPermissionInFoldersQuery) (bool, error)
// SaveAlerts saves dashboard alerts.
SaveAlerts(ctx context.Context, dashID int64, alerts []*alertmodels.Alert) error
SaveDashboard(ctx context.Context, cmd SaveDashboardCommand) (*Dashboard, error)
SaveProvisionedDashboard(ctx context.Context, cmd SaveDashboardCommand, provisioning *DashboardProvisioning) (*Dashboard, error)

View File

@ -5,8 +5,10 @@ package dashboards
import (
context "context"
models "github.com/grafana/grafana/pkg/models"
folder "github.com/grafana/grafana/pkg/services/folder"
mock "github.com/stretchr/testify/mock"
models "github.com/grafana/grafana/pkg/models"
)
// FakeDashboardService is an autogenerated mock type for the DashboardService type
@ -180,31 +182,45 @@ func (_m *FakeDashboardService) GetDashboards(ctx context.Context, query *GetDas
}
// HasAdminPermissionInDashboardsOrFolders provides a mock function with given fields: ctx, query
func (_m *FakeDashboardService) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
func (_m *FakeDashboardService) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *folder.HasAdminPermissionInDashboardsOrFoldersQuery) (bool, error) {
ret := _m.Called(ctx, query)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.HasAdminPermissionInDashboardsOrFoldersQuery) error); ok {
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, *folder.HasAdminPermissionInDashboardsOrFoldersQuery) bool); ok {
r0 = rf(ctx, query)
} else {
r0 = ret.Error(0)
r0 = ret.Get(0).(bool)
}
return r0
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *folder.HasAdminPermissionInDashboardsOrFoldersQuery) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// HasEditPermissionInFolders provides a mock function with given fields: ctx, query
func (_m *FakeDashboardService) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
func (_m *FakeDashboardService) HasEditPermissionInFolders(ctx context.Context, query *folder.HasEditPermissionInFoldersQuery) (bool, error) {
ret := _m.Called(ctx, query)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.HasEditPermissionInFoldersQuery) error); ok {
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, *folder.HasEditPermissionInFoldersQuery) bool); ok {
r0 = rf(ctx, query)
} else {
r0 = ret.Error(0)
r0 = ret.Get(0).(bool)
}
return r0
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *folder.HasEditPermissionInFoldersQuery) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ImportDashboard provides a mock function with given fields: ctx, dto

View File

@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/org"
)
@ -97,13 +98,13 @@ func (d *DashboardStore) GetDashboardACLInfoList(ctx context.Context, query *das
}
// HasEditPermissionInFolders validates that an user have access to a certain folder
func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
return d.store.WithDbSession(ctx, func(dbSession *db.Session) error {
if query.SignedInUser.HasRole(org.RoleEditor) {
query.Result = true
return nil
}
func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query *folder.HasEditPermissionInFoldersQuery) (bool, error) {
var queryResult bool
if query.SignedInUser.HasRole(org.RoleEditor) {
queryResult = true
return queryResult, nil
}
err := d.store.WithDbSession(ctx, func(dbSession *db.Session) error {
builder := db.NewSqlBuilder(d.cfg, d.store.GetDialect())
builder.Write("SELECT COUNT(dashboard.id) AS count FROM dashboard WHERE dashboard.org_id = ? AND dashboard.is_folder = ?",
query.SignedInUser.OrgID, d.store.GetDialect().BooleanStr(true))
@ -119,16 +120,21 @@ func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query *
return err
}
query.Result = len(resp) > 0 && resp[0].Count > 0
queryResult = len(resp) > 0 && resp[0].Count > 0
return nil
})
if err != nil {
return queryResult, err
}
return queryResult, nil
}
func (d *DashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
return d.store.WithDbSession(ctx, func(dbSession *db.Session) error {
func (d *DashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *folder.HasAdminPermissionInDashboardsOrFoldersQuery) (bool, error) {
var queryResult bool
err := d.store.WithDbSession(ctx, func(dbSession *db.Session) error {
if query.SignedInUser.HasRole(org.RoleAdmin) {
query.Result = true
queryResult = true
return nil
}
@ -145,10 +151,14 @@ func (d *DashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Con
return err
}
query.Result = len(resp) > 0 && resp[0].Count > 0
queryResult = len(resp) > 0 && resp[0].Count > 0
return nil
})
if err != nil {
return queryResult, err
}
return queryResult, nil
}
func (d *DashboardStore) DeleteACLByUser(ctx context.Context, userID int64) error {

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/sqlstore"
@ -27,7 +28,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
}
t.Run("Testing DB", func(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var folder, dashInRoot, childDash *dashboards.Dashboard
var flder, dashInRoot, childDash *dashboards.Dashboard
var currentUser user.User
var dashboardStore *DashboardStore
@ -38,10 +39,10 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
var err error
dashboardStore, err = ProvideDashboardStore(sqlStore, &setting.Cfg{}, testFeatureToggles, tagimpl.ProvideService(sqlStore, sqlStore.Cfg), quotaService)
require.NoError(t, err)
folder = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod", "webapp")
flder = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod", "webapp")
dashInRoot = insertTestDashboard(t, dashboardStore, "test dash 67", 1, 0, false, "prod", "webapp")
childDash = insertTestDashboard(t, dashboardStore, "test dash 23", 1, folder.ID, false, "prod", "webapp")
insertTestDashboard(t, dashboardStore, "test dash 45", 1, folder.ID, false, "prod")
childDash = insertTestDashboard(t, dashboardStore, "test dash 23", 1, flder.ID, false, "prod", "webapp")
insertTestDashboard(t, dashboardStore, "test dash 45", 1, flder.ID, false, "prod")
currentUser = createUser(t, sqlStore, "viewer", "Viewer", false)
}
@ -53,20 +54,20 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder.ID, dashInRoot.ID},
DashboardIds: []int64{flder.ID, dashInRoot.ID},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 2)
require.Equal(t, query.Result[0].ID, folder.ID)
require.Equal(t, query.Result[0].ID, flder.ID)
require.Equal(t, query.Result[1].ID, dashInRoot.ID)
})
})
t.Run("and acl is set for dashboard folder", func(t *testing.T) {
var otherUser int64 = 999
err := updateDashboardACL(t, dashboardStore, folder.ID, dashboards.DashboardACL{
DashboardID: folder.ID,
err := updateDashboardACL(t, dashboardStore, flder.ID, dashboards.DashboardACL{
DashboardID: flder.ID,
OrgID: 1,
UserID: otherUser,
Permission: models.PERMISSION_EDIT,
@ -76,7 +77,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
OrgId: 1, DashboardIds: []int64{folder.ID, dashInRoot.ID},
OrgId: 1, DashboardIds: []int64{flder.ID, dashInRoot.ID},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
@ -86,8 +87,8 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
})
t.Run("when the user is given permission", func(t *testing.T) {
err := updateDashboardACL(t, dashboardStore, folder.ID, dashboards.DashboardACL{
DashboardID: folder.ID, OrgID: 1, UserID: currentUser.ID, Permission: models.PERMISSION_EDIT,
err := updateDashboardACL(t, dashboardStore, flder.ID, dashboards.DashboardACL{
DashboardID: flder.ID, OrgID: 1, UserID: currentUser.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
@ -95,12 +96,12 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder.ID, dashInRoot.ID},
DashboardIds: []int64{flder.ID, dashInRoot.ID},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 2)
require.Equal(t, query.Result[0].ID, folder.ID)
require.Equal(t, query.Result[0].ID, flder.ID)
require.Equal(t, query.Result[1].ID, dashInRoot.ID)
})
})
@ -114,12 +115,12 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
OrgRole: org.RoleAdmin,
},
OrgId: 1,
DashboardIds: []int64{folder.ID, dashInRoot.ID},
DashboardIds: []int64{flder.ID, dashInRoot.ID},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 2)
require.Equal(t, query.Result[0].ID, folder.ID)
require.Equal(t, query.Result[0].ID, flder.ID)
require.Equal(t, query.Result[1].ID, dashInRoot.ID)
})
})
@ -127,16 +128,16 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("and acl is set for dashboard child and folder has all permissions removed", func(t *testing.T) {
var otherUser int64 = 999
err := updateDashboardACL(t, dashboardStore, folder.ID)
err := updateDashboardACL(t, dashboardStore, flder.ID)
require.NoError(t, err)
err = updateDashboardACL(t, dashboardStore, childDash.ID, dashboards.DashboardACL{
DashboardID: folder.ID, OrgID: 1, UserID: otherUser, Permission: models.PERMISSION_EDIT,
DashboardID: flder.ID, OrgID: 1, UserID: otherUser, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
t.Run("should not return folder or child", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.ID, childDash.ID, dashInRoot.ID},
SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{flder.ID, childDash.ID, dashInRoot.ID},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
@ -151,7 +152,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
require.NoError(t, err)
t.Run("should be able to search for child dashboard but not folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.ID, childDash.ID, dashInRoot.ID}}
query := &models.FindPersistedDashboardsQuery{SignedInUser: &user.SignedInUser{UserID: currentUser.ID, OrgID: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{flder.ID, childDash.ID, dashInRoot.ID}}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 2)
@ -169,12 +170,12 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
OrgRole: org.RoleAdmin,
},
OrgId: 1,
DashboardIds: []int64{folder.ID, dashInRoot.ID, childDash.ID},
DashboardIds: []int64{flder.ID, dashInRoot.ID, childDash.ID},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 3)
require.Equal(t, query.Result[0].ID, folder.ID)
require.Equal(t, query.Result[0].ID, flder.ID)
require.Equal(t, query.Result[1].ID, childDash.ID)
require.Equal(t, query.Result[2].ID, dashInRoot.ID)
})
@ -328,21 +329,21 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
})
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
query := &folder.HasEditPermissionInFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: adminUser.ID, OrgID: 1, OrgRole: org.RoleAdmin},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
queryResult, err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
require.NoError(t, err)
require.True(t, query.Result)
require.True(t, queryResult)
})
t.Run("should have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{
query := &folder.HasAdminPermissionInDashboardsOrFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: adminUser.ID, OrgID: 1, OrgRole: org.RoleAdmin},
}
err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
queryResult, err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
require.NoError(t, err)
require.True(t, query.Result)
require.True(t, queryResult)
})
})
@ -376,21 +377,21 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
})
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
query := &folder.HasEditPermissionInFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: editorUser.ID, OrgID: 1, OrgRole: org.RoleEditor},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
queryResult, err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
require.True(t, query.Result)
require.True(t, queryResult)
})
t.Run("should not have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{
query := &folder.HasAdminPermissionInDashboardsOrFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: adminUser.ID, OrgID: 1, OrgRole: org.RoleEditor},
}
err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
queryResult, err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
require.NoError(t, err)
require.False(t, query.Result)
require.False(t, queryResult)
})
})
@ -424,21 +425,21 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not have edit permission in folders", func(t *testing.T) {
setup3()
query := &models.HasEditPermissionInFoldersQuery{
query := &folder.HasEditPermissionInFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: viewerUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
queryResult, err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
require.False(t, query.Result)
require.False(t, queryResult)
})
t.Run("should not have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{
query := &folder.HasAdminPermissionInDashboardsOrFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: adminUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
queryResult, err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
require.NoError(t, err)
require.False(t, query.Result)
require.False(t, queryResult)
})
t.Run("and admin permission is given for user with org role viewer in one dashboard folder", func(t *testing.T) {
@ -448,12 +449,12 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
require.NoError(t, err)
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
query := &folder.HasEditPermissionInFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: viewerUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
queryResult, err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
require.True(t, query.Result)
require.True(t, queryResult)
})
})
@ -464,12 +465,12 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
require.NoError(t, err)
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
query := &folder.HasEditPermissionInFoldersQuery{
SignedInUser: &user.SignedInUser{UserID: viewerUser.ID, OrgID: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
queryResult, err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
require.True(t, query.Result)
require.True(t, queryResult)
})
})
})

View File

@ -336,7 +336,7 @@ func FromDashboard(dash *Dashboard) *folder.Folder {
UID: dash.UID,
Title: dash.Title,
HasACL: dash.HasACL,
Url: GetFolderURL(dash.UID, dash.Slug),
URL: GetFolderURL(dash.UID, dash.Slug),
Version: dash.Version,
Created: dash.Created,
CreatedBy: dash.CreatedBy,

View File

@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
@ -602,11 +603,11 @@ func (dr *DashboardServiceImpl) GetDashboardACLInfoList(ctx context.Context, que
return dr.dashboardStore.GetDashboardACLInfoList(ctx, query)
}
func (dr *DashboardServiceImpl) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
func (dr *DashboardServiceImpl) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *folder.HasAdminPermissionInDashboardsOrFoldersQuery) (bool, error) {
return dr.dashboardStore.HasAdminPermissionInDashboardsOrFolders(ctx, query)
}
func (dr *DashboardServiceImpl) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
func (dr *DashboardServiceImpl) HasEditPermissionInFolders(ctx context.Context, query *folder.HasEditPermissionInFoldersQuery) (bool, error) {
return dr.dashboardStore.HasEditPermissionInFolders(ctx, query)
}

View File

@ -6,6 +6,7 @@ import (
context "context"
alertingmodels "github.com/grafana/grafana/pkg/services/alerting/models"
folder "github.com/grafana/grafana/pkg/services/folder"
mock "github.com/stretchr/testify/mock"
@ -291,31 +292,45 @@ func (_m *FakeDashboardStore) GetProvisionedDataByDashboardUID(ctx context.Conte
}
// HasAdminPermissionInDashboardsOrFolders provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
func (_m *FakeDashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *folder.HasAdminPermissionInDashboardsOrFoldersQuery) (bool, error) {
ret := _m.Called(ctx, query)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.HasAdminPermissionInDashboardsOrFoldersQuery) error); ok {
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, *folder.HasAdminPermissionInDashboardsOrFoldersQuery) bool); ok {
r0 = rf(ctx, query)
} else {
r0 = ret.Error(0)
r0 = ret.Get(0).(bool)
}
return r0
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *folder.HasAdminPermissionInDashboardsOrFoldersQuery) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// HasEditPermissionInFolders provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
func (_m *FakeDashboardStore) HasEditPermissionInFolders(ctx context.Context, query *folder.HasEditPermissionInFoldersQuery) (bool, error) {
ret := _m.Called(ctx, query)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.HasEditPermissionInFoldersQuery) error); ok {
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, *folder.HasEditPermissionInFoldersQuery) bool); ok {
r0 = rf(ctx, query)
} else {
r0 = ret.Error(0)
r0 = ret.Get(0).(bool)
}
return r0
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *folder.HasEditPermissionInFoldersQuery) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SaveAlerts provides a mock function with given fields: ctx, dashID, alerts

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
@ -142,8 +141,8 @@ func TestIntegrationFolderService(t *testing.T) {
})
t.Run("When deleting folder by uid should return access denied error", func(t *testing.T) {
newFolder := models.NewFolder("Folder")
newFolder.Uid = folderUID
newFolder := folder.NewFolder("Folder", "")
newFolder.UID = folderUID
folderStore.On("GetFolderByID", mock.Anything, orgID, folderId).Return(newFolder, nil)
folderStore.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(newFolder, nil)

View File

@ -180,7 +180,7 @@ func (ss *sqlStore) Get(ctx context.Context, q folder.GetFolderQuery) (*folder.F
}
return nil
})
foldr.Url = dashboards.GetFolderURL(foldr.UID, slugify.Slugify(foldr.Title))
foldr.URL = dashboards.GetFolderURL(foldr.UID, slugify.Slugify(foldr.Title))
return foldr, err
}

View File

@ -36,7 +36,7 @@ type Folder struct {
// TODO: validate if this field is required/relevant to folders.
// currently there is no such column
Version int
Url string
URL string
UpdatedBy int64
CreatedBy int64
HasACL bool
@ -146,3 +146,11 @@ type GetChildrenQuery struct {
SignedInUser *user.SignedInUser `json:"-"`
}
type HasEditPermissionInFoldersQuery struct {
SignedInUser *user.SignedInUser
}
type HasAdminPermissionInDashboardsOrFoldersQuery struct {
SignedInUser *user.SignedInUser
}

View File

@ -77,7 +77,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) {
Title: "Testing ConnectLibraryPanelsForDashboard",
Data: simplejson.NewFromAny(dashJSON),
}
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.Id)
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID)
err := sc.service.ConnectLibraryPanelsForDashboard(sc.ctx, sc.user, dashInDB)
require.NoError(t, err)
@ -175,7 +175,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) {
Title: "Testing ConnectLibraryPanelsForDashboard",
Data: simplejson.NewFromAny(dashJSON),
}
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.Id)
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID)
err = sc.service.ConnectLibraryPanelsForDashboard(sc.ctx, sc.user, dashInDB)
require.NoError(t, err)
@ -221,7 +221,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) {
Title: "Testing ConnectLibraryPanelsForDashboard",
Data: simplejson.NewFromAny(dashJSON),
}
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.Id)
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID)
err := sc.service.ConnectLibraryPanelsForDashboard(sc.ctx, sc.user, dashInDB)
require.EqualError(t, err, errLibraryPanelHeaderUIDMissing.Error())
@ -230,7 +230,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) {
scenarioWithLibraryPanel(t, "When an admin tries to store a dashboard with unused/removed library panels, it should disconnect unused/removed library panels",
func(t *testing.T, sc scenarioContext) {
unused, err := sc.elementService.CreateElement(sc.ctx, sc.user, libraryelements.CreateLibraryElementCommand{
FolderID: sc.folder.Id,
FolderID: sc.folder.ID,
Name: "Unused Libray Panel",
Model: []byte(`
{
@ -277,7 +277,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) {
Title: "Testing ConnectLibraryPanelsForDashboard",
Data: simplejson.NewFromAny(dashJSON),
}
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.Id)
dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.ID)
err = sc.elementService.ConnectElementsToDashboard(sc.ctx, sc.user, []string{sc.initialResult.Result.UID}, dashInDB.ID)
require.NoError(t, err)
@ -406,7 +406,7 @@ func TestImportLibraryPanelsForDashboard(t *testing.T) {
_, err := sc.elementService.GetElement(sc.ctx, sc.user, existingUID)
require.NoError(t, err)
err = sc.service.ImportLibraryPanelsForDashboard(sc.ctx, sc.user, simplejson.New(), panels, sc.folder.Id)
err = sc.service.ImportLibraryPanelsForDashboard(sc.ctx, sc.user, simplejson.New(), panels, sc.folder.ID)
require.NoError(t, err)
element, err := sc.elementService.GetElement(sc.ctx, sc.user, existingUID)
@ -414,7 +414,7 @@ func TestImportLibraryPanelsForDashboard(t *testing.T) {
var expected = getExpected(t, element, existingUID, existingName, sc.initialResult.Result.Model)
expected.FolderID = sc.initialResult.Result.FolderID
expected.Description = sc.initialResult.Result.Description
expected.Meta.FolderUID = sc.folder.Uid
expected.Meta.FolderUID = sc.folder.UID
expected.Meta.FolderName = sc.folder.Title
var result = toLibraryElement(t, element)
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
@ -601,7 +601,7 @@ type scenarioContext struct {
service Service
elementService libraryelements.Service
user *user.SignedInUser
folder *models.Folder
folder *folder.Folder
initialResult libraryPanelResult
sqlStore db.DB
}
@ -778,7 +778,7 @@ func scenarioWithLibraryPanel(t *testing.T, desc string, fn func(t *testing.T, s
testScenario(t, desc, func(t *testing.T, sc scenarioContext) {
command := libraryelements.CreateLibraryElementCommand{
FolderID: sc.folder.Id,
FolderID: sc.folder.ID,
Name: "Text - Library Panel",
Model: []byte(`
{
@ -877,15 +877,15 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
sqlStore: sqlStore,
}
folder := createFolderWithACL(t, sc.sqlStore, "ScenarioFolder", sc.user, []folderACLItem{})
sc.folder = &models.Folder{
Id: folder.ID,
Uid: folder.UID,
Title: folder.Title,
Url: dashboards.GetFolderURL(folder.UID, slugify.Slugify(folder.Title)),
foldr := createFolderWithACL(t, sc.sqlStore, "ScenarioFolder", sc.user, []folderACLItem{})
sc.folder = &folder.Folder{
ID: foldr.ID,
UID: foldr.UID,
Title: foldr.Title,
URL: dashboards.GetFolderURL(foldr.UID, slugify.Slugify(foldr.Title)),
Version: 0,
Created: folder.Created,
Updated: folder.Updated,
Created: foldr.Created,
Updated: foldr.Updated,
UpdatedBy: 0,
CreatedBy: 0,
HasACL: false,

View File

@ -7,7 +7,7 @@ import (
"testing"
"time"
grafana_models "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
"github.com/grafana/grafana/pkg/util"
@ -194,7 +194,7 @@ func TestCalculateChanges(t *testing.T) {
groupKey := models.AlertRuleGroupKey{
OrgID: orgId,
NamespaceUID: namespace.Uid,
NamespaceUID: namespace.UID,
RuleGroup: groupName,
}
@ -442,12 +442,12 @@ func withUIDs(uids map[string]*models.AlertRule) func(rule *models.AlertRule) {
}
}
func randFolder() *grafana_models.Folder {
return &grafana_models.Folder{
Id: rand.Int63(),
Uid: util.GenerateShortUID(),
func randFolder() *folder.Folder {
return &folder.Folder{
ID: rand.Int63(),
UID: util.GenerateShortUID(),
Title: "TEST-FOLDER-" + util.GenerateShortUID(),
Url: "",
URL: "",
Version: 0,
Created: time.Time{},
Updated: time.Time{},