Skip to content

Commit

Permalink
Implement endpoint for APIv4: PUT /teams/{team_id}/members/{user_id}/…
Browse files Browse the repository at this point in the history
…roles (#5471)
  • Loading branch information
saturninoabril authored and grundleborg committed Feb 21, 2017
1 parent 5c19d9b commit a14e44b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
28 changes: 28 additions & 0 deletions api4/team.go
Expand Up @@ -23,6 +23,7 @@ func InitTeam() {

BaseRoutes.TeamByName.Handle("", ApiSessionRequired(getTeamByName)).Methods("GET")
BaseRoutes.TeamMember.Handle("", ApiSessionRequired(getTeamMember)).Methods("GET")
BaseRoutes.TeamMember.Handle("/roles", ApiSessionRequired(updateTeamMemberRoles)).Methods("PUT")
}

func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -140,3 +141,30 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
}

func updateTeamMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireTeamId().RequireUserId()
if c.Err != nil {
return
}

props := model.MapFromJson(r.Body)

newRoles := props["roles"]
if !model.IsValidUserRoles(newRoles) {
c.SetInvalidParam("team_member_roles")
return
}

if !app.SessionHasPermissionToTeam(c.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM_ROLES) {
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM_ROLES)
return
}

if _, err := app.UpdateTeamMemberRoles(c.Params.TeamId, c.Params.UserId, newRoles); err != nil {
c.Err = err
return
}

ReturnStatusOK(w)
}
78 changes: 78 additions & 0 deletions api4/team_test.go
Expand Up @@ -283,3 +283,81 @@ func TestGetTeamStats(t *testing.T) {
_, resp = Client.GetTeamStats(th.BasicTeam.Id, "")
CheckUnauthorizedStatus(t, resp)
}

func TestUpdateTeamMemberRoles(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer TearDown()
Client := th.Client
SystemAdminClient := th.SystemAdminClient

const TEAM_MEMBER = "team_user"
const TEAM_ADMIN = "team_user team_admin"

// user 1 tries to promote user 2
ok, resp := Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TEAM_ADMIN)
CheckForbiddenStatus(t, resp)
if ok {
t.Fatal("should have returned false")
}

// user 1 tries to promote himself
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TEAM_ADMIN)
CheckForbiddenStatus(t, resp)

// user 1 tries to demote someone
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TEAM_MEMBER)
CheckForbiddenStatus(t, resp)

// system admin promotes user 1
ok, resp = SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TEAM_ADMIN)
CheckNoError(t, resp)
if !ok {
t.Fatal("should have returned true")
}

// user 1 (team admin) promotes user 2
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TEAM_ADMIN)
CheckNoError(t, resp)

// user 1 (team admin) demotes user 2 (team admin)
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TEAM_MEMBER)
CheckNoError(t, resp)

// user 1 (team admin) tries to demote system admin (not member of a team)
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TEAM_MEMBER)
CheckBadRequestStatus(t, resp)

// user 1 (team admin) demotes system admin (member of a team)
LinkUserToTeam(th.SystemAdminUser, th.BasicTeam)
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TEAM_MEMBER)
CheckNoError(t, resp)
// Note from API v3
// Note to anyone who thinks this (above) test is wrong:
// This operation will not affect the system admin's permissions because they have global access to all teams.
// Their team level permissions are irrelavent. A team admin should be able to manage team level permissions.

// System admins should be able to manipulate permission no matter what their team level permissions are.
// system admin promotes user 2
_, resp = SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TEAM_ADMIN)
CheckNoError(t, resp)

// system admin demotes user 2 (team admin)
_, resp = SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TEAM_MEMBER)
CheckNoError(t, resp)

// user 1 (team admin) tries to promote himself to a random team
_, resp = Client.UpdateTeamMemberRoles(model.NewId(), th.BasicUser.Id, TEAM_ADMIN)
CheckForbiddenStatus(t, resp)

// user 1 (team admin) tries to promote a random user
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, model.NewId(), TEAM_ADMIN)
CheckBadRequestStatus(t, resp)

// user 1 (team admin) tries to promote invalid team permission
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, "junk")
CheckBadRequestStatus(t, resp)

// user 1 (team admin) demotes himself
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TEAM_MEMBER)
CheckNoError(t, resp)
}
11 changes: 11 additions & 0 deletions model/client4.go
Expand Up @@ -523,6 +523,17 @@ func (c *Client4) GetTeamMember(teamId, userId, etag string) (*TeamMember, *Resp
}
}

// UpdateTeamMemberRoles will update the roles on a team for a user
func (c *Client4) UpdateTeamMemberRoles(teamId, userId, newRoles string) (bool, *Response) {
requestBody := map[string]string{"roles": newRoles}
if r, err := c.DoApiPut(c.GetTeamMemberRoute(teamId, userId)+"/roles", MapToJson(requestBody)); err != nil {
return false, &Response{StatusCode: r.StatusCode, Error: err}
} else {
defer closeBody(r)
return CheckStatusOK(r), BuildResponse(r)
}
}

// GetTeamStats returns a team stats based on the team id string.
// Must be authenticated.
func (c *Client4) GetTeamStats(teamId, etag string) (*TeamStats, *Response) {
Expand Down

0 comments on commit a14e44b

Please sign in to comment.