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
44
api4/team.go
44
api4/team.go
@@ -364,9 +364,27 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(c.App.Session, member.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
|
||||
return
|
||||
if member.UserId == c.App.Session.UserId {
|
||||
var team *model.Team
|
||||
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)
|
||||
@@ -571,10 +589,12 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
var teams []*model.Team
|
||||
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)
|
||||
} else {
|
||||
teams, err = c.App.GetAllOpenTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
|
||||
} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) {
|
||||
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 {
|
||||
@@ -602,10 +622,14 @@ func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
var teams []*model.Team
|
||||
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)
|
||||
} 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 {
|
||||
teams, err = c.App.SearchOpenTeams(props.Term)
|
||||
teams = []*model.Team{}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -752,7 +776,7 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
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)
|
||||
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) &&
|
||||
(team.Type != model.TEAM_OPEN || team.AllowOpenInvite) {
|
||||
(team.Type != model.TEAM_OPEN || !team.AllowOpenInvite) {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -559,72 +559,105 @@ func TestGetAllTeams(t *testing.T) {
|
||||
defer th.TearDown()
|
||||
Client := th.Client
|
||||
|
||||
team := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true}
|
||||
_, resp := Client.CreateTeam(team)
|
||||
team1 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true}
|
||||
team1, resp := Client.CreateTeam(team1)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
if len(rrteams) != 1 {
|
||||
t.Log(len(rrteams))
|
||||
t.Fatal("wrong number of teams - should be 1")
|
||||
testCases := []struct {
|
||||
Name string
|
||||
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 {
|
||||
if !rt.AllowOpenInvite {
|
||||
t.Fatal("not all teams are open")
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
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)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
for _, rt := range rrteams {
|
||||
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)
|
||||
t.Run("Unauthorized", func(t *testing.T) {
|
||||
Client.Logout()
|
||||
_, resp = Client.GetAllTeams("", 1, 10)
|
||||
CheckUnauthorizedStatus(t, resp)
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -6250,6 +6250,10 @@
|
||||
"id": "store.sql_team.get_all.app_error",
|
||||
"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",
|
||||
"translation": "We could not get all teams"
|
||||
@@ -6354,6 +6358,10 @@
|
||||
"id": "store.sql_team.search_open_team.app_error",
|
||||
"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",
|
||||
"translation": "Unable to update the team"
|
||||
|
||||
@@ -33,6 +33,10 @@ var PERMISSION_CREATE_DIRECT_CHANNEL *Permission
|
||||
var PERMISSION_CREATE_GROUP_CHANNEL *Permission
|
||||
var PERMISSION_MANAGE_PUBLIC_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_JOIN_PUBLIC_CHANNELS *Permission
|
||||
var PERMISSION_DELETE_PUBLIC_CHANNEL *Permission
|
||||
@@ -198,6 +202,30 @@ func initializePermissions() {
|
||||
"authentication.permissions.manage_private_channel_properties.description",
|
||||
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{
|
||||
"list_team_channels",
|
||||
"authentication.permissions.list_team_channels.name",
|
||||
@@ -505,6 +533,10 @@ func initializePermissions() {
|
||||
PERMISSION_CREATE_GROUP_CHANNEL,
|
||||
PERMISSION_MANAGE_PUBLIC_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_JOIN_PUBLIC_CHANNELS,
|
||||
PERMISSION_DELETE_PUBLIC_CHANNEL,
|
||||
|
||||
@@ -264,6 +264,8 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
DisplayName: "authentication.roles.global_user.name",
|
||||
Description: "authentication.roles.global_user.description",
|
||||
Permissions: []string{
|
||||
PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
PERMISSION_PERMANENT_DELETE_USER.Id,
|
||||
@@ -354,6 +356,8 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
PERMISSION_MANAGE_BOTS.Id,
|
||||
PERMISSION_MANAGE_OTHERS_BOTS.Id,
|
||||
PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
},
|
||||
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 {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
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)
|
||||
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) {
|
||||
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1"
|
||||
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 0 ORDER BY DisplayName"
|
||||
|
||||
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
|
||||
@@ -421,10 +482,10 @@ func (s SqlTeamStore) GetAllTeamListing() store.StoreChannel {
|
||||
|
||||
func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) store.StoreChannel {
|
||||
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 {
|
||||
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
|
||||
|
||||
@@ -89,8 +89,11 @@ type TeamStore interface {
|
||||
SearchByName(name string) StoreChannel
|
||||
SearchAll(term string) StoreChannel
|
||||
SearchOpen(term string) StoreChannel
|
||||
SearchPrivate(term string) StoreChannel
|
||||
GetAll() StoreChannel
|
||||
GetAllPage(offset int, limit int) StoreChannel
|
||||
GetAllPrivateTeamListing() StoreChannel
|
||||
GetAllPrivateTeamPageListing(offset int, limit int) StoreChannel
|
||||
GetAllTeamListing() StoreChannel
|
||||
GetAllTeamPageListing(offset int, limit int) StoreChannel
|
||||
GetTeamsByUserId(userId string) StoreChannel
|
||||
|
||||
@@ -141,6 +141,38 @@ func (_m *TeamStore) GetAllPage(offset int, limit int) store.StoreChannel {
|
||||
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:
|
||||
func (_m *TeamStore) GetAllTeamListing() store.StoreChannel {
|
||||
ret := _m.Called()
|
||||
@@ -557,6 +589,22 @@ func (_m *TeamStore) SearchOpen(term string) store.StoreChannel {
|
||||
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
|
||||
func (_m *TeamStore) Update(team *model.Team) store.StoreChannel {
|
||||
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("SearchAll", func(t *testing.T) { testTeamStoreSearchAll(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("ByUserId", func(t *testing.T) { testTeamStoreByUserId(t, ss) })
|
||||
t.Run("GetAllTeamListing", func(t *testing.T) { testGetAllTeamListing(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("TeamCount", func(t *testing.T) { testTeamCount(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) {
|
||||
o1 := model.Team{}
|
||||
o1.DisplayName = "ADisplayName" + model.NewId()
|
||||
o1.Name = "zz" + model.NewId() + "a"
|
||||
o1.Email = MakeEmail()
|
||||
o1.Type = model.TEAM_OPEN
|
||||
o := model.Team{}
|
||||
o.DisplayName = "ADisplayName" + model.NewId()
|
||||
o.Name = "zzzzzz-" + model.NewId() + "a"
|
||||
o.Email = MakeEmail()
|
||||
o.Type = model.TEAM_OPEN
|
||||
o.AllowOpenInvite = true
|
||||
|
||||
if err := (<-ss.Team().Save(&o1)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
require.Nil(t, (<-ss.Team().Save(&o)).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{}
|
||||
p2.DisplayName = "BDisplayName" + model.NewId()
|
||||
p2.Name = "b" + model.NewId() + "b"
|
||||
p2.Email = MakeEmail()
|
||||
p2.Type = model.TEAM_INVITE
|
||||
|
||||
if err := (<-ss.Team().Save(&p2)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
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")
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
r1 := <-ss.Team().SearchAll(tc.Term)
|
||||
require.Nil(t, r1.Err)
|
||||
results := r1.Data.([]*model.Team)
|
||||
require.Equal(t, tc.ExpectedLenth, len(results))
|
||||
if tc.ExpectedFirstId != "" {
|
||||
assert.Equal(t, tc.ExpectedFirstId, results[0].Id)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testTeamStoreSearchOpen(t *testing.T, ss store.Store) {
|
||||
o1 := model.Team{}
|
||||
o1.DisplayName = "ADisplayName" + model.NewId()
|
||||
o1.Name = "zz" + model.NewId() + "a"
|
||||
o1.Email = MakeEmail()
|
||||
o1.Type = model.TEAM_OPEN
|
||||
o1.AllowOpenInvite = true
|
||||
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
|
||||
|
||||
if err := (<-ss.Team().Save(&o1)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
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 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{}
|
||||
o2.DisplayName = "ADisplayName" + model.NewId()
|
||||
o2.Name = "zz" + model.NewId() + "a"
|
||||
o2.Email = MakeEmail()
|
||||
o2.Type = model.TEAM_OPEN
|
||||
o2.AllowOpenInvite = false
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
r1 := <-ss.Team().SearchOpen(tc.Term)
|
||||
require.Nil(t, r1.Err)
|
||||
results := r1.Data.([]*model.Team)
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
func testTeamStoreSearchPrivate(t *testing.T, ss store.Store) {
|
||||
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{}
|
||||
p2.DisplayName = "BDisplayName" + model.NewId()
|
||||
p2.Name = "b" + model.NewId() + "b"
|
||||
p2.Email = MakeEmail()
|
||||
p2.Type = model.TEAM_INVITE
|
||||
p2.AllowOpenInvite = true
|
||||
|
||||
if err := (<-ss.Team().Save(&p2)).Err; err != nil {
|
||||
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")
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
r1 := <-ss.Team().SearchPrivate(tc.Term)
|
||||
require.Nil(t, r1.Err)
|
||||
results := r1.Data.([]*model.Team)
|
||||
require.Equal(t, tc.ExpectedLenth, len(results))
|
||||
if tc.ExpectedFirstId != "" {
|
||||
assert.Equal(t, tc.ExpectedFirstId, results[0].Id)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
o1 := model.Team{}
|
||||
o1.DisplayName = "DisplayName"
|
||||
|
||||
Ссылка в новой задаче
Block a user