[release-10.11] MM-68547: Tighten authorization on group syncable link and patch endpoints (#36434)

Automatic Merge
Этот коммит содержится в:
Maria A Nunez
2026-05-06 02:53:51 -04:00
коммит произвёл GitHub
родитель 977c791e5b
Коммит 202d125afa
8 изменённых файлов: 1006 добавлений и 23 удалений

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

@@ -777,6 +777,7 @@ func (s *SqlGroupStore) getGroupSyncable(groupID string, syncableID string, sync
groupSyncable.DeleteAt = groupTeam.DeleteAt
groupSyncable.UpdateAt = groupTeam.UpdateAt
groupSyncable.Type = syncableType
groupSyncable.SchemeAdmin = groupTeam.SchemeAdmin
case model.GroupSyncableTypeChannel:
groupChannel := result.(*groupChannel)
groupSyncable.SyncableId = groupChannel.ChannelId
@@ -786,6 +787,7 @@ func (s *SqlGroupStore) getGroupSyncable(groupID string, syncableID string, sync
groupSyncable.DeleteAt = groupChannel.DeleteAt
groupSyncable.UpdateAt = groupChannel.UpdateAt
groupSyncable.Type = syncableType
groupSyncable.SchemeAdmin = groupChannel.SchemeAdmin
default:
return nil, fmt.Errorf("unable to convert syncableType: %s", syncableType.String())
}
@@ -1834,7 +1836,7 @@ func (s *SqlGroupStore) AdminRoleGroupsForSyncableMember(userID, syncableID stri
func (s *SqlGroupStore) PermittedSyncableAdmins(syncableID string, syncableType model.GroupSyncableType) ([]string, error) {
builder := s.getQueryBuilder().Select("UserId").
From(fmt.Sprintf("Group%ss", syncableType)).
Join(fmt.Sprintf("GroupMembers ON GroupMembers.GroupId = Group%ss.GroupId AND Group%[1]ss.SchemeAdmin = TRUE AND GroupMembers.DeleteAt = 0", syncableType.String())).Where(fmt.Sprintf("Group%[1]ss.%[1]sId = ?", syncableType.String()), syncableID)
Join(fmt.Sprintf("GroupMembers ON GroupMembers.GroupId = Group%ss.GroupId AND Group%[1]ss.SchemeAdmin = TRUE AND Group%[1]ss.DeleteAt = 0 AND GroupMembers.DeleteAt = 0", syncableType.String())).Where(fmt.Sprintf("Group%[1]ss.%[1]sId = ?", syncableType.String()), syncableID)
var userIDs []string
if err := s.GetMaster().SelectBuilder(&userIDs, builder); err != nil {

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

@@ -1616,9 +1616,19 @@ func testGetGroupSyncable(t *testing.T, rctx request.CTX, ss store.Store) {
require.Equal(t, gt1.GroupId, dgt.GroupId)
require.Equal(t, gt1.SyncableId, dgt.SyncableId)
require.Equal(t, gt1.AutoAdd, dgt.AutoAdd)
require.Equal(t, gt1.SchemeAdmin, dgt.SchemeAdmin)
require.NotZero(t, gt1.CreateAt)
require.NotZero(t, gt1.UpdateAt)
require.Zero(t, gt1.DeleteAt)
// Round-trip SchemeAdmin: true through UpdateGroupSyncable and re-fetch.
dgt.SchemeAdmin = true
_, err = ss.Group().UpdateGroupSyncable(dgt)
require.NoError(t, err)
dgt, err = ss.Group().GetGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
require.NoError(t, err)
require.True(t, dgt.SchemeAdmin, "GetGroupSyncable must populate SchemeAdmin from the persisted row")
}
func testGetGroupSyncableErrors(t *testing.T, rctx request.CTX, ss store.Store) {
@@ -4989,6 +4999,15 @@ func groupTestPermittedSyncableAdminsTeam(t *testing.T, rctx request.CTX, ss sto
// deleted group syncable no longer includes group members
_, err = ss.Group().DeleteGroupSyncable(group1.Id, team.Id, model.GroupSyncableTypeTeam)
require.NoError(t, err)
// The persisted row must still carry SchemeAdmin=true after soft-delete;
// PermittedSyncableAdmins excludes it via the DeleteAt = 0 predicate, not
// via the field having been silently cleared.
deletedSyncable, err := ss.Group().GetGroupSyncable(group1.Id, team.Id, model.GroupSyncableTypeTeam)
require.NoError(t, err)
require.True(t, deletedSyncable.SchemeAdmin)
require.NotZero(t, deletedSyncable.DeleteAt)
actualUserIDs, err = ss.Group().PermittedSyncableAdmins(team.Id, model.GroupSyncableTypeTeam)
require.NoError(t, err)
require.ElementsMatch(t, []string{user3.Id}, actualUserIDs)
@@ -5096,6 +5115,15 @@ func groupTestPermittedSyncableAdminsChannel(t *testing.T, rctx request.CTX, ss
// deleted group syncable no longer includes group members
_, err = ss.Group().DeleteGroupSyncable(group1.Id, channel.Id, model.GroupSyncableTypeChannel)
require.NoError(t, err)
// The persisted row must still carry SchemeAdmin=true after soft-delete;
// PermittedSyncableAdmins excludes it via the DeleteAt = 0 predicate, not
// via the field having been silently cleared.
deletedSyncable, err := ss.Group().GetGroupSyncable(group1.Id, channel.Id, model.GroupSyncableTypeChannel)
require.NoError(t, err)
require.True(t, deletedSyncable.SchemeAdmin)
require.NotZero(t, deletedSyncable.DeleteAt)
actualUserIDs, err = ss.Group().PermittedSyncableAdmins(channel.Id, model.GroupSyncableTypeChannel)
require.NoError(t, err)
require.ElementsMatch(t, []string{user3.Id}, actualUserIDs)