Adding list/join public/private teams permissions (#10309)

* Adding list/join public/private teams permissions

* Add permission migration and allow to migrate based on role name

* Adding JoinTeam new endpoint

* Addressing PR review comments

* Keep the previous API consistent
Этот коммит содержится в:
Jesús Espino
2019-03-19 11:36:29 +01:00
коммит произвёл GitHub
родитель 030ba52b08
Коммит 5a9d95d9c7
13 изменённых файлов: 802 добавлений и 217 удалений

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

@@ -364,9 +364,27 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
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()