MM-22212 & MM-22208: Read from the higher-scoped scheme if the permission is non-moderated. (#13813)

* MM-22212: Read non-moderated permissions from higher-scoped scheme.

* MM-2212: Corrects test count in comment.

* MM-22212: Adds godoc comment.

* MM-2212: Switches to the channel roles check in a few more places.

* MM-22212: Refactors and fixes.

* MM-22212: Reverts change, no longer required.

* MM-22212: Removes translation.

* MM-22212: Un-comments merged new permission.

* MM-22212: Un-comments merged new permission.

* MM-22212: Performance tweak.

* MM-22212: Fixes some fmting.

* MM-22212: Add unit test for newly-added store methods.

* MM-22212: Renames app method.

* MM-22212: Re-uses existing function to find string in slice.

* MM-22212: Keeps 'higher-scoped' terminology for consistency.

* MM-22212: Refactors based on PR feedback.

* MM-22212: Fix for some bad merging.

* MM-22212: Renamed some things.

* MM-22212: Use an 'else' instead of a 'continue' for readability.

* MM-22212: Caches (*SqlRoleStore).ChannelRolesUnderTeamRole.

* MM-22212: Adds mock to new cache store.

* MM-22212: Adds missing open tracing app layer methods.

* MM-22212: Adds migration to add moderated permissions to channel_admin if present on channel_user.

* MM-22212: Migrates team schemes. Removes unused AppError.

* MM-22212: Fix for for if.

* MM-22212: Fixes iterator.

* MM-22212: Updates open tracing generated methods.

* MM-22212: Fix mocks.

* MM-22212: Change migration key name.

* MM-22212: Switched to data structure from other branch.

* MM-22212: Fixes tests after adding 'use_channel_mentions' to the channel_admin role.

* MM-22212: Adds tracking of channel moderation.

* Revert "MM-22212: Adds tracking of channel moderation."

This reverts commit 23689efa22c112e4ba37f6a212535dd7ebfb63db.

* MM-22212: Switch some functions to methods and vice versa.

* MM-22212: Fix for refactor bug not notifiying websocket about changed role.

* MM-22212: Adds test for public/private 'manage_members' handling.

* MM-22122 Fix manage channel members edge case for public and private channels (#14049)

* MM-22212: Adds moderated permission to team_admin.

* MM-22212: Updates migration.

* MM-22212: Revert unnecessary update to default roles.

* Add channel scheme updated event when channel scheme is deleted or created (#14057)

* MM-22212: Adds newline.

* MM-22212: Migration fix.

* MM-22212: Fix for migration.

* MM-22212: Test fix.

Co-authored-by: Farhan Munshi <3207297+fm2munsh@users.noreply.github.com>
Этот коммит содержится в:
Martin Kraft
2020-03-23 13:44:20 -04:00
коммит произвёл GitHub
родитель ace46443b3
Коммит 4d99aa22ba
39 изменённых файлов: 1252 добавлений и 123 удалений

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

@@ -16,6 +16,7 @@ import (
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/utils"
)
func TestGroupStore(t *testing.T, ss store.Store) {
@@ -3620,15 +3621,6 @@ func groupTestpUpdateMembersRoleTeam(t *testing.T, ss store.Store) {
},
}
includes := func(list []string, item string) bool {
for _, it := range list {
if it == item {
return true
}
}
return false
}
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
err = ss.Team().UpdateMembersRole(team.Id, tt.inUserIDs)
@@ -3639,7 +3631,7 @@ func groupTestpUpdateMembersRoleTeam(t *testing.T, ss store.Store) {
require.GreaterOrEqual(t, len(members), 4) // sanity check for team membership
for _, member := range members {
if includes(tt.inUserIDs, member.UserId) {
if utils.StringInSlice(member.UserId, tt.inUserIDs) {
require.True(t, member.SchemeAdmin)
} else {
require.False(t, member.SchemeAdmin)
@@ -3738,15 +3730,6 @@ func groupTestpUpdateMembersRoleChannel(t *testing.T, ss store.Store) {
},
}
includes := func(list []string, item string) bool {
for _, it := range list {
if it == item {
return true
}
}
return false
}
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
err = ss.Channel().UpdateMembersRole(channel.Id, tt.inUserIDs)
@@ -3758,7 +3741,7 @@ func groupTestpUpdateMembersRoleChannel(t *testing.T, ss store.Store) {
require.GreaterOrEqual(t, len(*members), 4) // sanity check for channel membership
for _, member := range *members {
if includes(tt.inUserIDs, member.UserId) {
if utils.StringInSlice(member.UserId, tt.inUserIDs) {
require.True(t, member.SchemeAdmin)
} else {
require.False(t, member.SchemeAdmin)

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

@@ -14,13 +14,88 @@ type RoleStore struct {
mock.Mock
}
// Delete provides a mock function with given fields: roldId
func (_m *RoleStore) Delete(roldId string) (*model.Role, *model.AppError) {
ret := _m.Called(roldId)
// AllChannelSchemeRoles provides a mock function with given fields:
func (_m *RoleStore) AllChannelSchemeRoles() ([]*model.Role, *model.AppError) {
ret := _m.Called()
var r0 []*model.Role
if rf, ok := ret.Get(0).(func() []*model.Role); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.Role)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func() *model.AppError); ok {
r1 = rf()
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// ChannelHigherScopedPermissions provides a mock function with given fields: roleNames
func (_m *RoleStore) ChannelHigherScopedPermissions(roleNames []string) (map[string]*model.RolePermissions, *model.AppError) {
ret := _m.Called(roleNames)
var r0 map[string]*model.RolePermissions
if rf, ok := ret.Get(0).(func([]string) map[string]*model.RolePermissions); ok {
r0 = rf(roleNames)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(map[string]*model.RolePermissions)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func([]string) *model.AppError); ok {
r1 = rf(roleNames)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// ChannelRolesUnderTeamRole provides a mock function with given fields: roleName
func (_m *RoleStore) ChannelRolesUnderTeamRole(roleName string) ([]*model.Role, *model.AppError) {
ret := _m.Called(roleName)
var r0 []*model.Role
if rf, ok := ret.Get(0).(func(string) []*model.Role); ok {
r0 = rf(roleName)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.Role)
}
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(roleName)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}
// Delete provides a mock function with given fields: roleId
func (_m *RoleStore) Delete(roleId string) (*model.Role, *model.AppError) {
ret := _m.Called(roleId)
var r0 *model.Role
if rf, ok := ret.Get(0).(func(string) *model.Role); ok {
r0 = rf(roldId)
r0 = rf(roleId)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Role)
@@ -29,7 +104,7 @@ func (_m *RoleStore) Delete(roldId string) (*model.Role, *model.AppError) {
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(roldId)
r1 = rf(roleId)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)

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

@@ -21,6 +21,7 @@ func TestRoleStore(t *testing.T, ss store.Store) {
t.Run("GetNames", func(t *testing.T) { testRoleStoreGetByNames(t, ss) })
t.Run("Delete", func(t *testing.T) { testRoleStoreDelete(t, ss) })
t.Run("PermanentDeleteAll", func(t *testing.T) { testRoleStorePermanentDeleteAll(t, ss) })
t.Run("LowerScopedChannelSchemeRoles_AllChannelSchemeRoles", func(t *testing.T) { testRoleStoreLowerScopedChannelSchemeRoles(t, ss) })
}
func testRoleStoreSave(t *testing.T, ss store.Store) {
@@ -356,3 +357,159 @@ func testRoleStorePermanentDeleteAll(t *testing.T, ss store.Store) {
assert.Nil(t, err)
assert.Empty(t, roles)
}
func testRoleStoreLowerScopedChannelSchemeRoles(t *testing.T, ss store.Store) {
createDefaultRoles(t, ss)
teamScheme1 := &model.Scheme{
DisplayName: model.NewId(),
Name: model.NewId(),
Description: model.NewId(),
Scope: model.SCHEME_SCOPE_TEAM,
}
teamScheme1, err := ss.Scheme().Save(teamScheme1)
require.Nil(t, err)
defer ss.Scheme().Delete(teamScheme1.Id)
teamScheme2 := &model.Scheme{
DisplayName: model.NewId(),
Name: model.NewId(),
Description: model.NewId(),
Scope: model.SCHEME_SCOPE_TEAM,
}
teamScheme2, err = ss.Scheme().Save(teamScheme2)
require.Nil(t, err)
defer ss.Scheme().Delete(teamScheme2.Id)
channelScheme1 := &model.Scheme{
DisplayName: model.NewId(),
Name: model.NewId(),
Description: model.NewId(),
Scope: model.SCHEME_SCOPE_CHANNEL,
}
channelScheme1, err = ss.Scheme().Save(channelScheme1)
require.Nil(t, err)
defer ss.Scheme().Delete(channelScheme1.Id)
channelScheme2 := &model.Scheme{
DisplayName: model.NewId(),
Name: model.NewId(),
Description: model.NewId(),
Scope: model.SCHEME_SCOPE_CHANNEL,
}
channelScheme2, err = ss.Scheme().Save(channelScheme2)
require.Nil(t, err)
defer ss.Scheme().Delete(channelScheme1.Id)
team1 := &model.Team{
DisplayName: "Name",
Name: "zz" + model.NewId(),
Email: MakeEmail(),
Type: model.TEAM_OPEN,
SchemeId: &teamScheme1.Id,
}
team1, err = ss.Team().Save(team1)
require.Nil(t, err)
defer ss.Team().PermanentDelete(team1.Id)
team2 := &model.Team{
DisplayName: "Name",
Name: "zz" + model.NewId(),
Email: MakeEmail(),
Type: model.TEAM_OPEN,
SchemeId: &teamScheme2.Id,
}
team2, err = ss.Team().Save(team2)
require.Nil(t, err)
defer ss.Team().PermanentDelete(team2.Id)
channel1 := &model.Channel{
TeamId: team1.Id,
DisplayName: "Display " + model.NewId(),
Name: "zz" + model.NewId() + "b",
Type: model.CHANNEL_OPEN,
SchemeId: &channelScheme1.Id,
}
channel1, err = ss.Channel().Save(channel1, -1)
require.Nil(t, err)
defer ss.Channel().Delete(channel1.Id, 0)
channel2 := &model.Channel{
TeamId: team2.Id,
DisplayName: "Display " + model.NewId(),
Name: "zz" + model.NewId() + "b",
Type: model.CHANNEL_OPEN,
SchemeId: &channelScheme2.Id,
}
channel2, err = ss.Channel().Save(channel2, -1)
require.Nil(t, err)
defer ss.Channel().Delete(channel2.Id, 0)
t.Run("ChannelRolesUnderTeamRole", func(t *testing.T) {
t.Run("guest role for the right team's channels are returned", func(t *testing.T) {
actualRoles, err := ss.Role().ChannelRolesUnderTeamRole(teamScheme1.DefaultChannelGuestRole)
require.Nil(t, err)
var actualRoleNames []string
for _, role := range actualRoles {
actualRoleNames = append(actualRoleNames, role.Name)
}
require.Contains(t, actualRoleNames, channelScheme1.DefaultChannelGuestRole)
require.NotContains(t, actualRoleNames, channelScheme2.DefaultChannelGuestRole)
})
t.Run("user role for the right team's channels are returned", func(t *testing.T) {
actualRoles, err := ss.Role().ChannelRolesUnderTeamRole(teamScheme1.DefaultChannelUserRole)
require.Nil(t, err)
var actualRoleNames []string
for _, role := range actualRoles {
actualRoleNames = append(actualRoleNames, role.Name)
}
require.Contains(t, actualRoleNames, channelScheme1.DefaultChannelUserRole)
require.NotContains(t, actualRoleNames, channelScheme2.DefaultChannelUserRole)
})
t.Run("admin role for the right team's channels are returned", func(t *testing.T) {
actualRoles, err := ss.Role().ChannelRolesUnderTeamRole(teamScheme1.DefaultChannelAdminRole)
require.Nil(t, err)
var actualRoleNames []string
for _, role := range actualRoles {
actualRoleNames = append(actualRoleNames, role.Name)
}
require.Contains(t, actualRoleNames, channelScheme1.DefaultChannelAdminRole)
require.NotContains(t, actualRoleNames, channelScheme2.DefaultChannelAdminRole)
})
})
t.Run("AllChannelSchemeRoles", func(t *testing.T) {
t.Run("guest role for the right team's channels are returned", func(t *testing.T) {
actualRoles, err := ss.Role().AllChannelSchemeRoles()
require.Nil(t, err)
var actualRoleNames []string
for _, role := range actualRoles {
actualRoleNames = append(actualRoleNames, role.Name)
}
allRoleNames := []string{
channelScheme1.DefaultChannelGuestRole,
channelScheme2.DefaultChannelGuestRole,
channelScheme1.DefaultChannelUserRole,
channelScheme2.DefaultChannelUserRole,
channelScheme1.DefaultChannelAdminRole,
channelScheme2.DefaultChannelAdminRole,
}
for _, roleName := range allRoleNames {
require.Contains(t, actualRoleNames, roleName)
}
})
})
}