[MM-63772] Add LDAP setting to re-add removed members (#30787)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
5021fc72c6
Коммит
c2d08b7540
@@ -49,10 +49,14 @@ func syncLdap(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
type LdapSyncOptions struct {
|
||||
IncludeRemovedMembers bool `json:"include_removed_members"`
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateLdapSyncJob) {
|
||||
c.SetPermissionError(model.PermissionCreateLdapSyncJob)
|
||||
return
|
||||
}
|
||||
|
||||
var opts struct {
|
||||
IncludeRemovedMembers *bool `json:"include_removed_members"`
|
||||
}
|
||||
var opts LdapSyncOptions
|
||||
err := json.NewDecoder(r.Body).Decode(&opts)
|
||||
if err != nil {
|
||||
c.Logger.LogM(mlog.MlvlLDAPInfo, "Error decoding LDAP sync options", mlog.Err(err))
|
||||
@@ -61,11 +65,6 @@ func syncLdap(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("syncLdap", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateLdapSyncJob) {
|
||||
c.SetPermissionError(model.PermissionCreateLdapSyncJob)
|
||||
return
|
||||
}
|
||||
|
||||
c.App.SyncLdap(c.AppContext, opts.IncludeRemovedMembers)
|
||||
|
||||
auditRec.Success()
|
||||
|
||||
@@ -147,29 +147,29 @@ func TestSyncLdap(t *testing.T) {
|
||||
"StartSynchronizeJob",
|
||||
mock.AnythingOfType("*request.Context"),
|
||||
mock.AnythingOfType("bool"),
|
||||
mock.AnythingOfType("bool"),
|
||||
mock.AnythingOfType("*bool"),
|
||||
).Return(nil, nil)
|
||||
ready := make(chan bool)
|
||||
includeRemovedMembers := false
|
||||
reAddRemovedMembers := false
|
||||
mockCall.RunFn = func(args mock.Arguments) {
|
||||
includeRemovedMembers = args[2].(bool)
|
||||
reAddRemovedMembers = *args[2].(*bool)
|
||||
ready <- true
|
||||
}
|
||||
th.App.Channels().Ldap = ldapMock
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
_, err := client.SyncLdap(context.Background(), false)
|
||||
_, err := client.SyncLdap(context.Background(), model.NewPointer(false))
|
||||
<-ready
|
||||
require.NoError(t, err)
|
||||
require.False(t, includeRemovedMembers)
|
||||
require.False(t, reAddRemovedMembers)
|
||||
|
||||
_, err = client.SyncLdap(context.Background(), true)
|
||||
_, err = client.SyncLdap(context.Background(), model.NewPointer(true))
|
||||
<-ready
|
||||
require.NoError(t, err)
|
||||
require.True(t, includeRemovedMembers)
|
||||
require.True(t, reAddRemovedMembers)
|
||||
})
|
||||
|
||||
resp, err := th.Client.SyncLdap(context.Background(), false)
|
||||
resp, err := th.Client.SyncLdap(context.Background(), model.NewPointer(false))
|
||||
require.Error(t, err)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
}
|
||||
|
||||
@@ -563,10 +563,10 @@ func (a *App) DeleteGroupSyncable(groupID string, syncableID string, syncableTyp
|
||||
// based on the groups configurations. The returned list can be optionally scoped to a single given team.
|
||||
//
|
||||
// Typically since will be the last successful group sync time.
|
||||
// If includeRemovedMembers is true, then team members who left or were removed from the team will
|
||||
// If reAddRemovedMembers is true, then team members who left or were removed from the team will
|
||||
// be included; otherwise, they will be excluded.
|
||||
func (a *App) TeamMembersToAdd(since int64, teamID *string, includeRemovedMembers bool) ([]*model.UserTeamIDPair, *model.AppError) {
|
||||
userTeams, err := a.Srv().Store().Group().TeamMembersToAdd(since, teamID, includeRemovedMembers)
|
||||
func (a *App) TeamMembersToAdd(since int64, teamID *string, reAddRemovedMembers bool) ([]*model.UserTeamIDPair, *model.AppError) {
|
||||
userTeams, err := a.Srv().Store().Group().TeamMembersToAdd(since, teamID, reAddRemovedMembers)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("TeamMembersToAdd", "app.select_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
@@ -578,10 +578,10 @@ func (a *App) TeamMembersToAdd(since int64, teamID *string, includeRemovedMember
|
||||
// based on the groups configurations. The returned list can be optionally scoped to a single given channel.
|
||||
//
|
||||
// Typically since will be the last successful group sync time.
|
||||
// If includeRemovedMembers is true, then channel members who left or were removed from the channel will
|
||||
// If reAddRemovedMembers is true, then channel members who left or were removed from the channel will
|
||||
// be included; otherwise, they will be excluded.
|
||||
func (a *App) ChannelMembersToAdd(since int64, channelID *string, includeRemovedMembers bool) ([]*model.UserChannelIDPair, *model.AppError) {
|
||||
userChannels, err := a.Srv().Store().Group().ChannelMembersToAdd(since, channelID, includeRemovedMembers)
|
||||
func (a *App) ChannelMembersToAdd(since int64, channelID *string, reAddRemovedMembers bool) ([]*model.UserChannelIDPair, *model.AppError) {
|
||||
userChannels, err := a.Srv().Store().Group().ChannelMembersToAdd(since, channelID, reAddRemovedMembers)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("ChannelMembersToAdd", "app.select_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ import (
|
||||
)
|
||||
|
||||
// SyncLdap starts an LDAP sync job.
|
||||
// If includeRemovedMembers is true, then members who left or were removed from a team/channel will
|
||||
// If reAddRemovedMembers is true, then members who left or were removed from a team/channel will
|
||||
// be re-added; otherwise, they will not be re-added.
|
||||
func (a *App) SyncLdap(c request.CTX, includeRemovedMembers bool) {
|
||||
func (a *App) SyncLdap(c request.CTX, reAddRemovedMembers *bool) {
|
||||
a.Srv().Go(func() {
|
||||
if license := a.Srv().License(); license != nil && *license.Features.LDAP {
|
||||
if !*a.Config().LdapSettings.EnableSync {
|
||||
@@ -30,7 +30,7 @@ func (a *App) SyncLdap(c request.CTX, includeRemovedMembers bool) {
|
||||
c.Logger().Error("Not executing ldap sync because ldap is not available")
|
||||
return
|
||||
}
|
||||
if _, appErr := ldapI.StartSynchronizeJob(c, false, includeRemovedMembers); appErr != nil {
|
||||
if _, appErr := ldapI.StartSynchronizeJob(c, false, reAddRemovedMembers); appErr != nil {
|
||||
c.Logger().Error("Failed to start LDAP sync job")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// createDefaultChannelMemberships adds users to channels based on their group memberships and how those groups are
|
||||
// configured to sync with channels for group members on or after the given timestamp. If a channelID is given
|
||||
// only that channel's members are created. If channelID is nil all channel memberships are created.
|
||||
// If includeRemovedMembers is true, then channel members who left or were removed from the channel will
|
||||
// If params.ReAddRemovedMembers is true, then channel members who left or were removed from the channel will
|
||||
// be re-added; otherwise, they will not be re-added.
|
||||
func (a *App) createDefaultChannelMemberships(rctx request.CTX, params model.CreateDefaultMembershipParams) error {
|
||||
channelMembers, appErr := a.ChannelMembersToAdd(params.Since, params.ScopedChannelID, params.ReAddRemovedMembers)
|
||||
@@ -86,7 +86,7 @@ func (a *App) createDefaultChannelMemberships(rctx request.CTX, params model.Cre
|
||||
// createDefaultTeamMemberships adds users to teams based on their group memberships and how those groups are
|
||||
// configured to sync with teams for group members on or after the given timestamp. If a teamID is given
|
||||
// only that team's members are created. If teamID is nil all team memberships are created.
|
||||
// If includeRemovedMembers is true, then team members who left or were removed from the team will
|
||||
// If params.ReAddRemovedMembers is true, then team members who left or were removed from the team will
|
||||
// be re-added; otherwise, they will not be re-added.
|
||||
func (a *App) createDefaultTeamMemberships(rctx request.CTX, params model.CreateDefaultMembershipParams) error {
|
||||
teamMembers, appErr := a.TeamMembersToAdd(params.Since, params.ScopedTeamID, params.ReAddRemovedMembers)
|
||||
@@ -123,7 +123,7 @@ func (a *App) createDefaultTeamMemberships(rctx request.CTX, params model.Create
|
||||
|
||||
// CreateDefaultMemberships adds users to teams and channels based on their group memberships and how those groups
|
||||
// are configured to sync with teams and channels for group members on or after the given timestamp.
|
||||
// If includeRemovedMembers is true, then members who left or were removed from a team/channel will
|
||||
// If params.AddRemovedMembers is true, then members who left or were removed from a team/channel will
|
||||
// be re-added; otherwise, they will not be re-added.
|
||||
func (a *App) CreateDefaultMemberships(rctx request.CTX, params model.CreateDefaultMembershipParams) error {
|
||||
err := a.createDefaultTeamMemberships(rctx, params)
|
||||
@@ -283,17 +283,17 @@ func (a *App) SyncRolesAndMembership(rctx request.CTX, syncableID string, syncab
|
||||
}
|
||||
|
||||
var since int64
|
||||
includeRemovedMembers := true
|
||||
reAddRemovedMembers := true
|
||||
if group.Source == model.GroupSourceLdap {
|
||||
lastJob, _ := a.Srv().Store().Job().GetNewestJobByStatusAndType(model.JobStatusSuccess, model.JobTypeLdapSync)
|
||||
if lastJob != nil {
|
||||
since = lastJob.StartAt
|
||||
}
|
||||
|
||||
includeRemovedMembers = false
|
||||
reAddRemovedMembers = *a.Config().LdapSettings.ReAddRemovedMembers
|
||||
}
|
||||
|
||||
params := model.CreateDefaultMembershipParams{Since: since, ReAddRemovedMembers: includeRemovedMembers}
|
||||
params := model.CreateDefaultMembershipParams{Since: since, ReAddRemovedMembers: reAddRemovedMembers}
|
||||
|
||||
switch syncableType {
|
||||
case model.GroupSyncableTypeTeam:
|
||||
|
||||
@@ -5186,11 +5186,11 @@ func (s *RetryLayerGroupStore) ChannelMembersMinusGroupMembers(channelID string,
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) ChannelMembersToAdd(since int64, channelID *string, includeRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
func (s *RetryLayerGroupStore) ChannelMembersToAdd(since int64, channelID *string, reAddRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.GroupStore.ChannelMembersToAdd(since, channelID, includeRemovedMembers)
|
||||
result, err := s.GroupStore.ChannelMembersToAdd(since, channelID, reAddRemovedMembers)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
@@ -6152,11 +6152,11 @@ func (s *RetryLayerGroupStore) TeamMembersMinusGroupMembers(teamID string, group
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) TeamMembersToAdd(since int64, teamID *string, includeRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
func (s *RetryLayerGroupStore) TeamMembersToAdd(since int64, teamID *string, reAddRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.GroupStore.TeamMembersToAdd(since, teamID, includeRemovedMembers)
|
||||
result, err := s.GroupStore.TeamMembersToAdd(since, teamID, reAddRemovedMembers)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -963,7 +963,7 @@ func (s *SqlGroupStore) DeleteGroupSyncable(groupID string, syncableID string, s
|
||||
return groupSyncable, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) TeamMembersToAdd(since int64, teamID *string, includeRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
func (s *SqlGroupStore) TeamMembersToAdd(since int64, teamID *string, reAddRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
builder := s.getQueryBuilder().Select("GroupMembers.UserId UserID", "GroupTeams.TeamId TeamID").
|
||||
From("GroupMembers").
|
||||
Join("GroupTeams ON GroupTeams.GroupId = GroupMembers.GroupId").
|
||||
@@ -977,7 +977,7 @@ func (s *SqlGroupStore) TeamMembersToAdd(since int64, teamID *string, includeRem
|
||||
"Teams.DeleteAt": 0,
|
||||
})
|
||||
|
||||
if !includeRemovedMembers {
|
||||
if !reAddRemovedMembers {
|
||||
builder = builder.
|
||||
JoinClause("LEFT OUTER JOIN TeamMembers ON TeamMembers.TeamId = GroupTeams.TeamId AND TeamMembers.UserId = GroupMembers.UserId").
|
||||
Where(sq.Eq{"TeamMembers.UserId": nil}).
|
||||
@@ -999,7 +999,7 @@ func (s *SqlGroupStore) TeamMembersToAdd(since int64, teamID *string, includeRem
|
||||
return teamMembers, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) ChannelMembersToAdd(since int64, channelID *string, includeRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
func (s *SqlGroupStore) ChannelMembersToAdd(since int64, channelID *string, reAddRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
builder := s.getQueryBuilder().Select("GroupMembers.UserId UserID", "GroupChannels.ChannelId ChannelID").
|
||||
From("GroupMembers").
|
||||
Join("GroupChannels ON GroupChannels.GroupId = GroupMembers.GroupId").
|
||||
@@ -1013,7 +1013,7 @@ func (s *SqlGroupStore) ChannelMembersToAdd(since int64, channelID *string, incl
|
||||
"Channels.DeleteAt": 0,
|
||||
})
|
||||
|
||||
if !includeRemovedMembers {
|
||||
if !reAddRemovedMembers {
|
||||
builder = builder.
|
||||
JoinClause("LEFT OUTER JOIN ChannelMemberHistory ON ChannelMemberHistory.ChannelId = GroupChannels.ChannelId AND ChannelMemberHistory.UserId = GroupMembers.UserId").
|
||||
Where(sq.Eq{
|
||||
|
||||
@@ -915,17 +915,17 @@ type GroupStore interface {
|
||||
// based on the groups configurations. The returned list can be optionally scoped to a single given team.
|
||||
//
|
||||
// Typically since will be the last successful group sync time.
|
||||
// If includeRemovedMembers is true, then team members who left or were removed from the team will
|
||||
// If reAddRemovedMembers is true, then team members who left or were removed from the team will
|
||||
// be included; otherwise, they will be excluded.
|
||||
TeamMembersToAdd(since int64, teamID *string, includeRemovedMembers bool) ([]*model.UserTeamIDPair, error)
|
||||
TeamMembersToAdd(since int64, teamID *string, reAddRemovedMembers bool) ([]*model.UserTeamIDPair, error)
|
||||
|
||||
// ChannelMembersToAdd returns a slice of UserChannelIDPair that need newly created memberships
|
||||
// based on the groups configurations. The returned list can be optionally scoped to a single given channel.
|
||||
//
|
||||
// Typically since will be the last successful group sync time.
|
||||
// If includeRemovedMembers is true, then channel members who left or were removed from the channel will
|
||||
// If reAddRemovedMembers is true, then channel members who left or were removed from the channel will
|
||||
// be included; otherwise, they will be excluded.
|
||||
ChannelMembersToAdd(since int64, channelID *string, includeRemovedMembers bool) ([]*model.UserChannelIDPair, error)
|
||||
ChannelMembersToAdd(since int64, channelID *string, reAddRemovedMembers bool) ([]*model.UserChannelIDPair, error)
|
||||
|
||||
// TeamMembersToRemove returns all team members that should be removed based on group constraints.
|
||||
TeamMembersToRemove(teamID *string) ([]*model.TeamMember, error)
|
||||
|
||||
@@ -2087,7 +2087,7 @@ func testTeamMembersToAdd(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, teamMembers)
|
||||
|
||||
// If includeRemovedMembers is set to true, removed members should be added back in
|
||||
// If reAddRemovedMembers is set to true, removed members should be added back in
|
||||
teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, true)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, teamMembers, 1)
|
||||
@@ -2352,7 +2352,7 @@ func testChannelMembersToAdd(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, channelMembers, 1)
|
||||
|
||||
// If includeRemovedMembers is set to true, removed members should be added back in
|
||||
// If reAddRemovedMembers is set to true, removed members should be added back in
|
||||
nErr = ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, model.GetMillis())
|
||||
require.NoError(t, nErr)
|
||||
channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, true)
|
||||
|
||||
@@ -74,9 +74,9 @@ func (_m *GroupStore) ChannelMembersMinusGroupMembers(channelID string, groupIDs
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ChannelMembersToAdd provides a mock function with given fields: since, channelID, includeRemovedMembers
|
||||
func (_m *GroupStore) ChannelMembersToAdd(since int64, channelID *string, includeRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
ret := _m.Called(since, channelID, includeRemovedMembers)
|
||||
// ChannelMembersToAdd provides a mock function with given fields: since, channelID, reAddRemovedMembers
|
||||
func (_m *GroupStore) ChannelMembersToAdd(since int64, channelID *string, reAddRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
ret := _m.Called(since, channelID, reAddRemovedMembers)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ChannelMembersToAdd")
|
||||
@@ -85,10 +85,10 @@ func (_m *GroupStore) ChannelMembersToAdd(since int64, channelID *string, includ
|
||||
var r0 []*model.UserChannelIDPair
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(int64, *string, bool) ([]*model.UserChannelIDPair, error)); ok {
|
||||
return rf(since, channelID, includeRemovedMembers)
|
||||
return rf(since, channelID, reAddRemovedMembers)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(int64, *string, bool) []*model.UserChannelIDPair); ok {
|
||||
r0 = rf(since, channelID, includeRemovedMembers)
|
||||
r0 = rf(since, channelID, reAddRemovedMembers)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.UserChannelIDPair)
|
||||
@@ -96,7 +96,7 @@ func (_m *GroupStore) ChannelMembersToAdd(since int64, channelID *string, includ
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(int64, *string, bool) error); ok {
|
||||
r1 = rf(since, channelID, includeRemovedMembers)
|
||||
r1 = rf(since, channelID, reAddRemovedMembers)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -1414,9 +1414,9 @@ func (_m *GroupStore) TeamMembersMinusGroupMembers(teamID string, groupIDs []str
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// TeamMembersToAdd provides a mock function with given fields: since, teamID, includeRemovedMembers
|
||||
func (_m *GroupStore) TeamMembersToAdd(since int64, teamID *string, includeRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
ret := _m.Called(since, teamID, includeRemovedMembers)
|
||||
// TeamMembersToAdd provides a mock function with given fields: since, teamID, reAddRemovedMembers
|
||||
func (_m *GroupStore) TeamMembersToAdd(since int64, teamID *string, reAddRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
ret := _m.Called(since, teamID, reAddRemovedMembers)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for TeamMembersToAdd")
|
||||
@@ -1425,10 +1425,10 @@ func (_m *GroupStore) TeamMembersToAdd(since int64, teamID *string, includeRemov
|
||||
var r0 []*model.UserTeamIDPair
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(int64, *string, bool) ([]*model.UserTeamIDPair, error)); ok {
|
||||
return rf(since, teamID, includeRemovedMembers)
|
||||
return rf(since, teamID, reAddRemovedMembers)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(int64, *string, bool) []*model.UserTeamIDPair); ok {
|
||||
r0 = rf(since, teamID, includeRemovedMembers)
|
||||
r0 = rf(since, teamID, reAddRemovedMembers)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.UserTeamIDPair)
|
||||
@@ -1436,7 +1436,7 @@ func (_m *GroupStore) TeamMembersToAdd(since int64, teamID *string, includeRemov
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(int64, *string, bool) error); ok {
|
||||
r1 = rf(since, teamID, includeRemovedMembers)
|
||||
r1 = rf(since, teamID, reAddRemovedMembers)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -4199,10 +4199,10 @@ func (s *TimerLayerGroupStore) ChannelMembersMinusGroupMembers(channelID string,
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) ChannelMembersToAdd(since int64, channelID *string, includeRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
func (s *TimerLayerGroupStore) ChannelMembersToAdd(since int64, channelID *string, reAddRemovedMembers bool) ([]*model.UserChannelIDPair, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.GroupStore.ChannelMembersToAdd(since, channelID, includeRemovedMembers)
|
||||
result, err := s.GroupStore.ChannelMembersToAdd(since, channelID, reAddRemovedMembers)
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -4935,10 +4935,10 @@ func (s *TimerLayerGroupStore) TeamMembersMinusGroupMembers(teamID string, group
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) TeamMembersToAdd(since int64, teamID *string, includeRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
func (s *TimerLayerGroupStore) TeamMembersToAdd(since int64, teamID *string, reAddRemovedMembers bool) ([]*model.UserTeamIDPair, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.GroupStore.TeamMembersToAdd(since, teamID, includeRemovedMembers)
|
||||
result, err := s.GroupStore.TeamMembersToAdd(since, teamID, reAddRemovedMembers)
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
|
||||
Ссылка в новой задаче
Block a user