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
Этот коммит содержится в:
Jesús Espino
2019-03-19 11:36:29 +01:00
коммит произвёл GitHub
родитель 030ba52b08
Коммит 5a9d95d9c7
13 изменённых файлов: 802 добавлений и 217 удалений

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

@@ -364,9 +364,27 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
if !c.App.SessionHasPermissionToTeam(c.App.Session, member.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) { if member.UserId == c.App.Session.UserId {
c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM) var team *model.Team
return team, err = c.App.GetTeam(member.TeamId)
if err != nil {
c.Err = err
return
}
if team.AllowOpenInvite && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_JOIN_PUBLIC_TEAMS) {
c.SetPermissionError(model.PERMISSION_JOIN_PUBLIC_TEAMS)
return
}
if !team.AllowOpenInvite && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_JOIN_PRIVATE_TEAMS) {
c.SetPermissionError(model.PERMISSION_JOIN_PRIVATE_TEAMS)
return
}
} else {
if !c.App.SessionHasPermissionToTeam(c.App.Session, member.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
return
}
} }
member, err = c.App.AddTeamMember(member.TeamId, member.UserId) member, err = c.App.AddTeamMember(member.TeamId, member.UserId)
@@ -571,10 +589,12 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
var teams []*model.Team var teams []*model.Team
var err *model.AppError var err *model.AppError
if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) { if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) && c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
teams, err = c.App.GetAllTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) teams, err = c.App.GetAllTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
} else { } else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) {
teams, err = c.App.GetAllOpenTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage) teams, err = c.App.GetAllPrivateTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
teams, err = c.App.GetAllPublicTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
} }
if err != nil { if err != nil {
@@ -602,10 +622,14 @@ func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) {
var teams []*model.Team var teams []*model.Team
var err *model.AppError var err *model.AppError
if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) { if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) && c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
teams, err = c.App.SearchAllTeams(props.Term) teams, err = c.App.SearchAllTeams(props.Term)
} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) {
teams, err = c.App.SearchPrivateTeams(props.Term)
} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
teams, err = c.App.SearchPublicTeams(props.Term)
} else { } else {
teams, err = c.App.SearchOpenTeams(props.Term) teams = []*model.Team{}
} }
if err != nil { if err != nil {
@@ -752,7 +776,7 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
if !(team.Type == model.TEAM_OPEN) { if team.Type != model.TEAM_OPEN {
c.Err = model.NewAppError("getInviteInfo", "api.team.get_invite_info.not_open_team", nil, "id="+c.Params.InviteId, http.StatusForbidden) c.Err = model.NewAppError("getInviteInfo", "api.team.get_invite_info.not_open_team", nil, "id="+c.Params.InviteId, http.StatusForbidden)
return return
} }
@@ -779,7 +803,7 @@ func getTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) && if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) &&
(team.Type != model.TEAM_OPEN || team.AllowOpenInvite) { (team.Type != model.TEAM_OPEN || !team.AllowOpenInvite) {
c.SetPermissionError(model.PERMISSION_VIEW_TEAM) c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
return return
} }

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

@@ -559,72 +559,105 @@ func TestGetAllTeams(t *testing.T) {
defer th.TearDown() defer th.TearDown()
Client := th.Client Client := th.Client
team := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true} team1 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true}
_, resp := Client.CreateTeam(team) team1, resp := Client.CreateTeam(team1)
CheckNoError(t, resp) CheckNoError(t, resp)
team2 := &model.Team{DisplayName: "Name2", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true} team2 := &model.Team{DisplayName: "Name2", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true}
_, resp = Client.CreateTeam(team2) team2, resp = Client.CreateTeam(team2)
CheckNoError(t, resp) CheckNoError(t, resp)
rrteams, resp := Client.GetAllTeams("", 0, 1) team3 := &model.Team{DisplayName: "Name3", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: false}
team3, resp = Client.CreateTeam(team3)
CheckNoError(t, resp) CheckNoError(t, resp)
if len(rrteams) != 1 { testCases := []struct {
t.Log(len(rrteams)) Name string
t.Fatal("wrong number of teams - should be 1") Page int
PerPage int
Permissions []string
ExpectedTeams []string
}{
{
Name: "Get 1 team per page",
Page: 0,
PerPage: 1,
Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
ExpectedTeams: []string{team1.Id},
},
{
Name: "Get second page with 1 team per page",
Page: 1,
PerPage: 1,
Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
ExpectedTeams: []string{team2.Id},
},
{
Name: "Get no items per page",
Page: 1,
PerPage: 0,
Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
ExpectedTeams: []string{},
},
{
Name: "Get all open teams",
Page: 0,
PerPage: 10,
Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
ExpectedTeams: []string{team1.Id, team2.Id},
},
{
Name: "Get all private teams",
Page: 0,
PerPage: 10,
Permissions: []string{model.PERMISSION_LIST_PRIVATE_TEAMS.Id},
ExpectedTeams: []string{th.BasicTeam.Id, team3.Id},
},
{
Name: "Get all teams",
Page: 0,
PerPage: 10,
Permissions: []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.PERMISSION_LIST_PRIVATE_TEAMS.Id},
ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id},
},
{
Name: "Get no teams because permissions",
Page: 0,
PerPage: 10,
Permissions: []string{},
ExpectedTeams: []string{},
},
} }
for _, rt := range rrteams { for _, tc := range testCases {
if !rt.AllowOpenInvite { t.Run(tc.Name, func(t *testing.T) {
t.Fatal("not all teams are open") defaultRolePermissions := th.SaveDefaultRolePermissions()
} defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.RemovePermissionFromRole(model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_JOIN_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_LIST_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_JOIN_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
for _, permission := range tc.Permissions {
th.AddPermissionToRole(permission, model.SYSTEM_USER_ROLE_ID)
}
var teams []*model.Team
teams, resp = Client.GetAllTeams("", tc.Page, tc.PerPage)
CheckNoError(t, resp)
require.Equal(t, len(tc.ExpectedTeams), len(teams))
for idx, team := range teams {
assert.Equal(t, tc.ExpectedTeams[idx], team.Id)
}
})
} }
rrteams, resp = Client.GetAllTeams("", 0, 10) t.Run("Unauthorized", func(t *testing.T) {
CheckNoError(t, resp) Client.Logout()
_, resp = Client.GetAllTeams("", 1, 10)
for _, rt := range rrteams { CheckUnauthorizedStatus(t, resp)
if !rt.AllowOpenInvite { })
t.Fatal("not all teams are open")
}
}
rrteams1, resp := Client.GetAllTeams("", 1, 0)
CheckNoError(t, resp)
if len(rrteams1) != 0 {
t.Fatal("wrong number of teams - should be 0")
}
rrteams2, resp := th.SystemAdminClient.GetAllTeams("", 1, 1)
CheckNoError(t, resp)
if len(rrteams2) != 1 {
t.Fatal("wrong number of teams - should be 1")
}
rrteams2, resp = Client.GetAllTeams("", 1, 0)
CheckNoError(t, resp)
if len(rrteams2) != 0 {
t.Fatal("wrong number of teams - should be 0")
}
rrteams, resp = Client.GetAllTeams("", 0, 2)
CheckNoError(t, resp)
rrteams2, resp = Client.GetAllTeams("", 1, 2)
CheckNoError(t, resp)
for _, t1 := range rrteams {
for _, t2 := range rrteams2 {
assert.NotEqual(t, t1.Id, t2.Id, "different pages should not have the same teams")
}
}
Client.Logout()
_, resp = Client.GetAllTeams("", 1, 10)
CheckUnauthorizedStatus(t, resp)
} }
func TestGetAllTeamsSanitization(t *testing.T) { func TestGetAllTeamsSanitization(t *testing.T) {
@@ -1411,6 +1444,96 @@ func TestAddTeamMember(t *testing.T) {
} }
} }
func TestAddTeamMemberMyself(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
Client := th.Client
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.LoginBasic()
testCases := []struct {
Name string
Public bool
PublicPermission bool
PrivatePermission bool
ExpectedSuccess bool
}{
{
Name: "Try to join an open team without the permissions",
Public: true,
PublicPermission: false,
PrivatePermission: false,
ExpectedSuccess: false,
},
{
Name: "Try to join a private team without the permissions",
Public: false,
PublicPermission: false,
PrivatePermission: false,
ExpectedSuccess: false,
},
{
Name: "Try to join an open team without public permission but with private permissions",
Public: true,
PublicPermission: false,
PrivatePermission: true,
ExpectedSuccess: false,
},
{
Name: "Try to join a private team without private permission but with public permission",
Public: false,
PublicPermission: true,
PrivatePermission: false,
ExpectedSuccess: false,
},
{
Name: "Join an open team with the permissions",
Public: true,
PublicPermission: true,
PrivatePermission: false,
ExpectedSuccess: true,
},
{
Name: "Join a private team with the permissions",
Public: false,
PublicPermission: false,
PrivatePermission: true,
ExpectedSuccess: true,
},
}
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
team := th.CreateTeam()
team.AllowOpenInvite = tc.Public
th.App.UpdateTeam(team)
if tc.PublicPermission {
th.AddPermissionToRole(model.PERMISSION_JOIN_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
} else {
th.RemovePermissionFromRole(model.PERMISSION_JOIN_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
}
if tc.PrivatePermission {
th.AddPermissionToRole(model.PERMISSION_JOIN_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
} else {
th.RemovePermissionFromRole(model.PERMISSION_JOIN_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
}
_, resp := Client.AddTeamMember(team.Id, th.BasicUser.Id)
if tc.ExpectedSuccess {
CheckNoError(t, resp)
} else {
CheckForbiddenStatus(t, resp)
}
})
}
}
func TestAddTeamMembers(t *testing.T) { func TestAddTeamMembers(t *testing.T) {
th := Setup().InitBasic() th := Setup().InitBasic()
defer th.TearDown() defer th.TearDown()

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

@@ -121,6 +121,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_DELETE_OTHERS_POSTS.Id, model.PERMISSION_DELETE_OTHERS_POSTS.Id,
}, },
"system_user": []string{ "system_user": []string{
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id, model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
model.PERMISSION_CREATE_GROUP_CHANNEL.Id, model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
model.PERMISSION_PERMANENT_DELETE_USER.Id, model.PERMISSION_PERMANENT_DELETE_USER.Id,
@@ -173,6 +175,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_MANAGE_BOTS.Id, model.PERMISSION_MANAGE_BOTS.Id,
model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.PERMISSION_MANAGE_OTHERS_BOTS.Id,
model.PERMISSION_REMOVE_OTHERS_REACTIONS.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_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id, model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.Id, model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
@@ -298,6 +302,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_DELETE_OTHERS_POSTS.Id, model.PERMISSION_DELETE_OTHERS_POSTS.Id,
}, },
"system_user": []string{ "system_user": []string{
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id, model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
model.PERMISSION_CREATE_GROUP_CHANNEL.Id, model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
model.PERMISSION_PERMANENT_DELETE_USER.Id, model.PERMISSION_PERMANENT_DELETE_USER.Id,
@@ -350,6 +356,8 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
model.PERMISSION_MANAGE_BOTS.Id, model.PERMISSION_MANAGE_BOTS.Id,
model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.PERMISSION_MANAGE_OTHERS_BOTS.Id,
model.PERMISSION_REMOVE_OTHERS_REACTIONS.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_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id, model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.Id, model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
@@ -491,6 +499,8 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
model.PERMISSION_MANAGE_BOTS.Id, model.PERMISSION_MANAGE_BOTS.Id,
model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.PERMISSION_MANAGE_OTHERS_BOTS.Id,
model.PERMISSION_REMOVE_OTHERS_REACTIONS.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_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id, model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.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) role3, err3 := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
assert.Nil(t, err3) assert.Nil(t, err3)
expected3 := []string{ expected3 := []string{
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id, model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
model.PERMISSION_CREATE_GROUP_CHANNEL.Id, model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
model.PERMISSION_PERMANENT_DELETE_USER.Id, model.PERMISSION_PERMANENT_DELETE_USER.Id,

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

@@ -3,19 +3,23 @@
package app package app
import "github.com/mattermost/mattermost-server/model" import (
"github.com/mattermost/mattermost-server/model"
)
type permissionTransformation struct { type permissionTransformation struct {
On func(map[string]bool) bool On func(string, map[string]bool) bool
Add []string Add []string
Remove []string Remove []string
} }
type permissionsMap []permissionTransformation type permissionsMap []permissionTransformation
const ( const (
MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split" MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split"
MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_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_EMOJIS = "manage_emojis"
PERMISSION_MANAGE_OTHERS_EMOJIS = "manage_others_emojis" PERMISSION_MANAGE_OTHERS_EMOJIS = "manage_others_emojis"
PERMISSION_CREATE_EMOJIS = "create_emojis" PERMISSION_CREATE_EMOJIS = "create_emojis"
@@ -27,26 +31,36 @@ const (
PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS = "manage_others_incoming_webhooks" PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS = "manage_others_incoming_webhooks"
PERMISSION_MANAGE_OUTGOING_WEBHOOKS = "manage_outgoing_webhooks" PERMISSION_MANAGE_OUTGOING_WEBHOOKS = "manage_outgoing_webhooks"
PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS = "manage_others_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 { func isRole(role string) func(string, map[string]bool) bool {
return func(permissions 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] val, ok := permissions[permission]
return ok && val return ok && val
} }
} }
func permissionNotExists(permission string) func(map[string]bool) bool { func permissionNotExists(permission string) func(string, map[string]bool) bool {
return func(permissions map[string]bool) bool { return func(roleName string, permissions map[string]bool) bool {
val, ok := permissions[permission] val, ok := permissions[permission]
return !(ok && val) return !(ok && val)
} }
} }
func permissionOr(funcs ...func(map[string]bool) bool) func(map[string]bool) bool { func permissionOr(funcs ...func(string, map[string]bool) bool) func(string, map[string]bool) bool {
return func(permissions map[string]bool) bool { return func(roleName string, permissions map[string]bool) bool {
for _, f := range funcs { for _, f := range funcs {
if f(permissions) { if f(roleName, permissions) {
return true 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 { func permissionAnd(funcs ...func(string, map[string]bool) bool) func(string, map[string]bool) bool {
return func(permissions map[string]bool) bool { return func(roleName string, permissions map[string]bool) bool {
for _, f := range funcs { for _, f := range funcs {
if !f(permissions) { if !f(roleName, permissions) {
return false 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) finalMap := make(map[string]bool)
var result []string var result []string
for _, permission := range permissions { for _, permission := range permissions {
@@ -73,7 +87,7 @@ func applyPermissionsMap(permissions []string, migrationMap permissionsMap) []st
} }
for _, transformation := range migrationMap { for _, transformation := range migrationMap {
if transformation.On(finalMap) { if transformation.On(roleName, finalMap) {
for _, add := range transformation.Add { for _, add := range transformation.Add {
finalMap[add] = true finalMap[add] = true
} }
@@ -102,7 +116,7 @@ func (a *App) doPermissionsMigration(key string, migrationMap permissionsMap) *m
} }
for _, role := range roles { 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 { if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
return result.Err 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. // DoPermissionsMigrations execute all the permissions migrations need by the current version.
func (a *App) DoPermissionsMigrations() *model.AppError { func (a *App) DoPermissionsMigrations() *model.AppError {
PermissionsMigrations := []struct { PermissionsMigrations := []struct {
@@ -152,6 +181,7 @@ func (a *App) DoPermissionsMigrations() *model.AppError {
}{ }{
{Key: MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration}, {Key: MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration},
{Key: MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration}, {Key: MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration},
{Key: MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: getListJoinPublicPrivateTeamsPermissionsMigration},
} }
for _, migration := range PermissionsMigrations { for _, migration := range PermissionsMigrations {

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

@@ -77,11 +77,29 @@ func TestApplyPermissionsMap(t *testing.T) {
}}, }},
[]string{"test1", "test2", "test3"}, []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 { for _, tc := range tt {
t.Run(tc.Name, func(t *testing.T) { 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) sort.Strings(result)
assert.Equal(t, tc.ExpectedResult, result) assert.Equal(t, tc.ExpectedResult, result)
}) })

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

@@ -562,7 +562,23 @@ func (a *App) GetAllTeamsPage(offset int, limit int) ([]*model.Team, *model.AppE
return result.Data.([]*model.Team), nil 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() result := <-a.Srv.Store.Team().GetAllTeamListing()
if result.Err != nil { if result.Err != nil {
return nil, result.Err return nil, result.Err
@@ -570,6 +586,14 @@ func (a *App) GetAllOpenTeams() ([]*model.Team, *model.AppError) {
return result.Data.([]*model.Team), nil 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) { func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) {
result := <-a.Srv.Store.Team().SearchAll(term) result := <-a.Srv.Store.Team().SearchAll(term)
if result.Err != nil { if result.Err != nil {
@@ -578,7 +602,7 @@ func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) {
return result.Data.([]*model.Team), nil 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) result := <-a.Srv.Store.Team().SearchOpen(term)
if result.Err != nil { if result.Err != nil {
return nil, result.Err return nil, result.Err
@@ -586,8 +610,8 @@ func (a *App) SearchOpenTeams(term string) ([]*model.Team, *model.AppError) {
return result.Data.([]*model.Team), nil return result.Data.([]*model.Team), nil
} }
func (a *App) GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) { func (a *App) SearchPrivateTeams(term string) ([]*model.Team, *model.AppError) {
result := <-a.Srv.Store.Team().GetAllTeamPageListing(offset, limit) result := <-a.Srv.Store.Team().SearchPrivate(term)
if result.Err != nil { if result.Err != nil {
return nil, result.Err return nil, result.Err
} }

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

@@ -6250,6 +6250,10 @@
"id": "store.sql_team.get_all.app_error", "id": "store.sql_team.get_all.app_error",
"translation": "We could not get all teams" "translation": "We could not get all teams"
}, },
{
"id": "store.sql_team.get_all_private_team_listing.app_error",
"translation": "We could not get all private teams"
},
{ {
"id": "store.sql_team.get_all_team_listing.app_error", "id": "store.sql_team.get_all_team_listing.app_error",
"translation": "We could not get all teams" "translation": "We could not get all teams"
@@ -6354,6 +6358,10 @@
"id": "store.sql_team.search_open_team.app_error", "id": "store.sql_team.search_open_team.app_error",
"translation": "We encountered an error searching open teams" "translation": "We encountered an error searching open teams"
}, },
{
"id": "store.sql_team.search_private_team.app_error",
"translation": "We encountered an error searching private teams"
},
{ {
"id": "store.sql_team.update.app_error", "id": "store.sql_team.update.app_error",
"translation": "Unable to update the team" "translation": "Unable to update the team"

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

@@ -33,6 +33,10 @@ var PERMISSION_CREATE_DIRECT_CHANNEL *Permission
var PERMISSION_CREATE_GROUP_CHANNEL *Permission var PERMISSION_CREATE_GROUP_CHANNEL *Permission
var PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES *Permission var PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES *Permission
var PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES *Permission var PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES *Permission
var PERMISSION_LIST_PUBLIC_TEAMS *Permission
var PERMISSION_JOIN_PUBLIC_TEAMS *Permission
var PERMISSION_LIST_PRIVATE_TEAMS *Permission
var PERMISSION_JOIN_PRIVATE_TEAMS *Permission
var PERMISSION_LIST_TEAM_CHANNELS *Permission var PERMISSION_LIST_TEAM_CHANNELS *Permission
var PERMISSION_JOIN_PUBLIC_CHANNELS *Permission var PERMISSION_JOIN_PUBLIC_CHANNELS *Permission
var PERMISSION_DELETE_PUBLIC_CHANNEL *Permission var PERMISSION_DELETE_PUBLIC_CHANNEL *Permission
@@ -198,6 +202,30 @@ func initializePermissions() {
"authentication.permissions.manage_private_channel_properties.description", "authentication.permissions.manage_private_channel_properties.description",
PERMISSION_SCOPE_CHANNEL, PERMISSION_SCOPE_CHANNEL,
} }
PERMISSION_LIST_PUBLIC_TEAMS = &Permission{
"list_public_teams",
"authentication.permissions.list_public_teams.name",
"authentication.permissions.list_public_teams.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_JOIN_PUBLIC_TEAMS = &Permission{
"join_public_teams",
"authentication.permissions.join_public_teams.name",
"authentication.permissions.join_public_teams.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_LIST_PRIVATE_TEAMS = &Permission{
"list_private_teams",
"authentication.permissions.list_private_teams.name",
"authentication.permissions.list_private_teams.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_JOIN_PRIVATE_TEAMS = &Permission{
"join_private_teams",
"authentication.permissions.join_private_teams.name",
"authentication.permissions.join_private_teams.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_LIST_TEAM_CHANNELS = &Permission{ PERMISSION_LIST_TEAM_CHANNELS = &Permission{
"list_team_channels", "list_team_channels",
"authentication.permissions.list_team_channels.name", "authentication.permissions.list_team_channels.name",
@@ -505,6 +533,10 @@ func initializePermissions() {
PERMISSION_CREATE_GROUP_CHANNEL, PERMISSION_CREATE_GROUP_CHANNEL,
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES, PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES,
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES, PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES,
PERMISSION_LIST_PUBLIC_TEAMS,
PERMISSION_JOIN_PUBLIC_TEAMS,
PERMISSION_LIST_PRIVATE_TEAMS,
PERMISSION_JOIN_PRIVATE_TEAMS,
PERMISSION_LIST_TEAM_CHANNELS, PERMISSION_LIST_TEAM_CHANNELS,
PERMISSION_JOIN_PUBLIC_CHANNELS, PERMISSION_JOIN_PUBLIC_CHANNELS,
PERMISSION_DELETE_PUBLIC_CHANNEL, PERMISSION_DELETE_PUBLIC_CHANNEL,

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

@@ -264,6 +264,8 @@ func MakeDefaultRoles() map[string]*Role {
DisplayName: "authentication.roles.global_user.name", DisplayName: "authentication.roles.global_user.name",
Description: "authentication.roles.global_user.description", Description: "authentication.roles.global_user.description",
Permissions: []string{ Permissions: []string{
PERMISSION_LIST_PUBLIC_TEAMS.Id,
PERMISSION_JOIN_PUBLIC_TEAMS.Id,
PERMISSION_CREATE_DIRECT_CHANNEL.Id, PERMISSION_CREATE_DIRECT_CHANNEL.Id,
PERMISSION_CREATE_GROUP_CHANNEL.Id, PERMISSION_CREATE_GROUP_CHANNEL.Id,
PERMISSION_PERMANENT_DELETE_USER.Id, PERMISSION_PERMANENT_DELETE_USER.Id,
@@ -354,6 +356,8 @@ func MakeDefaultRoles() map[string]*Role {
PERMISSION_MANAGE_BOTS.Id, PERMISSION_MANAGE_BOTS.Id,
PERMISSION_MANAGE_OTHERS_BOTS.Id, PERMISSION_MANAGE_OTHERS_BOTS.Id,
PERMISSION_REMOVE_OTHERS_REACTIONS.Id, PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
PERMISSION_LIST_PRIVATE_TEAMS.Id,
PERMISSION_JOIN_PRIVATE_TEAMS.Id,
}, },
roles[TEAM_USER_ROLE_ID].Permissions..., roles[TEAM_USER_ROLE_ID].Permissions...,
), ),

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

@@ -341,10 +341,23 @@ func (s SqlTeamStore) SearchOpen(term string) store.StoreChannel {
}) })
} }
func (s SqlTeamStore) SearchPrivate(term string) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
var teams []*model.Team
if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE (Type != 'O' OR AllowOpenInvite = false) AND (Name LIKE :Term OR DisplayName LIKE :Term)", map[string]interface{}{"Term": term + "%"}); err != nil {
result.Err = model.NewAppError("SqlTeamStore.SearchPrivate", "store.sql_team.search_private_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError)
return
}
result.Data = teams
})
}
func (s SqlTeamStore) GetAll() store.StoreChannel { func (s SqlTeamStore) GetAll() store.StoreChannel {
return store.Do(func(result *store.StoreResult) { return store.Do(func(result *store.StoreResult) {
var data []*model.Team var data []*model.Team
if _, err := s.GetReplica().Select(&data, "SELECT * FROM Teams"); err != nil { if _, err := s.GetReplica().Select(&data, "SELECT * FROM Teams ORDER BY DisplayName"); err != nil {
result.Err = model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) result.Err = model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
return return
} }
@@ -395,12 +408,60 @@ func (s SqlTeamStore) GetTeamsByUserId(userId string) store.StoreChannel {
}) })
} }
func (s SqlTeamStore) GetAllTeamListing() store.StoreChannel { func (s SqlTeamStore) GetAllPrivateTeamListing() store.StoreChannel {
return store.Do(func(result *store.StoreResult) { return store.Do(func(result *store.StoreResult) {
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1" query := "SELECT * FROM Teams WHERE AllowOpenInvite = 0 ORDER BY DisplayName"
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
query = "SELECT * FROM Teams WHERE AllowOpenInvite = true" query = "SELECT * FROM Teams WHERE AllowOpenInvite = false ORDER BY DisplayName"
}
var data []*model.Team
if _, err := s.GetReplica().Select(&data, query); err != nil {
result.Err = model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
return
}
for _, team := range data {
if len(team.InviteId) == 0 {
team.InviteId = team.Id
}
}
result.Data = data
})
}
func (s SqlTeamStore) GetAllPrivateTeamPageListing(offset int, limit int) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 0 ORDER BY DisplayName LIMIT :Limit OFFSET :Offset"
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
query = "SELECT * FROM Teams WHERE AllowOpenInvite = false ORDER BY DisplayName LIMIT :Limit OFFSET :Offset"
}
var data []*model.Team
if _, err := s.GetReplica().Select(&data, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
return
}
for _, team := range data {
if len(team.InviteId) == 0 {
team.InviteId = team.Id
}
}
result.Data = data
})
}
func (s SqlTeamStore) GetAllTeamListing() store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 ORDER BY DisplayName"
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
query = "SELECT * FROM Teams WHERE AllowOpenInvite = true ORDER BY DisplayName"
} }
var data []*model.Team var data []*model.Team
@@ -421,10 +482,10 @@ func (s SqlTeamStore) GetAllTeamListing() store.StoreChannel {
func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) store.StoreChannel { func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) store.StoreChannel {
return store.Do(func(result *store.StoreResult) { return store.Do(func(result *store.StoreResult) {
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 LIMIT :Limit OFFSET :Offset" query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 ORDER BY DisplayName LIMIT :Limit OFFSET :Offset"
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
query = "SELECT * FROM Teams WHERE AllowOpenInvite = true LIMIT :Limit OFFSET :Offset" query = "SELECT * FROM Teams WHERE AllowOpenInvite = true ORDER BY DisplayName LIMIT :Limit OFFSET :Offset"
} }
var data []*model.Team var data []*model.Team

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

@@ -89,8 +89,11 @@ type TeamStore interface {
SearchByName(name string) StoreChannel SearchByName(name string) StoreChannel
SearchAll(term string) StoreChannel SearchAll(term string) StoreChannel
SearchOpen(term string) StoreChannel SearchOpen(term string) StoreChannel
SearchPrivate(term string) StoreChannel
GetAll() StoreChannel GetAll() StoreChannel
GetAllPage(offset int, limit int) StoreChannel GetAllPage(offset int, limit int) StoreChannel
GetAllPrivateTeamListing() StoreChannel
GetAllPrivateTeamPageListing(offset int, limit int) StoreChannel
GetAllTeamListing() StoreChannel GetAllTeamListing() StoreChannel
GetAllTeamPageListing(offset int, limit int) StoreChannel GetAllTeamPageListing(offset int, limit int) StoreChannel
GetTeamsByUserId(userId string) StoreChannel GetTeamsByUserId(userId string) StoreChannel

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

@@ -141,6 +141,38 @@ func (_m *TeamStore) GetAllPage(offset int, limit int) store.StoreChannel {
return r0 return r0
} }
// GetAllPrivateTeamListing provides a mock function with given fields:
func (_m *TeamStore) GetAllPrivateTeamListing() store.StoreChannel {
ret := _m.Called()
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func() store.StoreChannel); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// GetAllPrivateTeamPageListing provides a mock function with given fields: offset, limit
func (_m *TeamStore) GetAllPrivateTeamPageListing(offset int, limit int) store.StoreChannel {
ret := _m.Called(offset, limit)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(int, int) store.StoreChannel); ok {
r0 = rf(offset, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// GetAllTeamListing provides a mock function with given fields: // GetAllTeamListing provides a mock function with given fields:
func (_m *TeamStore) GetAllTeamListing() store.StoreChannel { func (_m *TeamStore) GetAllTeamListing() store.StoreChannel {
ret := _m.Called() ret := _m.Called()
@@ -557,6 +589,22 @@ func (_m *TeamStore) SearchOpen(term string) store.StoreChannel {
return r0 return r0
} }
// SearchPrivate provides a mock function with given fields: term
func (_m *TeamStore) SearchPrivate(term string) store.StoreChannel {
ret := _m.Called(term)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
r0 = rf(term)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// Update provides a mock function with given fields: team // Update provides a mock function with given fields: team
func (_m *TeamStore) Update(team *model.Team) store.StoreChannel { func (_m *TeamStore) Update(team *model.Team) store.StoreChannel {
ret := _m.Called(team) ret := _m.Called(team)

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

@@ -26,10 +26,13 @@ func TestTeamStore(t *testing.T, ss store.Store) {
t.Run("SearchByName", func(t *testing.T) { testTeamStoreSearchByName(t, ss) }) t.Run("SearchByName", func(t *testing.T) { testTeamStoreSearchByName(t, ss) })
t.Run("SearchAll", func(t *testing.T) { testTeamStoreSearchAll(t, ss) }) t.Run("SearchAll", func(t *testing.T) { testTeamStoreSearchAll(t, ss) })
t.Run("SearchOpen", func(t *testing.T) { testTeamStoreSearchOpen(t, ss) }) t.Run("SearchOpen", func(t *testing.T) { testTeamStoreSearchOpen(t, ss) })
t.Run("SearchPrivate", func(t *testing.T) { testTeamStoreSearchPrivate(t, ss) })
t.Run("GetByIniviteId", func(t *testing.T) { testTeamStoreGetByIniviteId(t, ss) }) t.Run("GetByIniviteId", func(t *testing.T) { testTeamStoreGetByIniviteId(t, ss) })
t.Run("ByUserId", func(t *testing.T) { testTeamStoreByUserId(t, ss) }) t.Run("ByUserId", func(t *testing.T) { testTeamStoreByUserId(t, ss) })
t.Run("GetAllTeamListing", func(t *testing.T) { testGetAllTeamListing(t, ss) }) t.Run("GetAllTeamListing", func(t *testing.T) { testGetAllTeamListing(t, ss) })
t.Run("GetAllTeamPageListing", func(t *testing.T) { testGetAllTeamPageListing(t, ss) }) t.Run("GetAllTeamPageListing", func(t *testing.T) { testGetAllTeamPageListing(t, ss) })
t.Run("GetAllPrivateTeamListing", func(t *testing.T) { testGetAllPrivateTeamListing(t, ss) })
t.Run("GetAllPrivateTeamPageListing", func(t *testing.T) { testGetAllPrivateTeamPageListing(t, ss) })
t.Run("Delete", func(t *testing.T) { testDelete(t, ss) }) t.Run("Delete", func(t *testing.T) { testDelete(t, ss) })
t.Run("TeamCount", func(t *testing.T) { testTeamCount(t, ss) }) t.Run("TeamCount", func(t *testing.T) { testTeamCount(t, ss) })
t.Run("TeamMembers", func(t *testing.T) { testTeamMembers(t, ss) }) t.Run("TeamMembers", func(t *testing.T) { testTeamMembers(t, ss) })
@@ -185,143 +188,200 @@ func testTeamStoreSearchByName(t *testing.T, ss store.Store) {
} }
func testTeamStoreSearchAll(t *testing.T, ss store.Store) { func testTeamStoreSearchAll(t *testing.T, ss store.Store) {
o1 := model.Team{} o := model.Team{}
o1.DisplayName = "ADisplayName" + model.NewId() o.DisplayName = "ADisplayName" + model.NewId()
o1.Name = "zz" + model.NewId() + "a" o.Name = "zzzzzz-" + model.NewId() + "a"
o1.Email = MakeEmail() o.Email = MakeEmail()
o1.Type = model.TEAM_OPEN o.Type = model.TEAM_OPEN
o.AllowOpenInvite = true
if err := (<-ss.Team().Save(&o1)).Err; err != nil { require.Nil(t, (<-ss.Team().Save(&o)).Err)
t.Fatal(err)
p := model.Team{}
p.DisplayName = "ADisplayName" + model.NewId()
p.Name = "zzzzzz-" + model.NewId() + "a"
p.Email = MakeEmail()
p.Type = model.TEAM_OPEN
p.AllowOpenInvite = false
require.Nil(t, (<-ss.Team().Save(&p)).Err)
testCases := []struct {
Name string
Term string
ExpectedLenth int
ExpectedFirstId string
}{
{
"Search for open team name",
o.Name,
1,
o.Id,
},
{
"Search for open team displayName",
o.DisplayName,
1,
o.Id,
},
{
"Search for open team without results",
"junk",
0,
"",
},
{
"Search for private team",
p.DisplayName,
1,
p.Id,
},
{
"Search for both teams",
"zzzzzz",
2,
"",
},
} }
p2 := model.Team{} for _, tc := range testCases {
p2.DisplayName = "BDisplayName" + model.NewId() t.Run(tc.Name, func(t *testing.T) {
p2.Name = "b" + model.NewId() + "b" r1 := <-ss.Team().SearchAll(tc.Term)
p2.Email = MakeEmail() require.Nil(t, r1.Err)
p2.Type = model.TEAM_INVITE results := r1.Data.([]*model.Team)
require.Equal(t, tc.ExpectedLenth, len(results))
if err := (<-ss.Team().Save(&p2)).Err; err != nil { if tc.ExpectedFirstId != "" {
t.Fatal(err) assert.Equal(t, tc.ExpectedFirstId, results[0].Id)
} }
})
r1 := <-ss.Team().SearchAll(o1.Name)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != o1.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-ss.Team().SearchAll(p2.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != p2.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-ss.Team().SearchAll("junk")
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
} }
} }
func testTeamStoreSearchOpen(t *testing.T, ss store.Store) { func testTeamStoreSearchOpen(t *testing.T, ss store.Store) {
o1 := model.Team{} o := model.Team{}
o1.DisplayName = "ADisplayName" + model.NewId() o.DisplayName = "ADisplayName" + model.NewId()
o1.Name = "zz" + model.NewId() + "a" o.Name = "zz" + model.NewId() + "a"
o1.Email = MakeEmail() o.Email = MakeEmail()
o1.Type = model.TEAM_OPEN o.Type = model.TEAM_OPEN
o1.AllowOpenInvite = true o.AllowOpenInvite = true
if err := (<-ss.Team().Save(&o1)).Err; err != nil { require.Nil(t, (<-ss.Team().Save(&o)).Err)
t.Fatal(err)
p := model.Team{}
p.DisplayName = "ADisplayName" + model.NewId()
p.Name = "zz" + model.NewId() + "a"
p.Email = MakeEmail()
p.Type = model.TEAM_OPEN
p.AllowOpenInvite = false
require.Nil(t, (<-ss.Team().Save(&p)).Err)
testCases := []struct {
Name string
Term string
ExpectedLenth int
ExpectedFirstId string
}{
{
"Search for open team name",
o.Name,
1,
o.Id,
},
{
"Search for open team displayName",
o.DisplayName,
1,
o.Id,
},
{
"Search for open team without results",
"junk",
0,
"",
},
{
"Search for a private team (expected no results)",
p.DisplayName,
0,
"",
},
} }
o2 := model.Team{} for _, tc := range testCases {
o2.DisplayName = "ADisplayName" + model.NewId() t.Run(tc.Name, func(t *testing.T) {
o2.Name = "zz" + model.NewId() + "a" r1 := <-ss.Team().SearchOpen(tc.Term)
o2.Email = MakeEmail() require.Nil(t, r1.Err)
o2.Type = model.TEAM_OPEN results := r1.Data.([]*model.Team)
o2.AllowOpenInvite = false require.Equal(t, tc.ExpectedLenth, len(results))
if tc.ExpectedFirstId != "" {
assert.Equal(t, tc.ExpectedFirstId, results[0].Id)
}
})
}
}
if err := (<-ss.Team().Save(&o2)).Err; err != nil { func testTeamStoreSearchPrivate(t *testing.T, ss store.Store) {
t.Fatal(err) o := model.Team{}
o.DisplayName = "ADisplayName" + model.NewId()
o.Name = "zz" + model.NewId() + "a"
o.Email = MakeEmail()
o.Type = model.TEAM_OPEN
o.AllowOpenInvite = true
require.Nil(t, (<-ss.Team().Save(&o)).Err)
p := model.Team{}
p.DisplayName = "ADisplayName" + model.NewId()
p.Name = "zz" + model.NewId() + "a"
p.Email = MakeEmail()
p.Type = model.TEAM_OPEN
p.AllowOpenInvite = false
require.Nil(t, (<-ss.Team().Save(&p)).Err)
testCases := []struct {
Name string
Term string
ExpectedLenth int
ExpectedFirstId string
}{
{
"Search for private team name",
p.Name,
1,
p.Id,
},
{
"Search for private team displayName",
p.DisplayName,
1,
p.Id,
},
{
"Search for private team without results",
"junk",
0,
"",
},
{
"Search for a open team (expected no results)",
o.DisplayName,
0,
"",
},
} }
p2 := model.Team{} for _, tc := range testCases {
p2.DisplayName = "BDisplayName" + model.NewId() t.Run(tc.Name, func(t *testing.T) {
p2.Name = "b" + model.NewId() + "b" r1 := <-ss.Team().SearchPrivate(tc.Term)
p2.Email = MakeEmail() require.Nil(t, r1.Err)
p2.Type = model.TEAM_INVITE results := r1.Data.([]*model.Team)
p2.AllowOpenInvite = true require.Equal(t, tc.ExpectedLenth, len(results))
if tc.ExpectedFirstId != "" {
if err := (<-ss.Team().Save(&p2)).Err; err != nil { assert.Equal(t, tc.ExpectedFirstId, results[0].Id)
t.Fatal(err) }
} })
r1 := <-ss.Team().SearchOpen(o1.Name)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != o1.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-ss.Team().SearchOpen(o1.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 1 {
t.Fatal("should have returned 1 team")
}
if r1.Data.([]*model.Team)[0].ToJson() != o1.ToJson() {
t.Fatal("invalid returned team")
}
r1 = <-ss.Team().SearchOpen(p2.Name)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
r1 = <-ss.Team().SearchOpen(p2.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
r1 = <-ss.Team().SearchOpen("junk")
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
}
r1 = <-ss.Team().SearchOpen(o2.DisplayName)
if r1.Err != nil {
t.Fatal(r1.Err)
}
if len(r1.Data.([]*model.Team)) != 0 {
t.Fatal("should have not returned a team")
} }
} }
@@ -536,6 +596,144 @@ func testGetAllTeamPageListing(t *testing.T, ss store.Store) {
} }
} }
func testGetAllPrivateTeamListing(t *testing.T, ss store.Store) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = MakeEmail()
o1.Type = model.TEAM_OPEN
o1.AllowOpenInvite = true
store.Must(ss.Team().Save(&o1))
o2 := model.Team{}
o2.DisplayName = "DisplayName"
o2.Name = "zz" + model.NewId() + "b"
o2.Email = MakeEmail()
o2.Type = model.TEAM_OPEN
store.Must(ss.Team().Save(&o2))
o3 := model.Team{}
o3.DisplayName = "DisplayName"
o3.Name = "z-z-z" + model.NewId() + "b"
o3.Email = MakeEmail()
o3.Type = model.TEAM_INVITE
o3.AllowOpenInvite = true
store.Must(ss.Team().Save(&o3))
o4 := model.Team{}
o4.DisplayName = "DisplayName"
o4.Name = "zz" + model.NewId() + "b"
o4.Email = MakeEmail()
o4.Type = model.TEAM_INVITE
store.Must(ss.Team().Save(&o4))
if r1 := <-ss.Team().GetAllPrivateTeamListing(); r1.Err != nil {
t.Fatal(r1.Err)
} else {
teams := r1.Data.([]*model.Team)
for _, team := range teams {
if team.AllowOpenInvite {
t.Fatal("should have returned team with AllowOpenInvite as false")
}
}
if len(teams) == 0 {
t.Fatal("failed team listing")
}
}
}
func testGetAllPrivateTeamPageListing(t *testing.T, ss store.Store) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = MakeEmail()
o1.Type = model.TEAM_OPEN
o1.AllowOpenInvite = true
store.Must(ss.Team().Save(&o1))
o2 := model.Team{}
o2.DisplayName = "DisplayName"
o2.Name = "zz" + model.NewId() + "b"
o2.Email = MakeEmail()
o2.Type = model.TEAM_OPEN
o2.AllowOpenInvite = false
store.Must(ss.Team().Save(&o2))
o3 := model.Team{}
o3.DisplayName = "DisplayName"
o3.Name = "z-z-z" + model.NewId() + "b"
o3.Email = MakeEmail()
o3.Type = model.TEAM_INVITE
o3.AllowOpenInvite = true
store.Must(ss.Team().Save(&o3))
o4 := model.Team{}
o4.DisplayName = "DisplayName"
o4.Name = "zz" + model.NewId() + "b"
o4.Email = MakeEmail()
o4.Type = model.TEAM_INVITE
o4.AllowOpenInvite = false
store.Must(ss.Team().Save(&o4))
if r1 := <-ss.Team().GetAllPrivateTeamPageListing(0, 10); r1.Err != nil {
t.Fatal(r1.Err)
} else {
teams := r1.Data.([]*model.Team)
for _, team := range teams {
if team.AllowOpenInvite {
t.Fatal("should have returned team with AllowOpenInvite as false")
}
}
if len(teams) > 10 {
t.Fatal("should have returned max of 10 teams")
}
}
o5 := model.Team{}
o5.DisplayName = "DisplayName"
o5.Name = "z-z-z" + model.NewId() + "b"
o5.Email = MakeEmail()
o5.Type = model.TEAM_OPEN
o5.AllowOpenInvite = true
store.Must(ss.Team().Save(&o5))
if r1 := <-ss.Team().GetAllPrivateTeamPageListing(0, 4); r1.Err != nil {
t.Fatal(r1.Err)
} else {
teams := r1.Data.([]*model.Team)
for _, team := range teams {
if team.AllowOpenInvite {
t.Fatal("should have returned team with AllowOpenInvite as false")
}
}
if len(teams) > 4 {
t.Fatal("should have returned max of 4 teams")
}
}
if r1 := <-ss.Team().GetAllPrivateTeamPageListing(1, 1); r1.Err != nil {
t.Fatal(r1.Err)
} else {
teams := r1.Data.([]*model.Team)
for _, team := range teams {
if team.AllowOpenInvite {
t.Fatal("should have returned team with AllowOpenInvite as false")
}
}
if len(teams) > 1 {
t.Fatal("should have returned max of 1 team")
}
}
}
func testDelete(t *testing.T, ss store.Store) { func testDelete(t *testing.T, ss store.Store) {
o1 := model.Team{} o1 := model.Team{}
o1.DisplayName = "DisplayName" o1.DisplayName = "DisplayName"