mirror of
https://github.com/mattermost/mattermost.git
synced 2026-08-31 01:11:29 +08:00
Reject boards in id-batch lookups, unread, and member-mutation endpoints
- GetChannelsByIds, GetChannelsWithTeamDataByIds, and GetChannelUnread now exclude BO/BP at the store layer so boards can't slip through if callers stop filtering first. - updateChannelMemberNotifyProps, updateChannelMemberAutotranslation, and viewChannel now reject board IDs explicitly via the existing rejectBoardChannelByID helper, matching the other write endpoints. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1808,6 +1808,13 @@ func viewChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if view.ChannelId != "" && rejectBoardChannelByID(c, view.ChannelId) {
|
||||
return
|
||||
}
|
||||
if view.PrevChannelId != "" && rejectBoardChannelByID(c, view.PrevChannelId) {
|
||||
return
|
||||
}
|
||||
|
||||
times, err := c.App.ViewChannel(c.AppContext, &view, c.Params.UserId, c.AppContext.Session().Id, view.CollapsedThreadsSupported)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -1941,6 +1948,10 @@ func updateChannelMemberNotifyProps(c *Context, w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
|
||||
if rejectBoardChannelByID(c, c.Params.ChannelId) {
|
||||
return
|
||||
}
|
||||
|
||||
props := model.MapFromJSON(r.Body)
|
||||
if props == nil {
|
||||
c.SetInvalidParam("notify_props")
|
||||
@@ -1983,6 +1994,10 @@ func updateChannelMemberAutotranslation(c *Context, w http.ResponseWriter, r *ht
|
||||
return
|
||||
}
|
||||
|
||||
if rejectBoardChannelByID(c, c.Params.ChannelId) {
|
||||
return
|
||||
}
|
||||
|
||||
props := UpdateChannelMemberAutotranslationProps{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&props); err != nil {
|
||||
c.SetInvalidParamWithErr("autotranslation_disabled", err)
|
||||
|
||||
@@ -7102,6 +7102,24 @@ func TestChannelEndpointsRejectBoards(t *testing.T) {
|
||||
CheckForbiddenStatus(t, resp) // license check fires before channel fetch
|
||||
})
|
||||
|
||||
t.Run("updateChannelMemberNotifyProps rejects board", func(t *testing.T) {
|
||||
resp, err := client.UpdateChannelNotifyProps(ctx, boardChannel.Id, th.BasicUser.Id, map[string]string{model.DesktopNotifyProp: model.UserNotifyAll})
|
||||
require.Error(t, err)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("updateChannelMemberAutotranslation rejects board", func(t *testing.T) {
|
||||
resp, err := client.UpdateChannelMemberAutotranslation(ctx, boardChannel.Id, th.BasicUser.Id, true)
|
||||
require.Error(t, err)
|
||||
CheckForbiddenStatus(t, resp) // feature-availability check fires before channel fetch
|
||||
})
|
||||
|
||||
t.Run("viewChannel rejects board", func(t *testing.T) {
|
||||
_, resp, err := client.ViewChannel(ctx, th.BasicUser.Id, &model.ChannelView{ChannelId: boardChannel.Id})
|
||||
require.Error(t, err)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
})
|
||||
|
||||
// --- READ operations: boards are invisible (404) via store-level filter ---
|
||||
|
||||
t.Run("getChannel not found for board", func(t *testing.T) {
|
||||
|
||||
@@ -900,8 +900,9 @@ func (s SqlChannelStore) GetChannelUnread(channelId, userId string) (*model.Chan
|
||||
Id = ChannelId
|
||||
AND Id = ?
|
||||
AND UserId = ?
|
||||
AND DeleteAt = 0`,
|
||||
channelId, userId)
|
||||
AND DeleteAt = 0
|
||||
AND Channels.Type NOT IN (?, ?)`,
|
||||
channelId, userId, model.ChannelTypeOpenBoard, model.ChannelTypePrivateBoard)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, store.NewErrNotFound("Channel", fmt.Sprintf("channelId=%s,userId=%s", channelId, userId))
|
||||
@@ -2893,6 +2894,7 @@ func (s SqlChannelStore) GetChannelsByIds(channelIds []string, includeDeleted bo
|
||||
Select(channelSliceColumns(true)...).
|
||||
From("Channels").
|
||||
Where(sq.Eq{"Id": channelIds}).
|
||||
Where(sq.NotEq{"Type": []model.ChannelType{model.ChannelTypeOpenBoard, model.ChannelTypePrivateBoard}}).
|
||||
OrderBy("Name")
|
||||
|
||||
if !includeDeleted {
|
||||
@@ -2923,6 +2925,7 @@ func (s SqlChannelStore) GetChannelsWithTeamDataByIds(channelIDs []string, inclu
|
||||
From("Channels c").
|
||||
LeftJoin("Teams t ON c.TeamId = t.Id").
|
||||
Where(sq.Eq{"c.Id": channelIDs}).
|
||||
Where(sq.NotEq{"c.Type": []model.ChannelType{model.ChannelTypeOpenBoard, model.ChannelTypePrivateBoard}}).
|
||||
OrderBy("c.Name")
|
||||
|
||||
if !includeDeleted {
|
||||
|
||||
Reference in New Issue
Block a user