grafana/pkg/api/folder_permission_test.go
2026-04-07 13:00:45 -05:00

234 lines
9.6 KiB
Go

package api
import (
"encoding/json"
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
"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/folder/foldertest"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web/webtest"
)
func TestHTTPServer_GetFolderPermissionList(t *testing.T) {
t.Run("should not be able to list acl when user does not have permission to do so", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {})
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest("/api/folders/1/permissions"), userWithPermissions(1, nil)))
require.NoError(t, err)
assert.Equal(t, http.StatusForbidden, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should be able to list acl with correct permission", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.folderService = &foldertest.FakeService{ExpectedFolder: &folder.Folder{UID: "1"}}
hs.folderPermissionsService = &actest.FakePermissionsService{
ExpectedPermissions: []accesscontrol.ResourcePermission{},
}
})
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest("/api/folders/1/permissions"), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsRead, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should filter out hidden users from acl", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
cfg := setting.NewCfg()
cfg.HiddenUsers = map[string]struct{}{"hidden": {}}
hs.Cfg = cfg
hs.folderService = &foldertest.FakeService{ExpectedFolder: &folder.Folder{UID: "1"}}
hs.folderPermissionsService = &actest.FakePermissionsService{
ExpectedPermissions: []accesscontrol.ResourcePermission{
{UserID: 1, UserLogin: "regular", IsManaged: true},
{UserID: 2, UserLogin: "hidden", IsManaged: true},
},
}
})
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest("/api/folders/1/permissions"), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsRead, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
var result []dashboards.DashboardACLInfoDTO
require.NoError(t, json.NewDecoder(res.Body).Decode(&result))
assert.Len(t, result, 1)
assert.Equal(t, result[0].UserLogin, "regular")
require.NoError(t, res.Body.Close())
})
}
func TestHTTPServer_UpdateFolderPermissions(t *testing.T) {
t.Run("should not be able to update acl when user does not have permission to do so", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {})
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", nil), userWithPermissions(1, nil)))
require.NoError(t, err)
assert.Equal(t, http.StatusForbidden, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should be able to update acl with correct permissions", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.folderService = &foldertest.FakeService{ExpectedFolder: &folder.Folder{UID: "1"}}
hs.folderPermissionsService = &actest.FakePermissionsService{}
})
body := `{"items": []}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should not be able to specify team and user in same acl", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.folderService = &foldertest.FakeService{ExpectedFolder: &folder.Folder{UID: "1"}}
hs.folderPermissionsService = &actest.FakePermissionsService{}
})
body := `{"items": [{ userId:1, teamId: 2 }]}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusBadRequest, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should not be able to specify team and role in same acl", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.folderService = &foldertest.FakeService{ExpectedFolder: &folder.Folder{UID: "1"}}
hs.folderPermissionsService = &actest.FakePermissionsService{}
})
body := `{"items": [{ teamId:1, role: "Admin" }]}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusBadRequest, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should not be able to specify user and role in same acl", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.folderService = &foldertest.FakeService{ExpectedFolder: &folder.Folder{UID: "1"}}
hs.folderPermissionsService = &actest.FakePermissionsService{}
})
body := `{"items": [{ userId:1, role: "Admin" }]}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusBadRequest, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should not be able to update permissions for folders managed by provisioning", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
fakeFolderService := foldertest.NewFakeService()
fakeFolderService.ExpectedFolder = &folder.Folder{
ID: 1,
OrgID: 1,
UID: "1",
ManagedBy: utils.ManagerKindRepo,
}
hs.folderService = fakeFolderService
hs.folderPermissionsService = &actest.FakePermissionsService{
ExpectedPermissions: []accesscontrol.ResourcePermission{},
}
})
body := `{"items": [{"role": "Viewer", "permission": 1}]}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusForbidden, res.StatusCode)
var result map[string]interface{}
require.NoError(t, json.NewDecoder(res.Body).Decode(&result))
assert.Contains(t, result["message"].(string), "Cannot update permissions for folders managed by provisioning")
require.NoError(t, res.Body.Close())
})
t.Run("should be able to update permissions for provisioned folder when provisioningFolderMetadata is enabled", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Features = featuremgmt.WithFeatures(featuremgmt.FlagProvisioningFolderMetadata)
fakeFolderService := foldertest.NewFakeService()
fakeFolderService.ExpectedFolder = &folder.Folder{
ID: 1,
OrgID: 1,
UID: "1",
ManagedBy: utils.ManagerKindRepo,
}
hs.folderService = fakeFolderService
hs.folderPermissionsService = &actest.FakePermissionsService{
ExpectedPermissions: []accesscontrol.ResourcePermission{},
}
})
body := `{"items": [{"role": "Viewer", "permission": 1}]}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
require.NoError(t, res.Body.Close())
})
t.Run("should be able to update permissions for non-provisioned folders", func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
fakeFolderService := foldertest.NewFakeService()
fakeFolderService.ExpectedFolder = &folder.Folder{
ID: 1,
OrgID: 1,
UID: "1",
ManagedBy: utils.ManagerKindUnknown, // Not managed by provisioning
}
hs.folderService = fakeFolderService
hs.folderPermissionsService = &actest.FakePermissionsService{
ExpectedPermissions: []accesscontrol.ResourcePermission{},
}
})
body := `{"items": [{"role": "Viewer", "permission": 1}]}`
res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewPostRequest("/api/folders/1/permissions", strings.NewReader(body)), userWithPermissions(1, []accesscontrol.Permission{
{Action: folder.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
require.NoError(t, res.Body.Close())
})
}