Adding list/join public/private teams permissions (#10309)
* Adding list/join public/private teams permissions * Add permission migration and allow to migrate based on role name * Adding JoinTeam new endpoint * Addressing PR review comments * Keep the previous API consistent
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
030ba52b08
Коммит
5a9d95d9c7
@@ -121,6 +121,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
},
|
||||
"system_user": []string{
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
model.PERMISSION_PERMANENT_DELETE_USER.Id,
|
||||
@@ -173,6 +175,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_MANAGE_BOTS.Id,
|
||||
model.PERMISSION_MANAGE_OTHERS_BOTS.Id,
|
||||
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
model.PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -298,6 +302,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
},
|
||||
"system_user": []string{
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
model.PERMISSION_PERMANENT_DELETE_USER.Id,
|
||||
@@ -350,6 +356,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_MANAGE_BOTS.Id,
|
||||
model.PERMISSION_MANAGE_OTHERS_BOTS.Id,
|
||||
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
model.PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -491,6 +499,8 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_MANAGE_BOTS.Id,
|
||||
model.PERMISSION_MANAGE_OTHERS_BOTS.Id,
|
||||
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
model.PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -568,6 +578,8 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
|
||||
role3, err3 := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
|
||||
assert.Nil(t, err3)
|
||||
expected3 := []string{
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
model.PERMISSION_PERMANENT_DELETE_USER.Id,
|
||||
|
||||
@@ -3,19 +3,23 @@
|
||||
|
||||
package app
|
||||
|
||||
import "github.com/mattermost/mattermost-server/model"
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
)
|
||||
|
||||
type permissionTransformation struct {
|
||||
On func(map[string]bool) bool
|
||||
On func(string, map[string]bool) bool
|
||||
Add []string
|
||||
Remove []string
|
||||
}
|
||||
type permissionsMap []permissionTransformation
|
||||
|
||||
const (
|
||||
MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split"
|
||||
MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_permissions_split"
|
||||
MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split"
|
||||
MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_permissions_split"
|
||||
MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS = "list_join_public_private_teams"
|
||||
|
||||
PERMISSION_MANAGE_SYSTEM = "manage_system"
|
||||
PERMISSION_MANAGE_EMOJIS = "manage_emojis"
|
||||
PERMISSION_MANAGE_OTHERS_EMOJIS = "manage_others_emojis"
|
||||
PERMISSION_CREATE_EMOJIS = "create_emojis"
|
||||
@@ -27,26 +31,36 @@ const (
|
||||
PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS = "manage_others_incoming_webhooks"
|
||||
PERMISSION_MANAGE_OUTGOING_WEBHOOKS = "manage_outgoing_webhooks"
|
||||
PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS = "manage_others_outgoing_webhooks"
|
||||
PERMISSION_LIST_PUBLIC_TEAMS = "list_public_teams"
|
||||
PERMISSION_LIST_PRIVATE_TEAMS = "list_private_teams"
|
||||
PERMISSION_JOIN_PUBLIC_TEAMS = "join_public_teams"
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS = "join_private_teams"
|
||||
)
|
||||
|
||||
func permissionExists(permission string) func(map[string]bool) bool {
|
||||
return func(permissions map[string]bool) bool {
|
||||
func isRole(role string) func(string, map[string]bool) bool {
|
||||
return func(roleName string, permissions map[string]bool) bool {
|
||||
return roleName == role
|
||||
}
|
||||
}
|
||||
|
||||
func permissionExists(permission string) func(string, map[string]bool) bool {
|
||||
return func(roleName string, permissions map[string]bool) bool {
|
||||
val, ok := permissions[permission]
|
||||
return ok && val
|
||||
}
|
||||
}
|
||||
|
||||
func permissionNotExists(permission string) func(map[string]bool) bool {
|
||||
return func(permissions map[string]bool) bool {
|
||||
func permissionNotExists(permission string) func(string, map[string]bool) bool {
|
||||
return func(roleName string, permissions map[string]bool) bool {
|
||||
val, ok := permissions[permission]
|
||||
return !(ok && val)
|
||||
}
|
||||
}
|
||||
|
||||
func permissionOr(funcs ...func(map[string]bool) bool) func(map[string]bool) bool {
|
||||
return func(permissions map[string]bool) bool {
|
||||
func permissionOr(funcs ...func(string, map[string]bool) bool) func(string, map[string]bool) bool {
|
||||
return func(roleName string, permissions map[string]bool) bool {
|
||||
for _, f := range funcs {
|
||||
if f(permissions) {
|
||||
if f(roleName, permissions) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -54,10 +68,10 @@ func permissionOr(funcs ...func(map[string]bool) bool) func(map[string]bool) boo
|
||||
}
|
||||
}
|
||||
|
||||
func permissionAnd(funcs ...func(map[string]bool) bool) func(map[string]bool) bool {
|
||||
return func(permissions map[string]bool) bool {
|
||||
func permissionAnd(funcs ...func(string, map[string]bool) bool) func(string, map[string]bool) bool {
|
||||
return func(roleName string, permissions map[string]bool) bool {
|
||||
for _, f := range funcs {
|
||||
if !f(permissions) {
|
||||
if !f(roleName, permissions) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -65,7 +79,7 @@ func permissionAnd(funcs ...func(map[string]bool) bool) func(map[string]bool) bo
|
||||
}
|
||||
}
|
||||
|
||||
func applyPermissionsMap(permissions []string, migrationMap permissionsMap) []string {
|
||||
func applyPermissionsMap(roleName string, permissions []string, migrationMap permissionsMap) []string {
|
||||
finalMap := make(map[string]bool)
|
||||
var result []string
|
||||
for _, permission := range permissions {
|
||||
@@ -73,7 +87,7 @@ func applyPermissionsMap(permissions []string, migrationMap permissionsMap) []st
|
||||
}
|
||||
|
||||
for _, transformation := range migrationMap {
|
||||
if transformation.On(finalMap) {
|
||||
if transformation.On(roleName, finalMap) {
|
||||
for _, add := range transformation.Add {
|
||||
finalMap[add] = true
|
||||
}
|
||||
@@ -102,7 +116,7 @@ func (a *App) doPermissionsMigration(key string, migrationMap permissionsMap) *m
|
||||
}
|
||||
|
||||
for _, role := range roles {
|
||||
role.Permissions = applyPermissionsMap(role.Permissions, migrationMap)
|
||||
role.Permissions = applyPermissionsMap(role.Name, role.Permissions, migrationMap)
|
||||
if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
|
||||
return result.Err
|
||||
}
|
||||
@@ -144,6 +158,21 @@ func getWebhooksPermissionsSplitMigration() permissionsMap {
|
||||
}
|
||||
}
|
||||
|
||||
func getListJoinPublicPrivateTeamsPermissionsMigration() permissionsMap {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_LIST_PRIVATE_TEAMS, PERMISSION_JOIN_PRIVATE_TEAMS},
|
||||
Remove: []string{},
|
||||
},
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_USER_ROLE_ID),
|
||||
Add: []string{PERMISSION_LIST_PUBLIC_TEAMS, PERMISSION_JOIN_PUBLIC_TEAMS},
|
||||
Remove: []string{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
||||
func (a *App) DoPermissionsMigrations() *model.AppError {
|
||||
PermissionsMigrations := []struct {
|
||||
@@ -152,6 +181,7 @@ func (a *App) DoPermissionsMigrations() *model.AppError {
|
||||
}{
|
||||
{Key: MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration},
|
||||
{Key: MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration},
|
||||
{Key: MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: getListJoinPublicPrivateTeamsPermissionsMigration},
|
||||
}
|
||||
|
||||
for _, migration := range PermissionsMigrations {
|
||||
|
||||
@@ -77,11 +77,29 @@ func TestApplyPermissionsMap(t *testing.T) {
|
||||
}},
|
||||
[]string{"test1", "test2", "test3"},
|
||||
},
|
||||
{
|
||||
"When the role matches",
|
||||
[]string{"test1", "test2", "test3"},
|
||||
permissionsMap{permissionTransformation{
|
||||
On: isRole("system_admin"),
|
||||
Add: []string{"test4"},
|
||||
}},
|
||||
[]string{"test1", "test2", "test3", "test4"},
|
||||
},
|
||||
{
|
||||
"When the role doesn't match",
|
||||
[]string{"test1", "test2", "test3"},
|
||||
permissionsMap{permissionTransformation{
|
||||
On: isRole("system_user"),
|
||||
Add: []string{"test4"},
|
||||
}},
|
||||
[]string{"test1", "test2", "test3"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
result := applyPermissionsMap(tc.Permissions, tc.TranslationMap)
|
||||
result := applyPermissionsMap("system_admin", tc.Permissions, tc.TranslationMap)
|
||||
sort.Strings(result)
|
||||
assert.Equal(t, tc.ExpectedResult, result)
|
||||
})
|
||||
|
||||
32
app/team.go
32
app/team.go
@@ -562,7 +562,23 @@ func (a *App) GetAllTeamsPage(offset int, limit int) ([]*model.Team, *model.AppE
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) GetAllOpenTeams() ([]*model.Team, *model.AppError) {
|
||||
func (a *App) GetAllPrivateTeams() ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetAllPrivateTeamListing()
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) GetAllPrivateTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetAllPrivateTeamPageListing(offset, limit)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) GetAllPublicTeams() ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetAllTeamListing()
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
@@ -570,6 +586,14 @@ func (a *App) GetAllOpenTeams() ([]*model.Team, *model.AppError) {
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) GetAllPublicTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetAllTeamPageListing(offset, limit)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().SearchAll(term)
|
||||
if result.Err != nil {
|
||||
@@ -578,7 +602,7 @@ func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) {
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) SearchOpenTeams(term string) ([]*model.Team, *model.AppError) {
|
||||
func (a *App) SearchPublicTeams(term string) ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().SearchOpen(term)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
@@ -586,8 +610,8 @@ func (a *App) SearchOpenTeams(term string) ([]*model.Team, *model.AppError) {
|
||||
return result.Data.([]*model.Team), nil
|
||||
}
|
||||
|
||||
func (a *App) GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetAllTeamPageListing(offset, limit)
|
||||
func (a *App) SearchPrivateTeams(term string) ([]*model.Team, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().SearchPrivate(term)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user