github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/cmd/mattermost/commands/team.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package commands 5 6 import ( 7 "errors" 8 "fmt" 9 "sort" 10 "strings" 11 12 "github.com/spf13/cobra" 13 14 "github.com/mattermost/mattermost-server/v5/app" 15 "github.com/mattermost/mattermost-server/v5/audit" 16 "github.com/mattermost/mattermost-server/v5/model" 17 ) 18 19 var TeamCmd = &cobra.Command{ 20 Use: "team", 21 Short: "Management of teams", 22 } 23 24 var TeamCreateCmd = &cobra.Command{ 25 Use: "create", 26 Short: "Create a team", 27 Long: `Create a team.`, 28 Example: ` team create --name mynewteam --display_name "My New Team" 29 team create --name private --display_name "My New Private Team" --private`, 30 RunE: createTeamCmdF, 31 } 32 33 var RemoveUsersCmd = &cobra.Command{ 34 Use: "remove [team] [users]", 35 Short: "Remove users from team", 36 Long: "Remove some users from team", 37 Example: " team remove myteam user@example.com username", 38 Args: cobra.MinimumNArgs(2), 39 RunE: removeUsersCmdF, 40 } 41 42 var AddUsersCmd = &cobra.Command{ 43 Use: "add [team] [users]", 44 Short: "Add users to team", 45 Long: "Add some users to team", 46 Example: " team add myteam user@example.com username", 47 Args: cobra.MinimumNArgs(2), 48 RunE: addUsersCmdF, 49 } 50 51 var DeleteTeamsCmd = &cobra.Command{ 52 Use: "delete [teams]", 53 Short: "Delete teams", 54 Long: `Permanently delete some teams. 55 Permanently deletes a team along with all related information including posts from the database.`, 56 Example: " team delete myteam", 57 Args: cobra.MinimumNArgs(1), 58 RunE: deleteTeamsCmdF, 59 } 60 61 var ListTeamsCmd = &cobra.Command{ 62 Use: "list", 63 Short: "List all teams.", 64 Long: `List all teams on the server.`, 65 Example: " team list", 66 RunE: listTeamsCmdF, 67 } 68 69 var SearchTeamCmd = &cobra.Command{ 70 Use: "search [teams]", 71 Short: "Search for teams", 72 Long: "Search for teams based on name", 73 Example: " team search team1", 74 Args: cobra.MinimumNArgs(1), 75 RunE: searchTeamCmdF, 76 } 77 78 var ArchiveTeamCmd = &cobra.Command{ 79 Use: "archive [teams]", 80 Short: "Archive teams", 81 Long: "Archive teams based on name", 82 Example: " team archive team1", 83 Args: cobra.MinimumNArgs(1), 84 RunE: archiveTeamCmdF, 85 } 86 87 var RestoreTeamsCmd = &cobra.Command{ 88 Use: "restore [teams]", 89 Short: "Restore some teams", 90 Long: `Restore a previously deleted team`, 91 Example: " team restore myteam", 92 Args: cobra.MinimumNArgs(1), 93 RunE: restoreTeamsCmdF, 94 } 95 96 var TeamRenameCmd = &cobra.Command{ 97 Use: "rename", 98 Short: "Rename a team", 99 Long: `Rename a team.`, 100 Example: ` team rename myteam newteamname --display_name "My New Team Name" 101 team rename myteam - --display_name "My New Team Name"`, 102 Args: cobra.MinimumNArgs(2), 103 RunE: renameTeamCmdF, 104 } 105 106 var ModifyTeamCmd = &cobra.Command{ 107 Use: "modify [team] [flag]", 108 Short: "Modify a team's privacy setting to public or private", 109 Long: `Modify a team's privacy setting to public or private.`, 110 Example: " team modify myteam --private", 111 Args: cobra.ExactArgs(1), 112 RunE: modifyTeamCmdF, 113 } 114 115 func init() { 116 TeamCreateCmd.Flags().String("name", "", "Team Name") 117 TeamCreateCmd.Flags().String("display_name", "", "Team Display Name") 118 TeamCreateCmd.Flags().Bool("private", false, "Create a private team.") 119 TeamCreateCmd.Flags().String("email", "", "Administrator Email (anyone with this email is automatically a team admin)") 120 121 DeleteTeamsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the team and a DB backup has been performed.") 122 123 TeamRenameCmd.Flags().String("display_name", "", "Team Display Name") 124 125 ModifyTeamCmd.Flags().Bool("private", false, "Convert the team to a private team") 126 ModifyTeamCmd.Flags().Bool("public", false, "Convert the team to a public team") 127 128 TeamCmd.AddCommand( 129 TeamCreateCmd, 130 RemoveUsersCmd, 131 AddUsersCmd, 132 DeleteTeamsCmd, 133 ListTeamsCmd, 134 SearchTeamCmd, 135 ArchiveTeamCmd, 136 RestoreTeamsCmd, 137 TeamRenameCmd, 138 ModifyTeamCmd, 139 ) 140 RootCmd.AddCommand(TeamCmd) 141 } 142 143 func createTeamCmdF(command *cobra.Command, args []string) error { 144 a, err := InitDBCommandContextCobra(command) 145 if err != nil { 146 return err 147 } 148 defer a.Srv().Shutdown() 149 150 name, errn := command.Flags().GetString("name") 151 if errn != nil || name == "" { 152 return errors.New("Name is required") 153 } 154 displayname, errdn := command.Flags().GetString("display_name") 155 if errdn != nil || displayname == "" { 156 return errors.New("Display Name is required") 157 } 158 email, _ := command.Flags().GetString("email") 159 email = strings.ToLower(email) 160 useprivate, _ := command.Flags().GetBool("private") 161 162 teamType := model.TEAM_OPEN 163 if useprivate { 164 teamType = model.TEAM_INVITE 165 } 166 167 team := &model.Team{ 168 Name: name, 169 DisplayName: displayname, 170 Email: email, 171 Type: teamType, 172 } 173 174 createdTeam, errCreate := a.CreateTeam(team) 175 if errCreate != nil { 176 return errors.New("Team creation failed: " + errCreate.Error()) 177 } 178 179 auditRec := a.MakeAuditRecord("createTeam", audit.Success) 180 auditRec.AddMeta("team", createdTeam) 181 a.LogAuditRec(auditRec, nil) 182 183 return nil 184 } 185 186 func removeUsersCmdF(command *cobra.Command, args []string) error { 187 a, err := InitDBCommandContextCobra(command) 188 if err != nil { 189 return err 190 } 191 defer a.Srv().Shutdown() 192 193 team := getTeamFromTeamArg(a, args[0]) 194 if team == nil { 195 return errors.New("Unable to find team '" + args[0] + "'") 196 } 197 198 users := getUsersFromUserArgs(a, args[1:]) 199 for i, user := range users { 200 removeUserFromTeam(a, team, user, args[i+1]) 201 } 202 203 return nil 204 } 205 206 func removeUserFromTeam(a *app.App, team *model.Team, user *model.User, userArg string) { 207 if user == nil { 208 CommandPrintErrorln("Can't find user '" + userArg + "'") 209 return 210 } 211 if err := a.LeaveTeam(team, user, ""); err != nil { 212 CommandPrintErrorln("Unable to remove '" + userArg + "' from " + team.Name + ". Error: " + err.Error()) 213 return 214 } 215 216 auditRec := a.MakeAuditRecord("removeUserFromTeam", audit.Success) 217 auditRec.AddMeta("user", user) 218 auditRec.AddMeta("team", team) 219 a.LogAuditRec(auditRec, nil) 220 } 221 222 func addUsersCmdF(command *cobra.Command, args []string) error { 223 a, err := InitDBCommandContextCobra(command) 224 if err != nil { 225 return err 226 } 227 defer a.Srv().Shutdown() 228 229 team := getTeamFromTeamArg(a, args[0]) 230 if team == nil { 231 return errors.New("Unable to find team '" + args[0] + "'") 232 } 233 234 users := getUsersFromUserArgs(a, args[1:]) 235 for i, user := range users { 236 addUserToTeam(a, team, user, args[i+1]) 237 } 238 return nil 239 } 240 241 func addUserToTeam(a *app.App, team *model.Team, user *model.User, userArg string) { 242 if user == nil { 243 CommandPrintErrorln("Can't find user '" + userArg + "'") 244 return 245 } 246 if err := a.JoinUserToTeam(team, user, ""); err != nil { 247 CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name) 248 return 249 } 250 251 auditRec := a.MakeAuditRecord("addUserToTeam", audit.Success) 252 auditRec.AddMeta("user", user) 253 auditRec.AddMeta("team", team) 254 a.LogAuditRec(auditRec, nil) 255 } 256 257 func deleteTeamsCmdF(command *cobra.Command, args []string) error { 258 a, err := InitDBCommandContextCobra(command) 259 if err != nil { 260 return err 261 } 262 defer a.Srv().Shutdown() 263 264 confirmFlag, _ := command.Flags().GetBool("confirm") 265 if !confirmFlag { 266 var confirm string 267 CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") 268 fmt.Scanln(&confirm) 269 270 if confirm != "YES" { 271 return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") 272 } 273 CommandPrettyPrintln("Are you sure you want to delete the teams specified? All data will be permanently deleted? (YES/NO): ") 274 fmt.Scanln(&confirm) 275 if confirm != "YES" { 276 return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") 277 } 278 } 279 280 teams := getTeamsFromTeamArgs(a, args) 281 for i, team := range teams { 282 if team == nil { 283 CommandPrintErrorln("Unable to find team '" + args[i] + "'") 284 continue 285 } 286 if err := deleteTeam(a, team); err != nil { 287 CommandPrintErrorln("Unable to delete team '" + team.Name + "' error: " + err.Error()) 288 } else { 289 CommandPrettyPrintln("Deleted team '" + team.Name + "'") 290 291 auditRec := a.MakeAuditRecord("deleteTeams", audit.Success) 292 auditRec.AddMeta("team", team) 293 a.LogAuditRec(auditRec, nil) 294 } 295 } 296 return nil 297 } 298 299 func deleteTeam(a *app.App, team *model.Team) *model.AppError { 300 return a.PermanentDeleteTeam(team) 301 } 302 303 func listTeamsCmdF(command *cobra.Command, args []string) error { 304 a, err := InitDBCommandContextCobra(command) 305 if err != nil { 306 return err 307 } 308 defer a.Srv().Shutdown() 309 310 teams, err2 := a.GetAllTeams() 311 if err2 != nil { 312 return err2 313 } 314 315 for _, team := range teams { 316 if team.DeleteAt > 0 { 317 CommandPrettyPrintln(team.Name + " (archived)") 318 } else { 319 CommandPrettyPrintln(team.Name) 320 } 321 } 322 323 return nil 324 } 325 326 func searchTeamCmdF(command *cobra.Command, args []string) error { 327 a, err := InitDBCommandContextCobra(command) 328 if err != nil { 329 return err 330 } 331 defer a.Srv().Shutdown() 332 333 var teams []*model.Team 334 335 for _, searchTerm := range args { 336 foundTeams, _, err := a.SearchAllTeams(&model.TeamSearch{Term: searchTerm}) 337 if err != nil { 338 return err 339 } 340 teams = append(teams, foundTeams...) 341 } 342 343 sortedTeams := removeDuplicatesAndSortTeams(teams) 344 345 for _, team := range sortedTeams { 346 if team.DeleteAt > 0 { 347 CommandPrettyPrintln(team.Name + ": " + team.DisplayName + " (" + team.Id + ")" + " (archived)") 348 } else { 349 CommandPrettyPrintln(team.Name + ": " + team.DisplayName + " (" + team.Id + ")") 350 } 351 } 352 353 return nil 354 } 355 356 // Restores archived teams by name 357 func restoreTeamsCmdF(command *cobra.Command, args []string) error { 358 a, err := InitDBCommandContextCobra(command) 359 if err != nil { 360 return err 361 } 362 defer a.Srv().Shutdown() 363 364 teams := getTeamsFromTeamArgs(a, args) 365 for i, team := range teams { 366 if team == nil { 367 CommandPrintErrorln("Unable to find team '" + args[i] + "'") 368 continue 369 } 370 err := a.RestoreTeam(team.Id) 371 if err != nil { 372 CommandPrintErrorln("Unable to restore team '" + team.Name + "' error: " + err.Error()) 373 } else { 374 auditRec := a.MakeAuditRecord("restoreTeams", audit.Success) 375 auditRec.AddMeta("team", team) 376 a.LogAuditRec(auditRec, nil) 377 } 378 } 379 return nil 380 } 381 382 // Removes duplicates and sorts teams by name 383 func removeDuplicatesAndSortTeams(teams []*model.Team) []*model.Team { 384 keys := make(map[string]bool) 385 result := []*model.Team{} 386 for _, team := range teams { 387 if _, value := keys[team.Name]; !value { 388 keys[team.Name] = true 389 result = append(result, team) 390 } 391 } 392 sort.Slice(result, func(i, j int) bool { 393 return result[i].Name < result[j].Name 394 }) 395 return result 396 } 397 398 func archiveTeamCmdF(command *cobra.Command, args []string) error { 399 a, err := InitDBCommandContextCobra(command) 400 if err != nil { 401 return err 402 } 403 defer a.Srv().Shutdown() 404 405 foundTeams := getTeamsFromTeamArgs(a, args) 406 for i, team := range foundTeams { 407 if team == nil { 408 CommandPrintErrorln("Unable to find team '" + args[i] + "'") 409 continue 410 } 411 if err := a.SoftDeleteTeam(team.Id); err != nil { 412 CommandPrintErrorln("Unable to archive team '"+team.Name+"' error: ", err) 413 } else { 414 auditRec := a.MakeAuditRecord("archiveTeam", audit.Success) 415 auditRec.AddMeta("team", team) 416 a.LogAuditRec(auditRec, nil) 417 } 418 } 419 return nil 420 } 421 422 func renameTeamCmdF(command *cobra.Command, args []string) error { 423 424 a, err := InitDBCommandContextCobra(command) 425 if err != nil { 426 return err 427 } 428 defer a.Srv().Shutdown() 429 430 team := getTeamFromTeamArg(a, args[0]) 431 if team == nil { 432 return errors.New("Unable to find team '" + args[0] + "'") 433 } 434 435 var newDisplayName, newTeamName string 436 437 newTeamName = args[1] 438 439 // let user use old team Name when only Display Name change is wanted 440 if newTeamName == team.Name { 441 newTeamName = "-" 442 } 443 444 newDisplayName, errdn := command.Flags().GetString("display_name") 445 if errdn != nil { 446 return errdn 447 } 448 449 updatedTeam, errrt := a.RenameTeam(team, newTeamName, newDisplayName) 450 if errrt != nil { 451 CommandPrintErrorln("Unable to rename team to '"+newTeamName+"' error: ", errrt) 452 } 453 454 auditRec := a.MakeAuditRecord("renameTeam", audit.Success) 455 auditRec.AddMeta("team", team) 456 auditRec.AddMeta("update", updatedTeam) 457 a.LogAuditRec(auditRec, nil) 458 459 return nil 460 } 461 462 func modifyTeamCmdF(command *cobra.Command, args []string) error { 463 a, err := InitDBCommandContextCobra(command) 464 if err != nil { 465 return err 466 } 467 defer a.Srv().Shutdown() 468 469 team := getTeamFromTeamArg(a, args[0]) 470 if team == nil { 471 return errors.New("Unable to find team '" + args[0] + "'") 472 } 473 474 public, _ := command.Flags().GetBool("public") 475 private, _ := command.Flags().GetBool("private") 476 477 if public == private { 478 return errors.New("You must specify only one of --public or --private") 479 } 480 481 if public { 482 team.Type = model.TEAM_OPEN 483 team.AllowOpenInvite = true 484 } else if private { 485 team.Type = model.TEAM_INVITE 486 team.AllowOpenInvite = false 487 } 488 489 if err := a.UpdateTeamPrivacy(team.Id, team.Type, team.AllowOpenInvite); err != nil { 490 return errors.New("Failed to update privacy for team" + args[0]) 491 } 492 493 auditRec := a.MakeAuditRecord("modifyTeam", audit.Success) 494 auditRec.AddMeta("team", team) 495 auditRec.AddMeta("type", team.Type) 496 auditRec.AddMeta("allow_open_invite", team.AllowOpenInvite) 497 a.LogAuditRec(auditRec, nil) 498 499 return nil 500 }