2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 04:22:33 +08:00

feat: 2fa命令行

This commit is contained in:
2025-05-14 04:21:17 +08:00
parent daccf651b6
commit 896e242827
3 changed files with 52 additions and 1 deletions

View File

@@ -145,7 +145,7 @@ func (r *userRepo) UpdateTwoFA(id uint, code, secret string) error {
}
// 保存前先验证一次,防止错误开启
if !totp.Validate(code, secret) {
if secret != "" && !totp.Validate(code, secret) {
return errors.New(r.t.Get("invalid 2fa code"))
}

View File

@@ -75,6 +75,11 @@ func (route *Cli) Commands() []*cli.Command {
Usage: route.t.Get("Change user password"),
Action: route.cli.UserPassword,
},
{
Name: "2fa",
Usage: route.t.Get("Change user 2FA"),
Action: route.cli.UserTwoFA,
},
},
},
{

View File

@@ -1,10 +1,13 @@
package service
import (
"bufio"
"context"
"errors"
"fmt"
stdos "os"
"path/filepath"
"strings"
"time"
"github.com/go-rat/utils/collect"
@@ -260,6 +263,49 @@ func (s *CliService) UserPassword(ctx context.Context, cmd *cli.Command) error {
return nil
}
func (s *CliService) UserTwoFA(ctx context.Context, cmd *cli.Command) error {
user := new(biz.User)
username := cmd.Args().Get(0)
if username == "" {
return errors.New(s.t.Get("Username cannot be empty"))
}
if err := s.db.Where("username", username).First(user).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New(s.t.Get("User not exists"))
} else {
return errors.New(s.t.Get("Failed to get user: %v", err))
}
}
// 已开启关闭2FA
if user.TwoFA != "" {
user.TwoFA = ""
if err := s.db.Save(user).Error; err != nil {
return errors.New(s.t.Get("Failed to change 2FA status: %v", err))
}
fmt.Println(s.t.Get("2FA disabled for user %s", username))
return nil
}
// 未开启开启2FA
_, url, secret, err := s.userRepo.GenerateTwoFA(user.ID)
if err != nil {
return errors.New(s.t.Get("Failed to generate 2FA: %v", err))
}
fmt.Println(s.t.Get("2FA url: %s", url))
reader := bufio.NewReader(stdos.Stdin)
fmt.Print(s.t.Get("Please enter the 2FA code: "))
code, err := reader.ReadString('\n')
if err != nil {
return errors.New(s.t.Get("Failed to read input: %v", err))
}
if err = s.userRepo.UpdateTwoFA(user.ID, strings.TrimSpace(code), secret); err != nil {
return errors.New(s.t.Get("Failed to update 2FA: %v", err))
}
return nil
}
func (s *CliService) HTTPSOn(ctx context.Context, cmd *cli.Command) error {
config := new(types.PanelConfig)
raw, err := io.Read("/usr/local/etc/panel/config.yml")