summaryrefslogtreecommitdiffstats
path: root/cmd/platform/user.go
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2016-12-06 10:49:34 -0500
committerGitHub <noreply@github.com>2016-12-06 10:49:34 -0500
commit026553e4f87bfc647a5c03129752e30fc523fa07 (patch)
treed5403c760151c0fa26fc6d020f7f4326ea9d6f8a /cmd/platform/user.go
parentdcf11a14d8363c79ab62aefca46834d6daa615ab (diff)
downloadchat-026553e4f87bfc647a5c03129752e30fc523fa07.tar.gz
chat-026553e4f87bfc647a5c03129752e30fc523fa07.tar.bz2
chat-026553e4f87bfc647a5c03129752e30fc523fa07.zip
Improving command line interface (#4689)
Diffstat (limited to 'cmd/platform/user.go')
-rw-r--r--cmd/platform/user.go432
1 files changed, 432 insertions, 0 deletions
diff --git a/cmd/platform/user.go b/cmd/platform/user.go
new file mode 100644
index 000000000..43a00e68d
--- /dev/null
+++ b/cmd/platform/user.go
@@ -0,0 +1,432 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+package main
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/mattermost/platform/api"
+ "github.com/mattermost/platform/einterfaces"
+ "github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
+ "github.com/spf13/cobra"
+)
+
+var userCmd = &cobra.Command{
+ Use: "user",
+ Short: "Management of users",
+}
+
+var userActivateCmd = &cobra.Command{
+ Use: "activate [emails, usernames, userIds]",
+ Short: "Activate users",
+ Long: "Activate users that have been deactivated.",
+ Example: ` user activate user@example.com
+ user activate username`,
+ RunE: userActivateCmdF,
+}
+
+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.",
+ Example: ` user deactivate user@example.com
+ user deactivate username`,
+ RunE: userDeactivateCmdF,
+}
+
+var userCreateCmd = &cobra.Command{
+ Use: "create",
+ Short: "Create a user",
+ Long: "Create a user",
+ Example: ` user create --email user@example.com --username userexample --password Password1
+ user create --firstname Joe --system_admin --email joe@example.com --username joe --password Password1`,
+ RunE: userCreateCmdF,
+}
+
+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.
+You can invite a user to multiple teams by listing them.
+You can specify teams by name or ID.`,
+ Example: ` user invite user@example.com myteam
+ user invite user@example.com myteam1 myteam2`,
+ RunE: userInviteCmdF,
+}
+
+var resetUserPasswordCmd = &cobra.Command{
+ Use: "password [user] [password]",
+ Short: "Set a user's password",
+ Long: "Set a user's password",
+ Example: " user password user@example.com Password1",
+ RunE: resetUserPasswordCmdF,
+}
+
+var resetUserMfaCmd = &cobra.Command{
+ Use: "resetmfa [users]",
+ Short: "Turn off MFA",
+ Long: `Turn off multi-factor authentication for a user.
+If MFA enforcement is enabled, the user will be forced to re-enable MFA as soon as they login.`,
+ Example: " user resetmfa user@example.com",
+ RunE: resetUserMfaCmdF,
+}
+
+var deleteUserCmd = &cobra.Command{
+ Use: "delete [users]",
+ Short: "Delete users and all posts",
+ Long: "Permanently delete user and all related information including posts.",
+ Example: " user delete user@example.com",
+ RunE: deleteUserCmdF,
+}
+
+var deleteAllUsersCmd = &cobra.Command{
+ Use: "deleteall",
+ Short: "Delete all users and all posts",
+ Long: "Permanently delete all users and all related information including posts.",
+ Example: " user deleteall",
+ RunE: deleteUserCmdF,
+}
+
+var migrateAuthCmd = &cobra.Command{
+ Use: "migrate_auth [from_auth] [to_auth] [match_field]",
+ 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.
+
+from_auth:
+ The authentication service to migrate users accounts from.
+ Supported options: email, gitlab, saml.
+
+to_auth:
+ The authentication service to migrate users to.
+ Supported options: ldap.
+
+match_field:
+ The field that is guaranteed to be the same in both authentication services. For example, if the users emails are consistent set to email.
+ Supported options: email, username.
+
+Will display any accounts that are not migrated successfully.`,
+ Example: " user migrate_auth email ladp email",
+ RunE: migrateAuthCmdF,
+}
+
+var verifyUserCmd = &cobra.Command{
+ Use: "verify [users]",
+ Short: "Verify email of users",
+ Long: "Verify the emails of some users.",
+ Example: " user verify user1",
+ RunE: verifyUserCmdF,
+}
+
+func init() {
+ userCreateCmd.Flags().String("username", "", "Username")
+ userCreateCmd.Flags().String("email", "", "Email")
+ userCreateCmd.Flags().String("password", "", "Password")
+ userCreateCmd.Flags().String("nickname", "", "Nickname")
+ userCreateCmd.Flags().String("firstname", "", "First Name")
+ userCreateCmd.Flags().String("lastname", "", "Last Name")
+ userCreateCmd.Flags().String("locale", "", "Locale (ex: en, fr)")
+ userCreateCmd.Flags().Bool("system_admin", false, "Make the user a system administrator")
+
+ 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.")
+
+ userCmd.AddCommand(
+ userActivateCmd,
+ userDeactivateCmd,
+ userCreateCmd,
+ userInviteCmd,
+ resetUserPasswordCmd,
+ resetUserMfaCmd,
+ deleteUserCmd,
+ deleteAllUsersCmd,
+ migrateAuthCmd,
+ verifyUserCmd,
+ )
+}
+
+func userActivateCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+
+ if len(args) < 1 {
+ return errors.New("Enter user(s) to activate.")
+ }
+
+ changeUsersActiveStatus(args, true)
+ return nil
+}
+
+func changeUsersActiveStatus(userArgs []string, active bool) {
+ users := getUsersFromUserArgs(userArgs)
+ for i, user := range users {
+ changeUserActiveStatus(user, userArgs[i], active)
+ }
+}
+
+func changeUserActiveStatus(user *model.User, userArg string, activate bool) {
+ if user == nil {
+ CommandPrintErrorln("Can't find user '" + userArg + "'")
+ return
+ }
+ if user.IsLDAPUser() {
+ CommandPrintErrorln(utils.T("api.user.update_active.no_deactivate_ldap.app_error"))
+ return
+ }
+ if _, err := api.UpdateActive(user, activate); err != nil {
+ CommandPrintErrorln("Unable to change activation status of user: " + userArg)
+ }
+}
+
+func userDeactivateCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+
+ if len(args) < 1 {
+ return errors.New("Enter user(s) to deactivate.")
+ }
+
+ changeUsersActiveStatus(args, false)
+ return nil
+}
+
+func userCreateCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ username, erru := cmd.Flags().GetString("username")
+ if erru != nil || username == "" {
+ return errors.New("Username is required")
+ }
+ email, erre := cmd.Flags().GetString("email")
+ if erre != nil || email == "" {
+ return errors.New("Email is required")
+ }
+ password, errp := cmd.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")
+ system_admin, _ := cmd.Flags().GetBool("system_admin")
+
+ user := &model.User{
+ Username: username,
+ Email: email,
+ Password: password,
+ Nickname: nickname,
+ FirstName: firstname,
+ LastName: lastname,
+ Locale: locale,
+ }
+
+ ruser, err := api.CreateUser(user)
+ if err != nil {
+ return errors.New("Unable to create user. Error: " + err.Error())
+ }
+
+ if system_admin {
+ api.UpdateUserRoles(ruser, "system_user system_admin")
+ }
+
+ CommandPrettyPrintln("Created User")
+
+ return nil
+}
+
+func userInviteCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ utils.InitHTML()
+
+ if len(args) < 2 {
+ return errors.New("Not enough arguments.")
+ }
+
+ email := args[0]
+ if !model.IsValidEmail(email) {
+ return errors.New("Invalid email")
+ }
+
+ teams := getTeamsFromTeamArgs(args[1:])
+ for i, team := range teams {
+ inviteUser(email, team, args[i+1])
+ }
+
+ return nil
+}
+
+func inviteUser(email string, team *model.Team, teamArg string) {
+ invites := []string{email}
+ if team == nil {
+ CommandPrintErrorln("Can't find team '" + teamArg + "'")
+ return
+ }
+ api.InviteMembers(team, "Administrator", invites)
+ CommandPrettyPrintln("Invites may or may not have been sent.")
+}
+
+func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ if len(args) != 2 {
+ return errors.New("Incorect number of arguments.")
+ }
+
+ user := getUserFromUserArg(args[0])
+ if user == nil {
+ return errors.New("Unable to find user '" + args[0] + "'")
+ }
+ password := args[1]
+
+ if result := <-api.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(password)); result.Err != nil {
+ return result.Err
+ }
+
+ return nil
+}
+
+func resetUserMfaCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ if len(args) < 1 {
+ return errors.New("Enter at least one user.")
+ }
+
+ users := getUsersFromUserArgs(args)
+
+ for i, user := range users {
+ if user == nil {
+ return errors.New("Unable to find user '" + args[i] + "'")
+ }
+
+ if err := api.DeactivateMfa(user.Id); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func deleteUserCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ if len(args) < 1 {
+ return errors.New("Enter at least one user.")
+ }
+
+ 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 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.")
+ }
+ }
+
+ users := getUsersFromUserArgs(args)
+
+ for i, user := range users {
+ if user == nil {
+ return errors.New("Unable to find user '" + args[i] + "'")
+ }
+
+ if err := api.PermanentDeleteUser(user); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ if len(args) > 0 {
+ return errors.New("Don't enter any agruments.")
+ }
+
+ 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 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.")
+ }
+ }
+
+ if err := api.PermanentDeleteAllUsers(); err != nil {
+ return err
+ } else {
+ CommandPrettyPrintln("Sucsessfull. All users deleted.")
+ }
+
+ return nil
+}
+
+func migrateAuthCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ if len(args) != 3 {
+ return errors.New("Enter the correct number of arguments.")
+ }
+
+ fromAuth := args[0]
+ toAuth := args[1]
+ matchField := args[2]
+
+ if len(fromAuth) == 0 || (fromAuth != "email" && fromAuth != "gitlab" && fromAuth != "saml") {
+ return errors.New("Invalid from_auth argument")
+ }
+
+ if len(toAuth) == 0 || toAuth != "ldap" {
+ return errors.New("Invalid to_auth argument")
+ }
+
+ // Email auth in Mattermost system is represented by ""
+ if fromAuth == "email" {
+ fromAuth = ""
+ }
+
+ if len(matchField) == 0 || (matchField != "email" && matchField != "username") {
+ return errors.New("Invalid match_field argument")
+ }
+
+ if migrate := einterfaces.GetAccountMigrationInterface(); migrate != nil {
+ if err := migrate.MigrateToLdap(fromAuth, matchField); err != nil {
+ return errors.New("Error while migrating users: " + err.Error())
+ } else {
+ CommandPrettyPrintln("Sucessfully migrated accounts.")
+ }
+ }
+
+ return nil
+}
+
+func verifyUserCmdF(cmd *cobra.Command, args []string) error {
+ initDBCommandContextCobra(cmd)
+ if len(args) < 1 {
+ return errors.New("Enter at least one user.")
+ }
+
+ users := getUsersFromUserArgs(args)
+
+ for i, user := range users {
+ if user == nil {
+ CommandPrintErrorln("Unable to find user '" + args[i] + "'")
+ }
+ if cresult := <-api.Srv.Store.User().VerifyEmail(user.Id); cresult.Err != nil {
+ CommandPrintErrorln("Unable to verify '" + args[i] + "' email. Error: " + cresult.Err.Error())
+ }
+ }
+
+ return nil
+}