diff --git a/app/team.go b/app/team.go index 066d1ccae8..b6b15428b1 100644 --- a/app/team.go +++ b/app/team.go @@ -1000,6 +1000,20 @@ func (a *App) SoftDeleteTeam(teamId string) *model.AppError { return nil } +func (a *App) RestoreTeam(teamId string) *model.AppError { + team, err := a.GetTeam(teamId) + if err != nil { + return err + } + team.DeleteAt = 0 + result := <-a.Srv.Store.Team().Update(team) + if result.Err != nil { + return result.Err + } + a.sendTeamEvent(team, model.WEBSOCKET_EVENT_RESTORE_TEAM) + return nil +} + func (a *App) GetTeamStats(teamId string) (*model.TeamStats, *model.AppError) { tchan := a.Srv.Store.Team().GetTotalMemberCount(teamId) achan := a.Srv.Store.Team().GetActiveMemberCount(teamId) diff --git a/cmd/mattermost/commands/team.go b/cmd/mattermost/commands/team.go index 525ae76e3d..8a63ac1895 100644 --- a/cmd/mattermost/commands/team.go +++ b/cmd/mattermost/commands/team.go @@ -81,6 +81,15 @@ var ArchiveTeamCmd = &cobra.Command{ RunE: archiveTeamCmdF, } +var RestoreTeamsCmd = &cobra.Command{ + Use: "restore [teams]", + Short: "Restore some teams", + Long: `Restore a previously deleted team`, + Example: " team restore myteam", + Args: cobra.MinimumNArgs(1), + RunE: restoreTeamsCmdF, +} + func init() { TeamCreateCmd.Flags().String("name", "", "Team Name") TeamCreateCmd.Flags().String("display_name", "", "Team Display Name") @@ -97,6 +106,7 @@ func init() { ListTeamsCmd, SearchTeamCmd, ArchiveTeamCmd, + RestoreTeamsCmd, ) RootCmd.AddCommand(TeamCmd) } @@ -294,6 +304,28 @@ func searchTeamCmdF(command *cobra.Command, args []string) error { return nil } +// Restores archived teams by name +func restoreTeamsCmdF(command *cobra.Command, args []string) error { + a, err := InitDBCommandContextCobra(command) + if err != nil { + return err + } + defer a.Shutdown() + + teams := getTeamsFromTeamArgs(a, args) + for i, team := range teams { + if team == nil { + CommandPrintErrorln("Unable to find team '" + args[i] + "'") + continue + } + err := a.RestoreTeam(team.Id) + if err != nil { + CommandPrintErrorln("Unable to restore team '" + team.Name + "' error: " + err.Error()) + } + } + return nil +} + // Removes duplicates and sorts teams by name func removeDuplicatesAndSortTeams(teams []*model.Team) []*model.Team { keys := make(map[string]bool) diff --git a/cmd/mattermost/commands/team_test.go b/cmd/mattermost/commands/team_test.go index a956e38bed..9d970b897a 100644 --- a/cmd/mattermost/commands/team_test.go +++ b/cmd/mattermost/commands/team_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/mattermost/mattermost-server/model" + "github.com/stretchr/testify/require" ) func TestCreateTeam(t *testing.T) { @@ -185,3 +186,22 @@ func TestArchiveTeams(t *testing.T) { t.Fatal("should have archived team") } } + +func TestRestoreTeams(t *testing.T) { + th := Setup().InitBasic() + defer th.TearDown() + + id := model.NewId() + name := "name" + id + displayName := "Name " + id + + th.CheckCommand(t, "team", "create", "--name", name, "--display_name", displayName) + + th.CheckCommand(t, "team", "archive", name) + + th.CheckCommand(t, "team", "restore", name) + + found := th.SystemAdminClient.Must(th.SystemAdminClient.TeamExists(name, "")).(bool) + + require.True(t, found) +} diff --git a/model/websocket_message.go b/model/websocket_message.go index 9cf80e7871..132b89a084 100644 --- a/model/websocket_message.go +++ b/model/websocket_message.go @@ -26,6 +26,7 @@ const ( WEBSOCKET_EVENT_LEAVE_TEAM = "leave_team" WEBSOCKET_EVENT_UPDATE_TEAM = "update_team" WEBSOCKET_EVENT_DELETE_TEAM = "delete_team" + WEBSOCKET_EVENT_RESTORE_TEAM = "restore_team" WEBSOCKET_EVENT_USER_ADDED = "user_added" WEBSOCKET_EVENT_USER_UPDATED = "user_updated" WEBSOCKET_EVENT_USER_ROLE_UPDATED = "user_role_updated"