From 04cd6d35e9864266cddf00fbcf7a3d74a3e8d9ca Mon Sep 17 00:00:00 2001 From: Ashish Bhate Date: Thu, 28 Jul 2022 20:25:20 +0530 Subject: [PATCH] MM-45272: Fix getPostThread permissions (#20565) Summary Fix permissions for the the getPostThread API Method. User can view thread if user is member of the channel User can view threads in public channels (in the user's team) that they're not a member of, only if compliance export is disabled. Ticket Link https://mattermost.atlassian.net/browse/MM-45272 --- api4/post.go | 29 +++++++++++++++++++++++++++++ api4/post_test.go | 18 +++++++++++++++++- i18n/en.json | 4 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/api4/post.go b/api4/post.go index 024bcdc873..dda1619eb5 100644 --- a/api4/post.go +++ b/api4/post.go @@ -525,6 +525,35 @@ func getPostThread(c *Context, w http.ResponseWriter, r *http.Request) { return } + rPost, err := c.App.GetSinglePost(c.Params.PostId, false) + if err != nil { + c.Err = err + return + } + hasPermission := false + becauseCompliance := false + if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), rPost.ChannelId, model.PermissionReadChannel) { + hasPermission = true + } else if channel, cErr := c.App.GetChannel(c.AppContext, rPost.ChannelId); cErr == nil { + if channel.Type == model.ChannelTypeOpen && + c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), channel.TeamId, model.PermissionReadPublicChannel) { + hasPermission = true + if *c.App.Config().MessageExportSettings.EnableExport { + hasPermission = false + becauseCompliance = true + } + } + } + + if !hasPermission { + if becauseCompliance { + c.Err = model.NewAppError("getPostThread", "api.post.compliance_enabled.join_channel_to_view_post", nil, "", http.StatusForbidden) + } else { + c.SetPermissionError(model.PermissionReadChannel) + } + return + } + // For now, by default we return all items unless it's set to maintain // backwards compatibility with mobile. But when the next ESR passes, we need to // change this to web.PerPageDefault. diff --git a/api4/post_test.go b/api4/post_test.go index e90ed309f9..baa113731b 100644 --- a/api4/post_test.go +++ b/api4/post_test.go @@ -2191,10 +2191,26 @@ func TestGetPostThread(t *testing.T) { client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id) - // Channel is public, should be able to read post + messageExportEnabled := *th.App.Config().MessageExportSettings.EnableExport + // Channel is public, and compliance export is OFF, should be able to read post + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MessageExportSettings.EnableExport = false + }) _, _, err = client.GetPostThread(th.BasicPost.Id, "", false) require.NoError(t, err) + // channel is public, and compliance export is ON, should NOT be able to read post + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MessageExportSettings.EnableExport = true + }) + _, resp, err = client.GetPostThread(th.BasicPost.Id, "", false) + require.Error(t, err) + CheckForbiddenStatus(t, resp) + + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MessageExportSettings.EnableExport = messageExportEnabled + }) + privatePost := th.CreatePostWithClient(client, th.BasicPrivateChannel) _, _, err = client.GetPostThread(privatePost.Id, "", false) diff --git a/i18n/en.json b/i18n/en.json index 146a1c8f2c..627780f3b5 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2237,6 +2237,10 @@ "id": "api.post.check_for_out_of_channel_mentions.message.one", "translation": "@{{.Username}} did not get notified by this mention because they are not in the channel." }, + { + "id": "api.post.compliance_enabled.join_channel_to_view_post", + "translation": "Due to compliance rules configured on this instance the channel must be joined before its posts can be read." + }, { "id": "api.post.create_post.can_not_post_to_deleted.error", "translation": "Can not post to deleted channel."