From 58b2a3d16e08a5d332031c26a7d13c1903b759d3 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Mon, 28 Jan 2019 19:42:49 +0000 Subject: [PATCH] MM-13796: Don't allow pin/unpin in read-only town square. (#10184) --- api4/post.go | 29 ++++++++++++++++++++++++++++- api4/post_test.go | 16 ++++++++++++++++ i18n/en.json | 6 +++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/api4/post.go b/api4/post.go index 7b9f41c4af..d70f0ba1ae 100644 --- a/api4/post.go +++ b/api4/post.go @@ -515,10 +515,37 @@ func saveIsPinnedPost(c *Context, w http.ResponseWriter, r *http.Request, isPinn return } + // Restrict pinning if the experimental read-only-town-square setting is on. + user, err := c.App.GetUser(c.App.Session.UserId) + if err != nil { + c.Err = err + return + } + + post, err := c.App.GetSinglePost(c.Params.PostId) + if err != nil { + c.Err = err + return + } + + channel, err := c.App.GetChannel(post.ChannelId) + if err != nil { + c.Err = err + return + } + + if c.App.License() != nil && + *c.App.Config().TeamSettings.ExperimentalTownSquareIsReadOnly && + channel.Name == model.DEFAULT_CHANNEL && + !c.App.RolesGrantPermission(user.GetRoles(), model.PERMISSION_MANAGE_SYSTEM.Id) { + c.Err = model.NewAppError("saveIsPinnedPost", "api.post.save_is_pinned_post.town_square_read_only", nil, "", http.StatusForbidden) + return + } + patch := &model.PostPatch{} patch.IsPinned = model.NewBool(isPinned) - _, err := c.App.PatchPost(c.Params.PostId, patch) + _, err = c.App.PatchPost(c.Params.PostId, patch) if err != nil { c.Err = err return diff --git a/api4/post_test.go b/api4/post_test.go index 8b85b5f222..db5e49c396 100644 --- a/api4/post_test.go +++ b/api4/post_test.go @@ -740,6 +740,22 @@ func TestPinPost(t *testing.T) { _, resp = Client.PinPost(GenerateTestId()) CheckForbiddenStatus(t, resp) + t.Run("unable-to-pin-post-in-read-only-town-square", func(t *testing.T) { + townSquareIsReadOnly := *th.App.GetConfig().TeamSettings.ExperimentalTownSquareIsReadOnly + th.App.SetLicense(model.NewTestLicense()) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true }) + + defer th.App.RemoveLicense() + defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = townSquareIsReadOnly }) + + channel, err := th.App.GetChannelByName("town-square", th.BasicTeam.Id, true) + assert.Nil(t, err) + post := th.CreatePostWithClient(th.SystemAdminClient, channel) + + _, resp := Client.PinPost(post.Id) + CheckForbiddenStatus(t, resp) + }) + Client.Logout() _, resp = Client.PinPost(post.Id) CheckUnauthorizedStatus(t, resp) diff --git a/i18n/en.json b/i18n/en.json index 42fc5b1ef4..1639e9b900 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1448,6 +1448,10 @@ "id": "api.post.create_post.town_square_read_only", "translation": "This channel is read-only. Only members with permission can post here." }, + { + "id": "api.post.save_is_pinned_post.town_square_read_only", + "translation": "This channel is read-only. Only members with permission can pin or unpin posts here." + }, { "id": "api.post.create_webhook_post.creating.app_error", "translation": "Error creating post" @@ -6938,4 +6942,4 @@ "id": "ent.ldap.app_error", "translation": "ldap interface was nil" } -] \ No newline at end of file +]