github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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 "errors" 8 "fmt" 9 10 "github.com/mattermost/mattermost-server/app" 11 "github.com/mattermost/mattermost-server/model" 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 RemoveChannelUsersCmd = &cobra.Command{ 30 Use: "remove [channel] [users]", 31 Short: "Remove users from channel", 32 Long: "Remove some users from channel", 33 Example: " channel remove myteam:mychannel user@example.com username", 34 RunE: removeChannelUsersCmdF, 35 } 36 37 var AddChannelUsersCmd = &cobra.Command{ 38 Use: "add [channel] [users]", 39 Short: "Add users to channel", 40 Long: "Add some users to channel", 41 Example: " channel add myteam:mychannel user@example.com username", 42 RunE: addChannelUsersCmdF, 43 } 44 45 var ArchiveChannelsCmd = &cobra.Command{ 46 Use: "archive [channels]", 47 Short: "Archive channels", 48 Long: `Archive some channels. 49 Archive a channel along with all related information including posts from the database. 50 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 51 Example: " channel archive myteam:mychannel", 52 RunE: archiveChannelsCmdF, 53 } 54 55 var DeleteChannelsCmd = &cobra.Command{ 56 Use: "delete [channels]", 57 Short: "Delete channels", 58 Long: `Permanently delete some channels. 59 Permanently deletes a channel along with all related information including posts from the database. 60 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 61 Example: " channel delete myteam:mychannel", 62 RunE: deleteChannelsCmdF, 63 } 64 65 var ListChannelsCmd = &cobra.Command{ 66 Use: "list [teams]", 67 Short: "List all channels on specified teams.", 68 Long: `List all channels on specified teams. 69 Archived channels are appended with ' (archived)'.`, 70 Example: " channel list myteam", 71 RunE: listChannelsCmdF, 72 } 73 74 var MoveChannelsCmd = &cobra.Command{ 75 Use: "move [team] [channels]", 76 Short: "Moves channels to the specified team", 77 Long: `Moves the provided channels to the specified team. 78 Validates that all users in the channel belong to the target team. Incoming/Outgoing webhooks are moved along with the channel. 79 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 80 Example: " channel move newteam oldteam:mychannel", 81 RunE: moveChannelsCmdF, 82 } 83 84 var RestoreChannelsCmd = &cobra.Command{ 85 Use: "restore [channels]", 86 Short: "Restore some channels", 87 Long: `Restore a previously deleted channel 88 Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 89 Example: " channel restore myteam:mychannel", 90 RunE: restoreChannelsCmdF, 91 } 92 93 var ModifyChannelCmd = &cobra.Command{ 94 Use: "modify [channel]", 95 Short: "Modify a channel's public/private type", 96 Long: `Change the public/private type of a channel. 97 Channel can be specified by [team]:[channel]. ie. myteam:mychannel or by channel ID.`, 98 Example: " channel modify myteam:mychannel --private", 99 RunE: modifyChannelCmdF, 100 } 101 102 func init() { 103 ChannelCreateCmd.Flags().String("name", "", "Channel Name") 104 ChannelCreateCmd.Flags().String("display_name", "", "Channel Display Name") 105 ChannelCreateCmd.Flags().String("team", "", "Team name or ID") 106 ChannelCreateCmd.Flags().String("header", "", "Channel header") 107 ChannelCreateCmd.Flags().String("purpose", "", "Channel purpose") 108 ChannelCreateCmd.Flags().Bool("private", false, "Create a private channel.") 109 110 MoveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.") 111 112 DeleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.") 113 114 ModifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel") 115 ModifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel") 116 ModifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.") 117 118 ChannelCmd.AddCommand( 119 ChannelCreateCmd, 120 RemoveChannelUsersCmd, 121 AddChannelUsersCmd, 122 ArchiveChannelsCmd, 123 DeleteChannelsCmd, 124 ListChannelsCmd, 125 MoveChannelsCmd, 126 RestoreChannelsCmd, 127 ModifyChannelCmd, 128 ) 129 130 RootCmd.AddCommand(ChannelCmd) 131 } 132 133 func createChannelCmdF(command *cobra.Command, args []string) error { 134 a, err := InitDBCommandContextCobra(command) 135 if err != nil { 136 return err 137 } 138 defer a.Shutdown() 139 140 name, errn := command.Flags().GetString("name") 141 if errn != nil || name == "" { 142 return errors.New("Name is required") 143 } 144 displayname, errdn := command.Flags().GetString("display_name") 145 if errdn != nil || displayname == "" { 146 return errors.New("Display Name is required") 147 } 148 teamArg, errteam := command.Flags().GetString("team") 149 if errteam != nil || teamArg == "" { 150 return errors.New("Team is required") 151 } 152 header, _ := command.Flags().GetString("header") 153 purpose, _ := command.Flags().GetString("purpose") 154 useprivate, _ := command.Flags().GetBool("private") 155 156 channelType := model.CHANNEL_OPEN 157 if useprivate { 158 channelType = model.CHANNEL_PRIVATE 159 } 160 161 team := getTeamFromTeamArg(a, teamArg) 162 if team == nil { 163 return errors.New("Unable to find team: " + teamArg) 164 } 165 166 channel := &model.Channel{ 167 TeamId: team.Id, 168 Name: name, 169 DisplayName: displayname, 170 Header: header, 171 Purpose: purpose, 172 Type: channelType, 173 CreatorId: "", 174 } 175 176 if _, err := a.CreateChannel(channel, false); err != nil { 177 return err 178 } 179 180 return nil 181 } 182 183 func removeChannelUsersCmdF(command *cobra.Command, args []string) error { 184 a, err := InitDBCommandContextCobra(command) 185 if err != nil { 186 return err 187 } 188 defer a.Shutdown() 189 190 if len(args) < 2 { 191 return errors.New("Not enough arguments.") 192 } 193 194 channel := getChannelFromChannelArg(a, args[0]) 195 if channel == nil { 196 return errors.New("Unable to find channel '" + args[0] + "'") 197 } 198 199 users := getUsersFromUserArgs(a, args[1:]) 200 for i, user := range users { 201 removeUserFromChannel(a, channel, user, args[i+1]) 202 } 203 204 return nil 205 } 206 207 func removeUserFromChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) { 208 if user == nil { 209 CommandPrintErrorln("Can't find user '" + userArg + "'") 210 return 211 } 212 if err := a.RemoveUserFromChannel(user.Id, "", channel); err != nil { 213 CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) 214 } 215 } 216 217 func addChannelUsersCmdF(command *cobra.Command, args []string) error { 218 a, err := InitDBCommandContextCobra(command) 219 if err != nil { 220 return err 221 } 222 defer a.Shutdown() 223 224 if len(args) < 2 { 225 return errors.New("Not enough arguments.") 226 } 227 228 channel := getChannelFromChannelArg(a, args[0]) 229 if channel == nil { 230 return errors.New("Unable to find channel '" + args[0] + "'") 231 } 232 233 users := getUsersFromUserArgs(a, args[1:]) 234 for i, user := range users { 235 addUserToChannel(a, channel, user, args[i+1]) 236 } 237 238 return nil 239 } 240 241 func addUserToChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) { 242 if user == nil { 243 CommandPrintErrorln("Can't find user '" + userArg + "'") 244 return 245 } 246 if _, err := a.AddUserToChannel(user, channel); err != nil { 247 CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) 248 } 249 } 250 251 func archiveChannelsCmdF(command *cobra.Command, args []string) error { 252 a, err := InitDBCommandContextCobra(command) 253 if err != nil { 254 return err 255 } 256 defer a.Shutdown() 257 258 if len(args) < 1 { 259 return errors.New("Enter at least one channel to archive.") 260 } 261 262 channels := getChannelsFromChannelArgs(a, args) 263 for i, channel := range channels { 264 if channel == nil { 265 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 266 continue 267 } 268 if result := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil { 269 CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error()) 270 } 271 } 272 273 return nil 274 } 275 276 func deleteChannelsCmdF(command *cobra.Command, args []string) error { 277 a, err := InitDBCommandContextCobra(command) 278 if err != nil { 279 return err 280 } 281 defer a.Shutdown() 282 283 if len(args) < 1 { 284 return errors.New("Enter at least one channel to delete.") 285 } 286 287 confirmFlag, _ := command.Flags().GetBool("confirm") 288 if !confirmFlag { 289 var confirm string 290 CommandPrettyPrintln("Are you sure you want to delete the channels specified? All data will be permanently deleted? (YES/NO): ") 291 fmt.Scanln(&confirm) 292 if confirm != "YES" { 293 return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") 294 } 295 } 296 297 channels := getChannelsFromChannelArgs(a, args) 298 for i, channel := range channels { 299 if channel == nil { 300 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 301 continue 302 } 303 if err := deleteChannel(a, channel); err != nil { 304 CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error()) 305 } else { 306 CommandPrettyPrintln("Deleted channel '" + channel.Name + "'") 307 } 308 } 309 310 return nil 311 } 312 313 func deleteChannel(a *app.App, channel *model.Channel) *model.AppError { 314 return a.PermanentDeleteChannel(channel) 315 } 316 317 func moveChannelsCmdF(command *cobra.Command, args []string) error { 318 a, err := InitDBCommandContextCobra(command) 319 if err != nil { 320 return err 321 } 322 defer a.Shutdown() 323 324 if len(args) < 2 { 325 return errors.New("Enter the destination team and at least one channel to move.") 326 } 327 328 team := getTeamFromTeamArg(a, args[0]) 329 if team == nil { 330 return errors.New("Unable to find destination team '" + args[0] + "'") 331 } 332 333 username, erru := command.Flags().GetString("username") 334 if erru != nil || username == "" { 335 return errors.New("Username is required") 336 } 337 user := getUserFromUserArg(a, username) 338 339 channels := getChannelsFromChannelArgs(a, args[1:]) 340 for i, channel := range channels { 341 if channel == nil { 342 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 343 continue 344 } 345 originTeamID := channel.TeamId 346 if err := moveChannel(a, team, channel, user); err != nil { 347 CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error()) 348 } else { 349 CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".") 350 } 351 } 352 353 return nil 354 } 355 356 func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *model.User) *model.AppError { 357 oldTeamId := channel.TeamId 358 359 if err := a.MoveChannel(team, channel, user); err != nil { 360 return err 361 } 362 363 if incomingWebhooks, err := a.GetIncomingWebhooksForTeamPage(oldTeamId, 0, 10000000); err != nil { 364 return err 365 } else { 366 for _, webhook := range incomingWebhooks { 367 if webhook.ChannelId == channel.Id { 368 webhook.TeamId = team.Id 369 if result := <-a.Srv.Store.Webhook().UpdateIncoming(webhook); result.Err != nil { 370 CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.") 371 } 372 } 373 } 374 } 375 376 if outgoingWebhooks, err := a.GetOutgoingWebhooksForTeamPage(oldTeamId, 0, 10000000); err != nil { 377 return err 378 } else { 379 for _, webhook := range outgoingWebhooks { 380 if webhook.ChannelId == channel.Id { 381 webhook.TeamId = team.Id 382 if result := <-a.Srv.Store.Webhook().UpdateOutgoing(webhook); result.Err != nil { 383 CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.") 384 } 385 } 386 } 387 } 388 389 return nil 390 } 391 392 func listChannelsCmdF(command *cobra.Command, args []string) error { 393 a, err := InitDBCommandContextCobra(command) 394 if err != nil { 395 return err 396 } 397 defer a.Shutdown() 398 399 if len(args) < 1 { 400 return errors.New("Enter at least one team.") 401 } 402 403 teams := getTeamsFromTeamArgs(a, args) 404 for i, team := range teams { 405 if team == nil { 406 CommandPrintErrorln("Unable to find team '" + args[i] + "'") 407 continue 408 } 409 if result := <-a.Srv.Store.Channel().GetAll(team.Id); result.Err != nil { 410 CommandPrintErrorln("Unable to list channels for '" + args[i] + "'") 411 } else { 412 channels := result.Data.([]*model.Channel) 413 414 for _, channel := range channels { 415 if channel.DeleteAt > 0 { 416 CommandPrettyPrintln(channel.Name + " (archived)") 417 } else { 418 CommandPrettyPrintln(channel.Name) 419 } 420 } 421 } 422 } 423 424 return nil 425 } 426 427 func restoreChannelsCmdF(command *cobra.Command, args []string) error { 428 a, err := InitDBCommandContextCobra(command) 429 if err != nil { 430 return err 431 } 432 defer a.Shutdown() 433 434 if len(args) < 1 { 435 return errors.New("Enter at least one channel.") 436 } 437 438 channels := getChannelsFromChannelArgs(a, args) 439 for i, channel := range channels { 440 if channel == nil { 441 CommandPrintErrorln("Unable to find channel '" + args[i] + "'") 442 continue 443 } 444 if result := <-a.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil { 445 CommandPrintErrorln("Unable to restore channel '" + args[i] + "'") 446 } 447 } 448 449 return nil 450 } 451 452 func modifyChannelCmdF(command *cobra.Command, args []string) error { 453 a, err := InitDBCommandContextCobra(command) 454 if err != nil { 455 return err 456 } 457 defer a.Shutdown() 458 459 if len(args) != 1 { 460 return errors.New("Enter at one channel to modify.") 461 } 462 463 username, erru := command.Flags().GetString("username") 464 if erru != nil || username == "" { 465 return errors.New("Username is required") 466 } 467 468 public, _ := command.Flags().GetBool("public") 469 private, _ := command.Flags().GetBool("private") 470 471 if public == private { 472 return errors.New("You must specify only one of --public or --private") 473 } 474 475 channel := getChannelFromChannelArg(a, args[0]) 476 if channel == nil { 477 return errors.New("Unable to find channel '" + args[0] + "'") 478 } 479 480 if !(channel.Type == model.CHANNEL_OPEN || channel.Type == model.CHANNEL_PRIVATE) { 481 return errors.New("You can only change the type of public/private channels.") 482 } 483 484 channel.Type = model.CHANNEL_OPEN 485 if private { 486 channel.Type = model.CHANNEL_PRIVATE 487 } 488 489 user := getUserFromUserArg(a, username) 490 if _, err := a.UpdateChannelPrivacy(channel, user); err != nil { 491 return errors.New("Failed to update channel ('" + args[0] + "') privacy - " + err.Error()) 492 } 493 494 return nil 495 }