chore: `password` removed from the `DeleteAccount` function

Asking for a password when removing a key is not necessary.
This commit is contained in:
Sale Djenic 2023-05-05 09:43:05 +02:00 committed by saledjenic
parent a669e7d038
commit 31144ed5a3
14 changed files with 162 additions and 122 deletions

View File

@ -1 +1 @@
0.150.1 0.150.2

View File

@ -640,8 +640,8 @@ func (m *Manager) ReEncryptKeyStoreDir(keyDirPath, oldPass, newPass string) erro
return nil return nil
} }
func (m *Manager) DeleteAccount(address types.Address, password string) error { func (m *Manager) DeleteAccount(address types.Address) error {
return m.keystore.Delete(types.Account{Address: address}, password) return m.keystore.Delete(types.Account{Address: address})
} }
func (m *Manager) GetVerifiedWalletAccount(db *accounts.Database, address, password string) (*SelectedExtKey, error) { func (m *Manager) GetVerifiedWalletAccount(db *accounts.Database, address, password string) (*SelectedExtKey, error) {

View File

@ -761,15 +761,15 @@ func TestConvertAccount(t *testing.T) {
const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
const password = "111111" // represents password for a regular user const password = "111111" // represents password for a regular user
const keycardPassword = "222222" // represents password for a keycard user const keycardPassword = "222222" // represents password for a keycard user
const pathMaster = "m" const keycardUID = "1234"
const pathWalletRoot = "m/44'/60'/0'/0"
const pathEIP1581Root = "m/43'/60'/1581'" const pathEIP1581Root = "m/43'/60'/1581'"
const pathEIP1581Chat = "m/43'/60'/1581'/0/0" const pathEIP1581Chat = pathEIP1581Root + "/0'/0"
const pathDefaultWalletAccount = "m/44'/60'/0'/0/0" const pathWalletRoot = "m/44'/60'/0'/0"
const customWalletPath1 = "m/44'/60'/0'/0/1" const pathDefaultWalletAccount = pathWalletRoot + "/0"
const customWalletPath2 = "m/44'/60'/0'/0/2" const customWalletPath1 = pathWalletRoot + "/1"
const customWalletPath2 = pathWalletRoot + "/2"
var allGeneratedPaths []string var allGeneratedPaths []string
allGeneratedPaths = append(allGeneratedPaths, customWalletPath1, customWalletPath2, pathWalletRoot, pathEIP1581Root, pathDefaultWalletAccount) allGeneratedPaths = append(allGeneratedPaths, pathEIP1581Root, pathEIP1581Chat, pathWalletRoot, pathDefaultWalletAccount, customWalletPath1, customWalletPath2)
var err error var err error
@ -823,34 +823,32 @@ func TestConvertAccount(t *testing.T) {
genAccInfo, err := backend.AccountManager().AccountsGenerator().ImportMnemonic(mnemonic, "") genAccInfo, err := backend.AccountManager().AccountsGenerator().ImportMnemonic(mnemonic, "")
assert.NoError(t, err) assert.NoError(t, err)
masterAddress := genAccInfo.Address
accountInfo, err := backend.AccountManager().AccountsGenerator().StoreAccount(genAccInfo.ID, password) accountInfo, err := backend.AccountManager().AccountsGenerator().StoreAccount(genAccInfo.ID, password)
assert.NoError(t, err) assert.NoError(t, err)
found := keystoreContainsFileForAccount(keyStoreDir, accountInfo.Address) found := keystoreContainsFileForAccount(keyStoreDir, accountInfo.Address)
require.NoError(t, err)
require.True(t, found) require.True(t, found)
derivedAccounts, err := backend.AccountManager().AccountsGenerator().StoreDerivedAccounts(genAccInfo.ID, password, allGeneratedPaths) derivedAccounts, err := backend.AccountManager().AccountsGenerator().StoreDerivedAccounts(genAccInfo.ID, password, allGeneratedPaths)
assert.NoError(t, err) assert.NoError(t, err)
accs, err := backend.AccountManager().AccountsGenerator().DeriveAddresses(genAccInfo.ID, []string{pathMaster}) chatAddress := derivedAccounts[pathEIP1581Chat].Address
require.NoError(t, err) found = keystoreContainsFileForAccount(keyStoreDir, chatAddress)
require.Equal(t, 1, len(accs))
masterAddress := accs[pathMaster].Address
found = keystoreContainsFileForAccount(keyStoreDir, masterAddress)
require.NoError(t, err)
require.True(t, found) require.True(t, found)
var accountsToStore []*accounts.Account var accountsToStore []*accounts.Account
accountsToStore = append(accountsToStore, &accounts.Account{ accountsToStore = append(accountsToStore, &accounts.Account{
Address: types.HexToAddress(masterAddress), Address: types.HexToAddress(chatAddress),
KeyUID: genAccInfo.KeyUID, DerivedFrom: masterAddress,
Type: accounts.AccountTypeGenerated, KeyUID: genAccInfo.KeyUID,
PublicKey: types.Hex2Bytes(accountInfo.PublicKey), Type: accounts.AccountTypeGenerated,
Path: pathEIP1581Chat, PublicKey: types.Hex2Bytes(accountInfo.PublicKey),
Wallet: false, Path: pathEIP1581Chat,
Chat: true, Wallet: false,
Name: "GeneratedAccount", Chat: true,
Name: "GeneratedAccount",
}) })
for p, dAccInfo := range derivedAccounts { for p, dAccInfo := range derivedAccounts {
@ -927,30 +925,46 @@ func TestConvertAccount(t *testing.T) {
KeycardPairing: "pairing", KeycardPairing: "pairing",
} }
// Ensure we're able to open the DB
err = backend.ensureAppDBOpened(keycardAccount, keycardPassword)
require.NoError(t, err)
// db creation
db, err := accounts.NewDB(backend.appDB)
require.NoError(t, err)
// Check that there is no registered keycards
keycardKeyPairs, err := db.GetMigratedKeyPairByKeyUID(genAccInfo.KeyUID)
require.NoError(t, err)
require.Equal(t, 0, len(keycardKeyPairs))
// Converting to a keycard account // Converting to a keycard account
err = backend.ConvertToKeycardAccount(keycardAccount, keycardSettings, password, keycardPassword) err = backend.ConvertToKeycardAccount(keycardAccount, keycardSettings, keycardUID, password, keycardPassword)
require.NoError(t, err) require.NoError(t, err)
// Validating results of converting to a keycard account. // Validating results of converting to a keycard account.
// All keystore files for the account which is migrated need to be removed. // All keystore files for the account which is migrated need to be removed.
found = keystoreContainsFileForAccount(keyStoreDir, accountInfo.Address) found = keystoreContainsFileForAccount(keyStoreDir, masterAddress)
require.NoError(t, err)
require.False(t, found) require.False(t, found)
for _, dAccInfo := range derivedAccounts { for _, dAccInfo := range derivedAccounts {
found = keystoreContainsFileForAccount(keyStoreDir, dAccInfo.Address) found = keystoreContainsFileForAccount(keyStoreDir, dAccInfo.Address)
require.NoError(t, err)
require.False(t, found) require.False(t, found)
} }
found = keystoreContainsFileForAccount(keyStoreDir, masterAddress)
require.NoError(t, err)
require.False(t, found)
// Ensure we're able to open the DB // Ensure we're able to open the DB
err = backend.ensureAppDBOpened(keycardAccount, keycardPassword) err = backend.ensureAppDBOpened(keycardAccount, keycardPassword)
require.NoError(t, err) require.NoError(t, err)
// db creation after re-encryption
db1, err := accounts.NewDB(backend.appDB)
require.NoError(t, err)
// Check that there is a registered keycard
keycardKeyPairs, err = db1.GetMigratedKeyPairByKeyUID(genAccInfo.KeyUID)
require.NoError(t, err)
require.Equal(t, 1, len(keycardKeyPairs))
b1 := NewGethStatusBackend() b1 := NewGethStatusBackend()
require.NoError(t, b1.OpenAccounts()) require.NoError(t, b1.OpenAccounts())
@ -961,23 +975,29 @@ func TestConvertAccount(t *testing.T) {
// Validating results of converting to a regular account. // Validating results of converting to a regular account.
// All keystore files for need to be created. // All keystore files for need to be created.
found = keystoreContainsFileForAccount(keyStoreDir, accountInfo.Address) found = keystoreContainsFileForAccount(keyStoreDir, accountInfo.Address)
require.NoError(t, err)
require.True(t, found) require.True(t, found)
for _, dAccInfo := range derivedAccounts { for _, dAccInfo := range derivedAccounts {
found = keystoreContainsFileForAccount(keyStoreDir, dAccInfo.Address) found = keystoreContainsFileForAccount(keyStoreDir, dAccInfo.Address)
require.NoError(t, err)
require.True(t, found) require.True(t, found)
} }
found = keystoreContainsFileForAccount(keyStoreDir, masterAddress) found = keystoreContainsFileForAccount(keyStoreDir, masterAddress)
require.NoError(t, err)
require.True(t, found) require.True(t, found)
// Ensure we're able to open the DB // Ensure we're able to open the DB
err = backend.ensureAppDBOpened(keycardAccount, password) err = backend.ensureAppDBOpened(keycardAccount, password)
require.NoError(t, err) require.NoError(t, err)
// db creation after re-encryption
db2, err := accounts.NewDB(backend.appDB)
require.NoError(t, err)
// Check that there is no registered keycards
keycardKeyPairs, err = db2.GetMigratedKeyPairByKeyUID(genAccInfo.KeyUID)
require.NoError(t, err)
require.Equal(t, 0, len(keycardKeyPairs))
b2 := NewGethStatusBackend() b2 := NewGethStatusBackend()
require.NoError(t, b2.OpenAccounts()) require.NoError(t, b2.OpenAccounts())
} }

View File

@ -29,6 +29,7 @@ import (
"github.com/status-im/status-go/logutils" "github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/multiaccounts" "github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts" "github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/keypairs"
"github.com/status-im/status-go/multiaccounts/settings" "github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/node" "github.com/status-im/status-go/node"
"github.com/status-im/status-go/nodecfg" "github.com/status-im/status-go/nodecfg"
@ -594,20 +595,7 @@ func (b *GethStatusBackend) ChangeDatabasePassword(keyUID string, password strin
return nil return nil
} }
func (b *GethStatusBackend) tryToDeleteAccount(address types.Address, password, newPassword string) error { func (b *GethStatusBackend) ConvertToKeycardAccount(account multiaccounts.Account, s settings.Settings, keycardUID string, password string, newPassword string) error {
err := b.accountManager.DeleteAccount(address, newPassword)
if err != nil {
err = b.accountManager.DeleteAccount(address, password)
if err != nil && err.Error() != "no key for given address or file" {
b.log.Error("error on deleting account", "err", err)
return err
}
}
return nil
}
func (b *GethStatusBackend) ConvertToKeycardAccount(account multiaccounts.Account, s settings.Settings, password string, newPassword string) error {
err := b.multiaccountsDB.UpdateAccountKeycardPairing(account.KeyUID, account.KeycardPairing) err := b.multiaccountsDB.UpdateAccountKeycardPairing(account.KeyUID, account.KeycardPairing)
if err != nil { if err != nil {
return err return err
@ -642,12 +630,40 @@ func (b *GethStatusBackend) ConvertToKeycardAccount(account multiaccounts.Accoun
return err return err
} }
knownAccounts, err := accountDB.GetAccounts() relatedAccounts, err := accountDB.GetAccountsByKeyUID(account.KeyUID)
if err != nil { if err != nil {
return err return err
} }
dappsAddress, err := accountDB.GetDappsAddress() // This check is added due to mobile app cause it doesn't support a Keycard features as desktop app.
// We should remove the following line once mobile and desktop app align.
if len(keycardUID) > 0 {
displayName, err := accountDB.DisplayName()
if err != nil {
return err
}
kp := keypairs.KeyPair{
KeycardUID: keycardUID,
KeycardName: displayName,
KeycardLocked: false,
KeyUID: account.KeyUID,
LastUpdateClock: uint64(time.Now().Unix()),
}
for _, acc := range relatedAccounts {
kp.AccountsAddresses = append(kp.AccountsAddresses, acc.Address)
}
addedKc, _, err := accountDB.AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(kp)
if err != nil {
return err
}
if !addedKc {
return errors.New("couldn't register a keypair to keycards table")
}
}
masterAddress, err := accountDB.GetMasterAddress()
if err != nil { if err != nil {
return err return err
} }
@ -673,26 +689,24 @@ func (b *GethStatusBackend) ConvertToKeycardAccount(account multiaccounts.Accoun
} }
// We need to delete all accounts for the keypair which is being migrated // We need to delete all accounts for the keypair which is being migrated
for _, acc := range knownAccounts { for _, acc := range relatedAccounts {
if account.KeyUID == acc.KeyUID { err = b.accountManager.DeleteAccount(acc.Address)
err = b.tryToDeleteAccount(acc.Address, password, newPassword) if err != nil {
if err != nil { return err
return err
}
} }
} }
err = b.tryToDeleteAccount(dappsAddress, password, newPassword) err = b.accountManager.DeleteAccount(masterAddress)
if err != nil { if err != nil {
return err return err
} }
err = b.tryToDeleteAccount(eip1581Address, password, newPassword) err = b.accountManager.DeleteAccount(eip1581Address)
if err != nil { if err != nil {
return err return err
} }
err = b.tryToDeleteAccount(walletRootAddress, password, newPassword) err = b.accountManager.DeleteAccount(walletRootAddress)
if err != nil { if err != nil {
return err return err
} }

View File

@ -48,13 +48,13 @@ func (k *gethKeyStoreAdapter) AccountDecryptedKey(a types.Account, auth string)
return accountFrom(gethAccount), keyFrom(gethKey), err return accountFrom(gethAccount), keyFrom(gethKey), err
} }
func (k *gethKeyStoreAdapter) Delete(a types.Account, auth string) error { func (k *gethKeyStoreAdapter) Delete(a types.Account) error {
gethAccount, err := gethAccountFrom(a) gethAccount, err := gethAccountFrom(a)
if err != nil { if err != nil {
return err return err
} }
return k.keystore.Delete(gethAccount, auth) return k.keystore.Delete(gethAccount)
} }
// parseGethURL converts a user supplied URL into the accounts specific structure. // parseGethURL converts a user supplied URL into the accounts specific structure.

View File

@ -22,5 +22,5 @@ type KeyStore interface {
AccountDecryptedKey(a Account, auth string) (Account, *Key, error) AccountDecryptedKey(a Account, auth string) (Account, *Key, error)
// Delete deletes the key matched by account if the passphrase is correct. // Delete deletes the key matched by account if the passphrase is correct.
// If the account contains no filename, the address must match a unique key. // If the account contains no filename, the address must match a unique key.
Delete(a Account, auth string) error Delete(a Account) error
} }

2
go.mod
View File

@ -2,7 +2,7 @@ module github.com/status-im/status-go
go 1.19 go 1.19
replace github.com/ethereum/go-ethereum v1.10.26 => github.com/status-im/go-ethereum v1.10.25-status.4 replace github.com/ethereum/go-ethereum v1.10.26 => github.com/status-im/go-ethereum v1.10.25-status.6
replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.20190717161051-705d9623b7c1 replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.20190717161051-705d9623b7c1

4
go.sum
View File

@ -1989,8 +1989,8 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY= github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY=
github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU= github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU=
github.com/status-im/go-ethereum v1.10.25-status.4 h1:Ff35UseaP49DK2RRpSLo3DL7NUmMKzicQ/7/yub6gfU= github.com/status-im/go-ethereum v1.10.25-status.6 h1:5YC8k1inTBqA6LpON0uX6y86niOKukA/LnKxzd5GFyI=
github.com/status-im/go-ethereum v1.10.25-status.4/go.mod h1:Dt4K5JYMhJRdtXJwBEyGZLZn9iz/chSOZyjVmt5ZhwQ= github.com/status-im/go-ethereum v1.10.25-status.6/go.mod h1:Dt4K5JYMhJRdtXJwBEyGZLZn9iz/chSOZyjVmt5ZhwQ=
github.com/status-im/go-multiaddr-ethv4 v1.2.4 h1:7fw0Y48TJXEqx4fOHlDOUiM/uBq9zG5w4x975Mjh4E0= github.com/status-im/go-multiaddr-ethv4 v1.2.4 h1:7fw0Y48TJXEqx4fOHlDOUiM/uBq9zG5w4x975Mjh4E0=
github.com/status-im/go-multiaddr-ethv4 v1.2.4/go.mod h1:PDh4D7h5CvecPIy0ji0rLNwTnzzEcyz9uTPHD42VyH4= github.com/status-im/go-multiaddr-ethv4 v1.2.4/go.mod h1:PDh4D7h5CvecPIy0ji0rLNwTnzzEcyz9uTPHD42VyH4=
github.com/status-im/gomoji v1.1.3-0.20220213022530-e5ac4a8732d4 h1:CtobZoiNdHpx+xurFxnuJ1xsGm3oKMfcZkB3vmomJmA= github.com/status-im/gomoji v1.1.3-0.20220213022530-e5ac4a8732d4 h1:CtobZoiNdHpx+xurFxnuJ1xsGm3oKMfcZkB3vmomJmA=

View File

@ -904,7 +904,7 @@ func ChangeDatabasePassword(KeyUID, password, newPassword string) string {
return makeJSONResponse(nil) return makeJSONResponse(nil)
} }
func ConvertToKeycardAccount(accountData, settingsJSON, password, newPassword string) string { func ConvertToKeycardAccount(accountData, settingsJSON, keycardUID, password, newPassword string) string {
var account multiaccounts.Account var account multiaccounts.Account
err := json.Unmarshal([]byte(accountData), &account) err := json.Unmarshal([]byte(accountData), &account)
if err != nil { if err != nil {
@ -916,7 +916,7 @@ func ConvertToKeycardAccount(accountData, settingsJSON, password, newPassword st
return makeJSONResponse(err) return makeJSONResponse(err)
} }
err = statusBackend.ConvertToKeycardAccount(account, settings, password, newPassword) err = statusBackend.ConvertToKeycardAccount(account, settings, keycardUID, password, newPassword)
if err != nil { if err != nil {
return makeJSONResponse(err) return makeJSONResponse(err)
} }

View File

@ -188,11 +188,7 @@ func (m *Messenger) AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx context.
return addedKc || addedAccs, m.dispatchKeycardActivity(ctx, activityMessage) return addedKc || addedAccs, m.dispatchKeycardActivity(ctx, activityMessage)
} }
func (m *Messenger) RemoveMigratedAccountsForKeycard(ctx context.Context, kcUID string, accountAddresses []string, clock uint64) error { func (m *Messenger) RemoveMigratedAccountsForKeycard(ctx context.Context, kcUID string, addresses []types.Address, clock uint64) error {
var addresses []types.Address
for _, addr := range accountAddresses {
addresses = append(addresses, types.HexToAddress(addr))
}
err := m.settings.RemoveMigratedAccountsForKeycard(kcUID, addresses, clock) err := m.settings.RemoveMigratedAccountsForKeycard(kcUID, addresses, clock)
if err != nil { if err != nil {

View File

@ -178,17 +178,12 @@ func (s *MessengerSyncKeycardChangeSuite) TestRemovingAccountsFromKeycard() {
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
var accountAddressesToRemove []string
for _, acc := range keycardToSync.AccountsAddresses[:2] {
accountAddressesToRemove = append(accountAddressesToRemove, acc.String())
}
// Remove accounts from sender // Remove accounts from sender
updatedKeycard := getKeycardsForTest()[:1][0] updatedKeycard := getKeycardsForTest()[:1][0]
updatedKeycard.AccountsAddresses = updatedKeycard.AccountsAddresses[2:] updatedKeycard.AccountsAddresses = updatedKeycard.AccountsAddresses[2:]
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID, err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID,
accountAddressesToRemove, keycardToSync.LastUpdateClock) keycardToSync.AccountsAddresses[:2], keycardToSync.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response
@ -224,14 +219,9 @@ func (s *MessengerSyncKeycardChangeSuite) TestRemovingAllAccountsFromKeycard() {
s.Require().Equal(true, addedKc) s.Require().Equal(true, addedKc)
s.Require().Equal(false, addedAccs) s.Require().Equal(false, addedAccs)
var accountAddressesToRemove []string
for _, acc := range keycardToSync.AccountsAddresses {
accountAddressesToRemove = append(accountAddressesToRemove, acc.String())
}
// Remove all accounts from sender // Remove all accounts from sender
err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID, err = s.main.RemoveMigratedAccountsForKeycard(context.Background(), keycardToSync.KeycardUID,
accountAddressesToRemove, keycardToSync.LastUpdateClock) keycardToSync.AccountsAddresses, keycardToSync.LastUpdateClock)
s.Require().NoError(err) s.Require().NoError(err)
// Wait for the response // Wait for the response

View File

@ -80,41 +80,56 @@ func (api *API) GetAccountsByKeyUID(ctx context.Context, keyUID string) ([]*acco
return api.checkDerivedFromField(accounts) return api.checkDerivedFromField(accounts)
} }
func (api *API) DeleteAccount(ctx context.Context, address types.Address, password string) error { func (api *API) DeleteAccount(ctx context.Context, address types.Address) error {
acc, err := api.db.GetAccountByAddress(address) acc, err := api.db.GetAccountByAddress(address)
if err != nil { if err != nil {
return err return err
} }
migratedKeyPairs, err := api.db.GetMigratedKeyPairByKeyUID(acc.KeyUID) allAccountsOfKeypairWithKeyUID, err := api.db.GetAccountsByKeyUID(acc.KeyUID)
if err != nil { if err != nil {
return err return err
} }
lastAcccountOfKeypairWithTheSameKey := len(allAccountsOfKeypairWithKeyUID) == 1
if acc.Type != accounts.AccountTypeWatch && len(migratedKeyPairs) == 0 { if acc.Type != accounts.AccountTypeWatch {
if len(password) == 0 { migratedKeyPairs, err := api.db.GetMigratedKeyPairByKeyUID(acc.KeyUID)
return errors.New("`password` must be provided for non keycard accounts") if err != nil {
}
err = api.manager.DeleteAccount(address, password)
var e *account.ErrCannotLocateKeyFile
if err != nil && !errors.As(err, &e) {
return err return err
} }
if acc.Type != accounts.AccountTypeKey { if len(migratedKeyPairs) == 0 {
allAccountsOfKeypairWithKeyUID, err := api.db.GetAccountsByKeyUID(acc.KeyUID) err = api.manager.DeleteAccount(address)
if err != nil { var e *account.ErrCannotLocateKeyFile
if err != nil && !errors.As(err, &e) {
return err return err
} }
lastAcccountOfKeypairWithTheSameKey := len(allAccountsOfKeypairWithKeyUID) == 1 if acc.Type != accounts.AccountTypeKey {
if lastAcccountOfKeypairWithTheSameKey {
err = api.manager.DeleteAccount(types.Address(common.HexToAddress(acc.DerivedFrom)))
var e *account.ErrCannotLocateKeyFile
if err != nil && !errors.As(err, &e) {
return err
}
}
}
} else {
if lastAcccountOfKeypairWithTheSameKey { if lastAcccountOfKeypairWithTheSameKey {
err = api.manager.DeleteAccount(types.Address(common.HexToAddress(acc.DerivedFrom)), password) knownKeycards, err := api.db.GetAllKnownKeycards()
var e *account.ErrCannotLocateKeyFile if err != nil {
if err != nil && !errors.As(err, &e) {
return err return err
} }
for _, kc := range knownKeycards {
if kc.KeyUID == acc.KeyUID {
clock := uint64(time.Now().Unix())
err = (*api.messenger).RemoveMigratedAccountsForKeycard(ctx, kc.KeycardUID, kc.AccountsAddresses, clock)
if err != nil {
return err
}
}
}
} }
} }
} }
@ -254,7 +269,7 @@ func (api *API) VerifyPassword(password string) bool {
return api.VerifyKeystoreFileForAccount(address, password) return api.VerifyKeystoreFileForAccount(address, password)
} }
func (api *API) AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx context.Context, kcUID string, kpName string, keyUID string, accountAddresses []string, password string) error { func (api *API) AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx context.Context, kcUID string, kpName string, keyUID string, accountAddresses []string) error {
if len(accountAddresses) == 0 { if len(accountAddresses) == 0 {
return errors.New("cannot migrate a keypair without any address") return errors.New("cannot migrate a keypair without any address")
} }
@ -279,21 +294,27 @@ func (api *API) AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx context.Cont
kp.AccountsAddresses = append(kp.AccountsAddresses, types.Address(common.HexToAddress(addr))) kp.AccountsAddresses = append(kp.AccountsAddresses, types.Address(common.HexToAddress(addr)))
} }
migratedKeyPairs, err := api.db.GetMigratedKeyPairByKeyUID(keyUID)
if err != nil {
return err
}
added, err := (*api.messenger).AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx, &kp) added, err := (*api.messenger).AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx, &kp)
if err != nil { if err != nil {
return err return err
} }
// Once we migrate a keypair, corresponding keystore files need to be deleted. // Once we migrate a keypair, corresponding keystore files need to be deleted
if added && len(password) > 0 { // if the keypair being migrated is not already migrated (in case user is creating a copy of an existing Keycard)
if added && len(migratedKeyPairs) == 0 && acc.Type != accounts.AccountTypeWatch {
for _, addr := range kp.AccountsAddresses { for _, addr := range kp.AccountsAddresses {
err = api.manager.DeleteAccount(addr, password) err = api.manager.DeleteAccount(addr)
if err != nil { if err != nil {
return err return err
} }
} }
err = api.manager.DeleteAccount(types.Address(common.HexToAddress(acc.DerivedFrom)), password) err = api.manager.DeleteAccount(types.Address(common.HexToAddress(acc.DerivedFrom)))
if err != nil { if err != nil {
return err return err
} }
@ -304,7 +325,11 @@ func (api *API) AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(ctx context.Cont
func (api *API) RemoveMigratedAccountsForKeycard(ctx context.Context, kcUID string, accountAddresses []string) error { func (api *API) RemoveMigratedAccountsForKeycard(ctx context.Context, kcUID string, accountAddresses []string) error {
clock := uint64(time.Now().Unix()) clock := uint64(time.Now().Unix())
return (*api.messenger).RemoveMigratedAccountsForKeycard(ctx, kcUID, accountAddresses, clock) var addresses []types.Address
for _, addr := range accountAddresses {
addresses = append(addresses, types.HexToAddress(addr))
}
return (*api.messenger).RemoveMigratedAccountsForKeycard(ctx, kcUID, addresses, clock)
} }
func (api *API) GetAllKnownKeycards(ctx context.Context) ([]*keypairs.KeyPair, error) { func (api *API) GetAllKnownKeycards(ctx context.Context) ([]*keypairs.KeyPair, error) {

View File

@ -241,22 +241,17 @@ func (ks *KeyStore) AccountDecryptedKey(a accounts.Account, auth string) (accoun
return ks.getDecryptedKey(a, auth) return ks.getDecryptedKey(a, auth)
} }
// Delete deletes the key matched by account if the passphrase is correct. // Delete deletes the key matched by account.
// If the account contains no filename, the address must match a unique key. // If the account contains no filename, the address must match a unique key.
func (ks *KeyStore) Delete(a accounts.Account, passphrase string) error { func (ks *KeyStore) Delete(a accounts.Account) error {
// Decrypting the key isn't really necessary, but we do
// it anyway to check the password and zero out the key
// immediately afterwards.
a, key, err := ks.getDecryptedKey(a, passphrase)
if key != nil {
zeroKey(key.PrivateKey)
}
if err != nil {
return err
}
// The order is crucial here. The key is dropped from the // The order is crucial here. The key is dropped from the
// cache after the file is gone so that a reload happening in // cache after the file is gone so that a reload happening in
// between won't insert it into the cache again. // between won't insert it into the cache again.
a, err := ks.Find(a)
if err != nil {
return err
}
err = os.Remove(a.URL.Path) err = os.Remove(a.URL.Path)
if err == nil { if err == nil {
ks.cache.delete(a) ks.cache.delete(a)

2
vendor/modules.txt vendored
View File

@ -197,7 +197,7 @@ github.com/edsrzf/mmap-go
## explicit; go 1.14 ## explicit; go 1.14
github.com/elastic/gosigar github.com/elastic/gosigar
github.com/elastic/gosigar/sys/windows github.com/elastic/gosigar/sys/windows
# github.com/ethereum/go-ethereum v1.10.26 => github.com/status-im/go-ethereum v1.10.25-status.4 # github.com/ethereum/go-ethereum v1.10.26 => github.com/status-im/go-ethereum v1.10.25-status.6
## explicit; go 1.17 ## explicit; go 1.17
github.com/ethereum/go-ethereum github.com/ethereum/go-ethereum
github.com/ethereum/go-ethereum/accounts github.com/ethereum/go-ethereum/accounts