[MM-21919] Add use_channel_mentions permission (#13781)

* MM-21919 Add channel_mention permission

* MM-21919 Fix emojis migration test

* Enforce Channel Mentions on the in the posts api

* MM-21919 Rename permission to use_channel_mentions

Allow posts with channel mentions to still be posted without the permission just don't send notifications to users

* MM-21919 Add tests for a post with @all and @here

* MM-21919 Add use channel mentions to all roles that have create post

* MM-21919 Update app_test to include use_channel_mentions permission in default permissions
Этот коммит содержится в:
Farhan Munshi
2020-02-12 10:45:34 -05:00
коммит произвёл GitHub
родитель a7854f1b97
Коммит 897715f883
7 изменённых файлов: 85 добавлений и 25 удалений

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

@@ -112,6 +112,30 @@ func TestCreatePost(t *testing.T) {
assert.Equal(t, model.StringArray{fileId}, actualPostWithFiles.FileIds)
})
t.Run("creates a post that has channel mentions without the USE_CHANNEL_MENTIONS Permission", func(t *testing.T) {
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
post.RootId = rpost.Id
post.ParentId = rpost.Id
post.Message = "a post with @channel"
_, resp = Client.CreatePost(post)
CheckNoError(t, resp)
post.RootId = rpost.Id
post.ParentId = rpost.Id
post.Message = "a post with @all"
_, resp = Client.CreatePost(post)
CheckNoError(t, resp)
post.RootId = rpost.Id
post.ParentId = rpost.Id
post.Message = "a post with @here"
_, resp = Client.CreatePost(post)
CheckNoError(t, resp)
})
post.RootId = ""
post.ParentId = ""
post.Type = model.POST_SYSTEM_GENERIC

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

@@ -77,6 +77,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
@@ -101,9 +102,11 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
},
"team_post_all": {
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"team_post_all_public": {
model.PERMISSION_CREATE_POST_PUBLIC.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"team_admin": {
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
@@ -130,9 +133,11 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
},
"system_post_all": {
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"system_post_all_public": {
model.PERMISSION_CREATE_POST_PUBLIC.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"system_user_access_token": {
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
@@ -191,6 +196,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
model.PERMISSION_MANAGE_TEAM.Id,
@@ -262,6 +268,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
@@ -284,9 +291,11 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
},
"team_post_all": {
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"team_post_all_public": {
model.PERMISSION_CREATE_POST_PUBLIC.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"team_admin": {
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
@@ -315,9 +324,11 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
},
"system_post_all": {
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"system_post_all_public": {
model.PERMISSION_CREATE_POST_PUBLIC.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
"system_user_access_token": {
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
@@ -376,6 +387,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
model.PERMISSION_MANAGE_TEAM.Id,
@@ -537,6 +549,7 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
model.PERMISSION_DELETE_EMOJIS.Id,
model.PERMISSION_DELETE_OTHERS_EMOJIS.Id,
model.PERMISSION_VIEW_MEMBERS.Id,
model.PERMISSION_USE_CHANNEL_MENTIONS.Id,
}
sort.Strings(expectedSystemAdmin)

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

@@ -624,6 +624,10 @@ func getMentionsEnabledFields(post *model.Post) model.StringArray {
// allowChannelMentions returns whether or not the channel mentions are allowed for the given post.
func (a *App) allowChannelMentions(post *model.Post, numProfiles int) bool {
if !a.HasPermissionToChannel(post.UserId, post.ChannelId, model.PERMISSION_USE_CHANNEL_MENTIONS) {
return false
}
if post.Type == model.POST_HEADER_CHANGE || post.Type == model.POST_PURPOSE_CHANGE {
return false
}

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

@@ -876,47 +876,37 @@ func TestGetExplicitMentionsAtHere(t *testing.T) {
}
func TestAllowChannelMentions(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
post := &model.Post{ChannelId: th.BasicChannel.Id, UserId: th.BasicUser.Id}
t.Run("should return true for a regular post with few channel members", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
post := &model.Post{}
allowChannelMentions := th.App.allowChannelMentions(post, 5)
assert.True(t, allowChannelMentions)
})
t.Run("should return false for a channel header post", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
post := &model.Post{Type: model.POST_HEADER_CHANGE}
allowChannelMentions := th.App.allowChannelMentions(post, 5)
headerChangePost := &model.Post{ChannelId: th.BasicChannel.Id, UserId: th.BasicUser.Id, Type: model.POST_HEADER_CHANGE}
allowChannelMentions := th.App.allowChannelMentions(headerChangePost, 5)
assert.False(t, allowChannelMentions)
})
t.Run("should return false for a channel purpose post", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
post := &model.Post{Type: model.POST_PURPOSE_CHANGE}
allowChannelMentions := th.App.allowChannelMentions(post, 5)
purposeChangePost := &model.Post{ChannelId: th.BasicChannel.Id, UserId: th.BasicUser.Id, Type: model.POST_PURPOSE_CHANGE}
allowChannelMentions := th.App.allowChannelMentions(purposeChangePost, 5)
assert.False(t, allowChannelMentions)
})
t.Run("should return false for a regular post with many channel members", func(t *testing.T) {
th := Setup(t)
defer th.TearDown()
post := &model.Post{}
allowChannelMentions := th.App.allowChannelMentions(post, int(*th.App.Config().TeamSettings.MaxNotificationsPerChannel)+1)
assert.False(t, allowChannelMentions)
})
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)
th.RemovePermissionFromRole(model.PERMISSION_USE_CHANNEL_MENTIONS.Id, model.CHANNEL_USER_ROLE_ID)
allowChannelMentions := th.App.allowChannelMentions(post, 5)
assert.False(t, allowChannelMentions)
})
}

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

@@ -24,6 +24,7 @@ const (
MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER = "remove_channel_manage_delete_from_team_user"
MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION = "view_members_new_permission"
MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS = "add_manage_guests_permissions"
MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION = "add_use_channel_mentions_permission"
PERMISSION_MANAGE_SYSTEM = "manage_system"
PERMISSION_MANAGE_EMOJIS = "manage_emojis"
@@ -56,6 +57,9 @@ const (
PERMISSION_INVITE_GUEST = "invite_guest"
PERMISSION_PROMOTE_GUEST = "promote_guest"
PERMISSION_DEMOTE_TO_GUEST = "demote_to_guest"
PERMISSION_USE_CHANNEL_MENTIONS = "use_channel_mentions"
PERMISSION_CREATE_POST = "create_post"
PERMISSION_CREATE_POST_PUBLIC = "create_post_public"
)
func isRole(role string) func(string, map[string]map[string]bool) bool {
@@ -287,6 +291,15 @@ func getAddManageGuestsPermissionsMigration() permissionsMap {
}
}
func getAddUseMentionChannelsPermissionMigration() permissionsMap {
return permissionsMap{
permissionTransformation{
On: permissionOr(permissionExists(PERMISSION_CREATE_POST), permissionExists(PERMISSION_CREATE_POST_PUBLIC)),
Add: []string{PERMISSION_USE_CHANNEL_MENTIONS},
},
}
}
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
func (a *App) DoPermissionsMigrations() *model.AppError {
PermissionsMigrations := []struct {
@@ -302,6 +315,7 @@ func (a *App) DoPermissionsMigrations() *model.AppError {
{Key: MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: removeChannelManageDeleteFromTeamUser},
{Key: MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Migration: getViewMembersPermissionMigration},
{Key: MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS, Migration: getAddManageGuestsPermissionsMigration},
{Key: MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION, Migration: getAddUseMentionChannelsPermissionMigration},
}
for _, migration := range PermissionsMigrations {

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

@@ -90,6 +90,7 @@ var PERMISSION_VIEW_MEMBERS *Permission
var PERMISSION_INVITE_GUEST *Permission
var PERMISSION_PROMOTE_GUEST *Permission
var PERMISSION_DEMOTE_TO_GUEST *Permission
var PERMISSION_USE_CHANNEL_MENTIONS *Permission
// General permission that encompasses all system admin functions
// in the future this could be broken up to allow access to some
@@ -556,6 +557,13 @@ func initializePermissions() {
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_USE_CHANNEL_MENTIONS = &Permission{
"use_channel_mentions",
"authentication.permissions.use_channel_mentions.name",
"authentication.permissions.use_channel_mentions.description",
PERMISSION_SCOPE_CHANNEL,
}
ALL_PERMISSIONS = []*Permission{
PERMISSION_INVITE_USER,
PERMISSION_ADD_USER_TO_TEAM,
@@ -631,6 +639,7 @@ func initializePermissions() {
PERMISSION_INVITE_GUEST,
PERMISSION_PROMOTE_GUEST,
PERMISSION_DEMOTE_TO_GUEST,
PERMISSION_USE_CHANNEL_MENTIONS,
}
}

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

@@ -187,6 +187,7 @@ func MakeDefaultRoles() map[string]*Role {
PERMISSION_UPLOAD_FILE.Id,
PERMISSION_EDIT_POST.Id,
PERMISSION_CREATE_POST.Id,
PERMISSION_USE_CHANNEL_MENTIONS.Id,
PERMISSION_USE_SLASH_COMMANDS.Id,
},
SchemeManaged: true,
@@ -205,6 +206,7 @@ func MakeDefaultRoles() map[string]*Role {
PERMISSION_UPLOAD_FILE.Id,
PERMISSION_GET_PUBLIC_LINK.Id,
PERMISSION_CREATE_POST.Id,
PERMISSION_USE_CHANNEL_MENTIONS.Id,
PERMISSION_USE_SLASH_COMMANDS.Id,
},
SchemeManaged: true,
@@ -253,6 +255,7 @@ func MakeDefaultRoles() map[string]*Role {
Description: "authentication.roles.team_post_all.description",
Permissions: []string{
PERMISSION_CREATE_POST.Id,
PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
SchemeManaged: false,
BuiltIn: true,
@@ -264,6 +267,7 @@ func MakeDefaultRoles() map[string]*Role {
Description: "authentication.roles.team_post_all_public.description",
Permissions: []string{
PERMISSION_CREATE_POST_PUBLIC.Id,
PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
SchemeManaged: false,
BuiltIn: true,
@@ -323,6 +327,7 @@ func MakeDefaultRoles() map[string]*Role {
Description: "authentication.roles.system_post_all.description",
Permissions: []string{
PERMISSION_CREATE_POST.Id,
PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
SchemeManaged: false,
BuiltIn: true,
@@ -334,6 +339,7 @@ func MakeDefaultRoles() map[string]*Role {
Description: "authentication.roles.system_post_all_public.description",
Permissions: []string{
PERMISSION_CREATE_POST_PUBLIC.Id,
PERMISSION_USE_CHANNEL_MENTIONS.Id,
},
SchemeManaged: false,
BuiltIn: true,