[MM-42421] Prevent guests from seeing users through groups API (#21151)

Этот коммит содержится в:
cyrilzhang-mm
2022-10-25 11:54:51 -04:00
коммит произвёл GitHub
родитель c5f4882f0a
Коммит a648ced221
17 изменённых файлов: 406 добавлений и 178 удалений

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

@@ -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)
}