diff --git a/cmd/user_data.go b/cmd/user_data.go index 6432cc77..939aabfe 100644 --- a/cmd/user_data.go +++ b/cmd/user_data.go @@ -86,6 +86,19 @@ var UserData = &cli.Command{ }, }, }, + { + Name: "send-password-reset-mail", + Usage: "Send password reset mail", + Action: sendPasswordResetMail, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "username", + Aliases: []string{"n"}, + Required: true, + Usage: "Specific user name", + }, + }, + }, { Name: "user-enable", Usage: "Enable specified user", @@ -265,6 +278,26 @@ func modifyUserPassword(c *cli.Context) error { return nil } +func sendPasswordResetMail(c *cli.Context) error { + _, err := initializeSystem(c) + + if err != nil { + return err + } + + username := c.String("username") + err = clis.UserData.SendPasswordResetMail(c, username) + + if err != nil { + log.BootErrorf("[user_data.sendPasswordResetMail] error occurs when sending password reset email") + return err + } + + log.BootInfof("[user_data.sendPasswordResetMail] a password reset email for user \"%s\" has been sent", username) + + return nil +} + func enableUser(c *cli.Context) error { _, err := initializeSystem(c) diff --git a/pkg/cli/user_data.go b/pkg/cli/user_data.go index 0e1a12ec..de63678f 100644 --- a/pkg/cli/user_data.go +++ b/pkg/cli/user_data.go @@ -26,6 +26,7 @@ type UserDataCli struct { users *services.UserService twoFactorAuthorizations *services.TwoFactorAuthorizationService tokens *services.TokenService + forgetPasswords *services.ForgetPasswordService } // Initialize an user data cli singleton instance @@ -39,6 +40,7 @@ var ( users: services.Users, twoFactorAuthorizations: services.TwoFactorAuthorizations, tokens: services.Tokens, + forgetPasswords: services.ForgetPasswords, } ) @@ -161,6 +163,37 @@ func (l *UserDataCli) ModifyUserPassword(c *cli.Context, username string, passwo return nil } +// SendPasswordResetMail sends an email with password reset link +func (l *UserDataCli) SendPasswordResetMail(c *cli.Context, username string) error { + if username == "" { + log.BootErrorf("[user_data.SendPasswordResetMail] user name is empty") + return errs.ErrUsernameIsEmpty + } + + user, err := l.users.GetUserByUsername(username) + + if err != nil { + log.BootErrorf("[user_data.SendPasswordResetMail] failed to get user by user name \"%s\", because %s", username, err.Error()) + return err + } + + token, _, err := l.tokens.CreatePasswordResetToken(user, nil) + + if err != nil { + log.BootErrorf("[user_data.SendPasswordResetMail] failed to create token for user \"uid:%d\", because %s", user.Uid, err.Error()) + return err + } + + err = l.forgetPasswords.SendPasswordResetEmail(user, token) + + if err != nil { + log.BootWarnf("[user_data.SendPasswordResetMail] cannot send email to \"%s\", because %s", user.Email, err.Error()) + return err + } + + return nil +} + // EnableUser sets user enabled according to the specified user name func (l *UserDataCli) EnableUser(c *cli.Context, username string) error { if username == "" {