From 090408f09f53ffc9afc6c65c7c7c1fd3a8cd22f3 Mon Sep 17 00:00:00 2001 From: David Krauser Date: Mon, 16 Mar 2026 13:17:43 -0400 Subject: [PATCH] [MM-67809] Check create post permission when editing posts (#35558) --- server/channels/api4/post.go | 12 +++++++++ server/channels/api4/post_test.go | 44 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/server/channels/api4/post.go b/server/channels/api4/post.go index 952c1d980c8..0f6b5db44d1 100644 --- a/server/channels/api4/post.go +++ b/server/channels/api4/post.go @@ -1046,6 +1046,12 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { return } + // Users who can't create posts in a channel shouldn't be able to edit them either. + userCreatePostPermissionCheckWithContext(c, originalPost.ChannelId) + if c.Err != nil { + return + } + auditRec.AddEventPriorState(originalPost) auditRec.AddEventObjectType("post") @@ -1183,6 +1189,12 @@ func postPatchChecks(c *Context, auditRec *model.AuditRecord, message *string) b return false } + // Users who can't create posts in a channel shouldn't be able to edit them either. + userCreatePostPermissionCheckWithContext(c, originalPost.ChannelId) + if c.Err != nil { + return false + } + if *c.App.Config().ServiceSettings.PostEditTimeLimit != -1 && model.GetMillis() > originalPost.CreateAt+int64(*c.App.Config().ServiceSettings.PostEditTimeLimit*1000) && message != nil { c.Err = model.NewAppError("patchPost", "api.post.update_post.permissions_time_limit.app_error", map[string]any{"timeLimit": *c.App.Config().ServiceSettings.PostEditTimeLimit}, "", http.StatusBadRequest) return isMember diff --git a/server/channels/api4/post_test.go b/server/channels/api4/post_test.go index efff02abdcc..9697fde175d 100644 --- a/server/channels/api4/post_test.go +++ b/server/channels/api4/post_test.go @@ -1701,6 +1701,29 @@ func TestUpdatePost(t *testing.T) { assert.Contains(t, updatedPost.FileIds, fileId) }) + t.Run("should prevent editing when create_post permission is revoked", func(t *testing.T) { + th.LoginBasic(t) + + postToEdit, _, appErr := th.App.CreatePost(th.Context, &model.Post{ + UserId: th.BasicUser.Id, + ChannelId: channel.Id, + Message: "original message", + }, channel, model.CreatePostFlags{SetOnline: true}) + require.Nil(t, appErr) + + th.RemovePermissionFromRole(t, model.PermissionCreatePost.Id, model.ChannelUserRoleId) + defer th.AddPermissionToRole(t, model.PermissionCreatePost.Id, model.ChannelUserRoleId) + + updatePost := &model.Post{ + Id: postToEdit.Id, + ChannelId: channel.Id, + Message: "edited message", + } + _, resp, err := client.UpdatePost(context.Background(), postToEdit.Id, updatePost) + require.Error(t, err) + CheckForbiddenStatus(t, resp) + }) + t.Run("logged out", func(t *testing.T) { _, err := client.Logout(context.Background()) require.NoError(t, err) @@ -2085,6 +2108,27 @@ func TestPatchPost(t *testing.T) { require.NoError(t, err) }) + t.Run("should prevent patching when create_post permission is revoked", func(t *testing.T) { + th.LoginBasic(t) + + postToEdit, _, err := client.CreatePost(context.Background(), &model.Post{ + ChannelId: channel.Id, + Message: "original message", + }) + require.NoError(t, err) + + defaultPerms := th.SaveDefaultRolePermissions(t) + defer th.RestoreDefaultRolePermissions(t, defaultPerms) + th.RemovePermissionFromRole(t, model.PermissionCreatePost.Id, model.ChannelUserRoleId) + + patch := &model.PostPatch{ + Message: model.NewPointer("edited message"), + } + _, resp, err := client.PatchPost(context.Background(), postToEdit.Id, patch) + require.Error(t, err) + CheckForbiddenStatus(t, resp) + }) + t.Run("time limit expired", func(t *testing.T) { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.PostEditTimeLimit = 1