Implement endpoint for APIv4: PUT /teams/{team_id}/members/{user_id}/roles (#5471)
Этот коммит содержится в:
коммит произвёл
George Goldberg
родитель
5c19d9be7f
Коммит
a14e44b4ec
28
api4/team.go
28
api4/team.go
@@ -23,6 +23,7 @@ func InitTeam() {
|
|||||||
|
|
||||||
BaseRoutes.TeamByName.Handle("", ApiSessionRequired(getTeamByName)).Methods("GET")
|
BaseRoutes.TeamByName.Handle("", ApiSessionRequired(getTeamByName)).Methods("GET")
|
||||||
BaseRoutes.TeamMember.Handle("", ApiSessionRequired(getTeamMember)).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) {
|
func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -140,3 +141,30 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -283,3 +283,81 @@ func TestGetTeamStats(t *testing.T) {
|
|||||||
_, resp = Client.GetTeamStats(th.BasicTeam.Id, "")
|
_, resp = Client.GetTeamStats(th.BasicTeam.Id, "")
|
||||||
CheckUnauthorizedStatus(t, resp)
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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.
|
// GetTeamStats returns a team stats based on the team id string.
|
||||||
// Must be authenticated.
|
// Must be authenticated.
|
||||||
func (c *Client4) GetTeamStats(teamId, etag string) (*TeamStats, *Response) {
|
func (c *Client4) GetTeamStats(teamId, etag string) (*TeamStats, *Response) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user