diff options
author | Joram Wilander <jwawilander@gmail.com> | 2017-03-25 02:38:24 -0400 |
---|---|---|
committer | enahum <nahumhbl@gmail.com> | 2017-03-25 03:38:24 -0300 |
commit | ea74613444c65e965a76a6ad7640f6c011c2c69b (patch) | |
tree | 6d4941d695a5637bb2ff112706edeabc7ba79ef9 | |
parent | 54d3d47daf9190275bbdaf8703b84969a4593451 (diff) | |
download | chat-ea74613444c65e965a76a6ad7640f6c011c2c69b.tar.gz chat-ea74613444c65e965a76a6ad7640f6c011c2c69b.tar.bz2 chat-ea74613444c65e965a76a6ad7640f6c011c2c69b.zip |
Implement some team endpoints for APIv4 (#5870)
* Implement GET /users/{user_id}/teams/members endpoint for APIv4
* Implement DELETE /teams/{team_id}/members/{user_id} endpoint for APIv4
-rw-r--r-- | api4/api.go | 16 | ||||
-rw-r--r-- | api4/team.go | 43 | ||||
-rw-r--r-- | api4/team_test.go | 69 | ||||
-rw-r--r-- | model/client4.go | 20 |
4 files changed, 141 insertions, 7 deletions
diff --git a/api4/api.go b/api4/api.go index 6a55fbcbb..c967537ee 100644 --- a/api4/api.go +++ b/api4/api.go @@ -25,13 +25,14 @@ type Routes struct { UserByUsername *mux.Router // 'api/v4/users/username/{username:[A-Za-z0-9_-\.]+}' UserByEmail *mux.Router // 'api/v4/users/email/{email}' - Teams *mux.Router // 'api/v4/teams' - TeamsForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams' - Team *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}' - TeamForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams/{team_id:[A-Za-z0-9]+}' - TeamByName *mux.Router // 'api/v4/teams/name/{team_name:[A-Za-z0-9_-]+}' - TeamMembers *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9_-]+}/members' - TeamMember *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9_-]+}/members/{user_id:[A-Za-z0-9_-]+}' + Teams *mux.Router // 'api/v4/teams' + TeamsForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams' + Team *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}' + TeamForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams/{team_id:[A-Za-z0-9]+}' + TeamByName *mux.Router // 'api/v4/teams/name/{team_name:[A-Za-z0-9_-]+}' + TeamMembers *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9_-]+}/members' + TeamMember *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9_-]+}/members/{user_id:[A-Za-z0-9_-]+}' + TeamMembersForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams/members' Channels *mux.Router // 'api/v4/channels' Channel *mux.Router // 'api/v4/channels/{channel_id:[A-Za-z0-9]+}' @@ -111,6 +112,7 @@ func InitApi(full bool) { BaseRoutes.TeamByName = BaseRoutes.Teams.PathPrefix("/name/{team_name:[A-Za-z0-9_-]+}").Subrouter() BaseRoutes.TeamMembers = BaseRoutes.Team.PathPrefix("/members").Subrouter() BaseRoutes.TeamMember = BaseRoutes.TeamMembers.PathPrefix("/{user_id:[A-Za-z0-9]+}").Subrouter() + BaseRoutes.TeamMembersForUser = BaseRoutes.User.PathPrefix("/teams/members").Subrouter() BaseRoutes.Channels = BaseRoutes.ApiRoot.PathPrefix("/channels").Subrouter() BaseRoutes.Channel = BaseRoutes.Channels.PathPrefix("/{channel_id:[A-Za-z0-9]+}").Subrouter() diff --git a/api4/team.go b/api4/team.go index a9be5c8ab..489265251 100644 --- a/api4/team.go +++ b/api4/team.go @@ -26,7 +26,9 @@ func InitTeam() { BaseRoutes.Team.Handle("/stats", ApiSessionRequired(getTeamStats)).Methods("GET") BaseRoutes.TeamMembers.Handle("", ApiSessionRequired(getTeamMembers)).Methods("GET") BaseRoutes.TeamMembers.Handle("/ids", ApiSessionRequired(getTeamMembersByIds)).Methods("POST") + BaseRoutes.TeamMembersForUser.Handle("", ApiSessionRequired(getTeamMembersForUser)).Methods("GET") BaseRoutes.TeamMembers.Handle("", ApiSessionRequired(addTeamMember)).Methods("POST") + BaseRoutes.TeamMember.Handle("", ApiSessionRequired(removeTeamMember)).Methods("DELETE") BaseRoutes.TeamForUser.Handle("/unread", ApiSessionRequired(getTeamUnread)).Methods("GET") @@ -239,6 +241,26 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { } } +func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) { + c.RequireUserId() + if c.Err != nil { + return + } + + if !app.SessionHasPermissionToUser(c.Session, c.Params.UserId) { + c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) + return + } + + members, err := app.GetTeamMembersForUser(c.Params.UserId) + if err != nil { + c.Err = err + return + } + + w.Write([]byte(model.TeamMembersToJson(members))) +} + func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) { c.RequireTeamId() if c.Err != nil { @@ -317,6 +339,27 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(member.ToJson())) } +func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { + c.RequireTeamId().RequireUserId() + if c.Err != nil { + return + } + + if c.Session.UserId != c.Params.UserId { + if !app.SessionHasPermissionToTeam(c.Session, c.Params.TeamId, model.PERMISSION_REMOVE_USER_FROM_TEAM) { + c.SetPermissionError(model.PERMISSION_REMOVE_USER_FROM_TEAM) + return + } + } + + if err := app.RemoveUserFromTeam(c.Params.TeamId, c.Params.UserId); err != nil { + c.Err = err + return + } + + ReturnStatusOK(w) +} + func getTeamUnread(c *Context, w http.ResponseWriter, r *http.Request) { c.RequireTeamId().RequireUserId() if c.Err != nil { diff --git a/api4/team_test.go b/api4/team_test.go index 1f1e031b3..36d6df147 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -534,6 +534,44 @@ func TestGetTeamMembers(t *testing.T) { CheckNoError(t, resp) } +func TestGetTeamMembersForUser(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer TearDown() + Client := th.Client + + members, resp := Client.GetTeamMembersForUser(th.BasicUser.Id, "") + CheckNoError(t, resp) + + found := false + for _, m := range members { + if m.TeamId == th.BasicTeam.Id { + found = true + } + } + + if !found { + t.Fatal("missing team member") + } + + _, resp = Client.GetTeamMembersForUser("junk", "") + CheckBadRequestStatus(t, resp) + + _, resp = Client.GetTeamMembersForUser(model.NewId(), "") + CheckForbiddenStatus(t, resp) + + Client.Logout() + _, resp = Client.GetTeamMembersForUser(th.BasicUser.Id, "") + CheckUnauthorizedStatus(t, resp) + + user := th.CreateUser() + Client.Login(user.Email, user.Password) + _, resp = Client.GetTeamMembersForUser(th.BasicUser.Id, "") + CheckForbiddenStatus(t, resp) + + _, resp = th.SystemAdminClient.GetTeamMembersForUser(th.BasicUser.Id, "") + CheckNoError(t, resp) +} + func TestGetTeamMembersByIds(t *testing.T) { th := Setup().InitBasic() defer TearDown() @@ -706,6 +744,37 @@ func TestAddTeamMember(t *testing.T) { CheckNotFoundStatus(t, resp) } +func TestRemoveTeamMember(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer TearDown() + Client := th.Client + + pass, resp := Client.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser.Id) + CheckNoError(t, resp) + + if !pass { + t.Fatal("should have passed") + } + + _, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "", "", "") + CheckNoError(t, resp) + + _, resp = Client.RemoveTeamMember(th.BasicTeam.Id, "junk") + CheckBadRequestStatus(t, resp) + + _, resp = Client.RemoveTeamMember("junk", th.BasicUser2.Id) + CheckBadRequestStatus(t, resp) + + _, resp = Client.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser2.Id) + CheckForbiddenStatus(t, resp) + + _, resp = Client.RemoveTeamMember(model.NewId(), th.BasicUser.Id) + CheckNotFoundStatus(t, resp) + + _, resp = th.SystemAdminClient.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser.Id) + CheckNoError(t, resp) +} + func TestGetTeamStats(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer TearDown() diff --git a/model/client4.go b/model/client4.go index 9ad9c9ae4..19d4a9a00 100644 --- a/model/client4.go +++ b/model/client4.go @@ -819,6 +819,16 @@ func (c *Client4) GetTeamMembers(teamId string, page int, perPage int, etag stri } } +// GetTeamMembersForUser returns the team members for a user. +func (c *Client4) GetTeamMembersForUser(userId string, etag string) ([]*TeamMember, *Response) { + if r, err := c.DoApiGet(c.GetUserRoute(userId)+"/teams/members", etag); err != nil { + return nil, &Response{StatusCode: r.StatusCode, Error: err} + } else { + defer closeBody(r) + return TeamMembersFromJson(r.Body), BuildResponse(r) + } +} + // GetTeamMembersByIds will return an array of team members based on the // team id and a list of user ids provided. Must be authenticated. func (c *Client4) GetTeamMembersByIds(teamId string, userIds []string) ([]*TeamMember, *Response) { @@ -852,6 +862,16 @@ func (c *Client4) AddTeamMember(teamId, userId, hash, dataToHash, inviteId strin } } +// RemoveTeamMember will remove a user from a team. +func (c *Client4) RemoveTeamMember(teamId, userId string) (bool, *Response) { + if r, err := c.DoApiDelete(c.GetTeamMemberRoute(teamId, userId)); 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) { |