Sanatize LastViewedAt and LastUpdateAt for other users on channel member object (#33835) (#33905)

Automatic Merge
Этот коммит содержится в:
Mattermost Build
2025-09-16 13:19:10 +03:00
коммит произвёл GitHub
родитель d41872f1f3
Коммит 98acefe911
5 изменённых файлов: 202 добавлений и 0 удалений

Просмотреть файл

@@ -1516,6 +1516,12 @@ func getChannelMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
// Sanitize members for current user
currentUserId := c.AppContext.Session().UserId
for i := range members {
members[i].SanitizeForCurrentUser(currentUserId)
}
if err := json.NewEncoder(w).Encode(members); err != nil {
c.Logger.Warn("Error while writing response", mlog.Err(err))
}
@@ -1569,6 +1575,12 @@ func getChannelMembersByIds(c *Context, w http.ResponseWriter, r *http.Request)
return
}
// Sanitize members for current user
currentUserId := c.AppContext.Session().UserId
for i := range members {
members[i].SanitizeForCurrentUser(currentUserId)
}
if err := json.NewEncoder(w).Encode(members); err != nil {
c.Logger.Warn("Error while writing response", mlog.Err(err))
}
@@ -1592,6 +1604,9 @@ func getChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
// Sanitize member for current user
member.SanitizeForCurrentUser(c.AppContext.Session().UserId)
if err := json.NewEncoder(w).Encode(member); err != nil {
c.Logger.Warn("Error while writing response", mlog.Err(err))
}
@@ -1619,6 +1634,12 @@ func getChannelMembersForTeamForUser(c *Context, w http.ResponseWriter, r *http.
return
}
// Sanitize members for current user
currentUserId := c.AppContext.Session().UserId
for i := range members {
members[i].SanitizeForCurrentUser(currentUserId)
}
if err := json.NewEncoder(w).Encode(members); err != nil {
c.Logger.Warn("Error while writing response", mlog.Err(err))
}
@@ -2005,6 +2026,12 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
// Sanitize the returned members
currentUserId := c.AppContext.Session().UserId
for i := range newChannelMembers {
newChannelMembers[i].SanitizeForCurrentUser(currentUserId)
}
w.WriteHeader(http.StatusCreated)
userId, ok := props["user_id"]
if ok && len(newChannelMembers) == 1 && newChannelMembers[0].UserId == userId {

Просмотреть файл

@@ -6318,3 +6318,87 @@ func TestViewChannelWithoutCollapsedThreads(t *testing.T) {
require.NoError(t, err)
require.Zero(t, threads.TotalUnreadMentions)
}
func TestChannelMemberSanitization(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic()
defer th.TearDown()
client := th.Client
user := th.BasicUser
user2 := th.BasicUser2
channel := th.CreatePublicChannel()
// Add second user to channel
_, _, err := client.AddChannelMember(context.Background(), channel.Id, user2.Id)
require.NoError(t, err)
t.Run("getChannelMembers sanitizes LastViewedAt and LastUpdateAt for other users", func(t *testing.T) {
members, _, err := client.GetChannelMembers(context.Background(), channel.Id, 0, 60, "")
require.NoError(t, err)
for _, member := range members {
if member.UserId == user.Id {
// Current user should see their own timestamps
assert.NotEqual(t, int64(-1), member.LastViewedAt, "Current user should see their LastViewedAt")
assert.NotEqual(t, int64(-1), member.LastUpdateAt, "Current user should see their LastUpdateAt")
} else {
// Other users' timestamps should be sanitized
assert.Equal(t, int64(-1), member.LastViewedAt, "Other users' LastViewedAt should be sanitized")
assert.Equal(t, int64(-1), member.LastUpdateAt, "Other users' LastUpdateAt should be sanitized")
}
}
})
t.Run("getChannelMember sanitizes LastViewedAt and LastUpdateAt for other users", func(t *testing.T) {
// Get other user's membership data
member, _, err := client.GetChannelMember(context.Background(), channel.Id, user2.Id, "")
require.NoError(t, err)
// Should be sanitized since it's not the current user
assert.Equal(t, int64(-1), member.LastViewedAt, "Other user's LastViewedAt should be sanitized")
assert.Equal(t, int64(-1), member.LastUpdateAt, "Other user's LastUpdateAt should be sanitized")
// Get current user's membership data
currentMember, _, err := client.GetChannelMember(context.Background(), channel.Id, user.Id, "")
require.NoError(t, err)
// Should not be sanitized since it's the current user
assert.NotEqual(t, int64(-1), currentMember.LastViewedAt, "Current user should see their LastViewedAt")
assert.NotEqual(t, int64(-1), currentMember.LastUpdateAt, "Current user should see their LastUpdateAt")
})
t.Run("getChannelMembersByIds sanitizes data appropriately", func(t *testing.T) {
userIds := []string{user.Id, user2.Id}
members, _, err := client.GetChannelMembersByIds(context.Background(), channel.Id, userIds)
require.NoError(t, err)
require.Len(t, members, 2)
for _, member := range members {
if member.UserId == user.Id {
// Current user should see their own timestamps
assert.NotEqual(t, int64(-1), member.LastViewedAt, "Current user should see their LastViewedAt")
assert.NotEqual(t, int64(-1), member.LastUpdateAt, "Current user should see their LastUpdateAt")
} else {
// Other users' timestamps should be sanitized
assert.Equal(t, int64(-1), member.LastViewedAt, "Other users' LastViewedAt should be sanitized")
assert.Equal(t, int64(-1), member.LastUpdateAt, "Other users' LastUpdateAt should be sanitized")
}
}
})
t.Run("addChannelMember sanitizes returned member data", func(t *testing.T) {
newUser := th.CreateUser()
th.LinkUserToTeam(newUser, th.BasicTeam)
// Add new user and check returned member data
returnedMember, _, err := client.AddChannelMember(context.Background(), channel.Id, newUser.Id)
require.NoError(t, err)
// The returned member should be sanitized since it's not the current user
assert.Equal(t, int64(-1), returnedMember.LastViewedAt, "Returned member LastViewedAt should be sanitized")
assert.Equal(t, int64(-1), returnedMember.LastUpdateAt, "Returned member LastUpdateAt should be sanitized")
assert.Equal(t, newUser.Id, returnedMember.UserId, "UserId should be preserved")
assert.Equal(t, channel.Id, returnedMember.ChannelId, "ChannelId should be preserved")
})
}

Просмотреть файл

@@ -3128,6 +3128,12 @@ func getChannelMembersForUser(c *Context, w http.ResponseWriter, r *http.Request
return
}
// Sanitize members for current user
currentUserId := c.AppContext.Session().UserId
for i := range members {
members[i].SanitizeForCurrentUser(currentUserId)
}
if err := json.NewEncoder(w).Encode(members); err != nil {
c.Logger.Warn("Error while writing response", mlog.Err(err))
}
@@ -3161,7 +3167,10 @@ func getChannelMembersForUser(c *Context, w http.ResponseWriter, r *http.Request
return
}
currentUserId := c.AppContext.Session().UserId
for _, member := range members {
// Sanitize each member before encoding in the stream
member.SanitizeForCurrentUser(currentUserId)
if err := enc.Encode(member); err != nil {
c.Logger.Warn("Error while writing response", mlog.Err(err))
}