[MM-42421] Prevent guests from seeing users through groups API (#21151)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c5f4882f0a
Коммит
a648ced221
@@ -4152,7 +4152,7 @@ func (s *OpenTracingLayerGroupStore) GetGroupSyncable(groupID string, syncableID
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerGroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts) ([]*model.Group, error) {
|
||||
func (s *OpenTracingLayerGroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts, viewRestrictions *model.ViewUsersRestrictions) ([]*model.Group, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GetGroups")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -4161,7 +4161,7 @@ func (s *OpenTracingLayerGroupStore) GetGroups(page int, perPage int, opts model
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.GroupStore.GetGroups(page, perPage, opts)
|
||||
result, err := s.GroupStore.GetGroups(page, perPage, opts, viewRestrictions)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
@@ -4260,6 +4260,24 @@ func (s *OpenTracingLayerGroupStore) GetMemberCount(groupID string) (int64, erro
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerGroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GetMemberCountWithRestrictions")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.GroupStore.GetMemberCountWithRestrictions(groupID, viewRestrictions)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerGroupStore) GetMemberUsers(groupID string) ([]*model.User, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GetMemberUsers")
|
||||
@@ -4314,7 +4332,7 @@ func (s *OpenTracingLayerGroupStore) GetMemberUsersNotInChannel(groupID string,
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerGroupStore) GetMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *OpenTracingLayerGroupStore) GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GetMemberUsersPage")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -4323,7 +4341,7 @@ func (s *OpenTracingLayerGroupStore) GetMemberUsersPage(groupID string, page int
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.GroupStore.GetMemberUsersPage(groupID, page, perPage)
|
||||
result, err := s.GroupStore.GetMemberUsersPage(groupID, page, perPage, viewRestrictions)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
@@ -4332,7 +4350,7 @@ func (s *OpenTracingLayerGroupStore) GetMemberUsersPage(groupID string, page int
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *OpenTracingLayerGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GetNonMemberUsersPage")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -4341,7 +4359,7 @@ func (s *OpenTracingLayerGroupStore) GetNonMemberUsersPage(groupID string, page
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.GroupStore.GetNonMemberUsersPage(groupID, page, perPage)
|
||||
result, err := s.GroupStore.GetNonMemberUsersPage(groupID, page, perPage, viewRestrictions)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
|
||||
@@ -4677,11 +4677,11 @@ func (s *RetryLayerGroupStore) GetGroupSyncable(groupID string, syncableID strin
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts) ([]*model.Group, error) {
|
||||
func (s *RetryLayerGroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts, viewRestrictions *model.ViewUsersRestrictions) ([]*model.Group, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.GroupStore.GetGroups(page, perPage, opts)
|
||||
result, err := s.GroupStore.GetGroups(page, perPage, opts, viewRestrictions)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
@@ -4803,6 +4803,27 @@ func (s *RetryLayerGroupStore) GetMemberCount(groupID string) (int64, error) {
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.GroupStore.GetMemberCountWithRestrictions(groupID, viewRestrictions)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
timepkg.Sleep(100 * timepkg.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) GetMemberUsers(groupID string) ([]*model.User, error) {
|
||||
|
||||
tries := 0
|
||||
@@ -4866,11 +4887,11 @@ func (s *RetryLayerGroupStore) GetMemberUsersNotInChannel(groupID string, channe
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) GetMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *RetryLayerGroupStore) GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.GroupStore.GetMemberUsersPage(groupID, page, perPage)
|
||||
result, err := s.GroupStore.GetMemberUsersPage(groupID, page, perPage, viewRestrictions)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
@@ -4887,11 +4908,11 @@ func (s *RetryLayerGroupStore) GetMemberUsersPage(groupID string, page int, perP
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *RetryLayerGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.GroupStore.GetNonMemberUsersPage(groupID, page, perPage)
|
||||
result, err := s.GroupStore.GetNonMemberUsersPage(groupID, page, perPage, viewRestrictions)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -401,58 +401,59 @@ func (s *SqlGroupStore) GetMemberUsers(groupID string) ([]*model.User, error) {
|
||||
return groupMembers, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *SqlGroupStore) GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
groupMembers := []*model.User{}
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
Users.*
|
||||
FROM
|
||||
GroupMembers
|
||||
JOIN Users ON Users.Id = GroupMembers.UserId
|
||||
WHERE
|
||||
GroupMembers.DeleteAt = 0
|
||||
AND Users.DeleteAt = 0
|
||||
AND GroupId = ?
|
||||
ORDER BY
|
||||
GroupMembers.CreateAt DESC
|
||||
LIMIT
|
||||
?
|
||||
OFFSET
|
||||
?`
|
||||
query := s.getQueryBuilder().
|
||||
Select("u.*").
|
||||
From("GroupMembers").
|
||||
Join("Users u ON u.Id = GroupMembers.UserId").
|
||||
Where(sq.Eq{"GroupMembers.DeleteAt": 0}).
|
||||
Where(sq.Eq{"u.DeleteAt": 0}).
|
||||
Where(sq.Eq{"GroupId": groupID}).
|
||||
Limit(uint64(perPage)).
|
||||
Offset(uint64(page * perPage)).
|
||||
OrderBy("u.CreateAt DESC")
|
||||
|
||||
if err := s.GetReplicaX().Select(&groupMembers, query, groupID, perPage, page*perPage); err != nil {
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
if err := s.GetReplicaX().Select(&groupMembers, queryString, args...); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to find member Users for Group with id=%s", groupID)
|
||||
}
|
||||
|
||||
return groupMembers, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *SqlGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
groupMembers := []*model.User{}
|
||||
|
||||
if err := s.GetReplicaX().Get(&model.Group{}, "SELECT * FROM UserGroups WHERE Id = ?", groupID); err != nil {
|
||||
return nil, errors.Wrap(err, "GetNonMemberUsersPage")
|
||||
}
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
Users.*
|
||||
FROM
|
||||
Users
|
||||
LEFT JOIN
|
||||
GroupMembers ON (GroupMembers.UserId = Users.Id AND GroupMembers.GroupId = ?)
|
||||
WHERE
|
||||
Users.DeleteAt = 0
|
||||
AND ( GroupMembers.UserId IS NULL OR GroupMembers.DeleteAt != 0)
|
||||
ORDER BY
|
||||
GroupMembers.CreateAt DESC
|
||||
LIMIT
|
||||
?
|
||||
OFFSET
|
||||
?`
|
||||
query := s.getQueryBuilder().
|
||||
Select("u.*").
|
||||
From("Users u").
|
||||
LeftJoin("GroupMembers ON (GroupMembers.UserId = u.Id AND GroupMembers.GroupId = ?)", groupID).
|
||||
Where(sq.Eq{"u.DeleteAt": 0}).
|
||||
Where("(GroupMembers.UserID IS NULL OR GroupMembers.DeleteAt != 0)").
|
||||
Limit(uint64(perPage)).
|
||||
Offset(uint64(page * perPage)).
|
||||
OrderBy("u.CreateAt DESC")
|
||||
|
||||
if err := s.GetReplicaX().Select(&groupMembers, query, groupID, perPage, page*perPage); err != nil {
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
if err := s.GetReplicaX().Select(&groupMembers, queryString, args...); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to find member Users for Group with id=%s", groupID)
|
||||
}
|
||||
|
||||
@@ -460,19 +461,27 @@ func (s *SqlGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetMemberCount(groupID string) (int64, error) {
|
||||
query := `
|
||||
SELECT
|
||||
count(*)
|
||||
FROM
|
||||
GroupMembers
|
||||
JOIN Users ON Users.Id = GroupMembers.UserId
|
||||
WHERE
|
||||
GroupMembers.GroupId = ?
|
||||
AND Users.DeleteAt = 0
|
||||
AND GroupMembers.DeleteAt = 0`
|
||||
return s.GetMemberCountWithRestrictions(groupID, nil)
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("COUNT(DISTINCT u.Id)").
|
||||
From("GroupMembers").
|
||||
Join("Users u ON u.Id = GroupMembers.UserId").
|
||||
Where(sq.Eq{"GroupMembers.GroupId": groupID}).
|
||||
Where(sq.Eq{"u.DeleteAt": 0}).
|
||||
Where(sq.Eq{"GroupMembers.DeleteAt": 0})
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, false)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return int64(0), errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
var count int64
|
||||
err := s.GetReplicaX().Get(&count, query, groupID)
|
||||
err = s.GetReplicaX().Get(&count, queryString, args...)
|
||||
if err != nil {
|
||||
return int64(0), errors.Wrapf(err, "failed to count member Users for Group with id=%s", groupID)
|
||||
}
|
||||
@@ -1385,15 +1394,30 @@ func (s *SqlGroupStore) GetGroupsAssociatedToChannelsByTeam(teamId string, opts
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetGroups(page, perPage int, opts model.GroupSearchOpts) ([]*model.Group, error) {
|
||||
func (s *SqlGroupStore) GetGroups(page, perPage int, opts model.GroupSearchOpts, viewRestrictions *model.ViewUsersRestrictions) ([]*model.Group, error) {
|
||||
groupsVar := groups{}
|
||||
|
||||
groupsQuery := s.getQueryBuilder().Select("g.*")
|
||||
|
||||
if opts.IncludeMemberCount {
|
||||
countQuery := s.getQueryBuilder().
|
||||
Select("GroupMembers.GroupId, COUNT(DISTINCT u.Id) AS MemberCount").
|
||||
From("GroupMembers").
|
||||
LeftJoin("Users u ON u.Id = GroupMembers.UserId").
|
||||
Where(sq.Eq{"GroupMembers.DeleteAt": 0}).
|
||||
Where(sq.Eq{"u.DeleteAt": 0}).
|
||||
GroupBy("GroupId")
|
||||
|
||||
countQuery = applyViewRestrictionsFilter(countQuery, viewRestrictions, false)
|
||||
|
||||
countString, params, err := countQuery.PlaceholderFormat(sq.Question).ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get_groups_tosql")
|
||||
}
|
||||
|
||||
groupsQuery = s.getQueryBuilder().
|
||||
Select("g.*, coalesce(Members.MemberCount, 0) AS MemberCount").
|
||||
LeftJoin("(SELECT GroupMembers.GroupId, COUNT(*) AS MemberCount FROM GroupMembers LEFT JOIN Users ON Users.Id = GroupMembers.UserId WHERE GroupMembers.DeleteAt = 0 AND Users.DeleteAt = 0 GROUP BY GroupId) AS Members ON Members.GroupId = g.Id")
|
||||
LeftJoin("("+countString+") AS Members ON Members.GroupId = g.Id", params...)
|
||||
}
|
||||
|
||||
if opts.FilterHasMember != "" {
|
||||
|
||||
@@ -833,10 +833,11 @@ type GroupStore interface {
|
||||
Delete(groupID string) (*model.Group, error)
|
||||
|
||||
GetMemberUsers(groupID string) ([]*model.User, error)
|
||||
GetMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error)
|
||||
GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error)
|
||||
GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error)
|
||||
GetMemberCount(groupID string) (int64, error)
|
||||
|
||||
GetNonMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error)
|
||||
GetNonMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error)
|
||||
|
||||
GetMemberUsersInTeam(groupID string, teamID string) ([]*model.User, error)
|
||||
GetMemberUsersNotInChannel(groupID string, channelID string) ([]*model.User, error)
|
||||
@@ -880,7 +881,7 @@ type GroupStore interface {
|
||||
GetGroupsAssociatedToChannelsByTeam(teamID string, opts model.GroupSearchOpts) (map[string][]*model.GroupWithSchemeAdmin, error)
|
||||
CountGroupsByTeam(teamID string, opts model.GroupSearchOpts) (int64, error)
|
||||
|
||||
GetGroups(page, perPage int, opts model.GroupSearchOpts) ([]*model.Group, error)
|
||||
GetGroups(page, perPage int, opts model.GroupSearchOpts, viewRestrictions *model.ViewUsersRestrictions) ([]*model.Group, error)
|
||||
|
||||
TeamMembersMinusGroupMembers(teamID string, groupIDs []string, page, perPage int) ([]*model.UserWithGroups, error)
|
||||
CountTeamMembersMinusGroupMembers(teamID string, groupIDs []string) (int64, error)
|
||||
|
||||
@@ -836,25 +836,25 @@ func testGroupGetMemberUsersPage(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check returns members
|
||||
groupMembers, err := ss.Group().GetMemberUsersPage(group.Id, 0, 100)
|
||||
groupMembers, err := ss.Group().GetMemberUsersPage(group.Id, 0, 100, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(groupMembers))
|
||||
|
||||
// Check page 1
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 0, 2)
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 0, 2, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(groupMembers))
|
||||
require.Equal(t, user3.Id, groupMembers[0].Id)
|
||||
require.Equal(t, user2.Id, groupMembers[1].Id)
|
||||
|
||||
// Check page 2
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 1, 2)
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 1, 2, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(groupMembers))
|
||||
require.Equal(t, user1.Id, groupMembers[0].Id)
|
||||
|
||||
// Check madeup id
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(model.NewId(), 0, 100)
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(model.NewId(), 0, 100, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(groupMembers))
|
||||
|
||||
@@ -863,7 +863,7 @@ func testGroupGetMemberUsersPage(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should not return deleted members
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 0, 100)
|
||||
groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 0, 100, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(groupMembers))
|
||||
}
|
||||
@@ -3476,6 +3476,13 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
user2, err := ss.User().Save(u2)
|
||||
require.NoError(t, err)
|
||||
|
||||
u3 := &model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewId(),
|
||||
}
|
||||
user3, err := ss.User().Save(u3)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -3485,9 +3492,20 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
_, err = ss.Group().UpsertMember(group2.Id, user2.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = ss.Group().UpsertMember(group2.Id, user3.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = ss.Group().UpsertMember(deletedGroup.Id, user1.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
m1 := model.ChannelMember{
|
||||
ChannelId: channel1.Id,
|
||||
UserId: user1.Id,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, err = ss.Channel().SaveMember(&m1)
|
||||
require.NoError(t, err)
|
||||
|
||||
user2.DeleteAt = 1
|
||||
u2Update, _ := ss.User().Update(user2, true)
|
||||
|
||||
@@ -3519,39 +3537,44 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, nErr)
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Page int
|
||||
PerPage int
|
||||
Opts model.GroupSearchOpts
|
||||
Resultf func([]*model.Group) bool
|
||||
Name string
|
||||
Page int
|
||||
PerPage int
|
||||
Opts model.GroupSearchOpts
|
||||
Resultf func([]*model.Group) bool
|
||||
Restrictions *model.ViewUsersRestrictions
|
||||
}{
|
||||
{
|
||||
Name: "Get all the Groups",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 0,
|
||||
PerPage: 3,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 3 },
|
||||
Name: "Get all the Groups",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 0,
|
||||
PerPage: 3,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 3 },
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Get first Group with page 0 with 1 element",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 0,
|
||||
PerPage: 1,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
|
||||
Name: "Get first Group with page 0 with 1 element",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 0,
|
||||
PerPage: 1,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Get single result from page 1",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 1,
|
||||
PerPage: 1,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
|
||||
Name: "Get single result from page 1",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 1,
|
||||
PerPage: 1,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Get multiple results from page 1",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 1,
|
||||
PerPage: 2,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 2 },
|
||||
Name: "Get multiple results from page 1",
|
||||
Opts: model.GroupSearchOpts{},
|
||||
Page: 1,
|
||||
PerPage: 2,
|
||||
Resultf: func(groups []*model.Group) bool { return len(groups) == 2 },
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Get group matching name",
|
||||
@@ -3566,6 +3589,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Get group matching display name",
|
||||
@@ -3580,6 +3604,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Get group matching multiple display names",
|
||||
@@ -3594,6 +3619,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Include member counts",
|
||||
@@ -3605,7 +3631,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
if g.MemberCount == nil {
|
||||
return false
|
||||
}
|
||||
if g.Id == group1.Id && *g.MemberCount != 1 {
|
||||
if (g.Id == group1.Id || g.Id == group2.Id) && *g.MemberCount != 1 {
|
||||
return false
|
||||
}
|
||||
if g.DeleteAt != 0 {
|
||||
@@ -3614,6 +3640,31 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Include member counts with restrictions",
|
||||
Opts: model.GroupSearchOpts{IncludeMemberCount: true},
|
||||
Page: 0,
|
||||
PerPage: 100,
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
for _, g := range groups {
|
||||
if g.MemberCount == nil {
|
||||
return false
|
||||
}
|
||||
if g.Id == group1.Id && *g.MemberCount != 1 {
|
||||
return false
|
||||
}
|
||||
if g.Id == group2.Id && *g.MemberCount != 0 {
|
||||
return false
|
||||
}
|
||||
if g.DeleteAt != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: &model.ViewUsersRestrictions{Channels: []string{channel1.Id}},
|
||||
},
|
||||
{
|
||||
Name: "Not associated to team",
|
||||
@@ -3634,6 +3685,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Not associated to other team",
|
||||
@@ -3654,6 +3706,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Include allow reference",
|
||||
@@ -3674,6 +3727,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Use Since return all",
|
||||
@@ -3691,6 +3745,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
}
|
||||
return true
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Use Since return none",
|
||||
@@ -3700,6 +3755,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return len(groups) == 0
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Filter groups from group-constrained teams",
|
||||
@@ -3709,6 +3765,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return len(groups) == 2 && groups[0].Id == group1.Id && groups[1].Id == group2.Id
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Filter groups from group-constrained page 0",
|
||||
@@ -3718,6 +3775,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return groups[0].Id == group1.Id
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Filter groups from group-constrained page 1",
|
||||
@@ -3727,6 +3785,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return groups[0].Id == group2.Id
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Non-group constrained team with no associated groups still returns groups for the child channel",
|
||||
@@ -3736,6 +3795,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return len(groups) > 0
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Filter by group member",
|
||||
@@ -3745,6 +3805,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return len(groups) == 1 && groups[0].Id == group1.Id
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Filter by non-existent group member",
|
||||
@@ -3754,6 +3815,7 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return len(groups) == 0
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
{
|
||||
Name: "Filter by non-member member",
|
||||
@@ -3763,12 +3825,13 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
||||
Resultf: func(groups []*model.Group) bool {
|
||||
return len(groups) == 2
|
||||
},
|
||||
Restrictions: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
groups, err := ss.Group().GetGroups(tc.Page, tc.PerPage, tc.Opts)
|
||||
groups, err := ss.Group().GetGroups(tc.Page, tc.PerPage, tc.Opts, tc.Restrictions)
|
||||
require.NoError(t, err)
|
||||
require.True(t, tc.Resultf(groups))
|
||||
})
|
||||
@@ -5048,7 +5111,7 @@ func groupTestGetNonMemberUsersPage(t *testing.T, ss store.Store) {
|
||||
_, nErr = ss.User().Save(u2)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
users, err := ss.Group().GetNonMemberUsersPage(group.Id, 0, 1000)
|
||||
users, err := ss.Group().GetNonMemberUsersPage(group.Id, 0, 1000, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
originalLen := len(users)
|
||||
@@ -5056,11 +5119,11 @@ func groupTestGetNonMemberUsersPage(t *testing.T, ss store.Store) {
|
||||
_, err = ss.Group().UpsertMember(group.Id, user1.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
users, err = ss.Group().GetNonMemberUsersPage(group.Id, 0, 1000)
|
||||
users, err = ss.Group().GetNonMemberUsersPage(group.Id, 0, 1000, nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, users, originalLen-1)
|
||||
|
||||
users, err = ss.Group().GetNonMemberUsersPage(model.NewId(), 0, 1000)
|
||||
users, err = ss.Group().GetNonMemberUsersPage(model.NewId(), 0, 1000, nil)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, users)
|
||||
}
|
||||
|
||||
@@ -577,13 +577,13 @@ func (_m *GroupStore) GetGroupSyncable(groupID string, syncableID string, syncab
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetGroups provides a mock function with given fields: page, perPage, opts
|
||||
func (_m *GroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts) ([]*model.Group, error) {
|
||||
ret := _m.Called(page, perPage, opts)
|
||||
// GetGroups provides a mock function with given fields: page, perPage, opts, viewRestrictions
|
||||
func (_m *GroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts, viewRestrictions *model.ViewUsersRestrictions) ([]*model.Group, error) {
|
||||
ret := _m.Called(page, perPage, opts, viewRestrictions)
|
||||
|
||||
var r0 []*model.Group
|
||||
if rf, ok := ret.Get(0).(func(int, int, model.GroupSearchOpts) []*model.Group); ok {
|
||||
r0 = rf(page, perPage, opts)
|
||||
if rf, ok := ret.Get(0).(func(int, int, model.GroupSearchOpts, *model.ViewUsersRestrictions) []*model.Group); ok {
|
||||
r0 = rf(page, perPage, opts, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Group)
|
||||
@@ -591,8 +591,8 @@ func (_m *GroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpt
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(int, int, model.GroupSearchOpts) error); ok {
|
||||
r1 = rf(page, perPage, opts)
|
||||
if rf, ok := ret.Get(1).(func(int, int, model.GroupSearchOpts, *model.ViewUsersRestrictions) error); ok {
|
||||
r1 = rf(page, perPage, opts, viewRestrictions)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -713,6 +713,27 @@ func (_m *GroupStore) GetMemberCount(groupID string) (int64, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMemberCountWithRestrictions provides a mock function with given fields: groupID, viewRestrictions
|
||||
func (_m *GroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) {
|
||||
ret := _m.Called(groupID, viewRestrictions)
|
||||
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func(string, *model.ViewUsersRestrictions) int64); ok {
|
||||
r0 = rf(groupID, viewRestrictions)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, *model.ViewUsersRestrictions) error); ok {
|
||||
r1 = rf(groupID, viewRestrictions)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMemberUsers provides a mock function with given fields: groupID
|
||||
func (_m *GroupStore) GetMemberUsers(groupID string) ([]*model.User, error) {
|
||||
ret := _m.Called(groupID)
|
||||
@@ -782,13 +803,13 @@ func (_m *GroupStore) GetMemberUsersNotInChannel(groupID string, channelID strin
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMemberUsersPage provides a mock function with given fields: groupID, page, perPage
|
||||
func (_m *GroupStore) GetMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
ret := _m.Called(groupID, page, perPage)
|
||||
// GetMemberUsersPage provides a mock function with given fields: groupID, page, perPage, viewRestrictions
|
||||
func (_m *GroupStore) GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
ret := _m.Called(groupID, page, perPage, viewRestrictions)
|
||||
|
||||
var r0 []*model.User
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) []*model.User); ok {
|
||||
r0 = rf(groupID, page, perPage)
|
||||
if rf, ok := ret.Get(0).(func(string, int, int, *model.ViewUsersRestrictions) []*model.User); ok {
|
||||
r0 = rf(groupID, page, perPage, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.User)
|
||||
@@ -796,8 +817,8 @@ func (_m *GroupStore) GetMemberUsersPage(groupID string, page int, perPage int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, int, int) error); ok {
|
||||
r1 = rf(groupID, page, perPage)
|
||||
if rf, ok := ret.Get(1).(func(string, int, int, *model.ViewUsersRestrictions) error); ok {
|
||||
r1 = rf(groupID, page, perPage, viewRestrictions)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -805,13 +826,13 @@ func (_m *GroupStore) GetMemberUsersPage(groupID string, page int, perPage int)
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetNonMemberUsersPage provides a mock function with given fields: groupID, page, perPage
|
||||
func (_m *GroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
ret := _m.Called(groupID, page, perPage)
|
||||
// GetNonMemberUsersPage provides a mock function with given fields: groupID, page, perPage, viewRestrictions
|
||||
func (_m *GroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
ret := _m.Called(groupID, page, perPage, viewRestrictions)
|
||||
|
||||
var r0 []*model.User
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) []*model.User); ok {
|
||||
r0 = rf(groupID, page, perPage)
|
||||
if rf, ok := ret.Get(0).(func(string, int, int, *model.ViewUsersRestrictions) []*model.User); ok {
|
||||
r0 = rf(groupID, page, perPage, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.User)
|
||||
@@ -819,8 +840,8 @@ func (_m *GroupStore) GetNonMemberUsersPage(groupID string, page int, perPage in
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, int, int) error); ok {
|
||||
r1 = rf(groupID, page, perPage)
|
||||
if rf, ok := ret.Get(1).(func(string, int, int, *model.ViewUsersRestrictions) error); ok {
|
||||
r1 = rf(groupID, page, perPage, viewRestrictions)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -3781,10 +3781,10 @@ func (s *TimerLayerGroupStore) GetGroupSyncable(groupID string, syncableID strin
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts) ([]*model.Group, error) {
|
||||
func (s *TimerLayerGroupStore) GetGroups(page int, perPage int, opts model.GroupSearchOpts, viewRestrictions *model.ViewUsersRestrictions) ([]*model.Group, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.GroupStore.GetGroups(page, perPage, opts)
|
||||
result, err := s.GroupStore.GetGroups(page, perPage, opts, viewRestrictions)
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -3877,6 +3877,22 @@ func (s *TimerLayerGroupStore) GetMemberCount(groupID string) (int64, error) {
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.GroupStore.GetMemberCountWithRestrictions(groupID, viewRestrictions)
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("GroupStore.GetMemberCountWithRestrictions", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetMemberUsers(groupID string) ([]*model.User, error) {
|
||||
start := time.Now()
|
||||
|
||||
@@ -3925,10 +3941,10 @@ func (s *TimerLayerGroupStore) GetMemberUsersNotInChannel(groupID string, channe
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *TimerLayerGroupStore) GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.GroupStore.GetMemberUsersPage(groupID, page, perPage)
|
||||
result, err := s.GroupStore.GetMemberUsersPage(groupID, page, perPage, viewRestrictions)
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -3941,10 +3957,10 @@ func (s *TimerLayerGroupStore) GetMemberUsersPage(groupID string, page int, perP
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int) ([]*model.User, error) {
|
||||
func (s *TimerLayerGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.GroupStore.GetNonMemberUsersPage(groupID, page, perPage)
|
||||
result, err := s.GroupStore.GetNonMemberUsersPage(groupID, page, perPage, viewRestrictions)
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
|
||||
Ссылка в новой задаче
Block a user