diff options
Diffstat (limited to 'api')
-rw-r--r-- | api/cli_test.go | 37 | ||||
-rw-r--r-- | api/team.go | 115 | ||||
-rw-r--r-- | api/team_test.go | 35 |
3 files changed, 182 insertions, 5 deletions
diff --git a/api/cli_test.go b/api/cli_test.go index 8184c2e06..ae2abee4a 100644 --- a/api/cli_test.go +++ b/api/cli_test.go @@ -334,6 +334,43 @@ func TestCliJoinTeam(t *testing.T) { } } +func TestCliLeaveTeam(t *testing.T) { + if disableCliTests { + return + } + + th := Setup().InitBasic() + + cmd := exec.Command("bash", "-c", `go run ../mattermost.go -leave_team -team_name="`+th.BasicTeam.Name+`" -email="`+th.BasicUser.Email+`"`) + output, err := cmd.CombinedOutput() + if err != nil { + t.Log(string(output)) + t.Fatal(err) + } + + profiles := th.BasicClient.Must(th.BasicClient.GetProfiles(th.BasicTeam.Id, "")).Data.(map[string]*model.User) + + found := false + + for _, user := range profiles { + if user.Email == th.BasicUser.Email { + found = true + } + + } + + if !found { + t.Fatal("profile still should be in team even if deleted") + } + + if result := <-Srv.Store.Team().GetTeamsByUserId(th.BasicUser.Id); result.Err != nil { + teamMembers := result.Data.([]*model.TeamMember) + if len(teamMembers) > 0 { + t.Fatal("Shouldn't be in team") + } + } +} + func TestCliResetPassword(t *testing.T) { if disableCliTests { return diff --git a/api/team.go b/api/team.go index 50e32e625..7f8a421ce 100644 --- a/api/team.go +++ b/api/team.go @@ -17,7 +17,6 @@ import ( "github.com/gorilla/mux" "github.com/mattermost/platform/model" - "github.com/mattermost/platform/store" "github.com/mattermost/platform/utils" ) @@ -39,6 +38,7 @@ func InitTeam() { BaseRoutes.NeedTeam.Handle("/invite_members", ApiUserRequired(inviteMembers)).Methods("POST") BaseRoutes.NeedTeam.Handle("/add_user_to_team", ApiUserRequired(addUserToTeam)).Methods("POST") + BaseRoutes.NeedTeam.Handle("/remove_user_from_team", ApiUserRequired(removeUserFromTeam)).Methods("POST") // These should be moved to the global admin console BaseRoutes.NeedTeam.Handle("/import_team", ApiUserRequired(importTeam)).Methods("POST") @@ -266,11 +266,23 @@ func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError { channelRole = model.CHANNEL_ROLE_ADMIN } - if tmr := <-Srv.Store.Team().SaveMember(tm); tmr.Err != nil { - if tmr.Err.Id == store.TEAM_MEMBER_EXISTS_ERROR { + if etmr := <-Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil { + // Membership alredy exists. Check if deleted and and update, otherwise do nothing + rtm := etmr.Data.(model.TeamMember) + + // Do nothing if already added + if rtm.DeleteAt == 0 { return nil } - return tmr.Err + + if tmr := <-Srv.Store.Team().UpdateMember(tm); tmr.Err != nil { + return tmr.Err + } + } else { + // Membership appears to be missing. Lets try to add. + if tmr := <-Srv.Store.Team().SaveMember(tm); tmr.Err != nil { + return tmr.Err + } } if uua := <-Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil { @@ -291,6 +303,56 @@ func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError { return nil } +func LeaveTeam(team *model.Team, user *model.User) *model.AppError { + + var teamMember model.TeamMember + + if result := <-Srv.Store.Team().GetMember(team.Id, user.Id); result.Err != nil { + return model.NewLocAppError("RemoveUserFromTeam", "api.team.remove_user_from_team.missing.app_error", nil, result.Err.Error()) + } else { + teamMember = result.Data.(model.TeamMember) + } + + var channelMembers *model.ChannelList + + if result := <-Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil { + if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" { + channelMembers = &model.ChannelList{make([]*model.Channel, 0), make(map[string]*model.ChannelMember)} + } else { + return result.Err + } + + } else { + channelMembers = result.Data.(*model.ChannelList) + } + + for _, channel := range channelMembers.Channels { + if channel.Type != model.CHANNEL_DIRECT { + if result := <-Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil { + return result.Err + } + } + } + + teamMember.Roles = "" + teamMember.DeleteAt = model.GetMillis() + + if result := <-Srv.Store.Team().UpdateMember(&teamMember); result.Err != nil { + return result.Err + } + + if uua := <-Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil { + return uua.Err + } + + RemoveAllSessionsForUserId(user.Id) + InvalidateCacheForUser(user.Id) + + go Publish(model.NewMessage(team.Id, "", user.Id, model.ACTION_LEAVE_TEAM)) + + return nil +} + func isTeamCreationAllowed(c *Context, email string) bool { email = strings.ToLower(email) @@ -483,6 +545,51 @@ func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(model.MapToJson(params))) } +func removeUserFromTeam(c *Context, w http.ResponseWriter, r *http.Request) { + params := model.MapFromJson(r.Body) + userId := params["user_id"] + + if len(userId) != 26 { + c.SetInvalidParam("removeUserFromTeam", "user_id") + return + } + + tchan := Srv.Store.Team().Get(c.TeamId) + uchan := Srv.Store.User().Get(userId) + + var team *model.Team + if result := <-tchan; result.Err != nil { + c.Err = result.Err + return + } else { + team = result.Data.(*model.Team) + } + + var user *model.User + if result := <-uchan; result.Err != nil { + c.Err = result.Err + return + } else { + user = result.Data.(*model.User) + } + + if c.Session.UserId != user.Id { + if !c.IsTeamAdmin() { + c.Err = model.NewLocAppError("removeUserFromTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId) + c.Err.StatusCode = http.StatusForbidden + return + } + } + + err := LeaveTeam(team, user) + if err != nil { + c.Err = err + return + } + + w.Write([]byte(model.MapToJson(params))) +} + func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) { params := model.MapFromJson(r.Body) diff --git a/api/team_test.go b/api/team_test.go index a62ffcdb5..9fc3e8105 100644 --- a/api/team_test.go +++ b/api/team_test.go @@ -158,7 +158,7 @@ func TestAddUserToTeam(t *testing.T) { } user2 := th.CreateUser(th.BasicClient) - if result, err := th.BasicClient.AddUserToTeam(user2.Id); err != nil { + if result, err := th.BasicClient.AddUserToTeam("", user2.Id); err != nil { t.Fatal(err) } else { rm := result.Data.(map[string]string) @@ -168,6 +168,39 @@ func TestAddUserToTeam(t *testing.T) { } } +func TestRemoveUserFromTeam(t *testing.T) { + th := Setup().InitSystemAdmin().InitBasic() + + if _, err := th.BasicClient.RemoveUserFromTeam(th.SystemAdminTeam.Id, th.SystemAdminUser.Id); err == nil { + t.Fatal("should fail not enough permissions") + } else { + if err.Id != "api.context.permissions.app_error" { + t.Fatal("wrong error") + } + } + + if _, err := th.BasicClient.RemoveUserFromTeam("", th.SystemAdminUser.Id); err == nil { + t.Fatal("should fail not enough permissions") + } else { + if err.Id != "api.team.update_team.permissions.app_error" { + t.Fatal("wrong error") + } + } + + if _, err := th.BasicClient.RemoveUserFromTeam("", th.BasicUser.Id); err != nil { + t.Fatal("should have removed the user from the team") + } + + th.BasicClient.Logout() + th.LoginSystemAdmin() + + th.SystemAdminClient.Must(th.SystemAdminClient.AddUserToTeam(th.BasicTeam.Id, th.BasicUser.Id)) + + if _, err := th.SystemAdminClient.RemoveUserFromTeam(th.BasicTeam.Id, th.BasicUser.Id); err != nil { + t.Fatal("should have removed the user from the team") + } +} + func TestAddUserToTeamFromInvite(t *testing.T) { th := Setup().InitBasic() th.BasicClient.Logout() |