Merge branch 'master' into advanced-permissions-phase-1

Этот коммит содержится в:
George Goldberg
2018-03-13 13:36:23 +00:00
родитель b66e4bc932 f2d26801b9
Коммит fadcdd271a
167 изменённых файлов: 5008 добавлений и 3043 удалений

26
cmd/cmd.go Обычный файл
Просмотреть файл

@@ -0,0 +1,26 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package cmd
import (
"github.com/spf13/cobra"
)
type Command = cobra.Command
func Run(args []string) error {
RootCmd.SetArgs(args)
return RootCmd.Execute()
}
var RootCmd = &cobra.Command{
Use: "platform",
Short: "Open source, self-hosted Slack-alternative",
Long: `Mattermost offers workplace messaging across web, PC and phones with archiving, search and integration with your existing systems. Documentation available at https://docs.mattermost.com`,
}
func init() {
RootCmd.PersistentFlags().StringP("config", "c", "config.json", "Configuration file to use.")
RootCmd.PersistentFlags().Bool("disableconfigwatch", false, "When set config.json will not be loaded from disk when the file is changed.")
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package cmd
import (
"flag"
@@ -30,7 +30,7 @@ func execArgs(t *testing.T, args []string) []string {
return append(append(ret, "--", "--disableconfigwatch"), args...)
}
func checkCommand(t *testing.T, args ...string) string {
func CheckCommand(t *testing.T, args ...string) string {
path, err := os.Executable()
require.NoError(t, err)
output, err := exec.Command(path, execArgs(t, args)...).CombinedOutput()
@@ -38,16 +38,8 @@ func checkCommand(t *testing.T, args ...string) string {
return strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(string(output)), "PASS"))
}
func runCommand(t *testing.T, args ...string) error {
func RunCommand(t *testing.T, args ...string) error {
path, err := os.Executable()
require.NoError(t, err)
return exec.Command(path, execArgs(t, args)...).Run()
}
func TestExecCommand(t *testing.T) {
if filter := flag.Lookup("test.run").Value.String(); filter != "ExecCommand" {
t.Skip("use -run ExecCommand to execute a command via the test executable")
}
rootCmd.SetArgs(flag.Args())
require.NoError(t, rootCmd.Execute())
}

Просмотреть файл

@@ -1,22 +1,24 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
"fmt"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/spf13/cobra"
)
var channelCmd = &cobra.Command{
var ChannelCmd = &cobra.Command{
Use: "channel",
Short: "Management of channels",
}
var channelCreateCmd = &cobra.Command{
var ChannelCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a channel",
Long: `Create a channel.`,
@@ -25,7 +27,7 @@ var channelCreateCmd = &cobra.Command{
RunE: createChannelCmdF,
}
var removeChannelUsersCmd = &cobra.Command{
var RemoveChannelUsersCmd = &cobra.Command{
Use: "remove [channel] [users]",
Short: "Remove users from channel",
Long: "Remove some users from channel",
@@ -33,7 +35,7 @@ var removeChannelUsersCmd = &cobra.Command{
RunE: removeChannelUsersCmdF,
}
var addChannelUsersCmd = &cobra.Command{
var AddChannelUsersCmd = &cobra.Command{
Use: "add [channel] [users]",
Short: "Add users to channel",
Long: "Add some users to channel",
@@ -41,7 +43,7 @@ var addChannelUsersCmd = &cobra.Command{
RunE: addChannelUsersCmdF,
}
var archiveChannelsCmd = &cobra.Command{
var ArchiveChannelsCmd = &cobra.Command{
Use: "archive [channels]",
Short: "Archive channels",
Long: `Archive some channels.
@@ -51,7 +53,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe
RunE: archiveChannelsCmdF,
}
var deleteChannelsCmd = &cobra.Command{
var DeleteChannelsCmd = &cobra.Command{
Use: "delete [channels]",
Short: "Delete channels",
Long: `Permanently delete some channels.
@@ -61,7 +63,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe
RunE: deleteChannelsCmdF,
}
var listChannelsCmd = &cobra.Command{
var ListChannelsCmd = &cobra.Command{
Use: "list [teams]",
Short: "List all channels on specified teams.",
Long: `List all channels on specified teams.
@@ -70,7 +72,7 @@ Archived channels are appended with ' (archived)'.`,
RunE: listChannelsCmdF,
}
var moveChannelsCmd = &cobra.Command{
var MoveChannelsCmd = &cobra.Command{
Use: "move [team] [channels]",
Short: "Moves channels to the specified team",
Long: `Moves the provided channels to the specified team.
@@ -80,7 +82,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe
RunE: moveChannelsCmdF,
}
var restoreChannelsCmd = &cobra.Command{
var RestoreChannelsCmd = &cobra.Command{
Use: "restore [channels]",
Short: "Restore some channels",
Long: `Restore a previously deleted channel
@@ -89,7 +91,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe
RunE: restoreChannelsCmdF,
}
var modifyChannelCmd = &cobra.Command{
var ModifyChannelCmd = &cobra.Command{
Use: "modify [channel]",
Short: "Modify a channel's public/private type",
Long: `Change the public/private type of a channel.
@@ -99,55 +101,57 @@ Channel can be specified by [team]:[channel]. ie. myteam:mychannel or by channel
}
func init() {
channelCreateCmd.Flags().String("name", "", "Channel Name")
channelCreateCmd.Flags().String("display_name", "", "Channel Display Name")
channelCreateCmd.Flags().String("team", "", "Team name or ID")
channelCreateCmd.Flags().String("header", "", "Channel header")
channelCreateCmd.Flags().String("purpose", "", "Channel purpose")
channelCreateCmd.Flags().Bool("private", false, "Create a private channel.")
ChannelCreateCmd.Flags().String("name", "", "Channel Name")
ChannelCreateCmd.Flags().String("display_name", "", "Channel Display Name")
ChannelCreateCmd.Flags().String("team", "", "Team name or ID")
ChannelCreateCmd.Flags().String("header", "", "Channel header")
ChannelCreateCmd.Flags().String("purpose", "", "Channel purpose")
ChannelCreateCmd.Flags().Bool("private", false, "Create a private channel.")
moveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.")
MoveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.")
deleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.")
DeleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.")
modifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel")
modifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel")
modifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.")
ModifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel")
ModifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel")
ModifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.")
channelCmd.AddCommand(
channelCreateCmd,
removeChannelUsersCmd,
addChannelUsersCmd,
archiveChannelsCmd,
deleteChannelsCmd,
listChannelsCmd,
moveChannelsCmd,
restoreChannelsCmd,
modifyChannelCmd,
ChannelCmd.AddCommand(
ChannelCreateCmd,
RemoveChannelUsersCmd,
AddChannelUsersCmd,
ArchiveChannelsCmd,
DeleteChannelsCmd,
ListChannelsCmd,
MoveChannelsCmd,
RestoreChannelsCmd,
ModifyChannelCmd,
)
cmd.RootCmd.AddCommand(ChannelCmd)
}
func createChannelCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func createChannelCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
name, errn := cmd.Flags().GetString("name")
name, errn := command.Flags().GetString("name")
if errn != nil || name == "" {
return errors.New("Name is required")
}
displayname, errdn := cmd.Flags().GetString("display_name")
displayname, errdn := command.Flags().GetString("display_name")
if errdn != nil || displayname == "" {
return errors.New("Display Name is required")
}
teamArg, errteam := cmd.Flags().GetString("team")
teamArg, errteam := command.Flags().GetString("team")
if errteam != nil || teamArg == "" {
return errors.New("Team is required")
}
header, _ := cmd.Flags().GetString("header")
purpose, _ := cmd.Flags().GetString("purpose")
useprivate, _ := cmd.Flags().GetBool("private")
header, _ := command.Flags().GetString("header")
purpose, _ := command.Flags().GetString("purpose")
useprivate, _ := command.Flags().GetBool("private")
channelType := model.CHANNEL_OPEN
if useprivate {
@@ -176,8 +180,8 @@ func createChannelCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func removeChannelUsersCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func removeChannelUsersCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -201,16 +205,16 @@ func removeChannelUsersCmdF(cmd *cobra.Command, args []string) error {
func removeUserFromChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) {
if user == nil {
CommandPrintErrorln("Can't find user '" + userArg + "'")
cmd.CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
if err := a.RemoveUserFromChannel(user.Id, "", channel); err != nil {
CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
cmd.CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
}
}
func addChannelUsersCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func addChannelUsersCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -234,16 +238,16 @@ func addChannelUsersCmdF(cmd *cobra.Command, args []string) error {
func addUserToChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) {
if user == nil {
CommandPrintErrorln("Can't find user '" + userArg + "'")
cmd.CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
if _, err := a.AddUserToChannel(user, channel); err != nil {
CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
cmd.CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
}
}
func archiveChannelsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func archiveChannelsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -255,19 +259,19 @@ func archiveChannelsCmdF(cmd *cobra.Command, args []string) error {
channels := getChannelsFromChannelArgs(a, args)
for i, channel := range channels {
if channel == nil {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue
}
if result := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil {
CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error())
cmd.CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error())
}
}
return nil
}
func deleteChannelsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func deleteChannelsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -276,10 +280,10 @@ func deleteChannelsCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Enter at least one channel to delete.")
}
confirmFlag, _ := cmd.Flags().GetBool("confirm")
confirmFlag, _ := command.Flags().GetBool("confirm")
if !confirmFlag {
var confirm string
CommandPrettyPrintln("Are you sure you want to delete the channels specified? All data will be permanently deleted? (YES/NO): ")
cmd.CommandPrettyPrintln("Are you sure you want to delete the channels specified? All data will be permanently deleted? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
@@ -289,13 +293,13 @@ func deleteChannelsCmdF(cmd *cobra.Command, args []string) error {
channels := getChannelsFromChannelArgs(a, args)
for i, channel := range channels {
if channel == nil {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue
}
if err := deleteChannel(a, channel); err != nil {
CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error())
cmd.CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error())
} else {
CommandPrettyPrintln("Deleted channel '" + channel.Name + "'")
cmd.CommandPrettyPrintln("Deleted channel '" + channel.Name + "'")
}
}
@@ -306,8 +310,8 @@ func deleteChannel(a *app.App, channel *model.Channel) *model.AppError {
return a.PermanentDeleteChannel(channel)
}
func moveChannelsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func moveChannelsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -321,7 +325,7 @@ func moveChannelsCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Unable to find destination team '" + args[0] + "'")
}
username, erru := cmd.Flags().GetString("username")
username, erru := command.Flags().GetString("username")
if erru != nil || username == "" {
return errors.New("Username is required")
}
@@ -330,14 +334,14 @@ func moveChannelsCmdF(cmd *cobra.Command, args []string) error {
channels := getChannelsFromChannelArgs(a, args[1:])
for i, channel := range channels {
if channel == nil {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue
}
originTeamID := channel.TeamId
if err := moveChannel(a, team, channel, user); err != nil {
CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error())
cmd.CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error())
} else {
CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".")
cmd.CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".")
}
}
@@ -358,7 +362,7 @@ func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *mod
if webhook.ChannelId == channel.Id {
webhook.TeamId = team.Id
if result := <-a.Srv.Store.Webhook().UpdateIncoming(webhook); result.Err != nil {
CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.")
cmd.CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.")
}
}
}
@@ -371,7 +375,7 @@ func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *mod
if webhook.ChannelId == channel.Id {
webhook.TeamId = team.Id
if result := <-a.Srv.Store.Webhook().UpdateOutgoing(webhook); result.Err != nil {
CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.")
cmd.CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.")
}
}
}
@@ -380,8 +384,8 @@ func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *mod
return nil
}
func listChannelsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func listChannelsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -393,19 +397,19 @@ func listChannelsCmdF(cmd *cobra.Command, args []string) error {
teams := getTeamsFromTeamArgs(a, args)
for i, team := range teams {
if team == nil {
CommandPrintErrorln("Unable to find team '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find team '" + args[i] + "'")
continue
}
if result := <-a.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
CommandPrintErrorln("Unable to list channels for '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to list channels for '" + args[i] + "'")
} else {
channels := result.Data.([]*model.Channel)
for _, channel := range channels {
if channel.DeleteAt > 0 {
CommandPrettyPrintln(channel.Name + " (archived)")
cmd.CommandPrettyPrintln(channel.Name + " (archived)")
} else {
CommandPrettyPrintln(channel.Name)
cmd.CommandPrettyPrintln(channel.Name)
}
}
}
@@ -414,8 +418,8 @@ func listChannelsCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func restoreChannelsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func restoreChannelsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -427,19 +431,19 @@ func restoreChannelsCmdF(cmd *cobra.Command, args []string) error {
channels := getChannelsFromChannelArgs(a, args)
for i, channel := range channels {
if channel == nil {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue
}
if result := <-a.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil {
CommandPrintErrorln("Unable to restore channel '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to restore channel '" + args[i] + "'")
}
}
return nil
}
func modifyChannelCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func modifyChannelCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -448,13 +452,13 @@ func modifyChannelCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Enter at one channel to modify.")
}
username, erru := cmd.Flags().GetString("username")
username, erru := command.Flags().GetString("username")
if erru != nil || username == "" {
return errors.New("Username is required")
}
public, _ := cmd.Flags().GetBool("public")
private, _ := cmd.Flags().GetBool("private")
public, _ := command.Flags().GetBool("public")
private, _ := command.Flags().GetBool("private")
if public == private {
return errors.New("You must specify only one of --public or --private")

Просмотреть файл

@@ -1,13 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"strings"
"testing"
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/stretchr/testify/require"
)
@@ -18,13 +19,13 @@ func TestJoinChannel(t *testing.T) {
channel := th.CreateChannel(th.BasicClient, th.BasicTeam)
checkCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
cmd.CheckCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
// Joining twice should succeed
checkCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
cmd.CheckCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
// should fail because channel does not exist
require.Error(t, runCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name+"asdf", th.BasicUser2.Email))
require.Error(t, cmd.RunCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name+"asdf", th.BasicUser2.Email))
}
func TestRemoveChannel(t *testing.T) {
@@ -33,15 +34,15 @@ func TestRemoveChannel(t *testing.T) {
channel := th.CreateChannel(th.BasicClient, th.BasicTeam)
checkCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
cmd.CheckCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
// should fail because channel does not exist
require.Error(t, runCommand(t, "channel", "remove", th.BasicTeam.Name+":doesnotexist", th.BasicUser2.Email))
require.Error(t, cmd.RunCommand(t, "channel", "remove", th.BasicTeam.Name+":doesnotexist", th.BasicUser2.Email))
checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
cmd.CheckCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
// Leaving twice should succeed
checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
cmd.CheckCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
}
func TestMoveChannel(t *testing.T) {
@@ -63,12 +64,12 @@ func TestMoveChannel(t *testing.T) {
origin := team1.Name + ":" + channel.Name
dest := team2.Name
checkCommand(t, "channel", "add", origin, adminEmail)
cmd.CheckCommand(t, "channel", "add", origin, adminEmail)
// should fail with nill because errors are logged instead of returned when a channel does not exist
require.Nil(t, runCommand(t, "channel", "move", dest, team1.Name+":doesnotexist", "--username", adminUsername))
require.Nil(t, cmd.RunCommand(t, "channel", "move", dest, team1.Name+":doesnotexist", "--username", adminUsername))
checkCommand(t, "channel", "move", dest, origin, "--username", adminUsername)
cmd.CheckCommand(t, "channel", "move", dest, origin, "--username", adminUsername)
}
func TestListChannels(t *testing.T) {
@@ -78,7 +79,7 @@ func TestListChannels(t *testing.T) {
channel := th.CreateChannel(th.BasicClient, th.BasicTeam)
th.BasicClient.Must(th.BasicClient.DeleteChannel(channel.Id))
output := checkCommand(t, "channel", "list", th.BasicTeam.Name)
output := cmd.CheckCommand(t, "channel", "list", th.BasicTeam.Name)
if !strings.Contains(string(output), "town-square") {
t.Fatal("should have channels")
@@ -96,10 +97,10 @@ func TestRestoreChannel(t *testing.T) {
channel := th.CreateChannel(th.BasicClient, th.BasicTeam)
th.BasicClient.Must(th.BasicClient.DeleteChannel(channel.Id))
checkCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name)
cmd.CheckCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name)
// restoring twice should succeed
checkCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name)
cmd.CheckCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name)
}
func TestCreateChannel(t *testing.T) {
@@ -109,8 +110,8 @@ func TestCreateChannel(t *testing.T) {
id := model.NewId()
name := "name" + id
checkCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--name", name)
cmd.CheckCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--name", name)
name = name + "-private"
checkCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--private", "--name", name)
cmd.CheckCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--private", "--name", name)
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"fmt"

Просмотреть файл

@@ -1,20 +1,22 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/spf13/cobra"
)
var commandCmd = &cobra.Command{
var CommandCmd = &cobra.Command{
Use: "command",
Short: "Management of slash commands",
}
var commandMoveCmd = &cobra.Command{
var CommandMoveCmd = &cobra.Command{
Use: "move",
Short: "Move a slash command to a different team",
Long: `Move a slash command to a different team. Commands can be specified by [team]:[command-trigger-word]. ie. myteam:trigger or by command ID.`,
@@ -23,13 +25,14 @@ var commandMoveCmd = &cobra.Command{
}
func init() {
commandCmd.AddCommand(
commandMoveCmd,
CommandCmd.AddCommand(
CommandMoveCmd,
)
cmd.RootCmd.AddCommand(CommandCmd)
}
func moveCommandCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func moveCommandCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -44,16 +47,16 @@ func moveCommandCmdF(cmd *cobra.Command, args []string) error {
}
commands := getCommandsFromCommandArgs(a, args[1:])
CommandPrintErrorln(commands)
cmd.CommandPrintErrorln(commands)
for i, command := range commands {
if command == nil {
CommandPrintErrorln("Unable to find command '" + args[i+1] + "'")
cmd.CommandPrintErrorln("Unable to find command '" + args[i+1] + "'")
continue
}
if err := moveCommand(a, team, command); err != nil {
CommandPrintErrorln("Unable to move command '" + command.Trigger + "' error: " + err.Error())
cmd.CommandPrintErrorln("Unable to move command '" + command.Trigger + "' error: " + err.Error())
} else {
CommandPrettyPrintln("Moved command '" + command.Trigger + "'")
cmd.CommandPrettyPrintln("Moved command '" + command.Trigger + "'")
}
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"fmt"

Просмотреть файл

@@ -1,23 +1,25 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"encoding/json"
"errors"
"os"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/spf13/cobra"
)
var configCmd = &cobra.Command{
var ConfigCmd = &cobra.Command{
Use: "config",
Short: "Configuration",
}
var validateConfigCmd = &cobra.Command{
var ValidateConfigCmd = &cobra.Command{
Use: "validate",
Short: "Validate config file",
Long: "If the config file is valid, this command will output a success message and have a zero exit code. If it is invalid, this command will output an error and have a non-zero exit code.",
@@ -25,15 +27,16 @@ var validateConfigCmd = &cobra.Command{
}
func init() {
configCmd.AddCommand(
validateConfigCmd,
ConfigCmd.AddCommand(
ValidateConfigCmd,
)
cmd.RootCmd.AddCommand(ConfigCmd)
}
func configValidateCmdF(cmd *cobra.Command, args []string) error {
func configValidateCmdF(command *cobra.Command, args []string) error {
utils.TranslationsPreInit()
model.AppErrorInit(utils.T)
filePath, err := cmd.Flags().GetString("config")
filePath, err := command.Flags().GetString("config")
if err != nil {
return err
}
@@ -60,6 +63,6 @@ func configValidateCmdF(cmd *cobra.Command, args []string) error {
return errors.New(utils.T(err.Id))
}
CommandPrettyPrintln("The document is valid")
cmd.CommandPrettyPrintln("The document is valid")
return nil
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"io/ioutil"
@@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/utils"
)
@@ -34,8 +35,8 @@ func TestConfigFlag(t *testing.T) {
defer os.Chdir(prevDir)
os.Chdir(dir)
require.Error(t, runCommand(t, "version"))
checkCommand(t, "--config", "foo.json", "version")
checkCommand(t, "--config", "./foo.json", "version")
checkCommand(t, "--config", configPath, "version")
require.Error(t, cmd.RunCommand(t, "version"))
cmd.CheckCommand(t, "--config", "foo.json", "version")
cmd.CheckCommand(t, "--config", "./foo.json", "version")
cmd.CheckCommand(t, "--config", configPath, "version")
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"io/ioutil"
@@ -9,6 +9,7 @@ import (
"path/filepath"
"testing"
"github.com/mattermost/mattermost-server/cmd"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,6 +26,6 @@ func TestConfigValidate(t *testing.T) {
config.SetDefaults()
require.NoError(t, ioutil.WriteFile(path, []byte(config.ToJson()), 0600))
assert.Error(t, runCommand(t, "--config", "foo.json", "config", "validate"))
assert.NoError(t, runCommand(t, "--config", path, "config", "validate"))
assert.Error(t, cmd.RunCommand(t, "--config", "foo.json", "config", "validate"))
assert.NoError(t, cmd.RunCommand(t, "--config", path, "config", "validate"))
}

21
cmd/commands/exec_command_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,21 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package commands
import (
"flag"
"testing"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/cmd"
)
func TestExecCommand(t *testing.T) {
if filter := flag.Lookup("test.run").Value.String(); filter != "ExecCommand" {
t.Skip("use -run ExecCommand to execute a command via the test executable")
}
cmd.RootCmd.SetArgs(flag.Args())
require.NoError(t, cmd.RootCmd.Execute())
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
@@ -8,15 +9,16 @@ import (
"fmt"
"github.com/mattermost/mattermost-server/cmd"
"github.com/spf13/cobra"
)
var importCmd = &cobra.Command{
var ImportCmd = &cobra.Command{
Use: "import",
Short: "Import data.",
}
var slackImportCmd = &cobra.Command{
var SlackImportCmd = &cobra.Command{
Use: "slack [team] [file]",
Short: "Import a team from Slack.",
Long: "Import a team from a Slack export zip file.",
@@ -24,7 +26,7 @@ var slackImportCmd = &cobra.Command{
RunE: slackImportCmdF,
}
var bulkImportCmd = &cobra.Command{
var BulkImportCmd = &cobra.Command{
Use: "bulk [file]",
Short: "Import bulk data.",
Long: "Import data from a Mattermost Bulk Import File.",
@@ -33,18 +35,19 @@ var bulkImportCmd = &cobra.Command{
}
func init() {
bulkImportCmd.Flags().Bool("apply", false, "Save the import data to the database. Use with caution - this cannot be reverted.")
bulkImportCmd.Flags().Bool("validate", false, "Validate the import data without making any changes to the system.")
bulkImportCmd.Flags().Int("workers", 2, "How many workers to run whilst doing the import.")
BulkImportCmd.Flags().Bool("apply", false, "Save the import data to the database. Use with caution - this cannot be reverted.")
BulkImportCmd.Flags().Bool("validate", false, "Validate the import data without making any changes to the system.")
BulkImportCmd.Flags().Int("workers", 2, "How many workers to run whilst doing the import.")
importCmd.AddCommand(
bulkImportCmd,
slackImportCmd,
ImportCmd.AddCommand(
BulkImportCmd,
SlackImportCmd,
)
cmd.RootCmd.AddCommand(ImportCmd)
}
func slackImportCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func slackImportCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -69,32 +72,32 @@ func slackImportCmdF(cmd *cobra.Command, args []string) error {
return err
}
CommandPrettyPrintln("Running Slack Import. This may take a long time for large teams or teams with many messages.")
cmd.CommandPrettyPrintln("Running Slack Import. This may take a long time for large teams or teams with many messages.")
a.SlackImport(fileReader, fileInfo.Size(), team.Id)
CommandPrettyPrintln("Finished Slack Import.")
cmd.CommandPrettyPrintln("Finished Slack Import.")
return nil
}
func bulkImportCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func bulkImportCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
apply, err := cmd.Flags().GetBool("apply")
apply, err := command.Flags().GetBool("apply")
if err != nil {
return errors.New("Apply flag error")
}
validate, err := cmd.Flags().GetBool("validate")
validate, err := command.Flags().GetBool("validate")
if err != nil {
return errors.New("Validate flag error")
}
workers, err := cmd.Flags().GetInt("workers")
workers, err := command.Flags().GetInt("workers")
if err != nil {
return errors.New("Workers flag error")
}
@@ -110,28 +113,28 @@ func bulkImportCmdF(cmd *cobra.Command, args []string) error {
defer fileReader.Close()
if apply && validate {
CommandPrettyPrintln("Use only one of --apply or --validate.")
cmd.CommandPrettyPrintln("Use only one of --apply or --validate.")
return nil
} else if apply && !validate {
CommandPrettyPrintln("Running Bulk Import. This may take a long time.")
cmd.CommandPrettyPrintln("Running Bulk Import. This may take a long time.")
} else {
CommandPrettyPrintln("Running Bulk Import Data Validation.")
CommandPrettyPrintln("** This checks the validity of the entities in the data file, but does not persist any changes **")
CommandPrettyPrintln("Use the --apply flag to perform the actual data import.")
cmd.CommandPrettyPrintln("Running Bulk Import Data Validation.")
cmd.CommandPrettyPrintln("** This checks the validity of the entities in the data file, but does not persist any changes **")
cmd.CommandPrettyPrintln("Use the --apply flag to perform the actual data import.")
}
CommandPrettyPrintln("")
cmd.CommandPrettyPrintln("")
if err, lineNumber := a.BulkImport(fileReader, !apply, workers); err != nil {
CommandPrettyPrintln(err.Error())
cmd.CommandPrettyPrintln(err.Error())
if lineNumber != 0 {
CommandPrettyPrintln(fmt.Sprintf("Error occurred on data file line %v", lineNumber))
cmd.CommandPrettyPrintln(fmt.Sprintf("Error occurred on data file line %v", lineNumber))
}
} else {
if apply {
CommandPrettyPrintln("Finished Bulk Import.")
cmd.CommandPrettyPrintln("Finished Bulk Import.")
} else {
CommandPrettyPrintln("Validation complete. You can now perform the import by rerunning this command with the --apply flag.")
cmd.CommandPrettyPrintln("Validation complete. You can now perform the import by rerunning this command with the --apply flag.")
}
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"os"
@@ -8,27 +9,30 @@ import (
"syscall"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/cmd"
"github.com/spf13/cobra"
)
var jobserverCmd = &cobra.Command{
var JobserverCmd = &cobra.Command{
Use: "jobserver",
Short: "Start the Mattermost job server",
Run: jobserverCmdF,
}
func init() {
jobserverCmd.Flags().Bool("nojobs", false, "Do not run jobs on this jobserver.")
jobserverCmd.Flags().Bool("noschedule", false, "Do not schedule jobs from this jobserver.")
JobserverCmd.Flags().Bool("nojobs", false, "Do not run jobs on this jobserver.")
JobserverCmd.Flags().Bool("noschedule", false, "Do not schedule jobs from this jobserver.")
cmd.RootCmd.AddCommand(JobserverCmd)
}
func jobserverCmdF(cmd *cobra.Command, args []string) {
func jobserverCmdF(command *cobra.Command, args []string) {
// Options
noJobs, _ := cmd.Flags().GetBool("nojobs")
noSchedule, _ := cmd.Flags().GetBool("noschedule")
noJobs, _ := command.Flags().GetBool("nojobs")
noSchedule, _ := command.Flags().GetBool("noschedule")
// Initialize
a, err := initDBCommandContext("config.json")
a, err := cmd.InitDBCommandContext("config.json")
if err != nil {
panic(err.Error())
}

Просмотреть файл

@@ -1,18 +1,20 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/spf13/cobra"
)
var ldapCmd = &cobra.Command{
var LdapCmd = &cobra.Command{
Use: "ldap",
Short: "LDAP related utilities",
}
var ldapSyncCmd = &cobra.Command{
var LdapSyncCmd = &cobra.Command{
Use: "sync",
Short: "Synchronize now",
Long: "Synchronize all LDAP users now.",
@@ -21,13 +23,14 @@ var ldapSyncCmd = &cobra.Command{
}
func init() {
ldapCmd.AddCommand(
ldapSyncCmd,
LdapCmd.AddCommand(
LdapSyncCmd,
)
cmd.RootCmd.AddCommand(LdapCmd)
}
func ldapSyncCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func ldapSyncCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -35,9 +38,9 @@ func ldapSyncCmdF(cmd *cobra.Command, args []string) error {
if ldapI := a.Ldap; ldapI != nil {
job, err := ldapI.StartSynchronizeJob(true)
if err != nil || job.Status == model.JOB_STATUS_ERROR || job.Status == model.JOB_STATUS_CANCELED {
CommandPrintErrorln("ERROR: AD/LDAP Synchronization please check the server logs")
cmd.CommandPrintErrorln("ERROR: AD/LDAP Synchronization please check the server logs")
} else {
CommandPrettyPrintln("SUCCESS: AD/LDAP Synchronization Complete")
cmd.CommandPrettyPrintln("SUCCESS: AD/LDAP Synchronization Complete")
}
}

Просмотреть файл

@@ -1,20 +1,22 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
"io/ioutil"
"github.com/mattermost/mattermost-server/cmd"
"github.com/spf13/cobra"
)
var licenseCmd = &cobra.Command{
var LicenseCmd = &cobra.Command{
Use: "license",
Short: "Licensing commands",
}
var uploadLicenseCmd = &cobra.Command{
var UploadLicenseCmd = &cobra.Command{
Use: "upload [license]",
Short: "Upload a license.",
Long: "Upload a license. Replaces current license.",
@@ -23,11 +25,12 @@ var uploadLicenseCmd = &cobra.Command{
}
func init() {
licenseCmd.AddCommand(uploadLicenseCmd)
LicenseCmd.AddCommand(UploadLicenseCmd)
cmd.RootCmd.AddCommand(LicenseCmd)
}
func uploadLicenseCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func uploadLicenseCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -45,7 +48,7 @@ func uploadLicenseCmdF(cmd *cobra.Command, args []string) error {
return err
}
CommandPrettyPrintln("Uploaded license file")
cmd.CommandPrettyPrintln("Uploaded license file")
return nil
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
@@ -10,11 +10,12 @@ import (
"time"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/spf13/cobra"
)
var messageExportCmd = &cobra.Command{
var MessageExportCmd = &cobra.Command{
Use: "export",
Short: "Export data from Mattermost",
Long: "Export data from Mattermost in a format suitable for import into a third-party application",
@@ -23,13 +24,14 @@ var messageExportCmd = &cobra.Command{
}
func init() {
messageExportCmd.Flags().String("format", "actiance", "The format to export data in")
messageExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.")
messageExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.")
MessageExportCmd.Flags().String("format", "actiance", "The format to export data in")
MessageExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.")
MessageExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.")
cmd.RootCmd.AddCommand(MessageExportCmd)
}
func messageExportCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func messageExportCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -39,20 +41,20 @@ func messageExportCmdF(cmd *cobra.Command, args []string) error {
}
// for now, format is hard-coded to actiance. In time, we'll have to support other formats and inject them into job data
if format, err := cmd.Flags().GetString("format"); err != nil {
if format, err := command.Flags().GetString("format"); err != nil {
return errors.New("format flag error")
} else if format != "actiance" {
return errors.New("unsupported export format")
}
startTime, err := cmd.Flags().GetInt64("exportFrom")
startTime, err := command.Flags().GetInt64("exportFrom")
if err != nil {
return errors.New("exportFrom flag error")
} else if startTime < 0 {
return errors.New("exportFrom must be a positive integer")
}
timeoutSeconds, err := cmd.Flags().GetInt("timeoutSeconds")
timeoutSeconds, err := command.Flags().GetInt("timeoutSeconds")
if err != nil {
return errors.New("timeoutSeconds error")
} else if timeoutSeconds < 0 {
@@ -69,9 +71,9 @@ func messageExportCmdF(cmd *cobra.Command, args []string) error {
job, err := messageExportI.StartSynchronizeJob(ctx, startTime)
if err != nil || job.Status == model.JOB_STATUS_ERROR || job.Status == model.JOB_STATUS_CANCELED {
CommandPrintErrorln("ERROR: Message export job failed. Please check the server logs")
cmd.CommandPrintErrorln("ERROR: Message export job failed. Please check the server logs")
} else {
CommandPrettyPrintln("SUCCESS: Message export job complete")
cmd.CommandPrettyPrintln("SUCCESS: Message export job complete")
}
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"io/ioutil"
@@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
)
@@ -24,7 +25,7 @@ func TestMessageExportNotEnabled(t *testing.T) {
defer os.RemoveAll(filepath.Dir(configPath))
// should fail fast because the feature isn't enabled
require.Error(t, runCommand(t, "--config", configPath, "export"))
require.Error(t, cmd.RunCommand(t, "--config", configPath, "export"))
}
func TestMessageExportInvalidFormat(t *testing.T) {
@@ -32,7 +33,7 @@ func TestMessageExportInvalidFormat(t *testing.T) {
defer os.RemoveAll(filepath.Dir(configPath))
// should fail fast because format isn't supported
require.Error(t, runCommand(t, "--config", configPath, "--format", "not_actiance", "export"))
require.Error(t, cmd.RunCommand(t, "--config", configPath, "--format", "not_actiance", "export"))
}
func TestMessageExportNegativeExportFrom(t *testing.T) {
@@ -40,7 +41,7 @@ func TestMessageExportNegativeExportFrom(t *testing.T) {
defer os.RemoveAll(filepath.Dir(configPath))
// should fail fast because export from must be a valid timestamp
require.Error(t, runCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "-1", "export"))
require.Error(t, cmd.RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "-1", "export"))
}
func TestMessageExportNegativeTimeoutSeconds(t *testing.T) {
@@ -48,7 +49,7 @@ func TestMessageExportNegativeTimeoutSeconds(t *testing.T) {
defer os.RemoveAll(filepath.Dir(configPath))
// should fail fast because timeout seconds must be a positive int
require.Error(t, runCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "0", "--timeoutSeconds", "-1", "export"))
require.Error(t, cmd.RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "0", "--timeoutSeconds", "-1", "export"))
}
func writeTempConfig(t *testing.T, isMessageExportEnabled bool) string {

53
cmd/commands/reset.go Обычный файл
Просмотреть файл

@@ -0,0 +1,53 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package commands
import (
"errors"
"fmt"
"github.com/mattermost/mattermost-server/cmd"
"github.com/spf13/cobra"
)
var ResetCmd = &cobra.Command{
Use: "reset",
Short: "Reset the database to initial state",
Long: "Completely erases the database causing the loss of all data. This will reset Mattermost to its initial state.",
RunE: resetCmdF,
}
func init() {
ResetCmd.Flags().Bool("confirm", false, "Confirm you really want to delete everything and a DB backup has been performed.")
cmd.RootCmd.AddCommand(ResetCmd)
}
func resetCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
confirmFlag, _ := command.Flags().GetBool("confirm")
if !confirmFlag {
var confirm string
cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
cmd.CommandPrettyPrintln("Are you sure you want to delete everything? All data will be permanently deleted? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
}
a.Srv.Store.DropAllTables()
cmd.CommandPrettyPrintln("Database sucessfully reset")
return nil
}

Просмотреть файл

@@ -1,19 +1,21 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
"github.com/mattermost/mattermost-server/cmd"
"github.com/spf13/cobra"
)
var rolesCmd = &cobra.Command{
var RolesCmd = &cobra.Command{
Use: "roles",
Short: "Management of user roles",
}
var makeSystemAdminCmd = &cobra.Command{
var MakeSystemAdminCmd = &cobra.Command{
Use: "system_admin [users]",
Short: "Set a user as system admin",
Long: "Make some users system admins",
@@ -21,7 +23,7 @@ var makeSystemAdminCmd = &cobra.Command{
RunE: makeSystemAdminCmdF,
}
var makeMemberCmd = &cobra.Command{
var MakeMemberCmd = &cobra.Command{
Use: "member [users]",
Short: "Remove system admin privileges",
Long: "Remove system admin privileges from some users.",
@@ -30,14 +32,15 @@ var makeMemberCmd = &cobra.Command{
}
func init() {
rolesCmd.AddCommand(
makeSystemAdminCmd,
makeMemberCmd,
RolesCmd.AddCommand(
MakeSystemAdminCmd,
MakeMemberCmd,
)
cmd.RootCmd.AddCommand(RolesCmd)
}
func makeSystemAdminCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func makeSystemAdminCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -60,8 +63,8 @@ func makeSystemAdminCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func makeMemberCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func makeMemberCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}

Просмотреть файл

@@ -1,12 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"testing"
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
)
@@ -14,7 +15,7 @@ func TestAssignRole(t *testing.T) {
th := api.Setup().InitBasic()
defer th.TearDown()
checkCommand(t, "roles", "system_admin", th.BasicUser.Email)
cmd.CheckCommand(t, "roles", "system_admin", th.BasicUser.Email)
if result := <-th.App.Srv.Store.User().GetByEmail(th.BasicUser.Email); result.Err != nil {
t.Fatal()

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"encoding/json"
@@ -16,15 +17,34 @@ import (
"github.com/icrowley/fake"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/spf13/cobra"
)
var sampleDataCmd = &cobra.Command{
var SampleDataCmd = &cobra.Command{
Use: "sampledata",
Short: "Generate sample data",
RunE: sampleDataCmdF,
}
func init() {
SampleDataCmd.Flags().Int64P("seed", "s", 1, "Seed used for generating the random data (Different seeds generate different data).")
SampleDataCmd.Flags().IntP("teams", "t", 2, "The number of sample teams.")
SampleDataCmd.Flags().Int("channels-per-team", 10, "The number of sample channels per team.")
SampleDataCmd.Flags().IntP("users", "u", 15, "The number of sample users.")
SampleDataCmd.Flags().Int("team-memberships", 2, "The number of sample team memberships per user.")
SampleDataCmd.Flags().Int("channel-memberships", 5, "The number of sample channel memberships per user in a team.")
SampleDataCmd.Flags().Int("posts-per-channel", 100, "The number of sample post per channel.")
SampleDataCmd.Flags().Int("direct-channels", 30, "The number of sample direct message channels.")
SampleDataCmd.Flags().Int("posts-per-direct-channel", 15, "The number of sample posts per direct message channel.")
SampleDataCmd.Flags().Int("group-channels", 15, "The number of sample group message channels.")
SampleDataCmd.Flags().Int("posts-per-group-channel", 30, "The number of sample posts per group message channel.")
SampleDataCmd.Flags().IntP("workers", "w", 2, "How many workers to run during the import.")
SampleDataCmd.Flags().String("profile-images", "", "Optional. Path to folder with images to randomly pick as user profile image.")
SampleDataCmd.Flags().StringP("bulk", "b", "", "Optional. Path to write a JSONL bulk file instead of loading into the database.")
cmd.RootCmd.AddCommand(SampleDataCmd)
}
func sliceIncludes(vs []string, t string) bool {
for _, v := range vs {
if v == t {
@@ -109,81 +129,64 @@ func randomMessage(users []string) string {
return message
}
func init() {
sampleDataCmd.Flags().Int64P("seed", "s", 1, "Seed used for generating the random data (Different seeds generate different data).")
sampleDataCmd.Flags().IntP("teams", "t", 2, "The number of sample teams.")
sampleDataCmd.Flags().Int("channels-per-team", 10, "The number of sample channels per team.")
sampleDataCmd.Flags().IntP("users", "u", 15, "The number of sample users.")
sampleDataCmd.Flags().Int("team-memberships", 2, "The number of sample team memberships per user.")
sampleDataCmd.Flags().Int("channel-memberships", 5, "The number of sample channel memberships per user in a team.")
sampleDataCmd.Flags().Int("posts-per-channel", 100, "The number of sample post per channel.")
sampleDataCmd.Flags().Int("direct-channels", 30, "The number of sample direct message channels.")
sampleDataCmd.Flags().Int("posts-per-direct-channel", 15, "The number of sample posts per direct message channel.")
sampleDataCmd.Flags().Int("group-channels", 15, "The number of sample group message channels.")
sampleDataCmd.Flags().Int("posts-per-group-channel", 30, "The number of sample posts per group message channel.")
sampleDataCmd.Flags().IntP("workers", "w", 2, "How many workers to run during the import.")
sampleDataCmd.Flags().String("profile-images", "", "Optional. Path to folder with images to randomly pick as user profile image.")
sampleDataCmd.Flags().StringP("bulk", "b", "", "Optional. Path to write a JSONL bulk file instead of loading into the database.")
}
func sampleDataCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func sampleDataCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
seed, err := cmd.Flags().GetInt64("seed")
seed, err := command.Flags().GetInt64("seed")
if err != nil {
return errors.New("Invalid seed parameter")
}
bulk, err := cmd.Flags().GetString("bulk")
bulk, err := command.Flags().GetString("bulk")
if err != nil {
return errors.New("Invalid bulk parameter")
}
teams, err := cmd.Flags().GetInt("teams")
teams, err := command.Flags().GetInt("teams")
if err != nil || teams < 0 {
return errors.New("Invalid teams parameter")
}
channelsPerTeam, err := cmd.Flags().GetInt("channels-per-team")
channelsPerTeam, err := command.Flags().GetInt("channels-per-team")
if err != nil || channelsPerTeam < 0 {
return errors.New("Invalid channels-per-team parameter")
}
users, err := cmd.Flags().GetInt("users")
users, err := command.Flags().GetInt("users")
if err != nil || users < 0 {
return errors.New("Invalid users parameter")
}
teamMemberships, err := cmd.Flags().GetInt("team-memberships")
teamMemberships, err := command.Flags().GetInt("team-memberships")
if err != nil || teamMemberships < 0 {
return errors.New("Invalid team-memberships parameter")
}
channelMemberships, err := cmd.Flags().GetInt("channel-memberships")
channelMemberships, err := command.Flags().GetInt("channel-memberships")
if err != nil || channelMemberships < 0 {
return errors.New("Invalid channel-memberships parameter")
}
postsPerChannel, err := cmd.Flags().GetInt("posts-per-channel")
postsPerChannel, err := command.Flags().GetInt("posts-per-channel")
if err != nil || postsPerChannel < 0 {
return errors.New("Invalid posts-per-channel parameter")
}
directChannels, err := cmd.Flags().GetInt("direct-channels")
directChannels, err := command.Flags().GetInt("direct-channels")
if err != nil || directChannels < 0 {
return errors.New("Invalid direct-channels parameter")
}
postsPerDirectChannel, err := cmd.Flags().GetInt("posts-per-direct-channel")
postsPerDirectChannel, err := command.Flags().GetInt("posts-per-direct-channel")
if err != nil || postsPerDirectChannel < 0 {
return errors.New("Invalid posts-per-direct-channel parameter")
}
groupChannels, err := cmd.Flags().GetInt("group-channels")
groupChannels, err := command.Flags().GetInt("group-channels")
if err != nil || groupChannels < 0 {
return errors.New("Invalid group-channels parameter")
}
postsPerGroupChannel, err := cmd.Flags().GetInt("posts-per-group-channel")
postsPerGroupChannel, err := command.Flags().GetInt("posts-per-group-channel")
if err != nil || postsPerGroupChannel < 0 {
return errors.New("Invalid posts-per-group-channel parameter")
}
workers, err := cmd.Flags().GetInt("workers")
workers, err := command.Flags().GetInt("workers")
if err != nil {
return errors.New("Invalid workers parameter")
}
profileImagesPath, err := cmd.Flags().GetString("profile-images")
profileImagesPath, err := command.Flags().GetString("profile-images")
if err != nil {
return errors.New("Invalid profile-images parameter")
}
@@ -312,7 +315,7 @@ func sampleDataCmdF(cmd *cobra.Command, args []string) error {
}
importErr, lineNumber := a.BulkImport(bulkFile, false, workers)
if importErr != nil {
return errors.New(fmt.Sprintf("%s: %s, %s (line: %d)", importErr.Where, importErr.Message, importErr.DetailedError, lineNumber))
return fmt.Errorf("%s: %s, %s (line: %d)", importErr.Where, importErr.Message, importErr.DetailedError, lineNumber)
}
} else if bulk != "-" {
err := bulkFile.Close()
@@ -395,7 +398,7 @@ func createUser(idx int, teamMemberships int, channelMemberships int, teamsAndCh
position := rand.Intn(len(possibleTeams))
team := possibleTeams[position]
possibleTeams = append(possibleTeams[:position], possibleTeams[position+1:]...)
if teamChannels, err := teamsAndChannels[team]; err == true {
if teamChannels, err := teamsAndChannels[team]; err {
teams = append(teams, createTeamMembership(channelMemberships, teamChannels, &team))
}
}
@@ -429,10 +432,7 @@ func createTeamMembership(numOfchannels int, teamChannels []string, teamName *st
roles = "team_user team_admin"
}
channels := []app.UserChannelImportData{}
teamChannelsCopy := []string{}
for _, value := range teamChannels {
teamChannelsCopy = append(teamChannelsCopy, value)
}
teamChannelsCopy := append([]string(nil), teamChannels...)
for x := 0; x < numOfchannels; x++ {
if len(teamChannelsCopy) == 0 {
break

Просмотреть файл

@@ -1,12 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"testing"
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/cmd"
"github.com/stretchr/testify/require"
)
@@ -15,11 +16,11 @@ func TestSampledataBadParameters(t *testing.T) {
defer th.TearDown()
// should fail because you need at least 1 worker
require.Error(t, runCommand(t, "sampledata", "--workers", "0"))
require.Error(t, cmd.RunCommand(t, "sampledata", "--workers", "0"))
// should fail because you have more team memberships than teams
require.Error(t, runCommand(t, "sampledata", "--teams", "10", "--teams-memberships", "11"))
require.Error(t, cmd.RunCommand(t, "sampledata", "--teams", "10", "--teams-memberships", "11"))
// should fail because you have more channel memberships than channels per team
require.Error(t, runCommand(t, "sampledata", "--channels-per-team", "10", "--channel-memberships", "11"))
require.Error(t, cmd.RunCommand(t, "sampledata", "--channels-per-team", "10", "--channel-memberships", "11"))
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"net"
@@ -14,6 +14,7 @@ import (
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/api4"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/manualtesting"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
@@ -31,17 +32,22 @@ var MaxNotificationsPerChannelDefault int64 = 1000000
var serverCmd = &cobra.Command{
Use: "server",
Short: "Run the Mattermost server",
RunE: runServerCmd,
RunE: serverCmdF,
SilenceUsage: true,
}
func runServerCmd(cmd *cobra.Command, args []string) error {
config, err := cmd.Flags().GetString("config")
func init() {
cmd.RootCmd.AddCommand(serverCmd)
cmd.RootCmd.RunE = serverCmdF
}
func serverCmdF(command *cobra.Command, args []string) error {
config, err := command.Flags().GetString("config")
if err != nil {
return err
}
disableConfigWatch, _ := cmd.Flags().GetBool("disableconfigwatch")
disableConfigWatch, _ := command.Flags().GetBool("disableconfigwatch")
interruptChan := make(chan os.Signal, 1)
return runServer(config, disableConfigWatch, interruptChan)

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"io/ioutil"
@@ -110,7 +110,7 @@ func TestRunServerSystemdNotification(t *testing.T) {
panic(err)
}
data := buffer[0:count]
ch<- string(data)
ch <- string(data)
}(socketReader)
// Start and stop the server

Просмотреть файл

@@ -1,22 +1,24 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"errors"
"fmt"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/spf13/cobra"
)
var teamCmd = &cobra.Command{
var TeamCmd = &cobra.Command{
Use: "team",
Short: "Management of teams",
}
var teamCreateCmd = &cobra.Command{
var TeamCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a team",
Long: `Create a team.`,
@@ -25,7 +27,7 @@ var teamCreateCmd = &cobra.Command{
RunE: createTeamCmdF,
}
var removeUsersCmd = &cobra.Command{
var RemoveUsersCmd = &cobra.Command{
Use: "remove [team] [users]",
Short: "Remove users from team",
Long: "Remove some users from team",
@@ -33,7 +35,7 @@ var removeUsersCmd = &cobra.Command{
RunE: removeUsersCmdF,
}
var addUsersCmd = &cobra.Command{
var AddUsersCmd = &cobra.Command{
Use: "add [team] [users]",
Short: "Add users to team",
Long: "Add some users to team",
@@ -41,7 +43,7 @@ var addUsersCmd = &cobra.Command{
RunE: addUsersCmdF,
}
var deleteTeamsCmd = &cobra.Command{
var DeleteTeamsCmd = &cobra.Command{
Use: "delete [teams]",
Short: "Delete teams",
Long: `Permanently delete some teams.
@@ -51,37 +53,38 @@ Permanently deletes a team along with all related information including posts fr
}
func init() {
teamCreateCmd.Flags().String("name", "", "Team Name")
teamCreateCmd.Flags().String("display_name", "", "Team Display Name")
teamCreateCmd.Flags().Bool("private", false, "Create a private team.")
teamCreateCmd.Flags().String("email", "", "Administrator Email (anyone with this email is automatically a team admin)")
TeamCreateCmd.Flags().String("name", "", "Team Name")
TeamCreateCmd.Flags().String("display_name", "", "Team Display Name")
TeamCreateCmd.Flags().Bool("private", false, "Create a private team.")
TeamCreateCmd.Flags().String("email", "", "Administrator Email (anyone with this email is automatically a team admin)")
deleteTeamsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the team and a DB backup has been performed.")
DeleteTeamsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the team and a DB backup has been performed.")
teamCmd.AddCommand(
teamCreateCmd,
removeUsersCmd,
addUsersCmd,
deleteTeamsCmd,
TeamCmd.AddCommand(
TeamCreateCmd,
RemoveUsersCmd,
AddUsersCmd,
DeleteTeamsCmd,
)
cmd.RootCmd.AddCommand(TeamCmd)
}
func createTeamCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func createTeamCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
name, errn := cmd.Flags().GetString("name")
name, errn := command.Flags().GetString("name")
if errn != nil || name == "" {
return errors.New("Name is required")
}
displayname, errdn := cmd.Flags().GetString("display_name")
displayname, errdn := command.Flags().GetString("display_name")
if errdn != nil || displayname == "" {
return errors.New("Display Name is required")
}
email, _ := cmd.Flags().GetString("email")
useprivate, _ := cmd.Flags().GetBool("private")
email, _ := command.Flags().GetString("email")
useprivate, _ := command.Flags().GetBool("private")
teamType := model.TEAM_OPEN
if useprivate {
@@ -102,8 +105,8 @@ func createTeamCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func removeUsersCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func removeUsersCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -127,16 +130,16 @@ func removeUsersCmdF(cmd *cobra.Command, args []string) error {
func removeUserFromTeam(a *app.App, team *model.Team, user *model.User, userArg string) {
if user == nil {
CommandPrintErrorln("Can't find user '" + userArg + "'")
cmd.CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
if err := a.LeaveTeam(team, user, ""); err != nil {
CommandPrintErrorln("Unable to remove '" + userArg + "' from " + team.Name + ". Error: " + err.Error())
cmd.CommandPrintErrorln("Unable to remove '" + userArg + "' from " + team.Name + ". Error: " + err.Error())
}
}
func addUsersCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func addUsersCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -160,16 +163,16 @@ func addUsersCmdF(cmd *cobra.Command, args []string) error {
func addUserToTeam(a *app.App, team *model.Team, user *model.User, userArg string) {
if user == nil {
CommandPrintErrorln("Can't find user '" + userArg + "'")
cmd.CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
if err := a.JoinUserToTeam(team, user, ""); err != nil {
CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name)
cmd.CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name)
}
}
func deleteTeamsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func deleteTeamsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -178,16 +181,16 @@ func deleteTeamsCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Not enough arguments.")
}
confirmFlag, _ := cmd.Flags().GetBool("confirm")
confirmFlag, _ := command.Flags().GetBool("confirm")
if !confirmFlag {
var confirm string
CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
CommandPrettyPrintln("Are you sure you want to delete the teams specified? All data will be permanently deleted? (YES/NO): ")
cmd.CommandPrettyPrintln("Are you sure you want to delete the teams specified? All data will be permanently deleted? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
@@ -197,13 +200,13 @@ func deleteTeamsCmdF(cmd *cobra.Command, args []string) error {
teams := getTeamsFromTeamArgs(a, args)
for i, team := range teams {
if team == nil {
CommandPrintErrorln("Unable to find team '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find team '" + args[i] + "'")
continue
}
if err := deleteTeam(a, team); err != nil {
CommandPrintErrorln("Unable to delete team '" + team.Name + "' error: " + err.Error())
cmd.CommandPrintErrorln("Unable to delete team '" + team.Name + "' error: " + err.Error())
} else {
CommandPrettyPrintln("Deleted team '" + team.Name + "'")
cmd.CommandPrettyPrintln("Deleted team '" + team.Name + "'")
}
}

Просмотреть файл

@@ -1,12 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"testing"
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
)
@@ -18,7 +19,7 @@ func TestCreateTeam(t *testing.T) {
name := "name" + id
displayName := "Name " + id
checkCommand(t, "team", "create", "--name", name, "--display_name", displayName)
cmd.CheckCommand(t, "team", "create", "--name", name, "--display_name", displayName)
found := th.SystemAdminClient.Must(th.SystemAdminClient.FindTeamByName(name)).Data.(bool)
@@ -31,7 +32,7 @@ func TestJoinTeam(t *testing.T) {
th := api.Setup().InitSystemAdmin().InitBasic()
defer th.TearDown()
checkCommand(t, "team", "add", th.SystemAdminTeam.Name, th.BasicUser.Email)
cmd.CheckCommand(t, "team", "add", th.SystemAdminTeam.Name, th.BasicUser.Email)
profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfilesInTeam(th.SystemAdminTeam.Id, 0, 1000, "")).Data.(map[string]*model.User)
@@ -53,7 +54,7 @@ func TestLeaveTeam(t *testing.T) {
th := api.Setup().InitBasic()
defer th.TearDown()
checkCommand(t, "team", "remove", th.BasicTeam.Name, th.BasicUser.Email)
cmd.CheckCommand(t, "team", "remove", th.BasicTeam.Name, th.BasicUser.Email)
profiles := th.BasicClient.Must(th.BasicClient.GetProfilesInTeam(th.BasicTeam.Id, 0, 1000, "")).Data.(map[string]*model.User)

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"github.com/mattermost/mattermost-server/app"

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"bufio"
@@ -14,39 +14,41 @@ import (
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/api4"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/mattermost/mattermost-server/wsapi"
"github.com/spf13/cobra"
)
var testCmd = &cobra.Command{
var TestCmd = &cobra.Command{
Use: "test",
Short: "Testing Commands",
Hidden: true,
}
var runWebClientTestsCmd = &cobra.Command{
var RunWebClientTestsCmd = &cobra.Command{
Use: "web_client_tests",
Short: "Run the web client tests",
RunE: webClientTestsCmdF,
}
var runServerForWebClientTestsCmd = &cobra.Command{
var RunServerForWebClientTestsCmd = &cobra.Command{
Use: "web_client_tests_server",
Short: "Run the server configured for running the web client tests against it",
RunE: serverForWebClientTestsCmdF,
}
func init() {
testCmd.AddCommand(
runWebClientTestsCmd,
runServerForWebClientTestsCmd,
TestCmd.AddCommand(
RunWebClientTestsCmd,
RunServerForWebClientTestsCmd,
)
cmd.RootCmd.AddCommand(TestCmd)
}
func webClientTestsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func webClientTestsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -67,8 +69,8 @@ func webClientTestsCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func serverForWebClientTestsCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func serverForWebClientTestsCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -101,17 +103,17 @@ func setupClientTests(cfg *model.Config) {
cfg.ServiceSettings.EnableOutgoingWebhooks = false
}
func executeTestCommand(cmd *exec.Cmd) {
cmdOutPipe, err := cmd.StdoutPipe()
func executeTestCommand(command *exec.Cmd) {
cmdOutPipe, err := command.StdoutPipe()
if err != nil {
CommandPrintErrorln("Failed to run tests")
cmd.CommandPrintErrorln("Failed to run tests")
os.Exit(1)
return
}
cmdErrOutPipe, err := cmd.StderrPipe()
cmdErrOutPipe, err := command.StderrPipe()
if err != nil {
CommandPrintErrorln("Failed to run tests")
cmd.CommandPrintErrorln("Failed to run tests")
os.Exit(1)
return
}
@@ -130,8 +132,8 @@ func executeTestCommand(cmd *exec.Cmd) {
}
}()
if err := cmd.Run(); err != nil {
CommandPrintErrorln("Client Tests failed")
if err := command.Run(); err != nil {
cmd.CommandPrintErrorln("Client Tests failed")
os.Exit(1)
return
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"encoding/json"
@@ -10,16 +11,17 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/spf13/cobra"
)
var userCmd = &cobra.Command{
var UserCmd = &cobra.Command{
Use: "user",
Short: "Management of users",
}
var userActivateCmd = &cobra.Command{
var UserActivateCmd = &cobra.Command{
Use: "activate [emails, usernames, userIds]",
Short: "Activate users",
Long: "Activate users that have been deactivated.",
@@ -28,7 +30,7 @@ var userActivateCmd = &cobra.Command{
RunE: userActivateCmdF,
}
var userDeactivateCmd = &cobra.Command{
var UserDeactivateCmd = &cobra.Command{
Use: "deactivate [emails, usernames, userIds]",
Short: "Deactivate users",
Long: "Deactivate users. Deactivated users are immediately logged out of all sessions and are unable to log back in.",
@@ -37,7 +39,7 @@ var userDeactivateCmd = &cobra.Command{
RunE: userDeactivateCmdF,
}
var userCreateCmd = &cobra.Command{
var UserCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a user",
Long: "Create a user",
@@ -45,7 +47,7 @@ var userCreateCmd = &cobra.Command{
RunE: userCreateCmdF,
}
var userInviteCmd = &cobra.Command{
var UserInviteCmd = &cobra.Command{
Use: "invite [email] [teams]",
Short: "Send user an email invite to a team.",
Long: `Send user an email invite to a team.
@@ -56,7 +58,7 @@ You can specify teams by name or ID.`,
RunE: userInviteCmdF,
}
var resetUserPasswordCmd = &cobra.Command{
var ResetUserPasswordCmd = &cobra.Command{
Use: "password [user] [password]",
Short: "Set a user's password",
Long: "Set a user's password",
@@ -64,7 +66,16 @@ var resetUserPasswordCmd = &cobra.Command{
RunE: resetUserPasswordCmdF,
}
var resetUserMfaCmd = &cobra.Command{
var updateUserEmailCmd = &cobra.Command{
Use: "email [user] [new email]",
Short: "Change email of the user",
Long: "Change email of the user.",
Example: ` user email test user@example.com
user activate username`,
RunE: updateUserEmailCmdF,
}
var ResetUserMfaCmd = &cobra.Command{
Use: "resetmfa [users]",
Short: "Turn off MFA",
Long: `Turn off multi-factor authentication for a user.
@@ -73,7 +84,7 @@ If MFA enforcement is enabled, the user will be forced to re-enable MFA as soon
RunE: resetUserMfaCmdF,
}
var deleteUserCmd = &cobra.Command{
var DeleteUserCmd = &cobra.Command{
Use: "delete [users]",
Short: "Delete users and all posts",
Long: "Permanently delete user and all related information including posts.",
@@ -81,7 +92,7 @@ var deleteUserCmd = &cobra.Command{
RunE: deleteUserCmdF,
}
var deleteAllUsersCmd = &cobra.Command{
var DeleteAllUsersCmd = &cobra.Command{
Use: "deleteall",
Short: "Delete all users and all posts",
Long: "Permanently delete all users and all related information including posts.",
@@ -89,7 +100,7 @@ var deleteAllUsersCmd = &cobra.Command{
RunE: deleteAllUsersCommandF,
}
var migrateAuthCmd = &cobra.Command{
var MigrateAuthCmd = &cobra.Command{
Use: "migrate_auth [from_auth] [to_auth] [migration-options]",
Short: "Mass migrate user accounts authentication type",
Long: `Migrates accounts from one authentication provider to another. For example, you can upgrade your authentication provider from email to ldap.`,
@@ -127,7 +138,7 @@ var migrateAuthCmd = &cobra.Command{
RunE: migrateAuthCmdF,
}
var verifyUserCmd = &cobra.Command{
var VerifyUserCmd = &cobra.Command{
Use: "verify [users]",
Short: "Verify email of users",
Long: "Verify the emails of some users.",
@@ -135,7 +146,7 @@ var verifyUserCmd = &cobra.Command{
RunE: verifyUserCmdF,
}
var searchUserCmd = &cobra.Command{
var SearchUserCmd = &cobra.Command{
Use: "search [users]",
Short: "Search for users",
Long: "Search for users based on username, email, or user ID.",
@@ -144,23 +155,23 @@ var searchUserCmd = &cobra.Command{
}
func init() {
userCreateCmd.Flags().String("username", "", "Required. Username for the new user account.")
userCreateCmd.Flags().String("email", "", "Required. The email address for the new user account.")
userCreateCmd.Flags().String("password", "", "Required. The password for the new user account.")
userCreateCmd.Flags().String("nickname", "", "Optional. The nickname for the new user account.")
userCreateCmd.Flags().String("firstname", "", "Optional. The first name for the new user account.")
userCreateCmd.Flags().String("lastname", "", "Optional. The last name for the new user account.")
userCreateCmd.Flags().String("locale", "", "Optional. The locale (ex: en, fr) for the new user account.")
userCreateCmd.Flags().Bool("system_admin", false, "Optional. If supplied, the new user will be a system administrator. Defaults to false.")
UserCreateCmd.Flags().String("username", "", "Required. Username for the new user account.")
UserCreateCmd.Flags().String("email", "", "Required. The email address for the new user account.")
UserCreateCmd.Flags().String("password", "", "Required. The password for the new user account.")
UserCreateCmd.Flags().String("nickname", "", "Optional. The nickname for the new user account.")
UserCreateCmd.Flags().String("firstname", "", "Optional. The first name for the new user account.")
UserCreateCmd.Flags().String("lastname", "", "Optional. The last name for the new user account.")
UserCreateCmd.Flags().String("locale", "", "Optional. The locale (ex: en, fr) for the new user account.")
UserCreateCmd.Flags().Bool("system_admin", false, "Optional. If supplied, the new user will be a system administrator. Defaults to false.")
deleteUserCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.")
DeleteUserCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.")
deleteAllUsersCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.")
DeleteAllUsersCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.")
migrateAuthCmd.Flags().Bool("force", false, "Force the migration to occur even if there are duplicates on the LDAP server. Duplicates will not be migrated. (ldap only)")
migrateAuthCmd.Flags().Bool("auto", false, "Automatically migrate all users. Assumes the usernames and emails are identical between Mattermost and SAML services. (saml only)")
migrateAuthCmd.Flags().Bool("dryRun", false, "Run a simulation of the migration process without changing the database.")
migrateAuthCmd.SetUsageTemplate(`Usage:
MigrateAuthCmd.Flags().Bool("force", false, "Force the migration to occur even if there are duplicates on the LDAP server. Duplicates will not be migrated. (ldap only)")
MigrateAuthCmd.Flags().Bool("auto", false, "Automatically migrate all users. Assumes the usernames and emails are identical between Mattermost and SAML services. (saml only)")
MigrateAuthCmd.Flags().Bool("dryRun", false, "Run a simulation of the migration process without changing the database.")
MigrateAuthCmd.SetUsageTemplate(`Usage:
platform user migrate_auth [from_auth] [to_auth] [migration-options] [flags]
Examples:
@@ -184,7 +195,7 @@ Flags:
Global Flags:
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}
`)
migrateAuthCmd.SetHelpTemplate(`Usage:
MigrateAuthCmd.SetHelpTemplate(`Usage:
platform user migrate_auth [from_auth] [to_auth] [migration-options] [flags]
Examples:
@@ -221,23 +232,25 @@ Global Flags:
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}
`)
userCmd.AddCommand(
userActivateCmd,
userDeactivateCmd,
userCreateCmd,
userInviteCmd,
resetUserPasswordCmd,
resetUserMfaCmd,
deleteUserCmd,
deleteAllUsersCmd,
migrateAuthCmd,
verifyUserCmd,
searchUserCmd,
UserCmd.AddCommand(
UserActivateCmd,
UserDeactivateCmd,
UserCreateCmd,
UserInviteCmd,
ResetUserPasswordCmd,
updateUserEmailCmd,
ResetUserMfaCmd,
DeleteUserCmd,
DeleteAllUsersCmd,
MigrateAuthCmd,
VerifyUserCmd,
SearchUserCmd,
)
cmd.RootCmd.AddCommand(UserCmd)
}
func userActivateCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func userActivateCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -256,7 +269,7 @@ func changeUsersActiveStatus(a *app.App, userArgs []string, active bool) {
err := changeUserActiveStatus(a, user, userArgs[i], active)
if err != nil {
CommandPrintErrorln(err.Error())
cmd.CommandPrintErrorln(err.Error())
}
}
}
@@ -275,8 +288,8 @@ func changeUserActiveStatus(a *app.App, user *model.User, userArg string, activa
return nil
}
func userDeactivateCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func userDeactivateCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -289,29 +302,29 @@ func userDeactivateCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func userCreateCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func userCreateCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
username, erru := cmd.Flags().GetString("username")
username, erru := command.Flags().GetString("username")
if erru != nil || username == "" {
return errors.New("Username is required")
}
email, erre := cmd.Flags().GetString("email")
email, erre := command.Flags().GetString("email")
if erre != nil || email == "" {
return errors.New("Email is required")
}
password, errp := cmd.Flags().GetString("password")
password, errp := command.Flags().GetString("password")
if errp != nil || password == "" {
return errors.New("Password is required")
}
nickname, _ := cmd.Flags().GetString("nickname")
firstname, _ := cmd.Flags().GetString("firstname")
lastname, _ := cmd.Flags().GetString("lastname")
locale, _ := cmd.Flags().GetString("locale")
systemAdmin, _ := cmd.Flags().GetBool("system_admin")
nickname, _ := command.Flags().GetString("nickname")
firstname, _ := command.Flags().GetString("firstname")
lastname, _ := command.Flags().GetString("lastname")
locale, _ := command.Flags().GetString("locale")
systemAdmin, _ := command.Flags().GetBool("system_admin")
user := &model.User{
Username: username,
@@ -329,13 +342,13 @@ func userCreateCmdF(cmd *cobra.Command, args []string) error {
a.UpdateUserRoles(ruser.Id, "system_user system_admin", false)
}
CommandPrettyPrintln("Created User")
cmd.CommandPrettyPrintln("Created User")
return nil
}
func userInviteCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func userInviteCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -354,7 +367,7 @@ func userInviteCmdF(cmd *cobra.Command, args []string) error {
err := inviteUser(a, email, team, args[i+1])
if err != nil {
CommandPrintErrorln(err.Error())
cmd.CommandPrintErrorln(err.Error())
}
}
@@ -368,13 +381,13 @@ func inviteUser(a *app.App, email string, team *model.Team, teamArg string) erro
}
a.SendInviteEmails(team, "Administrator", invites, *a.Config().ServiceSettings.SiteURL)
CommandPrettyPrintln("Invites may or may not have been sent.")
cmd.CommandPrettyPrintln("Invites may or may not have been sent.")
return nil
}
func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func resetUserPasswordCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -396,8 +409,38 @@ func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func resetUserMfaCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func updateUserEmailCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
newEmail := args[1]
if !model.IsValidEmail(newEmail) {
return errors.New("Invalid email: '" + newEmail + "'")
}
if len(args) != 2 {
return errors.New("Expected two arguments. See help text for details.")
}
user := getUserFromUserArg(a, args[0])
if user == nil {
return errors.New("Unable to find user '" + args[0] + "'")
}
user.Email = newEmail
_, errUpdate := a.UpdateUser(user, true)
if err != nil {
return errUpdate
}
return nil
}
func resetUserMfaCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -421,8 +464,8 @@ func resetUserMfaCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func deleteUserCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func deleteUserCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -431,16 +474,16 @@ func deleteUserCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Expected at least one argument. See help text for details.")
}
confirmFlag, _ := cmd.Flags().GetBool("confirm")
confirmFlag, _ := command.Flags().GetBool("confirm")
if !confirmFlag {
var confirm string
CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
CommandPrettyPrintln("Are you sure you want to permanently delete the specified users? (YES/NO): ")
cmd.CommandPrettyPrintln("Are you sure you want to permanently delete the specified users? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
@@ -462,8 +505,8 @@ func deleteUserCmdF(cmd *cobra.Command, args []string) error {
return nil
}
func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func deleteAllUsersCommandF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -472,16 +515,16 @@ func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error {
return errors.New("Expected zero arguments.")
}
confirmFlag, _ := cmd.Flags().GetBool("confirm")
confirmFlag, _ := command.Flags().GetBool("confirm")
if !confirmFlag {
var confirm string
CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
CommandPrettyPrintln("Are you sure you want to permanently delete all user accounts? (YES/NO): ")
cmd.CommandPrettyPrintln("Are you sure you want to permanently delete all user accounts? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
@@ -492,19 +535,19 @@ func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error {
return err
}
CommandPrettyPrintln("All user accounts successfully deleted.")
cmd.CommandPrettyPrintln("All user accounts successfully deleted.")
return nil
}
func migrateAuthCmdF(cmd *cobra.Command, args []string) error {
func migrateAuthCmdF(command *cobra.Command, args []string) error {
if args[1] == "saml" {
return migrateAuthToSamlCmdF(cmd, args)
return migrateAuthToSamlCmdF(command, args)
}
return migrateAuthToLdapCmdF(cmd, args)
return migrateAuthToLdapCmdF(command, args)
}
func migrateAuthToLdapCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func migrateAuthToLdapCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -525,28 +568,28 @@ func migrateAuthToLdapCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Invalid match_field argument")
}
forceFlag, _ := cmd.Flags().GetBool("force")
dryRunFlag, _ := cmd.Flags().GetBool("dryRun")
forceFlag, _ := command.Flags().GetBool("force")
dryRunFlag, _ := command.Flags().GetBool("dryRun")
if migrate := a.AccountMigration; migrate != nil {
if err := migrate.MigrateToLdap(fromAuth, matchField, forceFlag, dryRunFlag); err != nil {
return errors.New("Error while migrating users: " + err.Error())
}
CommandPrettyPrintln("Sucessfully migrated accounts.")
cmd.CommandPrettyPrintln("Sucessfully migrated accounts.")
}
return nil
}
func migrateAuthToSamlCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func migrateAuthToSamlCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
dryRunFlag, _ := cmd.Flags().GetBool("dryRun")
autoFlag, _ := cmd.Flags().GetBool("auto")
dryRunFlag, _ := command.Flags().GetBool("dryRun")
autoFlag, _ := command.Flags().GetBool("auto")
matchesFile := ""
matches := map[string]string{}
@@ -570,7 +613,7 @@ func migrateAuthToSamlCmdF(cmd *cobra.Command, args []string) error {
if autoFlag && !dryRunFlag {
var confirm string
CommandPrettyPrintln("You are about to perform an automatic \"" + fromAuth + " to saml\" migration. This must only be done if your current Mattermost users with " + fromAuth + " auth have the same username and email in your SAML service. Otherwise, provide the usernames and emails from your SAML Service using the \"users file\" without the \"--auto\" option.\n\nDo you want to proceed with automatic migration anyway? (YES/NO):")
cmd.CommandPrettyPrintln("You are about to perform an automatic \"" + fromAuth + " to saml\" migration. This must only be done if your current Mattermost users with " + fromAuth + " auth have the same username and email in your SAML service. Otherwise, provide the usernames and emails from your SAML Service using the \"users file\" without the \"--auto\" option.\n\nDo you want to proceed with automatic migration anyway? (YES/NO):")
fmt.Scanln(&confirm)
if confirm != "YES" {
@@ -588,14 +631,14 @@ func migrateAuthToSamlCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Error while migrating users: " + err.Error())
}
l4g.Close()
CommandPrettyPrintln("Sucessfully migrated accounts.")
cmd.CommandPrettyPrintln("Sucessfully migrated accounts.")
}
return nil
}
func verifyUserCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func verifyUserCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -608,19 +651,19 @@ func verifyUserCmdF(cmd *cobra.Command, args []string) error {
for i, user := range users {
if user == nil {
CommandPrintErrorln("Unable to find user '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find user '" + args[i] + "'")
continue
}
if cresult := <-a.Srv.Store.User().VerifyEmail(user.Id); cresult.Err != nil {
CommandPrintErrorln("Unable to verify '" + args[i] + "' email. Error: " + cresult.Err.Error())
cmd.CommandPrintErrorln("Unable to verify '" + args[i] + "' email. Error: " + cresult.Err.Error())
}
}
return nil
}
func searchUserCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func searchUserCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -633,21 +676,21 @@ func searchUserCmdF(cmd *cobra.Command, args []string) error {
for i, user := range users {
if i > 0 {
CommandPrettyPrintln("------------------------------")
cmd.CommandPrettyPrintln("------------------------------")
}
if user == nil {
CommandPrintErrorln("Unable to find user '" + args[i] + "'")
cmd.CommandPrintErrorln("Unable to find user '" + args[i] + "'")
continue
}
CommandPrettyPrintln("id: " + user.Id)
CommandPrettyPrintln("username: " + user.Username)
CommandPrettyPrintln("nickname: " + user.Nickname)
CommandPrettyPrintln("position: " + user.Position)
CommandPrettyPrintln("first_name: " + user.FirstName)
CommandPrettyPrintln("last_name: " + user.LastName)
CommandPrettyPrintln("email: " + user.Email)
CommandPrettyPrintln("auth_service: " + user.AuthService)
cmd.CommandPrettyPrintln("id: " + user.Id)
cmd.CommandPrettyPrintln("username: " + user.Username)
cmd.CommandPrettyPrintln("nickname: " + user.Nickname)
cmd.CommandPrettyPrintln("position: " + user.Position)
cmd.CommandPrettyPrintln("first_name: " + user.FirstName)
cmd.CommandPrettyPrintln("last_name: " + user.LastName)
cmd.CommandPrettyPrintln("email: " + user.Email)
cmd.CommandPrettyPrintln("auth_service: " + user.AuthService)
}
return nil

Просмотреть файл

@@ -1,13 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"testing"
"github.com/mattermost/mattermost-server/api"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/stretchr/testify/require"
)
func TestCreateUserWithTeam(t *testing.T) {
@@ -18,9 +20,9 @@ func TestCreateUserWithTeam(t *testing.T) {
email := "success+" + id + "@simulator.amazonses.com"
username := "name" + id
checkCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username)
cmd.CheckCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username)
checkCommand(t, "team", "add", th.SystemAdminTeam.Id, email)
cmd.CheckCommand(t, "team", "add", th.SystemAdminTeam.Id, email)
profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfilesInTeam(th.SystemAdminTeam.Id, 0, 1000, "")).Data.(map[string]*model.User)
@@ -46,7 +48,7 @@ func TestCreateUserWithoutTeam(t *testing.T) {
email := "success+" + id + "@simulator.amazonses.com"
username := "name" + id
checkCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username)
cmd.CheckCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username)
if result := <-th.App.Srv.Store.User().GetByEmail(email); result.Err != nil {
t.Fatal()
@@ -62,7 +64,7 @@ func TestResetPassword(t *testing.T) {
th := api.Setup().InitBasic()
defer th.TearDown()
checkCommand(t, "user", "password", th.BasicUser.Email, "password2")
cmd.CheckCommand(t, "user", "password", th.BasicUser.Email, "password2")
th.BasicClient.Logout()
th.BasicUser.Password = "password2"
@@ -74,8 +76,35 @@ func TestMakeUserActiveAndInactive(t *testing.T) {
defer th.TearDown()
// first inactivate the user
checkCommand(t, "user", "deactivate", th.BasicUser.Email)
cmd.CheckCommand(t, "user", "deactivate", th.BasicUser.Email)
// activate the inactive user
checkCommand(t, "user", "activate", th.BasicUser.Email)
cmd.CheckCommand(t, "user", "activate", th.BasicUser.Email)
}
func TestChangeUserEmail(t *testing.T) {
th := api.Setup().InitBasic()
defer th.TearDown()
newEmail := model.NewId() + "@mattermost-test.com"
cmd.CheckCommand(t, "user", "email", th.BasicUser.Username, newEmail)
if result := <-th.App.Srv.Store.User().GetByEmail(th.BasicUser.Email); result.Err == nil {
t.Fatal("should've updated to the new email")
}
if result := <-th.App.Srv.Store.User().GetByEmail(newEmail); result.Err != nil {
t.Fatal()
} else {
user := result.Data.(*model.User)
if user.Email != newEmail {
t.Fatal("should've updated to the new email")
}
}
// should fail because using an invalid email
require.Error(t, cmd.RunCommand(t, "user", "email", th.BasicUser.Username, "wrong$email.com"))
// should fail because user not found
require.Error(t, cmd.RunCommand(t, "user", "email", "invalidUser", newEmail))
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"github.com/mattermost/mattermost-server/app"

Просмотреть файл

@@ -1,23 +1,29 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/cmd"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/store/sqlstore"
"github.com/spf13/cobra"
)
var versionCmd = &cobra.Command{
var VersionCmd = &cobra.Command{
Use: "version",
Short: "Display version information",
RunE: versionCmdF,
}
func versionCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
func init() {
cmd.RootCmd.AddCommand(VersionCmd)
}
func versionCmdF(command *cobra.Command, args []string) error {
a, err := cmd.InitDBCommandContextCobra(command)
if err != nil {
return err
}
@@ -28,12 +34,12 @@ func versionCmdF(cmd *cobra.Command, args []string) error {
}
func printVersion(a *app.App) {
CommandPrintln("Version: " + model.CurrentVersion)
CommandPrintln("Build Number: " + model.BuildNumber)
CommandPrintln("Build Date: " + model.BuildDate)
CommandPrintln("Build Hash: " + model.BuildHash)
CommandPrintln("Build Enterprise Ready: " + model.BuildEnterpriseReady)
cmd.CommandPrintln("Version: " + model.CurrentVersion)
cmd.CommandPrintln("Build Number: " + model.BuildNumber)
cmd.CommandPrintln("Build Date: " + model.BuildDate)
cmd.CommandPrintln("Build Hash: " + model.BuildHash)
cmd.CommandPrintln("Build Enterprise Ready: " + model.BuildEnterpriseReady)
if supplier, ok := a.Srv.Store.(*store.LayeredStore).DatabaseLayer.(*sqlstore.SqlSupplier); ok {
CommandPrintln("DB Version: " + supplier.GetCurrentSchemaVersion())
cmd.CommandPrintln("DB Version: " + supplier.GetCurrentSchemaVersion())
}
}

Просмотреть файл

@@ -1,12 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package commands
import (
"testing"
"github.com/mattermost/mattermost-server/cmd"
)
func TestVersion(t *testing.T) {
checkCommand(t, "version")
cmd.CheckCommand(t, "version")
}

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package cmd
import (
"github.com/mattermost/mattermost-server/app"
@@ -10,13 +10,13 @@ import (
"github.com/spf13/cobra"
)
func initDBCommandContextCobra(cmd *cobra.Command) (*app.App, error) {
func InitDBCommandContextCobra(cmd *cobra.Command) (*app.App, error) {
config, err := cmd.Flags().GetString("config")
if err != nil {
return nil, err
}
a, err := initDBCommandContext(config)
a, err := InitDBCommandContext(config)
if err != nil {
// Returning an error just prints the usage message, so actually panic
panic(err)
@@ -25,7 +25,7 @@ func initDBCommandContextCobra(cmd *cobra.Command) (*app.App, error) {
return a, nil
}
func initDBCommandContext(configFileLocation string) (*app.App, error) {
func InitDBCommandContext(configFileLocation string) (*app.App, error) {
if err := utils.TranslationsPreInit(); err != nil {
return nil, err
}

Просмотреть файл

@@ -1,6 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
package cmd
import (
"fmt"

Просмотреть файл

@@ -1,88 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
import (
"errors"
"fmt"
"os"
"github.com/spf13/cobra"
// Plugins
_ "github.com/mattermost/mattermost-server/model/gitlab"
// Enterprise Imports
_ "github.com/mattermost/mattermost-server/imports"
// Enterprise Deps
_ "github.com/dgryski/dgoogauth"
_ "github.com/go-ldap/ldap"
_ "github.com/hashicorp/memberlist"
_ "github.com/mattermost/rsc/qr"
_ "github.com/prometheus/client_golang/prometheus"
_ "github.com/prometheus/client_golang/prometheus/promhttp"
_ "github.com/tylerb/graceful"
_ "gopkg.in/olivere/elastic.v5"
// Temp imports for new dependencies
_ "github.com/gorilla/schema"
)
func main() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}
func init() {
rootCmd.PersistentFlags().StringP("config", "c", "config.json", "Configuration file to use.")
rootCmd.PersistentFlags().Bool("disableconfigwatch", false, "When set config.json will not be loaded from disk when the file is changed.")
resetCmd.Flags().Bool("confirm", false, "Confirm you really want to delete everything and a DB backup has been performed.")
rootCmd.AddCommand(serverCmd, versionCmd, userCmd, teamCmd, licenseCmd, importCmd, resetCmd, channelCmd, rolesCmd, testCmd, ldapCmd, configCmd, jobserverCmd, commandCmd, messageExportCmd, sampleDataCmd)
}
var rootCmd = &cobra.Command{
Use: "platform",
Short: "Open source, self-hosted Slack-alternative",
Long: `Mattermost offers workplace messaging across web, PC and phones with archiving, search and integration with your existing systems. Documentation available at https://docs.mattermost.com`,
RunE: runServerCmd,
}
var resetCmd = &cobra.Command{
Use: "reset",
Short: "Reset the database to initial state",
Long: "Completely erases the database causing the loss of all data. This will reset Mattermost to its initial state.",
RunE: resetCmdF,
}
func resetCmdF(cmd *cobra.Command, args []string) error {
a, err := initDBCommandContextCobra(cmd)
if err != nil {
return err
}
confirmFlag, _ := cmd.Flags().GetBool("confirm")
if !confirmFlag {
var confirm string
CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
CommandPrettyPrintln("Are you sure you want to delete everything? All data will be permanently deleted? (YES/NO): ")
fmt.Scanln(&confirm)
if confirm != "YES" {
return errors.New("ABORTED: You did not answer YES exactly, in all capitals.")
}
}
a.Srv.Store.DropAllTables()
CommandPrettyPrintln("Database sucessfully reset")
return nil
}