diff --git a/pkg/api/folder_permission.go b/pkg/api/folder_permission.go index e4b884a390d..815cf18826e 100644 --- a/pkg/api/folder_permission.go +++ b/pkg/api/folder_permission.go @@ -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{ diff --git a/pkg/api/folder_permission_test.go b/pkg/api/folder_permission_test.go index d10185a7360..f768936ec50 100644 --- a/pkg/api/folder_permission_test.go +++ b/pkg/api/folder_permission_test.go @@ -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()) + }) }