PLT-2057 User as a first class object (#2648)
* Adding TeamMember to system * Fixing all unit tests on the backend * Fixing merge conflicts * Fixing merge conflict * Adding javascript unit tests * Adding TeamMember to system * Fixing all unit tests on the backend * Fixing merge conflicts * Fixing merge conflict * Adding javascript unit tests * Adding client side unit test * Cleaning up the clint side tests * Fixing msg * Adding more client side unit tests * Adding more using tests * Adding last bit of client side unit tests and adding make cmd * Fixing bad merge * Fixing libraries * Updating to new client side API * Fixing borken unit test * Fixing unit tests * ugg...trying to beat gofmt * ugg...trying to beat gofmt * Cleaning up remainder of the server side routes * Adding inital load api * Increased coverage of webhook unit tests (#2660) * Adding loading ... to root html * Fixing bad merge * Removing explicit content type so superagent will guess corectly (#2685) * Fixing merge and unit tests * Adding create team UI * Fixing signup flows * Adding LDAP unit tests and enterprise unit test helper (#2702) * Add the ability to reset MFA from the commandline (#2706) * Fixing compliance unit tests * Fixing client side tests * Adding open server to system console * Moving websocket connection * Fixing unit test * Fixing unit tests * Fixing unit tests * Adding nickname and more LDAP unit tests (#2717) * Adding join open teams * Cleaning up all TODOs in the code * Fixing web sockets * Removing unused webockets file * PLT-2533 Add the ability to reset a user's MFA from the system console (#2715) * Add the ability to reset a user's MFA from the system console * Add client side unit test for adminResetMfa * Reorganizing authentication to fix LDAP error message (#2723) * Fixing failing unit test * Initial upgrade db code * Adding upgrade script * Fixing upgrade script after running on core * Update OAuth and Claim routes to work with user model changes (#2739) * Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740) * Fixing team invite ldap login call (#2741) * Fixing bluebar and some img stuff * Fix all the different file upload web utils (#2743) * Fixing invalid session redirect (#2744) * Redirect on bad channel name (#2746) * Fixing a bunch of issue and removing dead code * Patch to fix error message on leave channel (#2747) * Setting EnableOpenServer to false by default * Fixing config * Fixing upgrade * Fixing reported bugs * Bug fixes for PLT-2057 * PLT-2563 Redo password recovery to use a database table (#2745) * Redo password recovery to use a database table * Update reset password audits * Split out admin and user reset password APIs to be separate * Delete password recovery when user is permanently deleted * Consolidate password resetting into a single function * Removed private channels as an option for outgoing webhooks (#2752) * PLT-2577/PLT-2552 Fixes for backstage (#2753) * Added URL to incoming webhook list * Fixed client functions for adding/removing integrations * Disallowed slash commands without trigger words * Fixed clientside handling of errors on AddCommand page * Minor auth cleanup (#2758) * Changed EditPostModal to just close if you save without making any changes (#2759) * Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756) * Fixed url in channel info modal (#2755) * Fixing reported issues * Moving to version 3 of the apis * Fixing command unit tests (#2760) * Adding team admins * Fixing DM issue * Fixing eslint error * Properly set EditPostModal's originalText state in all cases (#2762) * Update client config check to assume features is defined if server is licensed (#2772) * Fixing url link * Fixing issue with websocket crashing when sending messages to different teams
Этот коммит содержится в:
430
mattermost.go
430
mattermost.go
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/mattermost/platform/einterfaces"
|
||||
"github.com/mattermost/platform/manualtesting"
|
||||
"github.com/mattermost/platform/model"
|
||||
"github.com/mattermost/platform/store"
|
||||
"github.com/mattermost/platform/utils"
|
||||
"github.com/mattermost/platform/web"
|
||||
|
||||
@@ -36,13 +37,18 @@ import (
|
||||
|
||||
//ENTERPRISE_IMPORTS
|
||||
|
||||
var flagCmdUpdateDb30 bool
|
||||
var flagCmdCreateTeam bool
|
||||
var flagCmdCreateUser bool
|
||||
var flagCmdAssignRole bool
|
||||
var flagCmdVersion bool
|
||||
var flagCmdResetPassword bool
|
||||
var flagCmdResetMfa bool
|
||||
var flagCmdPermanentDeleteUser bool
|
||||
var flagCmdPermanentDeleteTeam bool
|
||||
var flagCmdPermanentDeleteAllUsers bool
|
||||
var flagCmdResetDatabase bool
|
||||
var flagUsername string
|
||||
var flagCmdUploadLicense bool
|
||||
var flagConfigFile string
|
||||
var flagLicenseFile string
|
||||
@@ -69,6 +75,10 @@ func main() {
|
||||
l4g.Info(utils.T("mattermost.working_dir"), pwd)
|
||||
l4g.Info(utils.T("mattermost.config_file"), utils.FindConfigFile(flagConfigFile))
|
||||
|
||||
// Speical case for upgrading the db to 3.0
|
||||
// ADDED for 3.0 REMOVE for 3.4
|
||||
cmdUpdateDb30()
|
||||
|
||||
api.NewServer()
|
||||
api.InitApi()
|
||||
web.InitWeb()
|
||||
@@ -223,19 +233,24 @@ func parseCmds() {
|
||||
}
|
||||
|
||||
flag.StringVar(&flagConfigFile, "config", "config.json", "")
|
||||
flag.StringVar(&flagUsername, "username", "", "")
|
||||
flag.StringVar(&flagLicenseFile, "license", "", "")
|
||||
flag.StringVar(&flagEmail, "email", "", "")
|
||||
flag.StringVar(&flagPassword, "password", "", "")
|
||||
flag.StringVar(&flagTeamName, "team_name", "", "")
|
||||
flag.StringVar(&flagRole, "role", "", "")
|
||||
|
||||
flag.BoolVar(&flagCmdUpdateDb30, "upgrade_db_30", false, "")
|
||||
flag.BoolVar(&flagCmdCreateTeam, "create_team", false, "")
|
||||
flag.BoolVar(&flagCmdCreateUser, "create_user", false, "")
|
||||
flag.BoolVar(&flagCmdAssignRole, "assign_role", false, "")
|
||||
flag.BoolVar(&flagCmdVersion, "version", false, "")
|
||||
flag.BoolVar(&flagCmdResetPassword, "reset_password", false, "")
|
||||
flag.BoolVar(&flagCmdResetMfa, "reset_mfa", false, "")
|
||||
flag.BoolVar(&flagCmdPermanentDeleteUser, "permanent_delete_user", false, "")
|
||||
flag.BoolVar(&flagCmdPermanentDeleteTeam, "permanent_delete_team", false, "")
|
||||
flag.BoolVar(&flagCmdPermanentDeleteAllUsers, "permanent_delete_all_users", false, "")
|
||||
flag.BoolVar(&flagCmdResetDatabase, "reset_database", false, "")
|
||||
flag.BoolVar(&flagCmdUploadLicense, "upload_license", false, "")
|
||||
|
||||
flag.Parse()
|
||||
@@ -244,9 +259,12 @@ func parseCmds() {
|
||||
flagCmdCreateUser ||
|
||||
flagCmdAssignRole ||
|
||||
flagCmdResetPassword ||
|
||||
flagCmdResetMfa ||
|
||||
flagCmdVersion ||
|
||||
flagCmdPermanentDeleteUser ||
|
||||
flagCmdPermanentDeleteTeam ||
|
||||
flagCmdPermanentDeleteAllUsers ||
|
||||
flagCmdResetDatabase ||
|
||||
flagCmdUploadLicense)
|
||||
}
|
||||
|
||||
@@ -256,11 +274,258 @@ func runCmds() {
|
||||
cmdCreateUser()
|
||||
cmdAssignRole()
|
||||
cmdResetPassword()
|
||||
cmdResetMfa()
|
||||
cmdPermDeleteUser()
|
||||
cmdPermDeleteTeam()
|
||||
cmdPermDeleteAllUsers()
|
||||
cmdResetDatabase()
|
||||
cmdUploadLicense()
|
||||
}
|
||||
|
||||
type TeamForUpgrade struct {
|
||||
Id string
|
||||
Name string
|
||||
}
|
||||
|
||||
// ADDED for 3.0 REMOVE for 3.4
|
||||
func cmdUpdateDb30() {
|
||||
if flagCmdUpdateDb30 {
|
||||
api.Srv = &api.Server{}
|
||||
api.Srv.Store = store.NewSqlStoreForUpgrade30()
|
||||
store := api.Srv.Store.(*store.SqlStore)
|
||||
|
||||
l4g.Info("Attempting to run speical upgrade of the database schema to version 3.0 for user model changes")
|
||||
time.Sleep(time.Second)
|
||||
|
||||
if !store.DoesColumnExist("Users", "TeamId") {
|
||||
fmt.Println("**WARNING** the database schema appears to be upgraded to 3.0")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
if !(store.SchemaVersion == "2.2.0" ||
|
||||
store.SchemaVersion == "2.1.0" ||
|
||||
store.SchemaVersion == "2.0.0") {
|
||||
fmt.Println("**WARNING** the database schema needs to be version 2.2.0, 2.1.0 or 2.0.0 to upgrade")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var confirmBackup string
|
||||
fmt.Println("\nPlease see http://www.mattermost.org/upgrade-to-3-0/")
|
||||
fmt.Println("**WARNING** This upgrade process will be irreversible.")
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Fprintln(os.Stderr, "ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var flagTeamName string
|
||||
var teams []*TeamForUpgrade
|
||||
|
||||
if _, err := store.GetMaster().Select(&teams, "SELECT Id, Name FROM Teams"); err != nil {
|
||||
l4g.Error("Failed to load all teams details=%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
fmt.Println(fmt.Sprintf("We found %v teams.", len(teams)))
|
||||
|
||||
for _, team := range teams {
|
||||
fmt.Println(team.Name)
|
||||
}
|
||||
|
||||
fmt.Print("Please pick a primary team from the list above: ")
|
||||
fmt.Scanln(&flagTeamName)
|
||||
|
||||
var team *TeamForUpgrade
|
||||
for _, t := range teams {
|
||||
if t.Name == flagTeamName {
|
||||
team = t
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if team == nil {
|
||||
l4g.Error("Failed to find primary team details")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
l4g.Info("Starting speical 3.0 database upgrade with performed_backup=YES team_name=%v", team.Name)
|
||||
l4g.Info("Primary team %v will be left unchanged", team.Name)
|
||||
l4g.Info("Upgrading primary team %v", team.Name)
|
||||
|
||||
uniqueEmails := make(map[string]bool)
|
||||
uniqueUsernames := make(map[string]bool)
|
||||
primaryUsers := convertTeamTo30(team, uniqueEmails, uniqueUsernames)
|
||||
|
||||
l4g.Info("Upgraded %v users", len(primaryUsers))
|
||||
|
||||
for _, otherTeam := range teams {
|
||||
if otherTeam.Id != team.Id {
|
||||
l4g.Info("Upgrading team %v", otherTeam.Name)
|
||||
users := convertTeamTo30(otherTeam, uniqueEmails, uniqueUsernames)
|
||||
l4g.Info("Upgraded %v users", len(users))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
l4g.Info("Altering other scheme changes needed 3.0 for user model changes")
|
||||
|
||||
if _, err := store.GetMaster().Exec(`
|
||||
UPDATE Channels
|
||||
SET
|
||||
TeamId = ''
|
||||
WHERE
|
||||
Type = 'D'
|
||||
`,
|
||||
); err != nil {
|
||||
l4g.Error("Failed to update direct channel types details=%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
extraLength := store.GetMaxLengthOfColumnIfExists("Audits", "ExtraInfo")
|
||||
if len(extraLength) > 0 && extraLength != "1024" {
|
||||
store.AlterColumnTypeIfExists("Audits", "ExtraInfo", "VARCHAR(1024)", "VARCHAR(1024)")
|
||||
}
|
||||
|
||||
actionLength := store.GetMaxLengthOfColumnIfExists("Audits", "Action")
|
||||
if len(actionLength) > 0 && actionLength != "512" {
|
||||
store.AlterColumnTypeIfExists("Audits", "Action", "VARCHAR(512)", "VARCHAR(512)")
|
||||
}
|
||||
|
||||
if store.DoesColumnExist("Sessions", "TeamId") {
|
||||
store.RemoveColumnIfExists("Sessions", "TeamId")
|
||||
store.GetMaster().Exec(`TRUNCATE Sessions`)
|
||||
}
|
||||
|
||||
// ADDED for 2.2 REMOVE for 2.6
|
||||
store.CreateColumnIfNotExists("Users", "MfaActive", "tinyint(1)", "boolean", "0")
|
||||
store.CreateColumnIfNotExists("Users", "MfaSecret", "varchar(128)", "character varying(128)", "")
|
||||
|
||||
// ADDED for 2.2 REMOVE for 2.6
|
||||
if store.DoesColumnExist("Users", "TeamId") {
|
||||
store.RemoveIndexIfExists("idx_users_team_id", "Users")
|
||||
store.CreateUniqueIndexIfNotExists("idx_users_email_unique", "Users", "Email")
|
||||
store.CreateUniqueIndexIfNotExists("idx_users_username_unique", "Users", "Username")
|
||||
store.RemoveColumnIfExists("Teams", "AllowTeamListing")
|
||||
store.RemoveColumnIfExists("Users", "TeamId")
|
||||
}
|
||||
|
||||
l4g.Info("Finished running speical upgrade of the database schema to version 3.0 for user model changes")
|
||||
|
||||
if result := <-store.System().Update(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil {
|
||||
l4g.Error("Failed to update system schema version details=%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
l4g.Info(utils.T("store.sql.upgraded.warn"), model.CurrentVersion)
|
||||
fmt.Println("**SUCCESS** with upgrade")
|
||||
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
|
||||
type UserForUpgrade struct {
|
||||
Id string
|
||||
Username string
|
||||
Email string
|
||||
Roles string
|
||||
TeamId string
|
||||
}
|
||||
|
||||
func convertTeamTo30(team *TeamForUpgrade, uniqueEmails map[string]bool, uniqueUsernames map[string]bool) []*UserForUpgrade {
|
||||
store := api.Srv.Store.(*store.SqlStore)
|
||||
var users []*UserForUpgrade
|
||||
if _, err := store.GetMaster().Select(&users, "SELECT Users.Id, Users.Username, Users.Email, Users.Roles, Users.TeamId FROM Users WHERE Users.TeamId = :TeamId", map[string]interface{}{"TeamId": team.Id}); err != nil {
|
||||
l4g.Error("Failed to load profiles for team details=%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var members []*model.TeamMember
|
||||
if result := <-api.Srv.Store.Team().GetMembers(team.Id); result.Err != nil {
|
||||
l4g.Error("Failed to load team membership details=%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
members = result.Data.([]*model.TeamMember)
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
shouldUpdateUser := false
|
||||
previousRole := user.Roles
|
||||
previousEmail := user.Email
|
||||
previousUsername := user.Username
|
||||
|
||||
member := &model.TeamMember{
|
||||
TeamId: team.Id,
|
||||
UserId: user.Id,
|
||||
}
|
||||
|
||||
if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) {
|
||||
member.Roles = model.ROLE_TEAM_ADMIN
|
||||
user.Roles = ""
|
||||
shouldUpdateUser = true
|
||||
}
|
||||
|
||||
exists := false
|
||||
for _, member := range members {
|
||||
if member.UserId == user.Id {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
if result := <-api.Srv.Store.Team().SaveMember(member); result.Err != nil {
|
||||
l4g.Error("Failed to save membership for %v details=%v", user.Email, result.Err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if uniqueEmails[user.Email] {
|
||||
shouldUpdateUser = true
|
||||
emailParts := strings.Split(user.Email, "@")
|
||||
if len(emailParts) == 2 {
|
||||
user.Email = emailParts[0] + "+" + team.Name + "@" + emailParts[1]
|
||||
} else {
|
||||
user.Email = user.Email + "." + team.Name
|
||||
}
|
||||
}
|
||||
|
||||
if uniqueUsernames[user.Username] {
|
||||
shouldUpdateUser = true
|
||||
user.Username = user.Username + "." + team.Name
|
||||
}
|
||||
|
||||
if shouldUpdateUser {
|
||||
if _, err := store.GetMaster().Exec(`
|
||||
UPDATE Users
|
||||
SET
|
||||
Email = :Email,
|
||||
Username = :Username,
|
||||
Roles = :Roles
|
||||
WHERE
|
||||
Id = :Id
|
||||
`,
|
||||
map[string]interface{}{
|
||||
"Email": user.Email,
|
||||
"Username": user.Username,
|
||||
"Roles": user.Roles,
|
||||
"Id": user.Id,
|
||||
},
|
||||
); err != nil {
|
||||
l4g.Error("Failed to update user %v details=%v", user.Email, err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
l4g.Info("modified user_id=%v, changed email from=%v to=%v, changed username from=%v to %v changed roles from=%v to=%v", user.Id, previousEmail, user.Email, previousUsername, user.Username, previousRole, user.Roles)
|
||||
}
|
||||
|
||||
uniqueEmails[user.Email] = true
|
||||
uniqueUsernames[user.Username] = true
|
||||
}
|
||||
|
||||
return users
|
||||
}
|
||||
|
||||
func cmdCreateTeam() {
|
||||
if flagCmdCreateTeam {
|
||||
if len(flagTeamName) == 0 {
|
||||
@@ -327,10 +592,9 @@ func cmdCreateUser() {
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
user.TeamId = team.Id
|
||||
}
|
||||
|
||||
_, err := api.CreateUser(team, user)
|
||||
ruser, err := api.CreateUser(user)
|
||||
if err != nil {
|
||||
if err.Id != "store.sql_user.save.email_exists.app_error" {
|
||||
l4g.Error("%v", err)
|
||||
@@ -338,6 +602,12 @@ func cmdCreateUser() {
|
||||
}
|
||||
}
|
||||
|
||||
err = api.JoinUserToTeam(team, ruser)
|
||||
if err != nil {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
@@ -368,7 +638,7 @@ func cmdAssignRole() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !model.IsValidRoles(flagRole) {
|
||||
if !model.IsValidUserRoles(flagRole) {
|
||||
fmt.Fprintln(os.Stderr, "flag invalid argument: -role")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
@@ -376,16 +646,8 @@ func cmdAssignRole() {
|
||||
|
||||
c := getMockContext()
|
||||
|
||||
var team *model.Team
|
||||
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
@@ -426,16 +688,8 @@ func cmdResetPassword() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var team *model.Team
|
||||
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
@@ -451,14 +705,42 @@ func cmdResetPassword() {
|
||||
}
|
||||
}
|
||||
|
||||
func cmdPermDeleteUser() {
|
||||
if flagCmdPermanentDeleteUser {
|
||||
if len(flagTeamName) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -team_name")
|
||||
func cmdResetMfa() {
|
||||
if flagCmdResetMfa {
|
||||
if len(flagEmail) == 0 && len(flagUsername) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -email OR -username")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if len(flagEmail) > 0 {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
} else {
|
||||
if result := <-api.Srv.Store.User().GetByUsername(flagUsername); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
}
|
||||
|
||||
if err := api.DeactivateMfa(user.Id); err != nil {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdPermDeleteUser() {
|
||||
if flagCmdPermanentDeleteUser {
|
||||
if len(flagEmail) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -email")
|
||||
flag.Usage()
|
||||
@@ -467,16 +749,8 @@ func cmdPermDeleteUser() {
|
||||
|
||||
c := getMockContext()
|
||||
|
||||
var team *model.Team
|
||||
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
team = result.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
|
||||
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
|
||||
l4g.Error("%v", result.Err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
@@ -487,6 +761,7 @@ func cmdPermDeleteUser() {
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
@@ -494,6 +769,7 @@ func cmdPermDeleteUser() {
|
||||
fmt.Printf("Are you sure you want to delete the user %v? All data will be permanently deleted? (YES/NO): ", user.Email)
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
@@ -501,6 +777,7 @@ func cmdPermDeleteUser() {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
fmt.Print("SUCCESS: User deleted.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
@@ -528,6 +805,7 @@ func cmdPermDeleteTeam() {
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
@@ -535,6 +813,7 @@ func cmdPermDeleteTeam() {
|
||||
fmt.Printf("Are you sure you want to delete the team %v? All data will be permanently deleted? (YES/NO): ", team.Name)
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
@@ -542,11 +821,67 @@ func cmdPermDeleteTeam() {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
fmt.Print("SUCCESS: Team deleted.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cmdPermDeleteAllUsers() {
|
||||
if flagCmdPermanentDeleteAllUsers {
|
||||
c := getMockContext()
|
||||
|
||||
var confirmBackup string
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var confirm string
|
||||
fmt.Printf("Are you sure you want to delete all the users? All data will be permanently deleted? (YES/NO): ")
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
if err := api.PermanentDeleteAllUsers(c); err != nil {
|
||||
l4g.Error("%v", err)
|
||||
flushLogAndExit(1)
|
||||
} else {
|
||||
fmt.Print("SUCCESS: All users deleted.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cmdResetDatabase() {
|
||||
if flagCmdResetDatabase {
|
||||
var confirmBackup string
|
||||
fmt.Print("Have you performed a database backup? (YES/NO): ")
|
||||
fmt.Scanln(&confirmBackup)
|
||||
if confirmBackup != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
var confirm string
|
||||
fmt.Printf("Are you sure you want to delete everything? ALL data will be permanently deleted? (YES/NO): ")
|
||||
fmt.Scanln(&confirm)
|
||||
if confirm != "YES" {
|
||||
fmt.Print("ABORTED: You did not answer YES exactly, in all capitals.")
|
||||
flushLogAndExit(1)
|
||||
}
|
||||
|
||||
api.Srv.Store.DropAllTables()
|
||||
fmt.Print("SUCCESS: Database reset.")
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func cmdUploadLicense() {
|
||||
if flagCmdUploadLicense {
|
||||
if model.BuildEnterpriseReady != "true" {
|
||||
@@ -574,7 +909,7 @@ func cmdUploadLicense() {
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
flushLogAndExit(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,6 +939,8 @@ USAGE:
|
||||
FLAGS:
|
||||
-config="config.json" Path to the config file
|
||||
|
||||
-username="someuser" Username used in other commands
|
||||
|
||||
-license="ex.mattermost-license" Path to your license file
|
||||
|
||||
-email="user@example.com" Email address used in other commands
|
||||
@@ -644,14 +981,33 @@ COMMANDS:
|
||||
Example:
|
||||
platform -reset_password -team_name="name" -email="user@example.com" -password="newpassword"
|
||||
|
||||
-reset_mfa Turns off multi-factor authentication for a user. It requires the
|
||||
-email or -username flag.
|
||||
Example:
|
||||
platform -reset_mfa -username="someuser"
|
||||
|
||||
-reset_database Completely erases the database causing the loss of all data. This
|
||||
will reset Mattermost to it's initial state. (note this will not
|
||||
erase your configuration.)
|
||||
|
||||
Example:
|
||||
platform -reset_mfa -username="someuser"
|
||||
|
||||
-permanent_delete_user Permanently deletes a user and all related information
|
||||
including posts from the database. It requires the
|
||||
-email flag. You may need to restart the
|
||||
server to invalidate the cache
|
||||
Example:
|
||||
platform -permanent_delete_user -email="user@example.com"
|
||||
|
||||
-permanent_delete_all_users Permanently deletes all users and all related information
|
||||
including posts from the database. It requires the
|
||||
-team_name, and -email flag. You may need to restart the
|
||||
server to invalidate the cache
|
||||
Example:
|
||||
platform -permanent_delete_user -team_name="name" -email="user@example.com"
|
||||
platform -permanent_delete_all_users -team_name="name" -email="user@example.com"
|
||||
|
||||
-permanent_delete_team Permanently deletes a team and all users along with
|
||||
-permanent_delete_team Permanently deletes a team allong with
|
||||
all related information including posts from the database.
|
||||
It requires the -team_name flag. You may need to restart
|
||||
the server to invalidate the cache.
|
||||
|
||||
Ссылка в новой задаче
Block a user