You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

166 lines
4.6 KiB

package app
import (
"os"
"runtime"
"strings"
"github.com/grvlle/constellation_wallet/backend/models"
"golang.org/x/crypto/bcrypt"
)
// LoginError 获取一个字符串并将其作为 error 推送到登录屏幕
func (a *WalletApplication) LoginError(errMsg string) {
if errMsg != "" {
a.RT.Events.Emit("login_error", errMsg, true)
}
}
// Login 当用户使用 wallet 对象登录时,FE 会调用 Login 已在数据库中
func (a *WalletApplication) Login(keystorePath, keystorePassword, keyPassword, alias string) bool {
alias = strings.ToLower(alias)
a.wallet = models.Wallet{
KeyStorePath: keystorePath,
WalletAlias: alias}
if runtime.GOOS == "windows" && !a.javaInstalled() {
a.LoginError("无法检测到 Java 路径。请确保已安装 Java。")
return false
}
if !a.TransactionFinished {
a.log.Warn("在待处理交易期间无法登录其他钱包。")
a.LoginError("在待处理交易期间无法登录其他钱包。")
return false
}
if keystorePath == "" {
a.LoginError("请提供 KeyStore 文件的路径。")
return false
}
if !a.passwordsProvided(keystorePassword, keyPassword, alias) {
a.log.Warnln("未提供一个或多个密码。")
return false
}
_ = os.Setenv("CL_STOREPASS", keystorePassword)
_ = os.Setenv("CL_KEYPASS", keyPassword)
if err := a.DB.First(&a.wallet, "wallet_alias = ?", alias).Error; err != nil {
a.log.Errorln("无法查询现有钱包的数据库对象。原因: ", err)
return a.ImportWallet(keystorePath, keystorePassword, keyPassword, alias)
}
if !a.WalletKeystoreAccess() {
a.LoginError("访问被拒绝。请确保您输入了正确的凭据。")
return false
}
if !a.NewUser {
a.DB.Model(&a.wallet).Update("KeystorePath", keystorePath)
a.log.Infoln("PrivateKey path: ", keystorePath)
}
// 根据 DB 中存储的加盐哈希检查密码字符串。还要确保已访问 KeyStore。
if a.CheckAccess(keystorePassword, a.wallet.KeystorePasswordHash) && a.CheckAccess(keyPassword, a.wallet.KeyPasswordHash) && a.KeyStoreAccess {
a.UserLoggedIn = true
// os.Setenv("CL_STOREPASS", keystorePassword)
// os.Setenv("CL_KEYPASS", keyPassword)
} else {
a.UserLoggedIn = false
a.LoginError("访问被拒绝。请确保您输入了正确的凭据。")
}
if a.UserLoggedIn && a.KeyStoreAccess && !a.NewUser {
err := a.initWallet(keystorePath)
if err != nil {
a.UserLoggedIn = false
}
}
a.NewUser = false
return a.UserLoggedIn
}
// CheckTermsOfService 从 FE 调用 CheckTermsOfService 以检查 termsOfService 是否已被接受
func (a *WalletApplication) CheckTermsOfService() bool {
return a.wallet.TermsOfService
}
// LogOut 将重置钱包 UI 并清除钱包对象
func (a *WalletApplication) LogOut() bool {
if a.TransactionFinished {
a.UserLoggedIn = false
a.wallet = models.Wallet{}
return true
}
a.sendWarning("Cannot log out while transaction is processing. Please try again.")
return false
}
// ImportKey 在浏览 fs 中查找密钥文件时从前端调用
func (a *WalletApplication) ImportKey() string {
var keyfile = a.RT.Dialog.SelectFile()
if keyfile == "" {
a.LoginError("Access Denied. No key path detected.")
return ""
}
if keyfile[len(keyfile)-4:] != ".p12" {
a.LoginError("Access Denied. Not a key file.")
return ""
}
a.log.Info("Path to imported key: " + keyfile)
return keyfile
}
// SelectDirToStoreKey 在创建新的密钥文件时,从 FE 调用 SelectDirToStoreKey
func (a *WalletApplication) SelectDirToStoreKey() string {
var keyfile = a.RT.Dialog.SelectSaveFile()
if len(keyfile) <= 0 {
a.LoginError("No valid path were provided. Please try again.")
return ""
}
if keyfile[len(keyfile)-4:] != ".p12" {
keyfile = keyfile + ".p12"
return keyfile
}
return keyfile
}
// GenerateSaltedHash 将纯文本转换为加盐哈希
func (a *WalletApplication) GenerateSaltedHash(s string) (string, error) {
saltedBytes := []byte(s)
hashedBytes, err := bcrypt.GenerateFromPassword(saltedBytes, bcrypt.DefaultCost)
if err != nil {
return "", err
}
hash := string(hashedBytes[:])
return hash, nil
}
// CheckAccess 验证用户是否输入了正确的密码
func (a *WalletApplication) CheckAccess(password, passwordHash string) bool {
err := a.Compare(password, passwordHash)
if err != nil {
a.log.Warnln("用户尝试使用错误的凭据登录!")
return false
}
a.log.Infoln("密码检查通过")
return true
}
// Compare 将字符串与加盐哈希进行比较
func (a *WalletApplication) Compare(s, hash string) error {
incoming := []byte(s)
existing := []byte(hash)
return bcrypt.CompareHashAndPassword(existing, incoming)
}