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>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ace46443b3
Коммит
4d99aa22ba
@@ -102,7 +102,7 @@ type AppIface interface {
|
||||
// Notifies cluster peers through config change.
|
||||
DisablePlugin(id string) *model.AppError
|
||||
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
||||
DoPermissionsMigrations() *model.AppError
|
||||
DoPermissionsMigrations() error
|
||||
// EnablePlugin will set the config for an installed plugin to enabled, triggering asynchronous
|
||||
// activation if inactive anywhere in the cluster.
|
||||
// Notifies cluster peers through config change.
|
||||
@@ -782,7 +782,7 @@ type AppIface interface {
|
||||
SaveLicense(licenseBytes []byte) (*model.License, *model.AppError)
|
||||
SaveReactionForPost(reaction *model.Reaction) (*model.Reaction, *model.AppError)
|
||||
SaveUserTermsOfService(userId, termsOfServiceId string, accepted bool) *model.AppError
|
||||
SchemesIterator(batchSize int) func() []*model.Scheme
|
||||
SchemesIterator(scope string, batchSize int) func() []*model.Scheme
|
||||
SearchArchivedChannels(teamId string, term string, userId string) (*model.ChannelList, *model.AppError)
|
||||
SearchChannels(teamId string, term string) (*model.ChannelList, *model.AppError)
|
||||
SearchChannelsForUser(userId, teamId, term string) (*model.ChannelList, *model.AppError)
|
||||
|
||||
@@ -596,6 +596,12 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
model.PERMISSION_CREATE_EMOJIS.Id,
|
||||
model.PERMISSION_DELETE_EMOJIS.Id,
|
||||
model.PERMISSION_ADD_REACTION.Id,
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
|
||||
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
|
||||
model.PERMISSION_REMOVE_REACTION.Id,
|
||||
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
|
||||
}
|
||||
sort.Strings(expected2)
|
||||
sort.Strings(role2.Permissions)
|
||||
|
||||
@@ -6,7 +6,7 @@ package app
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
)
|
||||
@@ -31,7 +31,13 @@ func TestCheckIfRolesGrantPermission(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testcase := range cases {
|
||||
assert.Equal(t, th.App.RolesGrantPermission(testcase.roles, testcase.permissionId), testcase.shouldGrant)
|
||||
require.Equal(t, th.App.RolesGrantPermission(testcase.roles, testcase.permissionId), testcase.shouldGrant)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestChannelRolesGrantPermission(t *testing.T) {
|
||||
testPermissionInheritance(t, func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData) {
|
||||
require.Equal(t, testData.shouldHavePermission, th.App.RolesGrantPermission([]string{testData.channelRole.Name}, testData.permission.Id), "row: %+v\n", testData.truthTableRow)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -720,7 +720,7 @@ func (a *App) GetChannelModerationsForChannel(channel *model.Channel) ([]*model.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buildChannelModerations(memberRole, guestRole, higherScopedMemberRole, higherScopedGuestRole), nil
|
||||
return buildChannelModerations(channel.Type, memberRole, guestRole, higherScopedMemberRole, higherScopedGuestRole), nil
|
||||
}
|
||||
|
||||
// PatchChannelModerationsForChannel Updates a channels scheme roles based on a given ChannelModerationPatch, if the permissions match the higher scoped role the scheme is deleted.
|
||||
@@ -736,8 +736,8 @@ func (a *App) PatchChannelModerationsForChannel(channel *model.Channel, channelM
|
||||
return nil, err
|
||||
}
|
||||
|
||||
higherScopedMemberPermissions := higherScopedMemberRole.GetChannelModeratedPermissions()
|
||||
higherScopedGuestPermissions := higherScopedGuestRole.GetChannelModeratedPermissions()
|
||||
higherScopedMemberPermissions := higherScopedMemberRole.GetChannelModeratedPermissions(channel.Type)
|
||||
higherScopedGuestPermissions := higherScopedGuestRole.GetChannelModeratedPermissions(channel.Type)
|
||||
|
||||
for _, moderationPatch := range channelModerationsPatch {
|
||||
if moderationPatch.Roles.Members != nil && *moderationPatch.Roles.Members && !higherScopedMemberPermissions[*moderationPatch.Name] {
|
||||
@@ -753,6 +753,9 @@ func (a *App) PatchChannelModerationsForChannel(channel *model.Channel, channelM
|
||||
if _, err = a.CreateChannelScheme(channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_SCHEME_UPDATED, "", channel.Id, "", nil)
|
||||
a.Publish(message)
|
||||
mlog.Info("Permission scheme created.", mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name))
|
||||
}
|
||||
|
||||
@@ -796,6 +799,10 @@ func (a *App) PatchChannelModerationsForChannel(channel *model.Channel, channelM
|
||||
if _, err = a.DeleteChannelScheme(channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_SCHEME_UPDATED, "", channel.Id, "", nil)
|
||||
a.Publish(message)
|
||||
|
||||
memberRole = higherScopedMemberRole
|
||||
guestRole = higherScopedGuestRole
|
||||
mlog.Info("Permission scheme deleted.", mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name))
|
||||
@@ -810,14 +817,14 @@ func (a *App) PatchChannelModerationsForChannel(channel *model.Channel, channelM
|
||||
}
|
||||
}
|
||||
|
||||
return buildChannelModerations(memberRole, guestRole, higherScopedMemberRole, higherScopedGuestRole), nil
|
||||
return buildChannelModerations(channel.Type, memberRole, guestRole, higherScopedMemberRole, higherScopedGuestRole), nil
|
||||
}
|
||||
|
||||
func buildChannelModerations(memberRole *model.Role, guestRole *model.Role, higherScopedMemberRole *model.Role, higherScopedGuestRole *model.Role) []*model.ChannelModeration {
|
||||
memberPermissions := memberRole.GetChannelModeratedPermissions()
|
||||
guestPermissions := guestRole.GetChannelModeratedPermissions()
|
||||
higherScopedMemberPermissions := higherScopedMemberRole.GetChannelModeratedPermissions()
|
||||
higherScopedGuestPermissions := higherScopedGuestRole.GetChannelModeratedPermissions()
|
||||
func buildChannelModerations(channelType string, memberRole *model.Role, guestRole *model.Role, higherScopedMemberRole *model.Role, higherScopedGuestRole *model.Role) []*model.ChannelModeration {
|
||||
memberPermissions := memberRole.GetChannelModeratedPermissions(channelType)
|
||||
guestPermissions := guestRole.GetChannelModeratedPermissions(channelType)
|
||||
higherScopedMemberPermissions := higherScopedMemberRole.GetChannelModeratedPermissions(channelType)
|
||||
higherScopedGuestPermissions := higherScopedGuestRole.GetChannelModeratedPermissions(channelType)
|
||||
|
||||
var channelModerations []*model.ChannelModeration
|
||||
for _, permissionKey := range model.CHANNEL_MODERATED_PERMISSIONS {
|
||||
|
||||
@@ -905,7 +905,9 @@ func TestAllowChannelMentions(t *testing.T) {
|
||||
|
||||
t.Run("should return false for a post where the post user does not have USE_CHANNEL_MENTIONS permission", func(t *testing.T) {
|
||||
defer th.AddPermissionToRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
|
||||
defer th.AddPermissionToRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
allowChannelMentions := th.App.allowChannelMentions(post, 5)
|
||||
assert.False(t, allowChannelMentions)
|
||||
})
|
||||
|
||||
@@ -3046,7 +3046,7 @@ func (a *OpenTracingAppLayer) DoLogin(w http.ResponseWriter, r *http.Request, us
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) DoPermissionsMigrations() *model.AppError {
|
||||
func (a *OpenTracingAppLayer) DoPermissionsMigrations() error {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.DoPermissionsMigrations")
|
||||
|
||||
@@ -3060,11 +3060,6 @@ func (a *OpenTracingAppLayer) DoPermissionsMigrations() *model.AppError {
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.DoPermissionsMigrations()
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
@@ -11547,7 +11542,7 @@ func (a *OpenTracingAppLayer) SaveUserTermsOfService(userId string, termsOfServi
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) SchemesIterator(batchSize int) func() []*model.Scheme {
|
||||
func (a *OpenTracingAppLayer) SchemesIterator(scope string, batchSize int) func() []*model.Scheme {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SchemesIterator")
|
||||
|
||||
@@ -11559,7 +11554,7 @@ func (a *OpenTracingAppLayer) SchemesIterator(batchSize int) func() []*model.Sch
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.SchemesIterator(batchSize)
|
||||
resultVar0 := a.app.SchemesIterator(scope, batchSize)
|
||||
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (a *App) ResetPermissionsSystem() *model.AppError {
|
||||
|
||||
func (a *App) ExportPermissions(w io.Writer) error {
|
||||
|
||||
next := a.SchemesIterator(permissionsExportBatchSize)
|
||||
next := a.SchemesIterator("", permissionsExportBatchSize)
|
||||
var schemeBatch []*model.Scheme
|
||||
|
||||
for schemeBatch = next(); len(schemeBatch) > 0; schemeBatch = next() {
|
||||
|
||||
@@ -49,6 +49,10 @@ const (
|
||||
PERMISSION_USE_CHANNEL_MENTIONS = "use_channel_mentions"
|
||||
PERMISSION_CREATE_POST = "create_post"
|
||||
PERMISSION_CREATE_POST_PUBLIC = "create_post_public"
|
||||
PERMISSION_ADD_REACTION = "add_reaction"
|
||||
PERMISSION_REMOVE_REACTION = "remove_reaction"
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS = "manage_public_channel_members"
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS = "manage_private_channel_members"
|
||||
)
|
||||
|
||||
func isRole(role string) func(string, map[string]map[string]bool) bool {
|
||||
@@ -152,7 +156,7 @@ func (a *App) doPermissionsMigration(key string, migrationMap permissionsMap) *m
|
||||
return nil
|
||||
}
|
||||
|
||||
func getEmojisPermissionsSplitMigration() permissionsMap {
|
||||
func (a *App) getEmojisPermissionsSplitMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: permissionExists(PERMISSION_MANAGE_EMOJIS),
|
||||
@@ -164,10 +168,10 @@ func getEmojisPermissionsSplitMigration() permissionsMap {
|
||||
Add: []string{PERMISSION_DELETE_OTHERS_EMOJIS},
|
||||
Remove: []string{PERMISSION_MANAGE_OTHERS_EMOJIS},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getWebhooksPermissionsSplitMigration() permissionsMap {
|
||||
func (a *App) getWebhooksPermissionsSplitMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: permissionExists(PERMISSION_MANAGE_WEBHOOKS),
|
||||
@@ -179,10 +183,10 @@ func getWebhooksPermissionsSplitMigration() permissionsMap {
|
||||
Add: []string{PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS, PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS},
|
||||
Remove: []string{PERMISSION_MANAGE_OTHERS_WEBHOOKS},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getListJoinPublicPrivateTeamsPermissionsMigration() permissionsMap {
|
||||
func (a *App) getListJoinPublicPrivateTeamsPermissionsMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
@@ -194,29 +198,29 @@ func getListJoinPublicPrivateTeamsPermissionsMigration() permissionsMap {
|
||||
Add: []string{PERMISSION_LIST_PUBLIC_TEAMS, PERMISSION_JOIN_PUBLIC_TEAMS},
|
||||
Remove: []string{},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func removePermanentDeleteUserMigration() permissionsMap {
|
||||
func (a *App) removePermanentDeleteUserMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: permissionExists(PERMISSION_PERMANENT_DELETE_USER),
|
||||
Remove: []string{PERMISSION_PERMANENT_DELETE_USER},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getAddBotPermissionsMigration() permissionsMap {
|
||||
func (a *App) getAddBotPermissionsMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_CREATE_BOT, PERMISSION_READ_BOTS, PERMISSION_READ_OTHERS_BOTS, PERMISSION_MANAGE_BOTS, PERMISSION_MANAGE_OTHERS_BOTS},
|
||||
Remove: []string{},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func applyChannelManageDeleteToChannelUser() permissionsMap {
|
||||
func (a *App) applyChannelManageDeleteToChannelUser() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: permissionAnd(isRole(model.CHANNEL_USER_ROLE_ID), onOtherRole(model.TEAM_USER_ROLE_ID, permissionExists(PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES))),
|
||||
@@ -234,10 +238,10 @@ func applyChannelManageDeleteToChannelUser() permissionsMap {
|
||||
On: permissionAnd(isRole(model.CHANNEL_USER_ROLE_ID), onOtherRole(model.TEAM_USER_ROLE_ID, permissionExists(PERMISSION_DELETE_PUBLIC_CHANNEL))),
|
||||
Add: []string{PERMISSION_DELETE_PUBLIC_CHANNEL},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func removeChannelManageDeleteFromTeamUser() permissionsMap {
|
||||
func (a *App) removeChannelManageDeleteFromTeamUser() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: permissionAnd(isRole(model.TEAM_USER_ROLE_ID), permissionExists(PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES)),
|
||||
@@ -255,10 +259,10 @@ func removeChannelManageDeleteFromTeamUser() permissionsMap {
|
||||
On: permissionAnd(isRole(model.TEAM_USER_ROLE_ID), permissionExists(PERMISSION_DELETE_PUBLIC_CHANNEL)),
|
||||
Remove: []string{PERMISSION_DELETE_PUBLIC_CHANNEL},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getViewMembersPermissionMigration() permissionsMap {
|
||||
func (a *App) getViewMembersPermissionMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_USER_ROLE_ID),
|
||||
@@ -268,47 +272,154 @@ func getViewMembersPermissionMigration() permissionsMap {
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_VIEW_MEMBERS},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getAddManageGuestsPermissionsMigration() permissionsMap {
|
||||
func (a *App) getAddManageGuestsPermissionsMigration() (permissionsMap, error) {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_PROMOTE_GUEST, PERMISSION_DEMOTE_TO_GUEST, PERMISSION_INVITE_GUEST},
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getAddUseMentionChannelsPermissionMigration() permissionsMap {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: permissionOr(permissionExists(PERMISSION_CREATE_POST), permissionExists(PERMISSION_CREATE_POST_PUBLIC)),
|
||||
Add: []string{PERMISSION_USE_CHANNEL_MENTIONS},
|
||||
},
|
||||
func (a *App) channelModerationPermissionsMigration() (permissionsMap, error) {
|
||||
transformations := permissionsMap{}
|
||||
|
||||
var allTeamSchemes []*model.Scheme
|
||||
next := a.SchemesIterator(model.SCHEME_SCOPE_TEAM, 100)
|
||||
var schemeBatch []*model.Scheme
|
||||
for schemeBatch = next(); len(schemeBatch) > 0; schemeBatch = next() {
|
||||
allTeamSchemes = append(allTeamSchemes, schemeBatch...)
|
||||
}
|
||||
|
||||
moderatedPermissionsMinusCreatePost := []string{
|
||||
PERMISSION_ADD_REACTION,
|
||||
PERMISSION_REMOVE_REACTION,
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||
PERMISSION_USE_CHANNEL_MENTIONS,
|
||||
}
|
||||
|
||||
teamAndChannelAdminConditionalTransformations := func(teamAdminID, channelAdminID, channelUserID, channelGuestID string) []permissionTransformation {
|
||||
transformations := []permissionTransformation{}
|
||||
|
||||
for _, perm := range moderatedPermissionsMinusCreatePost {
|
||||
// add each moderated permission to the channel admin if channel user or guest has the permission
|
||||
trans := permissionTransformation{
|
||||
On: permissionAnd(
|
||||
isRole(channelAdminID),
|
||||
permissionOr(
|
||||
onOtherRole(channelUserID, permissionExists(perm)),
|
||||
onOtherRole(channelGuestID, permissionExists(perm)),
|
||||
),
|
||||
),
|
||||
Add: []string{perm},
|
||||
}
|
||||
transformations = append(transformations, trans)
|
||||
|
||||
// add each moderated permission to the team admin if channel admin, user, or guest has the permission
|
||||
trans = permissionTransformation{
|
||||
On: permissionAnd(
|
||||
isRole(teamAdminID),
|
||||
permissionOr(
|
||||
onOtherRole(channelAdminID, permissionExists(perm)),
|
||||
onOtherRole(channelUserID, permissionExists(perm)),
|
||||
onOtherRole(channelGuestID, permissionExists(perm)),
|
||||
),
|
||||
),
|
||||
Add: []string{perm},
|
||||
}
|
||||
transformations = append(transformations, trans)
|
||||
}
|
||||
|
||||
return transformations
|
||||
}
|
||||
|
||||
for _, ts := range allTeamSchemes {
|
||||
// ensure all team scheme channel admins have create_post because it's not exposed via the UI
|
||||
trans := permissionTransformation{
|
||||
On: isRole(ts.DefaultChannelAdminRole),
|
||||
Add: []string{PERMISSION_CREATE_POST},
|
||||
}
|
||||
transformations = append(transformations, trans)
|
||||
|
||||
// ensure all team scheme team admins have create_post because it's not exposed via the UI
|
||||
trans = permissionTransformation{
|
||||
On: isRole(ts.DefaultTeamAdminRole),
|
||||
Add: []string{PERMISSION_CREATE_POST},
|
||||
}
|
||||
transformations = append(transformations, trans)
|
||||
|
||||
// conditionally add all other moderated permissions to team and channel admins
|
||||
transformations = append(transformations, teamAndChannelAdminConditionalTransformations(
|
||||
ts.DefaultTeamAdminRole,
|
||||
ts.DefaultChannelAdminRole,
|
||||
ts.DefaultChannelUserRole,
|
||||
ts.DefaultChannelGuestRole,
|
||||
)...)
|
||||
}
|
||||
|
||||
// ensure team admins have create_post
|
||||
transformations = append(transformations, permissionTransformation{
|
||||
On: isRole(model.TEAM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_CREATE_POST},
|
||||
})
|
||||
|
||||
// ensure channel admins have create_post
|
||||
transformations = append(transformations, permissionTransformation{
|
||||
On: isRole(model.CHANNEL_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_CREATE_POST},
|
||||
})
|
||||
|
||||
// conditionally add all other moderated permissions to team and channel admins
|
||||
transformations = append(transformations, teamAndChannelAdminConditionalTransformations(
|
||||
model.TEAM_ADMIN_ROLE_ID,
|
||||
model.CHANNEL_ADMIN_ROLE_ID,
|
||||
model.CHANNEL_USER_ROLE_ID,
|
||||
model.CHANNEL_GUEST_ROLE_ID,
|
||||
)...)
|
||||
|
||||
// ensure system admin has all of the moderated permissions
|
||||
transformations = append(transformations, permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: append(moderatedPermissionsMinusCreatePost, PERMISSION_CREATE_POST),
|
||||
})
|
||||
|
||||
// add the new use_channel_mentions permission to everyone who has create_post
|
||||
transformations = append(transformations, permissionTransformation{
|
||||
On: permissionOr(permissionExists(PERMISSION_CREATE_POST), permissionExists(PERMISSION_CREATE_POST_PUBLIC)),
|
||||
Add: []string{PERMISSION_USE_CHANNEL_MENTIONS},
|
||||
})
|
||||
|
||||
return transformations, nil
|
||||
}
|
||||
|
||||
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
||||
func (a *App) DoPermissionsMigrations() *model.AppError {
|
||||
func (a *App) DoPermissionsMigrations() error {
|
||||
PermissionsMigrations := []struct {
|
||||
Key string
|
||||
Migration func() permissionsMap
|
||||
Migration func() (permissionsMap, error)
|
||||
}{
|
||||
{Key: model.MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration},
|
||||
{Key: model.MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration},
|
||||
{Key: model.MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: getListJoinPublicPrivateTeamsPermissionsMigration},
|
||||
{Key: model.MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER, Migration: removePermanentDeleteUserMigration},
|
||||
{Key: model.MIGRATION_KEY_ADD_BOT_PERMISSIONS, Migration: getAddBotPermissionsMigration},
|
||||
{Key: model.MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Migration: applyChannelManageDeleteToChannelUser},
|
||||
{Key: model.MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: removeChannelManageDeleteFromTeamUser},
|
||||
{Key: model.MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Migration: getViewMembersPermissionMigration},
|
||||
{Key: model.MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS, Migration: getAddManageGuestsPermissionsMigration},
|
||||
{Key: model.MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION, Migration: getAddUseMentionChannelsPermissionMigration},
|
||||
{Key: model.MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: a.getEmojisPermissionsSplitMigration},
|
||||
{Key: model.MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: a.getWebhooksPermissionsSplitMigration},
|
||||
{Key: model.MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: a.getListJoinPublicPrivateTeamsPermissionsMigration},
|
||||
{Key: model.MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER, Migration: a.removePermanentDeleteUserMigration},
|
||||
{Key: model.MIGRATION_KEY_ADD_BOT_PERMISSIONS, Migration: a.getAddBotPermissionsMigration},
|
||||
{Key: model.MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Migration: a.applyChannelManageDeleteToChannelUser},
|
||||
{Key: model.MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: a.removeChannelManageDeleteFromTeamUser},
|
||||
{Key: model.MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Migration: a.getViewMembersPermissionMigration},
|
||||
{Key: model.MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS, Migration: a.getAddManageGuestsPermissionsMigration},
|
||||
{Key: model.MIGRATION_KEY_CHANNEL_MODERATIONS_PERMISSIONS, Migration: a.channelModerationPermissionsMigration},
|
||||
}
|
||||
|
||||
for _, migration := range PermissionsMigrations {
|
||||
if err := a.doPermissionsMigration(migration.Key, migration.Migration()); err != nil {
|
||||
migMap, err := migration.Migration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.doPermissionsMigration(migration.Key, migMap); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,6 +708,7 @@ func TestCreatePost(t *testing.T) {
|
||||
|
||||
t.Run("Sets prop when post has mentions and user does not have USE_CHANNEL_MENTIONS", func(t *testing.T) {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
|
||||
postWithNoMention := &model.Post{
|
||||
ChannelId: th.BasicChannel.Id,
|
||||
@@ -728,6 +729,7 @@ func TestCreatePost(t *testing.T) {
|
||||
assert.Equal(t, rpost.GetProp(model.POST_PROPS_MENTION_HIGHLIGHT_DISABLED), true)
|
||||
|
||||
th.AddPermissionToRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -798,6 +800,7 @@ func TestPatchPost(t *testing.T) {
|
||||
|
||||
t.Run("Sets prop when user does not have USE_CHANNEL_MENTIONS", func(t *testing.T) {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
|
||||
patchWithNoMention := &model.PostPatch{Message: model.NewString("This patch still does not have a mention")}
|
||||
rpost, err = th.App.PatchPost(rpost.Id, patchWithNoMention)
|
||||
@@ -811,6 +814,7 @@ func TestPatchPost(t *testing.T) {
|
||||
assert.Equal(t, rpost.GetProp(model.POST_PROPS_MENTION_HIGHLIGHT_DISABLED), true)
|
||||
|
||||
th.AddPermissionToRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
97
app/role.go
97
app/role.go
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/utils"
|
||||
)
|
||||
|
||||
func (a *App) GetRole(id string) (*model.Role, *model.AppError) {
|
||||
@@ -20,11 +21,62 @@ func (a *App) GetAllRoles() ([]*model.Role, *model.AppError) {
|
||||
}
|
||||
|
||||
func (a *App) GetRoleByName(name string) (*model.Role, *model.AppError) {
|
||||
return a.Srv().Store.Role().GetByName(name)
|
||||
role, err := a.Srv().Store.Role().GetByName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = a.mergeChannelHigherScopedPermissions([]*model.Role{role})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return role, nil
|
||||
}
|
||||
|
||||
func (a *App) GetRolesByNames(names []string) ([]*model.Role, *model.AppError) {
|
||||
return a.Srv().Store.Role().GetByNames(names)
|
||||
roles, err := a.Srv().Store.Role().GetByNames(names)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = a.mergeChannelHigherScopedPermissions(roles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
// mergeChannelHigherScopedPermissions updates the permissions based on the role type, whether the permission is
|
||||
// moderated, and the value of the permission on the higher-scoped scheme.
|
||||
func (a *App) mergeChannelHigherScopedPermissions(roles []*model.Role) *model.AppError {
|
||||
var higherScopeNamesToQuery []string
|
||||
|
||||
for _, role := range roles {
|
||||
if role.SchemeManaged {
|
||||
higherScopeNamesToQuery = append(higherScopeNamesToQuery, role.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if len(higherScopeNamesToQuery) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
higherScopedPermissionsMap, err := a.Srv().Store.Role().ChannelHigherScopedPermissions(higherScopeNamesToQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, role := range roles {
|
||||
if role.SchemeManaged {
|
||||
if higherScopedPermissions, ok := higherScopedPermissionsMap[role.Name]; ok {
|
||||
role.MergeChannelHigherScopedPermissions(higherScopedPermissions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) PatchRole(role *model.Role, patch *model.RolePatch) (*model.Role, *model.AppError) {
|
||||
@@ -59,10 +111,47 @@ func (a *App) UpdateRole(role *model.Role) (*model.Role, *model.AppError) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.sendUpdatedRoleEvent(savedRole)
|
||||
|
||||
builtInChannelRoles := []string{
|
||||
model.CHANNEL_GUEST_ROLE_ID,
|
||||
model.CHANNEL_USER_ROLE_ID,
|
||||
model.CHANNEL_ADMIN_ROLE_ID,
|
||||
}
|
||||
|
||||
builtInRolesMinusChannelRoles := utils.RemoveStringsFromSlice(model.BuiltInSchemeManagedRoleIDs, builtInChannelRoles...)
|
||||
|
||||
if utils.StringInSlice(savedRole.Name, builtInRolesMinusChannelRoles) {
|
||||
return savedRole, nil
|
||||
}
|
||||
|
||||
var roleRetrievalFunc func() ([]*model.Role, *model.AppError)
|
||||
|
||||
if utils.StringInSlice(savedRole.Name, builtInChannelRoles) {
|
||||
roleRetrievalFunc = func() ([]*model.Role, *model.AppError) {
|
||||
return a.Srv().Store.Role().AllChannelSchemeRoles()
|
||||
}
|
||||
} else {
|
||||
roleRetrievalFunc = func() ([]*model.Role, *model.AppError) {
|
||||
return a.Srv().Store.Role().ChannelRolesUnderTeamRole(savedRole.Name)
|
||||
}
|
||||
}
|
||||
|
||||
impactedRoles, err := roleRetrievalFunc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
impactedRoles = append(impactedRoles, role)
|
||||
|
||||
err = a.mergeChannelHigherScopedPermissions(impactedRoles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ir := range impactedRoles {
|
||||
a.sendUpdatedRoleEvent(ir)
|
||||
}
|
||||
|
||||
return savedRole, nil
|
||||
|
||||
}
|
||||
|
||||
func (a *App) CheckRolesExist(roleNames []string) *model.AppError {
|
||||
|
||||
217
app/role_test.go
Обычный файл
217
app/role_test.go
Обычный файл
@@ -0,0 +1,217 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/utils"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type permissionInheritanceTestData struct {
|
||||
channelRole *model.Role
|
||||
permission *model.Permission
|
||||
shouldHavePermission bool
|
||||
channel *model.Channel
|
||||
higherScopedRole *model.Role
|
||||
truthTableRow []string
|
||||
}
|
||||
|
||||
func TestGetRolesByNames(t *testing.T) {
|
||||
testPermissionInheritance(t, func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData) {
|
||||
actualRoles, err := th.App.GetRolesByNames([]string{testData.channelRole.Name})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, actualRoles, 1)
|
||||
|
||||
actualRole := actualRoles[0]
|
||||
require.NotNil(t, actualRole)
|
||||
require.Equal(t, testData.channelRole.Name, actualRole.Name)
|
||||
|
||||
require.Equal(t, testData.shouldHavePermission, utils.StringInSlice(testData.permission.Id, actualRole.Permissions))
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetRoleByName(t *testing.T) {
|
||||
testPermissionInheritance(t, func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData) {
|
||||
actualRole, err := th.App.GetRoleByName(testData.channelRole.Name)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, actualRole)
|
||||
require.Equal(t, testData.channelRole.Name, actualRole.Name)
|
||||
require.Equal(t, testData.shouldHavePermission, utils.StringInSlice(testData.permission.Id, actualRole.Permissions), "row: %+v", testData.truthTableRow)
|
||||
})
|
||||
}
|
||||
|
||||
// testPermissionInheritance tests 48 combinations of scheme, permission, role data.
|
||||
func testPermissionInheritance(t *testing.T, testCallback func(t *testing.T, th *TestHelper, testData permissionInheritanceTestData)) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.SetLicense(model.NewTestLicense(""))
|
||||
th.App.SetPhase2PermissionsMigrationStatus(true)
|
||||
|
||||
permissionsDefault := []string{
|
||||
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
|
||||
}
|
||||
|
||||
// Defer resetting the system scheme permissions
|
||||
systemSchemeRoles, err := th.App.GetRolesByNames([]string{
|
||||
model.CHANNEL_GUEST_ROLE_ID,
|
||||
model.CHANNEL_USER_ROLE_ID,
|
||||
model.CHANNEL_ADMIN_ROLE_ID,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, systemSchemeRoles, 3)
|
||||
|
||||
// defer resetting the system role permissions
|
||||
for _, systemRole := range systemSchemeRoles {
|
||||
defer th.App.PatchRole(systemRole, &model.RolePatch{
|
||||
Permissions: &systemRole.Permissions,
|
||||
})
|
||||
}
|
||||
|
||||
// Make a channel scheme, clear its permissions
|
||||
channelScheme, err := th.App.CreateScheme(&model.Scheme{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Scope: model.SCHEME_SCOPE_CHANNEL,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
defer th.App.DeleteScheme(channelScheme.Id)
|
||||
|
||||
team := th.CreateTeam()
|
||||
defer th.App.PermanentDeleteTeamId(team.Id)
|
||||
|
||||
// Make a channel
|
||||
channel := th.CreateChannel(team)
|
||||
defer th.App.PermanentDeleteChannel(channel)
|
||||
|
||||
// Set the channel scheme
|
||||
channel.SchemeId = &channelScheme.Id
|
||||
channel, err = th.App.UpdateChannelScheme(channel)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Get the truth table from CSV
|
||||
file, e := os.Open("tests/channel-role-has-permission.csv")
|
||||
require.Nil(t, e)
|
||||
defer file.Close()
|
||||
|
||||
b, e := ioutil.ReadAll(file)
|
||||
require.Nil(t, e)
|
||||
|
||||
r := csv.NewReader(strings.NewReader(string(b)))
|
||||
records, e := r.ReadAll()
|
||||
require.Nil(t, e)
|
||||
|
||||
test := func(higherScopedGuest, higherScopedUser, higherScopedAdmin string) {
|
||||
for _, roleNameUnderTest := range []string{higherScopedGuest, higherScopedUser, higherScopedAdmin} {
|
||||
for i, row := range records {
|
||||
// skip csv header
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
higherSchemeHasPermission, e := strconv.ParseBool(row[0])
|
||||
require.Nil(t, e)
|
||||
|
||||
permissionIsModerated, e := strconv.ParseBool(row[1])
|
||||
require.Nil(t, e)
|
||||
|
||||
channelSchemeHasPermission, e := strconv.ParseBool(row[2])
|
||||
require.Nil(t, e)
|
||||
|
||||
channelRoleIsChannelAdmin, e := strconv.ParseBool(row[3])
|
||||
require.Nil(t, e)
|
||||
|
||||
shouldHavePermission, e := strconv.ParseBool(row[4])
|
||||
require.Nil(t, e)
|
||||
|
||||
// skip some invalid combinations because of the outer loop iterating all 3 channel roles
|
||||
if (channelRoleIsChannelAdmin && roleNameUnderTest != higherScopedAdmin) || (!channelRoleIsChannelAdmin && roleNameUnderTest == higherScopedAdmin) {
|
||||
continue
|
||||
}
|
||||
|
||||
// select the permission to test (moderated or non-moderated)
|
||||
var permission *model.Permission
|
||||
if permissionIsModerated {
|
||||
permission = model.PERMISSION_CREATE_POST // moderated
|
||||
} else {
|
||||
permission = model.PERMISSION_READ_CHANNEL // non-moderated
|
||||
}
|
||||
|
||||
// add or remove the permission from the higher-scoped scheme
|
||||
higherScopedRole, testErr := th.App.GetRoleByName(roleNameUnderTest)
|
||||
require.Nil(t, testErr)
|
||||
|
||||
var higherScopedPermissions []string
|
||||
if higherSchemeHasPermission {
|
||||
higherScopedPermissions = []string{permission.Id}
|
||||
} else {
|
||||
higherScopedPermissions = permissionsDefault
|
||||
}
|
||||
higherScopedRole, testErr = th.App.PatchRole(higherScopedRole, &model.RolePatch{Permissions: &higherScopedPermissions})
|
||||
require.Nil(t, testErr)
|
||||
|
||||
// get channel role
|
||||
var channelRoleName string
|
||||
switch roleNameUnderTest {
|
||||
case higherScopedGuest:
|
||||
channelRoleName = channelScheme.DefaultChannelGuestRole
|
||||
case higherScopedUser:
|
||||
channelRoleName = channelScheme.DefaultChannelUserRole
|
||||
case higherScopedAdmin:
|
||||
channelRoleName = channelScheme.DefaultChannelAdminRole
|
||||
}
|
||||
channelRole, testErr := th.App.GetRoleByName(channelRoleName)
|
||||
require.Nil(t, testErr)
|
||||
|
||||
// add or remove the permission from the channel scheme
|
||||
var channelSchemePermissions []string
|
||||
if channelSchemeHasPermission {
|
||||
channelSchemePermissions = []string{permission.Id}
|
||||
} else {
|
||||
channelSchemePermissions = permissionsDefault
|
||||
}
|
||||
channelRole, testErr = th.App.PatchRole(channelRole, &model.RolePatch{Permissions: &channelSchemePermissions})
|
||||
require.Nil(t, testErr)
|
||||
|
||||
testCallback(t, th, permissionInheritanceTestData{
|
||||
channelRole: channelRole,
|
||||
permission: permission,
|
||||
shouldHavePermission: shouldHavePermission,
|
||||
channel: channel,
|
||||
higherScopedRole: higherScopedRole,
|
||||
truthTableRow: row,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test 24 combinations where the higher-scoped scheme is the SYSTEM scheme
|
||||
test(model.CHANNEL_GUEST_ROLE_ID, model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID)
|
||||
|
||||
// create a team scheme
|
||||
teamScheme, err := th.App.CreateScheme(&model.Scheme{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Scope: model.SCHEME_SCOPE_TEAM,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
defer th.App.DeleteScheme(teamScheme.Id)
|
||||
|
||||
// assign the scheme to the team
|
||||
team.SchemeId = &teamScheme.Id
|
||||
team, err = th.App.UpdateTeamScheme(team)
|
||||
require.Nil(t, err)
|
||||
|
||||
// test 24 combinations where the higher-scoped scheme is a TEAM scheme
|
||||
test(teamScheme.DefaultChannelGuestRole, teamScheme.DefaultChannelUserRole, teamScheme.DefaultChannelAdminRole)
|
||||
}
|
||||
@@ -139,10 +139,10 @@ func (a *App) IsPhase2MigrationCompleted() *model.AppError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) SchemesIterator(batchSize int) func() []*model.Scheme {
|
||||
func (a *App) SchemesIterator(scope string, batchSize int) func() []*model.Scheme {
|
||||
offset := 0
|
||||
return func() []*model.Scheme {
|
||||
schemes, err := a.Srv().Store.Scheme().GetAllPage("", offset, batchSize)
|
||||
schemes, err := a.Srv().Store.Scheme().GetAllPage(scope, offset, batchSize)
|
||||
if err != nil {
|
||||
return []*model.Scheme{}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user