Restricting team stats using the VIEW_MEMBERS restrictions (#11694)

* Restricting team stats using the VIEW_MEMBERS restrictions

* Adding tests

* fixing tests
Этот коммит содержится в:
Jesús Espino
2019-07-31 18:34:03 +02:00
коммит произвёл GitHub
родитель 51cdae12c1
Коммит 0ec0616d89
8 изменённых файлов: 155 добавлений и 59 удалений

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

@@ -590,35 +590,43 @@ func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int, restricti
return dbMembers.ToModel(), nil
}
func (s SqlTeamStore) GetTotalMemberCount(teamId string) (int64, *model.AppError) {
count, err := s.GetReplica().SelectInt(`
SELECT
count(*)
FROM
TeamMembers,
Users
WHERE
TeamMembers.UserId = Users.Id
AND TeamMembers.TeamId = :TeamId
AND TeamMembers.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId})
func (s SqlTeamStore) GetTotalMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) {
query := s.getQueryBuilder().
Select("count(DISTINCT TeamMembers.UserId)").
From("TeamMembers, Users").
Where("TeamMembers.DeleteAt = 0").
Where("TeamMembers.UserId = Users.Id").
Where(sq.Eq{"TeamMembers.TeamId": teamId})
query = applyTeamMemberViewRestrictionsFilterForStats(query, teamId, restrictions)
queryString, args, err := query.ToSql()
if err != nil {
return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, err.Error(), http.StatusInternalServerError)
}
count, err := s.GetReplica().SelectInt(queryString, args...)
if err != nil {
return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
}
return count, nil
}
func (s SqlTeamStore) GetActiveMemberCount(teamId string) (int64, *model.AppError) {
count, err := s.GetReplica().SelectInt(`
SELECT
count(*)
FROM
TeamMembers,
Users
WHERE
TeamMembers.UserId = Users.Id
AND TeamMembers.TeamId = :TeamId
AND TeamMembers.DeleteAt = 0
AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId})
func (s SqlTeamStore) GetActiveMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) {
query := s.getQueryBuilder().
Select("count(DISTINCT TeamMembers.UserId)").
From("TeamMembers, Users").
Where("TeamMembers.DeleteAt = 0").
Where("TeamMembers.UserId = Users.Id").
Where("Users.DeleteAt = 0").
Where(sq.Eq{"TeamMembers.TeamId": teamId})
query = applyTeamMemberViewRestrictionsFilterForStats(query, teamId, restrictions)
queryString, args, err := query.ToSql()
if err != nil {
return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_active_member_count.app_error", nil, err.Error(), http.StatusInternalServerError)
}
count, err := s.GetReplica().SelectInt(queryString, args...)
if err != nil {
return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_active_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
}
@@ -1057,3 +1065,33 @@ func applyTeamMemberViewRestrictionsFilter(query sq.SelectBuilder, teamId string
return resultQuery.Distinct()
}
func applyTeamMemberViewRestrictionsFilterForStats(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder {
if restrictions == nil {
return query
}
// If you have no access to teams or channels, return and empty result.
if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 {
return query.Where("1 = 0")
}
teams := make([]interface{}, len(restrictions.Teams))
for i, v := range restrictions.Teams {
teams[i] = v
}
channels := make([]interface{}, len(restrictions.Channels))
for i, v := range restrictions.Channels {
channels[i] = v
}
resultQuery := query
if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = Users.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
}
if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = Users.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
}
return resultQuery
}

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

@@ -77,8 +77,8 @@ type TeamStore interface {
GetMember(teamId string, userId string) (*model.TeamMember, *model.AppError)
GetMembers(teamId string, offset int, limit int, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError)
GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError)
GetTotalMemberCount(teamId string) (int64, *model.AppError)
GetActiveMemberCount(teamId string) (int64, *model.AppError)
GetTotalMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError)
GetActiveMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError)
GetTeamsForUser(userId string) ([]*model.TeamMember, *model.AppError)
GetTeamsForUserWithPagination(userId string, page, perPage int) ([]*model.TeamMember, *model.AppError)
GetChannelUnreadsForAllTeams(excludeTeamId, userId string) ([]*model.ChannelUnread, *model.AppError)

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

@@ -104,20 +104,20 @@ func (_m *TeamStore) Get(id string) (*model.Team, *model.AppError) {
return r0, r1
}
// GetActiveMemberCount provides a mock function with given fields: teamId
func (_m *TeamStore) GetActiveMemberCount(teamId string) (int64, *model.AppError) {
ret := _m.Called(teamId)
// GetActiveMemberCount provides a mock function with given fields: teamId, restrictions
func (_m *TeamStore) GetActiveMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) {
ret := _m.Called(teamId, restrictions)
var r0 int64
if rf, ok := ret.Get(0).(func(string) int64); ok {
r0 = rf(teamId)
if rf, ok := ret.Get(0).(func(string, *model.ViewUsersRestrictions) int64); ok {
r0 = rf(teamId, restrictions)
} else {
r0 = ret.Get(0).(int64)
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(teamId)
if rf, ok := ret.Get(1).(func(string, *model.ViewUsersRestrictions) *model.AppError); ok {
r1 = rf(teamId, restrictions)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
@@ -602,20 +602,20 @@ func (_m *TeamStore) GetTeamsForUserWithPagination(userId string, page int, perP
return r0, r1
}
// GetTotalMemberCount provides a mock function with given fields: teamId
func (_m *TeamStore) GetTotalMemberCount(teamId string) (int64, *model.AppError) {
ret := _m.Called(teamId)
// GetTotalMemberCount provides a mock function with given fields: teamId, restrictions
func (_m *TeamStore) GetTotalMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) {
ret := _m.Called(teamId, restrictions)
var r0 int64
if rf, ok := ret.Get(0).(func(string) int64); ok {
r0 = rf(teamId)
if rf, ok := ret.Get(0).(func(string, *model.ViewUsersRestrictions) int64); ok {
r0 = rf(teamId, restrictions)
} else {
r0 = ret.Get(0).(int64)
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(teamId)
if rf, ok := ret.Get(1).(func(string, *model.ViewUsersRestrictions) *model.AppError); ok {
r1 = rf(teamId, restrictions)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)

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

@@ -903,7 +903,7 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
}(userIds[i])
}
if totalMemberCount, err := ss.Team().GetTotalMemberCount(team.Id); err != nil {
if totalMemberCount, err := ss.Team().GetTotalMemberCount(team.Id, nil); err != nil {
t.Fatal(err)
} else if int(totalMemberCount) != maxUsersPerTeam {
t.Fatalf("should start with 5 team members, had %v instead", totalMemberCount)
@@ -926,7 +926,7 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
t.Fatal("shouldn't be able to save member when at maximum members per team")
}
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id); teamErr != nil {
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil); teamErr != nil {
t.Fatal(teamErr)
} else if int(totalMemberCount) != maxUsersPerTeam {
t.Fatalf("should still have 5 team members, had %v instead", totalMemberCount)
@@ -941,7 +941,7 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
panic(teamErr)
}
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id); teamErr != nil {
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil); teamErr != nil {
t.Fatal(teamErr)
} else if int(totalMemberCount) != maxUsersPerTeam-1 {
t.Fatalf("should now only have 4 team members, had %v instead", totalMemberCount)
@@ -955,7 +955,7 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
}(newUserId)
}
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id); teamErr != nil {
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil); teamErr != nil {
t.Fatal(teamErr)
} else if int(totalMemberCount) != maxUsersPerTeam {
t.Fatalf("should have 5 team members again, had %v instead", totalMemberCount)
@@ -1117,7 +1117,7 @@ func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
require.Nil(t, err)
var totalMemberCount int64
if totalMemberCount, err = ss.Team().GetTotalMemberCount(teamId1); err != nil {
if totalMemberCount, err = ss.Team().GetTotalMemberCount(teamId1, nil); err != nil {
t.Fatal(err)
} else {
if totalMemberCount != 2 {
@@ -1126,7 +1126,7 @@ func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
}
var result int64
if result, err = ss.Team().GetActiveMemberCount(teamId1); err != nil {
if result, err = ss.Team().GetActiveMemberCount(teamId1, nil); err != nil {
t.Fatal(err)
} else {
if result != 1 {
@@ -1138,7 +1138,7 @@ func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
_, err = ss.Team().SaveMember(m3, -1)
require.Nil(t, err)
if totalMemberCount, err := ss.Team().GetTotalMemberCount(teamId1); err != nil {
if totalMemberCount, err := ss.Team().GetTotalMemberCount(teamId1, nil); err != nil {
t.Fatal(err)
} else {
if totalMemberCount != 2 {
@@ -1146,7 +1146,7 @@ func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
}
}
if result, err := ss.Team().GetActiveMemberCount(teamId1); err != nil {
if result, err := ss.Team().GetActiveMemberCount(teamId1, nil); err != nil {
t.Fatal(err)
} else {
if result != 1 {