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
|
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)
|
||||||
})
|
})
|
||||||
|
|||||||
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
|
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"
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user