github.com/rajatvaryani/mattermost-server@v5.11.1+incompatible/cmd/mattermost/commands/channel.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package commands 5 6 import ( 7 "fmt" 8 9 "github.com/mattermost/mattermost-server/app" 10 "github.com/mattermost/mattermost-server/model" 11 "github.com/pkg/errors" 12 "github.com/spf13/cobra" 13 ) 14 15 var ChannelCmd = &cobra.Command{ 16 Use: "channel", 17 Short: "Management of channels", 18 } 19 20 var ChannelCreateCmd = &cobra.Command{ 21 Use: "create", 22 Short: "Create a channel", 23 Long: `Create a channel.`, 24 Example: ` channel create --team myteam --name mynewchannel --display_name "My New Channel" 25 channel create --team myteam --name mynewprivatechannel --display_name "My New Private Channel" --private`, 26 RunE: createChannelCmdF, 27 } 28 29 var ChannelRenameCmd = &cobra.Command{ 30 Use: "rename", 31 Short: "Rename a channel", 32 Long: `Rename a channel.`, 33 Example: `" channel rename myteam:mychannel newchannelname --display_name "New Display Name"`, 34 Args: cobra.MinimumNArgs(2), 35 RunE: renameChannelCmdF, 36 } 37 38 var RemoveChannelUsersCmd = &cobra.Command{ 39 Use: "remove [channel] [users]", 40 Short: "Remove users from channel", 41 Long: "Remove some users from channel", 42 Example: ` channel remove myteam:mychannel user@example.com username 43 channel remove myteam:mychannel --all-users`, 44 RunE: removeChannelUsersCmdF, 45 } 46 47 var AddChannelUsersCmd = &cobra.Command{ 48 Use: "add [channel] [users]", 49 Short: "Add users to channel", 50 Long: "Add some users to channel", 51 Example: " channel add myteam:mychannel user@example.com username", 52 Args: cobra.MinimumNArgs(2), 53 RunE: addChannelUsersCmdF, 54 } 55 56 var ArchiveChannelsCmd = &cobra.Command{ 57 Use: "archive [channels]", 58 Short: "Archive channels", 59 Long: `Archive some channels. 60 Archive a channel along with all related information including posts from the database. 61 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 62 Example: " channel archive myteam:mychannel", 63 Args: cobra.MinimumNArgs(1), 64 RunE: archiveChannelsCmdF, 65 } 66 67 var DeleteChannelsCmd = &cobra.Command{ 68 Use: "delete [channels]", 69 Short: "Delete channels", 70 Long: `Permanently delete some channels. 71 Permanently deletes a channel along with all related information including posts from the database. 72 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 73 Example: " channel delete myteam:mychannel", 74 Args: cobra.MinimumNArgs(1), 75 RunE: deleteChannelsCmdF, 76 } 77 78 var ListChannelsCmd = &cobra.Command{ 79 Use: "list [teams]", 80 Short: "List all channels on specified teams.", 81 Long: `List all channels on specified teams. 82 Archived channels are appended with ' (archived)'.`, 83 Example: " channel list myteam", 84 Args: cobra.MinimumNArgs(1), 85 RunE: listChannelsCmdF, 86 } 87 88 var MoveChannelsCmd = &cobra.Command{ 89 Use: "move [team] [channels] --username [user]", 90 Short: "Moves channels to the specified team", 91 Long: `Moves the provided channels to the specified team. 92 Validates that all users in the channel belong to the target team. Incoming/Outgoing webhooks are moved along with the channel. 93 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 94 Example: " channel move newteam oldteam:mychannel --username myusername", 95 Args: cobra.MinimumNArgs(2), 96 RunE: moveChannelsCmdF, 97 } 98 99 var RestoreChannelsCmd = &cobra.Command{ 100 Use: "restore [channels]", 101 Short: "Restore some channels", 102 Long: `Restore a previously deleted channel 103 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 104 Example: " channel restore myteam:mychannel", 105 Args: cobra.MinimumNArgs(1), 106 RunE: restoreChannelsCmdF, 107 } 108 109 var ModifyChannelCmd = &cobra.Command{ 110 Use: "modify [channel] [flags] --username [user]", 111 Short: "Modify a channel's public/private type", 112 Long: `Change the public/private type of a channel. 113 Channel can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 114 Example: " channel modify myteam:mychannel --private --username myusername", 115 Args: cobra.MinimumNArgs(1), 116 RunE: modifyChannelCmdF, 117 } 118 119 var SearchChannelCmd = &cobra.Command{ 120 Use: "search [channel]\n mattermost search --team [team] [channel]", 121 Short: "Search a channel", 122 Long: `Search a channel by channel name. 123 Channel can be specified by team. ie. --team myTeam myChannel or by team ID.`, 124 Example: ` channel search myChannel 125 channel search --team myTeam myChannel`, 126 Args: cobra.ExactArgs(1), 127 RunE: searchChannelCmdF, 128 } 129 130 func init() { 131 ChannelCreateCmd.Flags().String("name", "", "Channel Name") 132 ChannelCreateCmd.Flags().String("display_name", "", "Channel Display Name") 133 ChannelCreateCmd.Flags().String("team", "", "Team name or ID") 134 ChannelCreateCmd.Flags().String("header", "", "Channel header") 135 ChannelCreateCmd.Flags().String("purpose", "", "Channel purpose") 136 ChannelCreateCmd.Flags().Bool("private", false, "Create a private channel.") 137 138 MoveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.") 139 MoveChannelsCmd.Flags().Bool("remove-deactivated-users", false, "Automatically remove any deactivated users from the channel before moving it.") 140 141 DeleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.") 142 143 ModifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel") 144 ModifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel") 145 ModifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.") 146 147 ChannelRenameCmd.Flags().String("display_name", "", "Channel Display Name") 148 SearchChannelCmd.Flags().String("team", "", "Team name or ID") 149 150 RemoveChannelUsersCmd.Flags().Bool("all-users", false, "Remove all users from the indicated channel.") 151 152 ChannelCmd.AddCommand( 153 ChannelCreateCmd, 154 RemoveChannelUsersCmd, 155 AddChannelUsersCmd, 156 ArchiveChannelsCmd, 157 DeleteChannelsCmd, 158 ListChannelsCmd, 159 MoveChannelsCmd, 160 RestoreChannelsCmd, 161 ModifyChannelCmd, 162 ChannelRenameCmd, 163 SearchChannelCmd, 164 ) 165 166 RootCmd.AddCommand(ChannelCmd) 167 } 168 169 func createChannelCmdF(command *cobra.Command, args []string) error { 170 a, err := InitDBCommandContextCobra(command) 171 if err != nil { 172 return err 173 } 174 defer a.Shutdown() 175 176 name, errn := command.Flags().GetString("name") 177 if errn != nil || name == "" { 178 return errors.New("Name is required") 179 } 180 displayname, errdn := command.Flags().GetString("display_name") 181 if errdn != nil || displayname == "" { 182 return errors.New("Display Name is required") 183 } 184 teamArg, errteam := command.Flags().GetString("team") 185 if errteam != nil || teamArg == "" { 186 return errors.New("Team is required") 187 } 188 header, _ := command.Flags().GetString("header") 189 purpose, _ := command.Flags().GetString("purpose") 190 useprivate, _ := command.Flags().GetBool("private") 191 192 channelType := model.CHANNEL_OPEN 193 if useprivate { 194 channelType = model.CHANNEL_PRIVATE 195 } 196 197 team := getTeamFromTeamArg(a, teamArg) 198 if team == nil { 199 return errors.New("Unable to find team: " + teamArg) 200 } 201 202 channel := &model.Channel{ 203 TeamId: team.Id, 204 Name: name, 205 DisplayName: displayname, 206 Header: header, 207 Purpose: purpose, 208 Type: channelType, 209 CreatorId: "", 210 } 211 212 createdChannel, errCreatedChannel := a.CreateChannel(channel, false) 213 if errCreatedChannel != nil { 214 return errCreatedChannel 215 } 216 217 CommandPrettyPrintln("Id: " + createdChannel.Id) 218 CommandPrettyPrintln("Name: " + createdChannel.Name) 219 CommandPrettyPrintln("Display Name: " + createdChannel.DisplayName) 220 return nil 221 } 222 223 func removeChannelUsersCmdF(command *cobra.Command, args []string) error { 224 a, err := InitDBCommandContextCobra(command) 225 if err != nil { 226 return err 227 } 228 defer a.Shutdown() 229 230 allUsers, _ := command.Flags().GetBool("all-users") 231 232 if allUsers && len(args) != 1 { 233 return errors.New("individual users must not be specified in conjunction with the --all-users flag") 234 } 235 236 if !allUsers && len(args) < 2 { 237 return errors.New("you must specify some users to remove from the channel, or use the --all-users flag to remove them all") 238 } 239 240 channel := getChannelFromChannelArg(a, args[0]) 241 if channel == nil { 242 return errors.New("Unable to find channel '" + args[0] + "'") 243 } 244 245 if allUsers { 246 removeAllUsersFromChannel(a, channel) 247 } else { 248 users := getUsersFromUserArgs(a, args[1:]) 249 for i, user := range users { 250 removeUserFromChannel(a, channel, user, args[i+1]) 251 } 252 } 253 254 return nil 255 } 256 257 func removeUserFromChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) { 258 if user == nil { 259 CommandPrintErrorln("Can't find user '" + userArg + "'") 260 return 261 } 262 if err := a.RemoveUserFromChannel(user.Id, "", channel); err != nil { 263 CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) 264 } 265 } 266 267 func removeAllUsersFromChannel(a *app.App, channel *model.Channel) { 268 if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByChannel(channel.Id); result.Err != nil { 269 CommandPrintErrorln("Unable to remove all users from " + channel.Name + ". Error: " + result.Err.Error()) 270 } 271 } 272 273 func addChannelUsersCmdF(command *cobra.Command, args []string) error { 274 a, err := InitDBCommandContextCobra(command) 275 if err != nil { 276 return err 277 } 278 defer a.Shutdown() 279 280 channel := getChannelFromChannelArg(a, args[0]) 281 if channel == nil { 282 return errors.New("Unable to find channel '" + args[0] + "'") 283 } 284 285 users := getUsersFromUserArgs(a, args[1:]) 286 for i, user := range users { 287 addUserToChannel(a, channel, user, args[i+1]) 288 } 289 290 return nil 291 } 292 293 func addUserToChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) { 294 if user == nil { 295 CommandPrintErrorln("Can't find user '" + userArg + "'") 296 return 297 } 298 if _, err := a.AddUserToChannel(user, channel); err != nil { 299 CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) 300 } 301 } 302 303 func archiveChannelsCmdF(command *cobra.Command, args []string) error { 304 a, err := InitDBCommandContextCobra(command) 305 if err != nil { 306 return err 307 } 308 defer a.Shutdown() 309 310 channels := getChannelsFromChannelArgs(a, args) 311 for i, channel := range channels { 312 if channel == nil { 313 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 314 continue 315 } 316 if result := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil { 317 CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error()) 318 } 319 } 320 321 return nil 322 } 323 324 func deleteChannelsCmdF(command *cobra.Command, args []string) error { 325 a, err := InitDBCommandContextCobra(command) 326 if err != nil { 327 return err 328 } 329 defer a.Shutdown() 330 331 confirmFlag, _ := command.Flags().GetBool("confirm") 332 if !confirmFlag { 333 var confirm string 334 CommandPrettyPrintln("Are you sure you want to delete the channels specified? All data will be permanently deleted? (YES/NO): ") 335 fmt.Scanln(&confirm) 336 if confirm != "YES" { 337 return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") 338 } 339 } 340 341 channels := getChannelsFromChannelArgs(a, args) 342 for i, channel := range channels { 343 if channel == nil { 344 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 345 continue 346 } 347 if err := deleteChannel(a, channel); err != nil { 348 CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error()) 349 } else { 350 CommandPrettyPrintln("Deleted channel '" + channel.Name + "'") 351 } 352 } 353 354 return nil 355 } 356 357 func deleteChannel(a *app.App, channel *model.Channel) *model.AppError { 358 return a.PermanentDeleteChannel(channel) 359 } 360 361 func moveChannelsCmdF(command *cobra.Command, args []string) error { 362 a, err := InitDBCommandContextCobra(command) 363 if err != nil { 364 return err 365 } 366 defer a.Shutdown() 367 368 team := getTeamFromTeamArg(a, args[0]) 369 if team == nil { 370 return errors.New("Unable to find destination team '" + args[0] + "'") 371 } 372 373 username, erru := command.Flags().GetString("username") 374 if erru != nil || username == "" { 375 return errors.New("Username is required.") 376 } 377 user := getUserFromUserArg(a, username) 378 379 removeDeactivatedMembers, _ := command.Flags().GetBool("remove-deactivated-users") 380 381 channels := getChannelsFromChannelArgs(a, args[1:]) 382 for i, channel := range channels { 383 if channel == nil { 384 CommandPrintErrorln("Unable to find channel '" + args[i+1] + "'") 385 continue 386 } 387 originTeamID := channel.TeamId 388 if err := moveChannel(a, team, channel, user, removeDeactivatedMembers); err != nil { 389 CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error()) 390 } else { 391 CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".") 392 } 393 } 394 395 return nil 396 } 397 398 func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *model.User, removeDeactivatedMembers bool) *model.AppError { 399 oldTeamId := channel.TeamId 400 401 if err := a.MoveChannel(team, channel, user, removeDeactivatedMembers); err != nil { 402 return err 403 } 404 405 if incomingWebhooks, err := a.GetIncomingWebhooksForTeamPage(oldTeamId, 0, 10000000); err != nil { 406 return err 407 } else { 408 for _, webhook := range incomingWebhooks { 409 if webhook.ChannelId == channel.Id { 410 webhook.TeamId = team.Id 411 if result := <-a.Srv.Store.Webhook().UpdateIncoming(webhook); result.Err != nil { 412 CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.") 413 } 414 } 415 } 416 } 417 418 if outgoingWebhooks, err := a.GetOutgoingWebhooksForTeamPage(oldTeamId, 0, 10000000); err != nil { 419 return err 420 } else { 421 for _, webhook := range outgoingWebhooks { 422 if webhook.ChannelId == channel.Id { 423 webhook.TeamId = team.Id 424 if result := <-a.Srv.Store.Webhook().UpdateOutgoing(webhook); result.Err != nil { 425 CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.") 426 } 427 } 428 } 429 } 430 431 return nil 432 } 433 434 func listChannelsCmdF(command *cobra.Command, args []string) error { 435 a, err := InitDBCommandContextCobra(command) 436 if err != nil { 437 return err 438 } 439 defer a.Shutdown() 440 441 teams := getTeamsFromTeamArgs(a, args) 442 for i, team := range teams { 443 if team == nil { 444 CommandPrintErrorln("Unable to find team '" + args[i] + "'") 445 continue 446 } 447 if result := <-a.Srv.Store.Channel().GetAll(team.Id); result.Err != nil { 448 CommandPrintErrorln("Unable to list channels for '" + args[i] + "'") 449 } else { 450 channels := result.Data.([]*model.Channel) 451 452 for _, channel := range channels { 453 if channel.DeleteAt > 0 { 454 CommandPrettyPrintln(channel.Name + " (archived)") 455 } else { 456 CommandPrettyPrintln(channel.Name) 457 } 458 } 459 } 460 } 461 462 return nil 463 } 464 465 func restoreChannelsCmdF(command *cobra.Command, args []string) error { 466 a, err := InitDBCommandContextCobra(command) 467 if err != nil { 468 return err 469 } 470 defer a.Shutdown() 471 472 channels := getChannelsFromChannelArgs(a, args) 473 for i, channel := range channels { 474 if channel == nil { 475 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 476 continue 477 } 478 if result := <-a.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil { 479 CommandPrintErrorln("Unable to restore channel '" + args[i] + "'") 480 } 481 } 482 483 return nil 484 } 485 486 func modifyChannelCmdF(command *cobra.Command, args []string) error { 487 a, err := InitDBCommandContextCobra(command) 488 if err != nil { 489 return err 490 } 491 defer a.Shutdown() 492 493 username, erru := command.Flags().GetString("username") 494 if erru != nil || username == "" { 495 return errors.New("Username is required.") 496 } 497 498 public, _ := command.Flags().GetBool("public") 499 private, _ := command.Flags().GetBool("private") 500 501 if public == private { 502 return errors.New("You must specify only one of --public or --private") 503 } 504 505 channel := getChannelFromChannelArg(a, args[0]) 506 if channel == nil { 507 return errors.New("Unable to find channel '" + args[0] + "'") 508 } 509 510 if !(channel.Type == model.CHANNEL_OPEN || channel.Type == model.CHANNEL_PRIVATE) { 511 return errors.New("You can only change the type of public/private channels.") 512 } 513 514 channel.Type = model.CHANNEL_OPEN 515 if private { 516 channel.Type = model.CHANNEL_PRIVATE 517 } 518 519 user := getUserFromUserArg(a, username) 520 if _, err := a.UpdateChannelPrivacy(channel, user); err != nil { 521 return errors.Wrapf(err, "Failed to update channel ('%s') privacy", args[0]) 522 } 523 524 return nil 525 } 526 527 func renameChannelCmdF(command *cobra.Command, args []string) error { 528 a, err := InitDBCommandContextCobra(command) 529 var newDisplayName, newChannelName string 530 if err != nil { 531 return err 532 } 533 defer a.Shutdown() 534 535 channel := getChannelFromChannelArg(a, args[0]) 536 if channel == nil { 537 return errors.New("Unable to find channel '" + args[0] + "'") 538 } 539 540 newChannelName = args[1] 541 newDisplayName, errdn := command.Flags().GetString("display_name") 542 if errdn != nil { 543 return errdn 544 } 545 546 _, errch := a.RenameChannel(channel, newChannelName, newDisplayName) 547 if errch != nil { 548 return errors.Wrapf(errch, "Error in updating channel from %s to %s", channel.Name, newChannelName) 549 } 550 551 return nil 552 } 553 554 func searchChannelCmdF(command *cobra.Command, args []string) error { 555 556 a, err := InitDBCommandContextCobra(command) 557 if err != nil { 558 return errors.Wrap(err, "failed to InitDBCommandContextCobra") 559 } 560 defer a.Shutdown() 561 562 var channel *model.Channel 563 564 if teamArg, _ := command.Flags().GetString("team"); teamArg != "" { 565 team := getTeamFromTeamArg(a, teamArg) 566 if team == nil { 567 CommandPrettyPrintln(fmt.Sprintf("Team %s is not found", teamArg)) 568 return nil 569 } 570 571 var aErr *model.AppError 572 channel, aErr = a.GetChannelByName(args[0], team.Id, true) 573 if aErr != nil || channel == nil { 574 CommandPrettyPrintln(fmt.Sprintf("Channel %s is not found in team %s", args[0], teamArg)) 575 return nil 576 } 577 } else { 578 teams, aErr := a.GetAllTeams() 579 if aErr != nil { 580 return errors.Wrap(err, "failed to GetAllTeams") 581 } 582 583 for _, team := range teams { 584 channel, _ = a.GetChannelByName(args[0], team.Id, true) 585 if channel != nil && channel.Name == args[0] { 586 break 587 } 588 } 589 590 if channel == nil { 591 CommandPrettyPrintln(fmt.Sprintf("Channel %s is not found in any team", args[0])) 592 return nil 593 } 594 } 595 596 if channel.DeleteAt > 0 { 597 CommandPrettyPrintln(fmt.Sprintf(`Channel Name :%s, Display Name :%s, Channel ID :%s (archived)`, channel.Name, channel.DisplayName, channel.Id)) 598 } else { 599 CommandPrettyPrintln(fmt.Sprintf(`Channel Name :%s, Display Name :%s, Channel ID :%s`, channel.Name, channel.DisplayName, channel.Id)) 600 } 601 return nil 602 }