[MM-22206] Add PATCH channel moderations (PUT /moderations/patch) (#13845)
* MM-22205 Add get channel moderations endpoint * MM-22206 Add patch channel moderations endpoint Add api tests for patch channel moderations * MM-22205 Ensure ordered permissions returned and create struct ChannelModeratedRoles * MM-22206 Use structs instead of map * MM-22206 Add test cases for GetChannelModeratedPermissions * MM-22206 Add tests for ChannelModeratedPermissionsChangedByPatch * MM-22206 Use NewBool instead of defining booleans * MM-22206 Tie Channel Mentions to Create Posts when building Channel Moderations * Revert "MM-22206 Tie Channel Mentions to Create Posts when building Channel Moderations" This reverts commit a0bfc95f1732955c5ef5fc3e4b05ea8ab954acea. * MM-22206 Review changes Modify GetSchemeRolesForChannel to return named variables Change calls to SessionHasPermissionToChannel to SessionHasPermissionTo Add a CreateChannelScheme method Add a DeleteChannelScheme method Move GetChannelModeratedPermissions to Role model * Fix lint * Add ChannelModeration methods to App interface * MM-22206 Rename method to GetTeamSchemeChannelRoles * MM-22206 Check CHANNEL_MODERATED_PERMISSIONS_MAP for existing permission before iterating through it * Modify wording to higherScoped to match #13813 * MM-22206 Delete channel scheme between tests * MM-22206 Fix tests * Actually patch role * MM-22206 Shadow declaration of err
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
bfde6d1f3e
Коммит
79c786bc0c
@@ -461,6 +461,7 @@ type AppIface interface {
|
||||
GetChannelMembersForUserWithPagination(teamId, userId string, page, perPage int) ([]*model.ChannelMember, *model.AppError)
|
||||
GetChannelMembersPage(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError)
|
||||
GetChannelMembersTimezones(channelId string) ([]string, *model.AppError)
|
||||
GetChannelModerationsForChannel(channel *model.Channel) ([]*model.ChannelModeration, *model.AppError)
|
||||
GetChannelPinnedPostCount(channelId string) (int64, *model.AppError)
|
||||
GetChannelUnread(channelId, userId string) (*model.ChannelUnread, *model.AppError)
|
||||
GetChannelsByNames(channelNames []string, teamId string) ([]*model.Channel, *model.AppError)
|
||||
@@ -715,6 +716,7 @@ type AppIface interface {
|
||||
OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError
|
||||
OriginChecker() func(*http.Request) bool
|
||||
PatchChannel(channel *model.Channel, patch *model.ChannelPatch, userId string) (*model.Channel, *model.AppError)
|
||||
PatchChannelModerationsForChannel(channel *model.Channel, channelModerationsPatch []*model.ChannelModerationPatch) ([]*model.ChannelModeration, *model.AppError)
|
||||
PatchPost(postId string, patch *model.PostPatch) (*model.Post, *model.AppError)
|
||||
PatchRole(role *model.Role, patch *model.RolePatch) (*model.Role, *model.AppError)
|
||||
PatchScheme(scheme *model.Scheme, patch *model.SchemePatch) (*model.Scheme, *model.AppError)
|
||||
|
||||
206
app/channel.go
206
app/channel.go
@@ -547,6 +547,34 @@ func (a *App) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppE
|
||||
return channel, nil
|
||||
}
|
||||
|
||||
// CreateChannelScheme creates a new Scheme of scope channel and assigns it to the channel.
|
||||
func (a *App) CreateChannelScheme(channel *model.Channel) (*model.Scheme, *model.AppError) {
|
||||
scheme, err := a.CreateScheme(&model.Scheme{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Scope: model.SCHEME_SCOPE_CHANNEL,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
channel.SchemeId = &scheme.Id
|
||||
if _, err := a.UpdateChannelScheme(channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return scheme, nil
|
||||
}
|
||||
|
||||
// DeleteChannelScheme deletes a channels scheme and sets its SchemeId to nil.
|
||||
func (a *App) DeleteChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError) {
|
||||
if _, err := a.DeleteScheme(*channel.SchemeId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channel.SchemeId = nil
|
||||
return a.UpdateChannelScheme(channel)
|
||||
}
|
||||
|
||||
// UpdateChannelScheme saves the new SchemeId of the channel passed.
|
||||
func (a *App) UpdateChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError) {
|
||||
var oldChannel *model.Channel
|
||||
var err *model.AppError
|
||||
@@ -555,13 +583,7 @@ func (a *App) UpdateChannelScheme(channel *model.Channel) (*model.Channel, *mode
|
||||
}
|
||||
|
||||
oldChannel.SchemeId = channel.SchemeId
|
||||
|
||||
newChannel, err := a.UpdateChannel(oldChannel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newChannel, nil
|
||||
return a.UpdateChannel(oldChannel)
|
||||
}
|
||||
|
||||
func (a *App) UpdateChannelPrivacy(oldChannel *model.Channel, user *model.User) (*model.Channel, *model.AppError) {
|
||||
@@ -685,35 +707,185 @@ func (a *App) PatchChannel(channel *model.Channel, patch *model.ChannelPatch, us
|
||||
return channel, nil
|
||||
}
|
||||
|
||||
func (a *App) GetSchemeRolesForChannel(channelId string) (string, string, string, *model.AppError) {
|
||||
// GetSchemeRolesForChannel Checks if a channel or its team has an override scheme for channel roles and returns the scheme roles or default channel roles.
|
||||
func (a *App) GetSchemeRolesForChannel(channelId string) (guestRoleName, userRoleName, adminRoleName string, err *model.AppError) {
|
||||
channel, err := a.GetChannel(channelId)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return
|
||||
}
|
||||
|
||||
if channel.SchemeId != nil && len(*channel.SchemeId) != 0 {
|
||||
var scheme *model.Scheme
|
||||
scheme, err = a.GetScheme(*channel.SchemeId)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return
|
||||
}
|
||||
return scheme.DefaultChannelGuestRole, scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole, nil
|
||||
|
||||
guestRoleName = scheme.DefaultChannelGuestRole
|
||||
userRoleName = scheme.DefaultChannelUserRole
|
||||
adminRoleName = scheme.DefaultChannelAdminRole
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
team, err := a.GetTeam(channel.TeamId)
|
||||
return a.GetTeamSchemeChannelRoles(channel.TeamId)
|
||||
}
|
||||
|
||||
// GetTeamSchemeChannelRoles Checks if a team has an override scheme and returns the scheme channel role names or default channel role names.
|
||||
func (a *App) GetTeamSchemeChannelRoles(teamId string) (guestRoleName, userRoleName, adminRoleName string, err *model.AppError) {
|
||||
team, err := a.GetTeam(teamId)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return
|
||||
}
|
||||
|
||||
if team.SchemeId != nil && len(*team.SchemeId) != 0 {
|
||||
scheme, err := a.GetScheme(*team.SchemeId)
|
||||
var scheme *model.Scheme
|
||||
scheme, err = a.GetScheme(*team.SchemeId)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return
|
||||
}
|
||||
return scheme.DefaultChannelGuestRole, scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole, nil
|
||||
|
||||
guestRoleName = scheme.DefaultChannelGuestRole
|
||||
userRoleName = scheme.DefaultChannelUserRole
|
||||
adminRoleName = scheme.DefaultChannelAdminRole
|
||||
} else {
|
||||
guestRoleName = model.CHANNEL_GUEST_ROLE_ID
|
||||
userRoleName = model.CHANNEL_USER_ROLE_ID
|
||||
adminRoleName = model.CHANNEL_ADMIN_ROLE_ID
|
||||
}
|
||||
|
||||
return model.CHANNEL_GUEST_ROLE_ID, model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, nil
|
||||
return
|
||||
}
|
||||
|
||||
// PatchChannelModerationsForChannel Gets a channels ChannelModerations from either the higherScoped roles or from the channel scheme roles.
|
||||
func (a *App) GetChannelModerationsForChannel(channel *model.Channel) ([]*model.ChannelModeration, *model.AppError) {
|
||||
guestRoleName, memberRoleName, _, _ := a.GetSchemeRolesForChannel(channel.Id)
|
||||
memberRole, err := a.GetRoleByName(memberRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
guestRole, err := a.GetRoleByName(guestRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
higherScopedGuestRoleName, higherScopedMemberRoleName, _, _ := a.GetTeamSchemeChannelRoles(channel.TeamId)
|
||||
higherScopedMemberRole, err := a.GetRoleByName(higherScopedMemberRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
higherScopedGuestRole, err := a.GetRoleByName(higherScopedGuestRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buildChannelModerations(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.
|
||||
func (a *App) PatchChannelModerationsForChannel(channel *model.Channel, channelModerationsPatch []*model.ChannelModerationPatch) ([]*model.ChannelModeration, *model.AppError) {
|
||||
higherScopedGuestRoleName, higherScopedMemberRoleName, _, _ := a.GetTeamSchemeChannelRoles(channel.TeamId)
|
||||
higherScopedMemberRole, err := a.GetRoleByName(higherScopedMemberRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
higherScopedGuestRole, err := a.GetRoleByName(higherScopedGuestRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
higherScopedMemberPermissions := higherScopedMemberRole.GetChannelModeratedPermissions()
|
||||
higherScopedGuestPermissions := higherScopedGuestRole.GetChannelModeratedPermissions()
|
||||
|
||||
for _, moderationPatch := range channelModerationsPatch {
|
||||
if moderationPatch.Roles.Members != nil && *moderationPatch.Roles.Members && !higherScopedMemberPermissions[*moderationPatch.Name] {
|
||||
return nil, &model.AppError{Message: "Cannot add a permission that is restricted by the team or system permission scheme"}
|
||||
}
|
||||
if moderationPatch.Roles.Guests != nil && *moderationPatch.Roles.Guests && !higherScopedGuestPermissions[*moderationPatch.Name] {
|
||||
return nil, &model.AppError{Message: "Cannot add a permission that is restricted by the team or system permission scheme"}
|
||||
}
|
||||
}
|
||||
|
||||
// Channel has no scheme so create one
|
||||
if channel.SchemeId == nil || len(*channel.SchemeId) == 0 {
|
||||
if _, err = a.CreateChannelScheme(channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
guestRoleName, memberRoleName, _, _ := a.GetSchemeRolesForChannel(channel.Id)
|
||||
memberRole, err := a.GetRoleByName(memberRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
guestRole, err := a.GetRoleByName(guestRoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberRolePatch := memberRole.RolePatchFromChannelModerationsPatch(channelModerationsPatch, "members")
|
||||
guestRolePatch := guestRole.RolePatchFromChannelModerationsPatch(channelModerationsPatch, "guests")
|
||||
|
||||
memberRolePermissionsUnmodified := len(model.ChannelModeratedPermissionsChangedByPatch(higherScopedMemberRole, memberRolePatch)) == 0
|
||||
guestRolePermissionsUnmodified := len(model.ChannelModeratedPermissionsChangedByPatch(higherScopedGuestRole, guestRolePatch)) == 0
|
||||
if memberRolePermissionsUnmodified && guestRolePermissionsUnmodified {
|
||||
// The channel scheme matches the permissions of its higherScoped scheme so delete the scheme
|
||||
if _, err = a.DeleteChannelScheme(channel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
memberRole = higherScopedMemberRole
|
||||
guestRole = higherScopedGuestRole
|
||||
} else {
|
||||
memberRole, err = a.PatchRole(memberRole, memberRolePatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
guestRole, err = a.PatchRole(guestRole, guestRolePatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return buildChannelModerations(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()
|
||||
|
||||
var channelModerations []*model.ChannelModeration
|
||||
for _, permissionKey := range model.CHANNEL_MODERATED_PERMISSIONS {
|
||||
roles := &model.ChannelModeratedRoles{}
|
||||
|
||||
roles.Members = &model.ChannelModeratedRole{
|
||||
Value: memberPermissions[permissionKey],
|
||||
Enabled: higherScopedMemberPermissions[permissionKey],
|
||||
}
|
||||
|
||||
if permissionKey == "manage_members" {
|
||||
roles.Guests = nil
|
||||
} else {
|
||||
roles.Guests = &model.ChannelModeratedRole{
|
||||
Value: guestPermissions[permissionKey],
|
||||
Enabled: higherScopedGuestPermissions[permissionKey],
|
||||
}
|
||||
}
|
||||
|
||||
moderation := &model.ChannelModeration{
|
||||
Name: permissionKey,
|
||||
Roles: roles,
|
||||
}
|
||||
|
||||
channelModerations = append(channelModerations, moderation)
|
||||
}
|
||||
|
||||
return channelModerations
|
||||
}
|
||||
|
||||
func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles string) (*model.ChannelMember, *model.AppError) {
|
||||
|
||||
@@ -1301,3 +1301,350 @@ func TestRemoveUserFromChannel(t *testing.T) {
|
||||
err = th.App.RemoveUserFromChannel(botUser.Id, th.SystemAdminUser.Id, privateChannel)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestPatchChannelModerationsForChannel(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.App.SetPhase2PermissionsMigrationStatus(true)
|
||||
channel := th.BasicChannel
|
||||
|
||||
createPosts := model.CHANNEL_MODERATED_PERMISSIONS[0]
|
||||
createReactions := model.CHANNEL_MODERATED_PERMISSIONS[1]
|
||||
manageMembers := model.CHANNEL_MODERATED_PERMISSIONS[2]
|
||||
channelMentions := model.CHANNEL_MODERATED_PERMISSIONS[3]
|
||||
|
||||
nonChannelModeratedPermission := model.PERMISSION_CREATE_BOT.Id
|
||||
|
||||
testCases := []struct {
|
||||
Name string
|
||||
ChannelModerationsPatch []*model.ChannelModerationPatch
|
||||
PermissionsModeratedByPatch map[string]*model.ChannelModeratedRoles
|
||||
RevertChannelModerationsPatch []*model.ChannelModerationPatch
|
||||
HigherScopedMemberPermissions []string
|
||||
HigherScopedGuestPermissions []string
|
||||
ShouldError bool
|
||||
ShouldHaveNoChannelScheme bool
|
||||
}{
|
||||
{
|
||||
Name: "Removing create posts from members role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
createPosts: {
|
||||
Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing create reactions from members role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createReactions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
createReactions: {
|
||||
Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createReactions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing channel mentions from members role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &channelMentions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
channelMentions: {
|
||||
Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &channelMentions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing manage members from members role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &manageMembers,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
manageMembers: {
|
||||
Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &manageMembers,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Members: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing create posts from guests role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
createPosts: {
|
||||
Guests: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing create reactions from guests role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createReactions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
createReactions: {
|
||||
Guests: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createReactions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing channel mentions from guests role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &channelMentions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
channelMentions: {
|
||||
Guests: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
},
|
||||
},
|
||||
RevertChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &channelMentions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(true)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Removing manage members from guests role should error",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &manageMembers,
|
||||
Roles: &model.ChannelModeratedRolesPatch{Guests: model.NewBool(false)},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
|
||||
ShouldError: true,
|
||||
},
|
||||
{
|
||||
Name: "Removing a permission that is not channel moderated should error",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &nonChannelModeratedPermission,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(false),
|
||||
Guests: model.NewBool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
|
||||
ShouldError: true,
|
||||
},
|
||||
{
|
||||
Name: "Error when adding a permission that is disabled in the parent member role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(true),
|
||||
Guests: model.NewBool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
|
||||
HigherScopedMemberPermissions: []string{},
|
||||
ShouldError: true,
|
||||
},
|
||||
{
|
||||
Name: "Error when adding a permission that is disabled in the parent guest role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(false),
|
||||
Guests: model.NewBool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
|
||||
HigherScopedGuestPermissions: []string{},
|
||||
ShouldError: true,
|
||||
},
|
||||
{
|
||||
Name: "Removing a permission from the member role that is disabled in the parent guest role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{
|
||||
createPosts: {
|
||||
Members: &model.ChannelModeratedRole{Value: false, Enabled: true},
|
||||
Guests: &model.ChannelModeratedRole{Value: false, Enabled: false},
|
||||
},
|
||||
createReactions: {
|
||||
Guests: &model.ChannelModeratedRole{Value: false, Enabled: false},
|
||||
},
|
||||
channelMentions: {
|
||||
Guests: &model.ChannelModeratedRole{Value: false, Enabled: false},
|
||||
},
|
||||
},
|
||||
HigherScopedGuestPermissions: []string{},
|
||||
ShouldError: false,
|
||||
},
|
||||
{
|
||||
Name: "Channel should have no scheme when all moderated permissions are equivalent to higher scoped role",
|
||||
ChannelModerationsPatch: []*model.ChannelModerationPatch{
|
||||
{
|
||||
Name: &createPosts,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(true),
|
||||
Guests: model.NewBool(true),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: &createReactions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(true),
|
||||
Guests: model.NewBool(true),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: &channelMentions,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(true),
|
||||
Guests: model.NewBool(true),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: &manageMembers,
|
||||
Roles: &model.ChannelModeratedRolesPatch{
|
||||
Members: model.NewBool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
PermissionsModeratedByPatch: map[string]*model.ChannelModeratedRoles{},
|
||||
ShouldHaveNoChannelScheme: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
higherScopedPermissionsOverriden := tc.HigherScopedMemberPermissions != nil || tc.HigherScopedGuestPermissions != nil
|
||||
// If the test case restricts higher scoped permissions.
|
||||
if higherScopedPermissionsOverriden {
|
||||
higherScopedGuestRoleName, higherScopedMemberRoleName, _, _ := th.App.GetTeamSchemeChannelRoles(channel.TeamId)
|
||||
if tc.HigherScopedMemberPermissions != nil {
|
||||
higherScopedMemberRole, err := th.App.GetRoleByName(higherScopedMemberRoleName)
|
||||
require.Nil(t, err)
|
||||
originalPermissions := higherScopedMemberRole.Permissions
|
||||
|
||||
th.App.PatchRole(higherScopedMemberRole, &model.RolePatch{Permissions: &tc.HigherScopedMemberPermissions})
|
||||
defer th.App.PatchRole(higherScopedMemberRole, &model.RolePatch{Permissions: &originalPermissions})
|
||||
}
|
||||
|
||||
if tc.HigherScopedGuestPermissions != nil {
|
||||
higherScopedGuestRole, err := th.App.GetRoleByName(higherScopedGuestRoleName)
|
||||
require.Nil(t, err)
|
||||
originalPermissions := higherScopedGuestRole.Permissions
|
||||
|
||||
th.App.PatchRole(higherScopedGuestRole, &model.RolePatch{Permissions: &tc.HigherScopedGuestPermissions})
|
||||
defer th.App.PatchRole(higherScopedGuestRole, &model.RolePatch{Permissions: &originalPermissions})
|
||||
}
|
||||
}
|
||||
|
||||
moderations, err := th.App.PatchChannelModerationsForChannel(channel, tc.ChannelModerationsPatch)
|
||||
if tc.ShouldError {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.Nil(t, err)
|
||||
|
||||
updatedChannel, _ := th.App.GetChannel(channel.Id)
|
||||
if tc.ShouldHaveNoChannelScheme {
|
||||
require.Nil(t, updatedChannel.SchemeId)
|
||||
} else {
|
||||
require.NotNil(t, updatedChannel.SchemeId)
|
||||
}
|
||||
|
||||
for _, moderation := range moderations {
|
||||
// If the permission is not found in the expected modified permissions table then require it to be true
|
||||
if permission, found := tc.PermissionsModeratedByPatch[moderation.Name]; found && permission.Members != nil {
|
||||
require.Equal(t, moderation.Roles.Members.Value, permission.Members.Value)
|
||||
require.Equal(t, moderation.Roles.Members.Enabled, permission.Members.Enabled)
|
||||
} else {
|
||||
require.Equal(t, moderation.Roles.Members.Value, true)
|
||||
require.Equal(t, moderation.Roles.Members.Enabled, true)
|
||||
}
|
||||
|
||||
if permission, found := tc.PermissionsModeratedByPatch[moderation.Name]; found && permission.Guests != nil {
|
||||
require.Equal(t, moderation.Roles.Guests.Value, permission.Guests.Value)
|
||||
require.Equal(t, moderation.Roles.Guests.Enabled, permission.Guests.Enabled)
|
||||
} else if moderation.Name == manageMembers {
|
||||
require.Empty(t, moderation.Roles.Guests)
|
||||
} else {
|
||||
require.Equal(t, moderation.Roles.Guests.Value, true)
|
||||
require.Equal(t, moderation.Roles.Guests.Enabled, true)
|
||||
}
|
||||
}
|
||||
|
||||
if tc.RevertChannelModerationsPatch != nil {
|
||||
th.App.PatchChannelModerationsForChannel(channel, tc.RevertChannelModerationsPatch)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user