Statefull login with keycard (#1587)
This commit is contained in:
parent
1a47893e75
commit
63dcdd4e94
|
@ -222,14 +222,18 @@ func (m *Manager) SelectAccount(loginParams LoginParams) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.watchAddresses = loginParams.WatchAddresses
|
||||
m.mainAccountAddress = loginParams.MainAccount
|
||||
m.selectedChatAccount = selectedChatAccount
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) SetAccountAddresses(main common.Address, secondary ...common.Address) {
|
||||
m.watchAddresses = []common.Address{main}
|
||||
m.watchAddresses = append(m.watchAddresses, secondary...)
|
||||
m.mainAccountAddress = main
|
||||
}
|
||||
|
||||
// SetChatAccount initializes selectedChatAccount with privKey
|
||||
func (m *Manager) SetChatAccount(privKey *ecdsa.PrivateKey) {
|
||||
m.mu.Lock()
|
||||
|
|
|
@ -189,6 +189,54 @@ func (b *StatusBackend) ensureAppDBOpened(account multiaccounts.Account, passwor
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *StatusBackend) SaveAccountAndStartNodeWithKey(acc multiaccounts.Account, conf *params.NodeConfig, password string, keyHex string) error {
|
||||
err := b.SaveAccount(acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.ensureAppDBOpened(acc, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.saveNodeConfig(conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.StartNodeWithKey(acc, password, keyHex)
|
||||
}
|
||||
|
||||
// StartNodeWithKey instead of loading addresses from database this method derives address from key
|
||||
// and uses it in application.
|
||||
func (b *StatusBackend) StartNodeWithKey(acc multiaccounts.Account, password string, keyHex string) error {
|
||||
err := b.ensureAppDBOpened(acc, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conf, err := b.loadNodeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := logutils.OverrideRootLogWithConfig(conf, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
chatKey, err := ethcrypto.HexToECDSA(keyHex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.StartNode(conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.accountManager.SetChatAccount(chatKey)
|
||||
chatAcc, err := b.accountManager.SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.accountManager.SetAccountAddresses(chatAcc.Address)
|
||||
return b.injectAccountIntoServices()
|
||||
}
|
||||
|
||||
func (b *StatusBackend) StartNodeWithAccount(acc multiaccounts.Account, password string) error {
|
||||
err := b.ensureAppDBOpened(acc, password)
|
||||
if err != nil {
|
||||
|
@ -753,6 +801,10 @@ func (b *StatusBackend) SelectAccount(loginParams account.LoginParams) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return b.injectAccountIntoServices()
|
||||
}
|
||||
|
||||
func (b *StatusBackend) injectAccountIntoServices() error {
|
||||
chatAccount, err := b.accountManager.SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -779,10 +831,10 @@ func (b *StatusBackend) SelectAccount(loginParams account.LoginParams) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
return b.startWallet(loginParams.Password)
|
||||
return b.startWallet()
|
||||
}
|
||||
|
||||
func (b *StatusBackend) startWallet(password string) error {
|
||||
func (b *StatusBackend) startWallet() error {
|
||||
if !b.statusNode.Config().WalletConfig.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -537,3 +537,35 @@ func TestBackendGetVerifiedAccount(t *testing.T) {
|
|||
require.Equal(t, address, key.Address)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoginWithKey(t *testing.T) {
|
||||
b := NewStatusBackend()
|
||||
pkey, err := crypto.GenerateKey()
|
||||
require.NoError(t, err)
|
||||
main := multiaccounts.Account{
|
||||
Address: crypto.PubkeyToAddress(pkey.PublicKey),
|
||||
}
|
||||
tmpdir, err := ioutil.TempDir("", "login-with-key-test-")
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(tmpdir)
|
||||
conf, err := params.NewNodeConfig(tmpdir, 1777)
|
||||
require.NoError(t, err)
|
||||
keyhex := hex.EncodeToString(crypto.FromECDSA(pkey))
|
||||
|
||||
require.NoError(t, b.accountManager.InitKeystore(conf.KeyStoreDir))
|
||||
b.UpdateRootDataDir(conf.DataDir)
|
||||
require.NoError(t, b.OpenAccounts())
|
||||
|
||||
require.NoError(t, b.SaveAccountAndStartNodeWithKey(main, conf, "test-pass", keyhex))
|
||||
require.NoError(t, b.Logout())
|
||||
require.NoError(t, b.StopNode())
|
||||
|
||||
require.NoError(t, b.StartNodeWithKey(main, "test-pass", keyhex))
|
||||
defer func() {
|
||||
assert.NoError(t, b.Logout())
|
||||
assert.NoError(t, b.StopNode())
|
||||
}()
|
||||
extkey, err := b.accountManager.SelectedChatAccount()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, crypto.PubkeyToAddress(pkey.PublicKey), extkey.Address)
|
||||
}
|
||||
|
|
|
@ -376,11 +376,50 @@ func InitKeystore(keydir string) string {
|
|||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// SaveAccountAndLoginWithKeycard saves account in status-go database..
|
||||
func SaveAccountAndLoginWithKeycard(accountData, password, configJSON, keyHex string) string {
|
||||
var account multiaccounts.Account
|
||||
err := json.Unmarshal([]byte(accountData), &account)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
var conf params.NodeConfig
|
||||
err = json.Unmarshal([]byte(configJSON), &conf)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
api.RunAsync(func() error {
|
||||
log.Debug("starting a node, and saving account with configuration", "address", account.Address)
|
||||
err := statusBackend.SaveAccountAndStartNodeWithKey(account, &conf, password, keyHex)
|
||||
if err != nil {
|
||||
log.Error("failed to start node and save account", "address", account.Address, "error", err)
|
||||
return err
|
||||
}
|
||||
log.Debug("started a node, and saved account", "address", account.Address)
|
||||
return nil
|
||||
})
|
||||
return makeJSONResponse(nil)
|
||||
}
|
||||
|
||||
// LoginWithKeycard initializes an account with a chat key and encryption key used for PFS.
|
||||
// It purges all the previous identities from Whisper, and injects the key as shh identity.
|
||||
func LoginWithKeycard(chatKeyData, encryptionKeyData string) string {
|
||||
err := statusBackend.InjectChatAccount(chatKeyData, encryptionKeyData)
|
||||
return makeJSONResponse(err)
|
||||
func LoginWithKeycard(accountData, password, keyHex string) string {
|
||||
var account multiaccounts.Account
|
||||
err := json.Unmarshal([]byte(accountData), &account)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
api.RunAsync(func() error {
|
||||
log.Debug("start a node with account", "address", account.Address)
|
||||
err := statusBackend.StartNodeWithKey(account, password, keyHex)
|
||||
if err != nil {
|
||||
log.Error("failed to start a node", "address", account.Address, "error", err)
|
||||
return err
|
||||
}
|
||||
log.Debug("started a node with", "address", account.Address)
|
||||
return nil
|
||||
})
|
||||
return makeJSONResponse(nil)
|
||||
}
|
||||
|
||||
// Logout is equivalent to clearing whisper identities.
|
||||
|
|
Loading…
Reference in New Issue