mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-06 06:40:27 +08:00
155 lines
3.8 KiB
Go
155 lines
3.8 KiB
Go
|
|
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|||
|
|
|
|||
|
|
package index
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"encoding/json"
|
|||
|
|
"fmt"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
|||
|
|
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/setup"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
|||
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
|||
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
|||
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|||
|
|
"github.com/iwind/TeaGo/actions"
|
|||
|
|
"github.com/iwind/TeaGo/maps"
|
|||
|
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
|||
|
|
"github.com/xlzd/gotp"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type OtpAction struct {
|
|||
|
|
actionutils.ParentAction
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (this *OtpAction) Init() {
|
|||
|
|
this.Nav("", "", "")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (this *OtpAction) RunGet(params struct {
|
|||
|
|
From string
|
|||
|
|
Sid string
|
|||
|
|
Remember bool
|
|||
|
|
}) {
|
|||
|
|
// 检查系统是否已经配置过
|
|||
|
|
if !setup.IsConfigured() {
|
|||
|
|
this.RedirectURL("/setup")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//// 是否新安装
|
|||
|
|
if setup.IsNewInstalled() {
|
|||
|
|
this.RedirectURL("/setup/confirm")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.Data["isUser"] = false
|
|||
|
|
this.Data["menu"] = "signIn"
|
|||
|
|
|
|||
|
|
var timestamp = fmt.Sprintf("%d", time.Now().Unix())
|
|||
|
|
this.Data["token"] = stringutil.Md5(TokenKey+timestamp) + timestamp
|
|||
|
|
this.Data["from"] = params.From
|
|||
|
|
this.Data["sid"] = params.Sid
|
|||
|
|
|
|||
|
|
uiConfig, err := configloaders.LoadAdminUIConfig()
|
|||
|
|
if err != nil {
|
|||
|
|
this.ErrorPage(err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
this.Data["systemName"] = uiConfig.AdminSystemName
|
|||
|
|
this.Data["showVersion"] = uiConfig.ShowVersion
|
|||
|
|
if len(uiConfig.Version) > 0 {
|
|||
|
|
this.Data["version"] = uiConfig.Version
|
|||
|
|
} else {
|
|||
|
|
this.Data["version"] = teaconst.Version
|
|||
|
|
}
|
|||
|
|
this.Data["faviconFileId"] = uiConfig.FaviconFileId
|
|||
|
|
this.Data["remember"] = params.Remember
|
|||
|
|
|
|||
|
|
this.Show()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (this *OtpAction) RunPost(params struct {
|
|||
|
|
Sid string
|
|||
|
|
OtpCode string
|
|||
|
|
Remember bool
|
|||
|
|
|
|||
|
|
Must *actions.Must
|
|||
|
|
Auth *helpers.UserShouldAuth
|
|||
|
|
}) {
|
|||
|
|
if len(params.OtpCode) == 0 {
|
|||
|
|
this.FailField("otpCode", "请输入正确的OTP动态密码")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var sid = params.Sid
|
|||
|
|
if len(sid) == 0 || len(sid) > 64 {
|
|||
|
|
this.Fail("参数错误,请重新登录(001)")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
sid += "_otp"
|
|||
|
|
|
|||
|
|
// 获取SESSION
|
|||
|
|
sessionResp, err := this.RPC().LoginSessionRPC().FindLoginSession(this.AdminContext(), &pb.FindLoginSessionRequest{Sid: sid})
|
|||
|
|
if err != nil {
|
|||
|
|
this.ErrorPage(err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
var session = sessionResp.LoginSession
|
|||
|
|
if session == nil || session.AdminId <= 0 {
|
|||
|
|
this.Fail("参数错误,请重新登录(002)")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
var adminId = session.AdminId
|
|||
|
|
|
|||
|
|
// 检查OTP
|
|||
|
|
otpLoginResp, err := this.RPC().LoginRPC().FindEnabledLogin(this.AdminContext(), &pb.FindEnabledLoginRequest{
|
|||
|
|
AdminId: adminId,
|
|||
|
|
Type: "otp",
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
this.ErrorPage(err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if otpLoginResp.Login != nil && otpLoginResp.Login.IsOn {
|
|||
|
|
var loginParams = maps.Map{}
|
|||
|
|
err = json.Unmarshal(otpLoginResp.Login.ParamsJSON, &loginParams)
|
|||
|
|
if err != nil {
|
|||
|
|
this.ErrorPage(err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
var secret = loginParams.GetString("secret")
|
|||
|
|
if gotp.NewDefaultTOTP(secret).Now() != params.OtpCode {
|
|||
|
|
this.FailField("otpCode", "请输入正确的OTP动态密码")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 写入SESSION
|
|||
|
|
params.Auth.StoreAdmin(adminId, params.Remember)
|
|||
|
|
|
|||
|
|
// 删除OTP SESSION
|
|||
|
|
_, err = this.RPC().LoginSessionRPC().DeleteLoginSession(this.AdminContext(), &pb.DeleteLoginSessionRequest{Sid: sid})
|
|||
|
|
if err != nil {
|
|||
|
|
this.ErrorPage(err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录日志
|
|||
|
|
rpcClient, err := rpc.SharedRPC()
|
|||
|
|
if err != nil {
|
|||
|
|
this.ErrorPage(err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
err = dao.SharedLogDAO.CreateAdminLog(rpcClient.Context(adminId), oplogs.LevelInfo, this.Request.URL.Path, "成功通过OTP验证登录系统", this.RequestRemoteIP())
|
|||
|
|
if err != nil {
|
|||
|
|
utils.PrintError(err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.Success()
|
|||
|
|
}
|