MM-39918: mmctl: list archived private channels in channel list command with system admin user (#28676)

Этот коммит содержится в:
Nicolas Le Cam
2024-11-07 12:07:30 +01:00
коммит произвёл GitHub
родитель 7846ac86b4
Коммит 5ebdea506f
12 изменённых файлов: 95 добавлений и 61 удалений

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

@@ -1425,7 +1425,7 @@ func (s *OpenTracingLayerChannelStore) GetChannelsWithUnreadsAndWithMentions(ctx
return result, resultVar1, resultVar2, err
}
func (s *OpenTracingLayerChannelStore) GetDeleted(teamID string, offset int, limit int, userID string) (model.ChannelList, error) {
func (s *OpenTracingLayerChannelStore) GetDeleted(teamID string, offset int, limit int, userID string, skipTeamMembershipCheck bool) (model.ChannelList, error) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.GetDeleted")
s.Root.Store.SetContext(newCtx)
@@ -1434,7 +1434,7 @@ func (s *OpenTracingLayerChannelStore) GetDeleted(teamID string, offset int, lim
}()
defer span.Finish()
result, err := s.ChannelStore.GetDeleted(teamID, offset, limit, userID)
result, err := s.ChannelStore.GetDeleted(teamID, offset, limit, userID, skipTeamMembershipCheck)
if err != nil {
span.LogFields(spanlog.Error(err))
ext.Error.Set(span, true)

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

@@ -1584,11 +1584,11 @@ func (s *RetryLayerChannelStore) GetChannelsWithUnreadsAndWithMentions(ctx conte
}
func (s *RetryLayerChannelStore) GetDeleted(teamID string, offset int, limit int, userID string) (model.ChannelList, error) {
func (s *RetryLayerChannelStore) GetDeleted(teamID string, offset int, limit int, userID string, skipTeamMembershipCheck bool) (model.ChannelList, error) {
tries := 0
for {
result, err := s.ChannelStore.GetDeleted(teamID, offset, limit, userID)
result, err := s.ChannelStore.GetDeleted(teamID, offset, limit, userID, skipTeamMembershipCheck)
if err == nil {
return result, nil
}

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

@@ -1490,24 +1490,37 @@ func (s SqlChannelStore) GetDeletedByName(teamId string, name string) (*model.Ch
return &channel, nil
}
func (s SqlChannelStore) GetDeleted(teamId string, offset int, limit int, userId string) (model.ChannelList, error) {
func (s SqlChannelStore) GetDeleted(teamId string, offset int, limit int, userId string, skipTeamMembershipCheck bool) (model.ChannelList, error) {
channels := model.ChannelList{}
query := `
SELECT * FROM Channels
WHERE (TeamId = ? OR TeamId = '')
AND DeleteAt != 0
AND Type != ?
UNION
SELECT * FROM Channels
WHERE (TeamId = ? OR TeamId = '')
AND DeleteAt != 0
AND Type = ?
AND Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = ?)
ORDER BY DisplayName LIMIT ? OFFSET ?
`
builder := s.getQueryBuilder().
Select("*").
From("Channels").
Where(sq.Or{
sq.Eq{"TeamId": teamId},
sq.Eq{"TeamId": ""},
}).
Where(sq.NotEq{"DeleteAt": 0}).
OrderBy("DisplayName").
Limit(uint64(limit)).
Offset(uint64(offset))
if err := s.GetReplicaX().Select(&channels, query, teamId, model.ChannelTypePrivate, teamId, model.ChannelTypePrivate, userId, limit, offset); err != nil {
if !skipTeamMembershipCheck {
builder = builder.Where(sq.Or{
sq.NotEq{"Type": model.ChannelTypePrivate},
sq.And{
sq.Eq{"Type": model.ChannelTypePrivate},
sq.Expr("Id IN (?)", sq.Select("ChannelId").From("ChannelMembers").Where(sq.Eq{"UserId": userId})),
},
})
}
query, args, err := builder.ToSql()
if err != nil {
return nil, errors.Wrapf(err, "GetDeleted_ToSql")
}
if err := s.GetReplicaX().Select(&channels, query, args...); err != nil {
if err == sql.ErrNoRows {
return nil, store.NewErrNotFound("Channel", fmt.Sprintf("TeamId=%s,UserId=%s", teamId, userId))
}

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

@@ -203,7 +203,7 @@ type ChannelStore interface {
GetByNameIncludeDeleted(teamID string, name string, allowFromCache bool) (*model.Channel, error)
GetByNamesIncludeDeleted(teamID string, names []string, allowFromCache bool) ([]*model.Channel, error)
GetDeletedByName(teamID string, name string) (*model.Channel, error)
GetDeleted(teamID string, offset int, limit int, userID string) (model.ChannelList, error)
GetDeleted(teamID string, offset int, limit int, userID string, skipTeamMembershipCheck bool) (model.ChannelList, error)
GetChannels(teamID, userID string, opts *model.ChannelSearchOpts) (model.ChannelList, error)
GetChannelsByUser(userID string, includeDeleted bool, lastDeleteAt, pageSize int, fromChannelID string) (model.ChannelList, error)
GetAllChannelMemberIdsByChannelId(id string) ([]string, error)

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

@@ -992,60 +992,79 @@ func testChannelStoreGetDeletedByName(t *testing.T, rctx request.CTX, ss store.S
}
func testChannelStoreGetDeleted(t *testing.T, rctx request.CTX, ss store.Store) {
o1 := model.Channel{}
o1.TeamId = model.NewId()
o1.DisplayName = "Channel1"
o1.Name = NewTestID()
o1.Type = model.ChannelTypeOpen
userID := model.NewId()
teamID := model.NewId()
o1 := model.Channel{
TeamId: teamID,
DisplayName: "Channel1",
Name: NewTestID(),
Type: model.ChannelTypeOpen,
}
_, nErr := ss.Channel().Save(rctx, &o1, -1)
require.NoError(t, nErr)
err := ss.Channel().Delete(o1.Id, model.GetMillis())
require.NoError(t, err, "channel should have been deleted")
list, nErr := ss.Channel().GetDeleted(o1.TeamId, 0, 100, userID)
userID := model.NewId()
list, nErr := ss.Channel().GetDeleted(teamID, 0, 100, userID, false)
require.NoError(t, nErr, nErr)
require.Len(t, list, 1, "wrong list")
require.Equal(t, o1.Name, list[0].Name, "missing channel")
o2 := model.Channel{}
o2.TeamId = o1.TeamId
o2.DisplayName = "Channel2"
o2.Name = NewTestID()
o2.Type = model.ChannelTypeOpen
o2 := model.Channel{
TeamId: teamID,
DisplayName: "Channel2",
Name: NewTestID(),
Type: model.ChannelTypeOpen,
}
_, nErr = ss.Channel().Save(rctx, &o2, -1)
require.NoError(t, nErr)
list, nErr = ss.Channel().GetDeleted(o1.TeamId, 0, 100, userID)
list, nErr = ss.Channel().GetDeleted(teamID, 0, 100, userID, false)
require.NoError(t, nErr, nErr)
require.Len(t, list, 1, "wrong list")
o3 := model.Channel{}
o3.TeamId = o1.TeamId
o3.DisplayName = "Channel3"
o3.Name = NewTestID()
o3.Type = model.ChannelTypeOpen
o3 := model.Channel{
TeamId: teamID,
DisplayName: "Channel3",
Name: NewTestID(),
Type: model.ChannelTypeOpen,
}
_, nErr = ss.Channel().Save(rctx, &o3, -1)
require.NoError(t, nErr)
o4 := model.Channel{
TeamId: teamID,
DisplayName: "Channel4",
Name: NewTestID(),
Type: model.ChannelTypePrivate,
}
_, nErr = ss.Channel().Save(rctx, &o4, -1)
require.NoError(t, nErr)
err = ss.Channel().Delete(o4.Id, model.GetMillis())
require.NoError(t, err, "channel should have been deleted")
err = ss.Channel().Delete(o3.Id, model.GetMillis())
require.NoError(t, err, "channel should have been deleted")
list, nErr = ss.Channel().GetDeleted(o1.TeamId, 0, 100, userID)
list, nErr = ss.Channel().GetDeleted(teamID, 0, 100, userID, false)
require.NoError(t, nErr, nErr)
require.Len(t, list, 2, "wrong list length")
list, nErr = ss.Channel().GetDeleted(o1.TeamId, 0, 1, userID)
list, nErr = ss.Channel().GetDeleted(teamID, 0, 1, userID, false)
require.NoError(t, nErr, nErr)
require.Len(t, list, 1, "wrong list length")
list, nErr = ss.Channel().GetDeleted(o1.TeamId, 1, 1, userID)
list, nErr = ss.Channel().GetDeleted(teamID, 1, 1, userID, false)
require.NoError(t, nErr, nErr)
require.Len(t, list, 1, "wrong list length")
list, nErr = ss.Channel().GetDeleted(teamID, 0, 100, userID, true)
require.NoError(t, nErr, nErr)
require.Len(t, list, 3, "wrong list length")
}
func testChannelMemberStore(t *testing.T, rctx request.CTX, ss store.Store) {

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

@@ -1210,9 +1210,9 @@ func (_m *ChannelStore) GetChannelsWithUnreadsAndWithMentions(ctx context.Contex
return r0, r1, r2, r3
}
// GetDeleted provides a mock function with given fields: teamID, offset, limit, userID
func (_m *ChannelStore) GetDeleted(teamID string, offset int, limit int, userID string) (model.ChannelList, error) {
ret := _m.Called(teamID, offset, limit, userID)
// GetDeleted provides a mock function with given fields: teamID, offset, limit, userID, skipTeamMembershipCheck
func (_m *ChannelStore) GetDeleted(teamID string, offset int, limit int, userID string, skipTeamMembershipCheck bool) (model.ChannelList, error) {
ret := _m.Called(teamID, offset, limit, userID, skipTeamMembershipCheck)
if len(ret) == 0 {
panic("no return value specified for GetDeleted")
@@ -1220,19 +1220,19 @@ func (_m *ChannelStore) GetDeleted(teamID string, offset int, limit int, userID
var r0 model.ChannelList
var r1 error
if rf, ok := ret.Get(0).(func(string, int, int, string) (model.ChannelList, error)); ok {
return rf(teamID, offset, limit, userID)
if rf, ok := ret.Get(0).(func(string, int, int, string, bool) (model.ChannelList, error)); ok {
return rf(teamID, offset, limit, userID, skipTeamMembershipCheck)
}
if rf, ok := ret.Get(0).(func(string, int, int, string) model.ChannelList); ok {
r0 = rf(teamID, offset, limit, userID)
if rf, ok := ret.Get(0).(func(string, int, int, string, bool) model.ChannelList); ok {
r0 = rf(teamID, offset, limit, userID, skipTeamMembershipCheck)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(model.ChannelList)
}
}
if rf, ok := ret.Get(1).(func(string, int, int, string) error); ok {
r1 = rf(teamID, offset, limit, userID)
if rf, ok := ret.Get(1).(func(string, int, int, string, bool) error); ok {
r1 = rf(teamID, offset, limit, userID, skipTeamMembershipCheck)
} else {
r1 = ret.Error(1)
}

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

@@ -1327,10 +1327,10 @@ func (s *TimerLayerChannelStore) GetChannelsWithUnreadsAndWithMentions(ctx conte
return result, resultVar1, resultVar2, err
}
func (s *TimerLayerChannelStore) GetDeleted(teamID string, offset int, limit int, userID string) (model.ChannelList, error) {
func (s *TimerLayerChannelStore) GetDeleted(teamID string, offset int, limit int, userID string, skipTeamMembershipCheck bool) (model.ChannelList, error) {
start := time.Now()
result, err := s.ChannelStore.GetDeleted(teamID, offset, limit, userID)
result, err := s.ChannelStore.GetDeleted(teamID, offset, limit, userID, skipTeamMembershipCheck)
elapsed := float64(time.Since(start)) / float64(time.Second)
if s.Root.Metrics != nil {