mirror of
https://github.com/grafana/grafana.git
synced 2025-09-25 11:54:20 +08:00
RBAC: Add access control metadata to folder dtos (#51158)
* RBAC: Add access control metadata to Folder dto * Add access control metadata to folder dto response * Add test to verify that access control metadata is attached * Attach access control metadata to multiple folders * Add access control metadata to frontend folder dto
This commit is contained in:
@ -4,15 +4,19 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web/webtest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -130,16 +134,106 @@ func TestFoldersAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestHTTPServer_FolderMetadata(t *testing.T) {
|
||||
setUpRBACGuardian(t)
|
||||
folderService := dashboards.NewFakeFolderService(t)
|
||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.folderService = folderService
|
||||
hs.AccessControl = acmock.New()
|
||||
})
|
||||
|
||||
t.Run("Should attach access control metadata to multiple folders", func(t *testing.T) {
|
||||
folderService.On("GetFolders", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]*models.Folder{
|
||||
{Uid: "1"},
|
||||
{Uid: "2"},
|
||||
{Uid: "3"},
|
||||
}, nil)
|
||||
|
||||
req := server.NewGetRequest("/api/folders?accesscontrol=true")
|
||||
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
|
||||
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: dashboards.ScopeFoldersAll},
|
||||
{Action: dashboards.ActionFoldersWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("2")},
|
||||
}),
|
||||
}})
|
||||
|
||||
res, err := server.Send(req)
|
||||
require.NoError(t, err)
|
||||
defer func() { require.NoError(t, res.Body.Close()) }()
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||
|
||||
body := []dtos.FolderSearchHit{}
|
||||
require.NoError(t, json.NewDecoder(res.Body).Decode(&body))
|
||||
|
||||
for _, f := range body {
|
||||
assert.True(t, f.AccessControl[dashboards.ActionFoldersRead])
|
||||
if f.Uid == "2" {
|
||||
assert.True(t, f.AccessControl[dashboards.ActionFoldersWrite])
|
||||
} else {
|
||||
assert.False(t, f.AccessControl[dashboards.ActionFoldersWrite])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Should attach access control metadata to folder response", func(t *testing.T) {
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&models.Folder{Uid: "folderUid"}, nil)
|
||||
|
||||
req := server.NewGetRequest("/api/folders/folderUid?accesscontrol=true")
|
||||
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
|
||||
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: dashboards.ScopeFoldersAll},
|
||||
{Action: dashboards.ActionFoldersWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("folderUid")},
|
||||
}),
|
||||
}})
|
||||
|
||||
res, err := server.Send(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||
defer func() { require.NoError(t, res.Body.Close()) }()
|
||||
|
||||
body := dtos.Folder{}
|
||||
require.NoError(t, json.NewDecoder(res.Body).Decode(&body))
|
||||
|
||||
assert.True(t, body.AccessControl[dashboards.ActionFoldersRead])
|
||||
assert.True(t, body.AccessControl[dashboards.ActionFoldersWrite])
|
||||
})
|
||||
|
||||
t.Run("Should attach access control metadata to folder response", func(t *testing.T) {
|
||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&models.Folder{Uid: "folderUid"}, nil)
|
||||
|
||||
req := server.NewGetRequest("/api/folders/folderUid")
|
||||
webtest.RequestWithSignedInUser(req, &models.SignedInUser{UserId: 1, OrgId: 1, Permissions: map[int64]map[string][]string{
|
||||
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: dashboards.ScopeFoldersAll},
|
||||
{Action: dashboards.ActionFoldersWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID("folderUid")},
|
||||
}),
|
||||
}})
|
||||
|
||||
res, err := server.Send(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||
defer func() { require.NoError(t, res.Body.Close()) }()
|
||||
|
||||
body := dtos.Folder{}
|
||||
require.NoError(t, json.NewDecoder(res.Body).Decode(&body))
|
||||
|
||||
assert.False(t, body.AccessControl[dashboards.ActionFoldersRead])
|
||||
assert.False(t, body.AccessControl[dashboards.ActionFoldersWrite])
|
||||
})
|
||||
}
|
||||
|
||||
func callCreateFolder(sc *scenarioContext) {
|
||||
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
|
||||
}
|
||||
|
||||
func createFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService dashboards.FolderService,
|
||||
cmd models.CreateFolderCommand, fn scenarioFunc) {
|
||||
setUpRBACGuardian(t)
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
hs := HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
AccessControl: acmock.New(),
|
||||
folderService: folderService,
|
||||
Cfg: setting.NewCfg(),
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
@ -165,9 +259,11 @@ func callUpdateFolder(sc *scenarioContext) {
|
||||
|
||||
func updateFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService dashboards.FolderService,
|
||||
cmd models.UpdateFolderCommand, fn scenarioFunc) {
|
||||
setUpRBACGuardian(t)
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
hs := HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
AccessControl: acmock.New(),
|
||||
folderService: folderService,
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user