Compare commits

...

1 Commits

Author SHA1 Message Date
Gonzalo Trigueros
2804351da1 folders: block permissions updates on folders managed by provisioning. 2026-01-05 17:57:24 +01:00
2 changed files with 61 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/infra/metrics"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/dashboards"
@@ -92,6 +93,11 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *contextmodel.ReqContext) respon
return apierrors.ToFolderErrorResponse(err)
}
// Block permission changes for folders managed by provisioning
if folder.ManagedBy == utils.ManagerKindRepo {
return response.Error(http.StatusForbidden, "Cannot update permissions for folders managed by provisioning.", nil)
}
items := make([]*dashboards.DashboardACL, 0, len(apiCmd.Items))
for _, item := range apiCmd.Items {
items = append(items, &dashboards.DashboardACL{

View File

@@ -9,6 +9,7 @@ import (
"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"
@@ -149,4 +150,58 @@ func TestHTTPServer_UpdateFolderPermissions(t *testing.T) {
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: dashboards.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 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: dashboards.ActionFoldersPermissionsWrite, Scope: "folders:uid:1"},
})))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
require.NoError(t, res.Body.Close())
})
}