2022-09-06 07:10:40 +00:00
|
|
|
package keypairs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2023-02-21 09:50:48 +00:00
|
|
|
"errors"
|
2022-09-20 10:45:50 +00:00
|
|
|
"fmt"
|
2023-01-06 09:57:22 +00:00
|
|
|
"strings"
|
2022-09-06 07:10:40 +00:00
|
|
|
|
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
2023-02-21 12:35:26 +00:00
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
2022-09-06 07:10:40 +00:00
|
|
|
)
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
var errDbTransactionIsNil = errors.New("keycard: database transaction is nil")
|
2023-02-21 09:50:48 +00:00
|
|
|
|
2022-09-06 07:10:40 +00:00
|
|
|
type KeyPair struct {
|
|
|
|
KeycardUID string `json:"keycard-uid"`
|
|
|
|
KeycardName string `json:"keycard-name"`
|
|
|
|
KeycardLocked bool `json:"keycard-locked"`
|
|
|
|
AccountsAddresses []types.Address `json:"accounts-addresses"`
|
|
|
|
KeyUID string `json:"key-uid"`
|
2023-02-21 09:50:48 +00:00
|
|
|
LastUpdateClock uint64
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
type KeycardAction struct {
|
|
|
|
Action string `json:"action"`
|
|
|
|
OldKeycardUID string `json:"old-keycard-uid,omitempty"`
|
|
|
|
Keycard *KeyPair `json:"keycard"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPair) ToSyncKeycard() *protobuf.SyncKeycard {
|
|
|
|
kc := &protobuf.SyncKeycard{
|
|
|
|
Uid: kp.KeycardUID,
|
|
|
|
Name: kp.KeycardName,
|
|
|
|
Locked: kp.KeycardLocked,
|
|
|
|
KeyUid: kp.KeyUID,
|
|
|
|
Clock: kp.LastUpdateClock,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, addr := range kp.AccountsAddresses {
|
|
|
|
kc.Addresses = append(kc.Addresses, addr.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
return kc
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPair) FromSyncKeycard(kc *protobuf.SyncKeycard) {
|
|
|
|
kp.KeycardUID = kc.Uid
|
|
|
|
kp.KeycardName = kc.Name
|
|
|
|
kp.KeycardLocked = kc.Locked
|
|
|
|
kp.KeyUID = kc.KeyUid
|
|
|
|
kp.LastUpdateClock = kc.Clock
|
|
|
|
|
|
|
|
for _, addr := range kc.Addresses {
|
|
|
|
kp.AccountsAddresses = append(kp.AccountsAddresses, types.BytesToAddress(addr))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func removeElementAtIndex[T any](s []T, index int) []T {
|
|
|
|
if index < 0 || index >= len(s) {
|
|
|
|
panic("keycard: index out of the range")
|
|
|
|
}
|
|
|
|
return append(s[:index], s[index+1:]...)
|
|
|
|
}
|
|
|
|
|
2022-09-06 07:10:40 +00:00
|
|
|
type KeyPairs struct {
|
|
|
|
db *sql.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewKeyPairs(db *sql.DB) *KeyPairs {
|
|
|
|
return &KeyPairs{
|
|
|
|
db: db,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 17:14:19 +00:00
|
|
|
func containsAddress(addresses []types.Address, address types.Address) bool {
|
|
|
|
for _, addr := range addresses {
|
|
|
|
if addr == address {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) processResult(rows *sql.Rows, groupByKeycard bool) ([]*KeyPair, error) {
|
2022-09-06 07:10:40 +00:00
|
|
|
keyPairs := []*KeyPair{}
|
|
|
|
for rows.Next() {
|
|
|
|
keyPair := &KeyPair{}
|
|
|
|
addr := types.Address{}
|
2023-02-21 09:50:48 +00:00
|
|
|
err := rows.Scan(&keyPair.KeycardUID, &keyPair.KeycardName, &keyPair.KeycardLocked, &addr, &keyPair.KeyUID,
|
|
|
|
&keyPair.LastUpdateClock)
|
2022-09-06 07:10:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
foundAtIndex := -1
|
|
|
|
for i := range keyPairs {
|
2022-12-07 17:14:19 +00:00
|
|
|
if groupByKeycard {
|
|
|
|
if keyPairs[i].KeycardUID == keyPair.KeycardUID {
|
|
|
|
foundAtIndex = i
|
|
|
|
break
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if keyPairs[i].KeyUID == keyPair.KeyUID {
|
|
|
|
foundAtIndex = i
|
|
|
|
break
|
|
|
|
}
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if foundAtIndex == -1 {
|
|
|
|
keyPair.AccountsAddresses = append(keyPair.AccountsAddresses, addr)
|
|
|
|
keyPairs = append(keyPairs, keyPair)
|
|
|
|
} else {
|
2022-12-07 17:14:19 +00:00
|
|
|
if containsAddress(keyPairs[foundAtIndex].AccountsAddresses, addr) {
|
|
|
|
continue
|
|
|
|
}
|
2022-09-06 07:10:40 +00:00
|
|
|
keyPairs[foundAtIndex].AccountsAddresses = append(keyPairs[foundAtIndex].AccountsAddresses, addr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return keyPairs, nil
|
|
|
|
}
|
|
|
|
|
2022-12-07 17:14:19 +00:00
|
|
|
func (kp *KeyPairs) getAllRows(groupByKeycard bool) ([]*KeyPair, error) {
|
2022-09-06 07:10:40 +00:00
|
|
|
rows, err := kp.db.Query(`
|
2023-01-13 17:12:46 +00:00
|
|
|
SELECT
|
2023-02-14 13:06:59 +00:00
|
|
|
k.keycard_uid,
|
|
|
|
k.keycard_name,
|
|
|
|
k.keycard_locked,
|
|
|
|
ka.account_address,
|
2023-02-21 09:50:48 +00:00
|
|
|
k.key_uid,
|
|
|
|
k.last_update_clock
|
2023-01-13 17:12:46 +00:00
|
|
|
FROM
|
2023-02-14 13:06:59 +00:00
|
|
|
keycards AS k
|
|
|
|
LEFT JOIN
|
|
|
|
keycards_accounts AS ka
|
|
|
|
ON
|
|
|
|
k.keycard_uid = ka.keycard_uid
|
2023-01-13 17:12:46 +00:00
|
|
|
ORDER BY
|
2022-09-06 07:10:40 +00:00
|
|
|
key_uid
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer rows.Close()
|
2022-12-07 17:14:19 +00:00
|
|
|
return kp.processResult(rows, groupByKeycard)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) GetAllKnownKeycards() ([]*KeyPair, error) {
|
|
|
|
return kp.getAllRows(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) GetAllMigratedKeyPairs() ([]*KeyPair, error) {
|
|
|
|
return kp.getAllRows(false)
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) GetMigratedKeyPairByKeyUID(keyUID string) ([]*KeyPair, error) {
|
|
|
|
rows, err := kp.db.Query(`
|
2023-02-14 13:06:59 +00:00
|
|
|
SELECT
|
|
|
|
k.keycard_uid,
|
|
|
|
k.keycard_name,
|
|
|
|
k.keycard_locked,
|
|
|
|
ka.account_address,
|
2023-02-21 09:50:48 +00:00
|
|
|
k.key_uid,
|
|
|
|
k.last_update_clock
|
2023-01-13 17:12:46 +00:00
|
|
|
FROM
|
2023-02-14 13:06:59 +00:00
|
|
|
keycards AS k
|
|
|
|
LEFT JOIN
|
|
|
|
keycards_accounts AS ka
|
|
|
|
ON
|
|
|
|
k.keycard_uid = ka.keycard_uid
|
2022-09-06 07:10:40 +00:00
|
|
|
WHERE
|
2023-02-14 13:06:59 +00:00
|
|
|
k.key_uid = ?
|
2023-01-13 17:12:46 +00:00
|
|
|
ORDER BY
|
2023-02-14 13:06:59 +00:00
|
|
|
k.keycard_uid
|
2022-09-06 07:10:40 +00:00
|
|
|
`, keyUID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer rows.Close()
|
2022-12-07 17:14:19 +00:00
|
|
|
return kp.processResult(rows, false)
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
func (kp *KeyPairs) startTransactionAndCheckIfNeedToProceed(kcUID string, clock uint64) (tx *sql.Tx, proceed bool, err error) {
|
2022-09-06 07:10:40 +00:00
|
|
|
tx, err = kp.db.Begin()
|
|
|
|
if err != nil {
|
2023-02-21 09:50:48 +00:00
|
|
|
return nil, false, err
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
var dbLastUpdateClock uint64
|
|
|
|
err = tx.QueryRow(`SELECT last_update_clock FROM keycards WHERE keycard_uid = ?`, kcUID).Scan(&dbLastUpdateClock)
|
2023-02-14 13:06:59 +00:00
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return tx, err == sql.ErrNoRows, err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
return tx, dbLastUpdateClock <= clock, nil
|
|
|
|
}
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
func (kp *KeyPairs) setLastUpdateClock(tx *sql.Tx, kcUID string, clock uint64) (err error) {
|
|
|
|
if tx == nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return errDbTransactionIsNil
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
_, err = tx.Exec(`
|
|
|
|
UPDATE
|
|
|
|
keycards
|
|
|
|
SET
|
|
|
|
last_update_clock = ?
|
|
|
|
WHERE
|
|
|
|
keycard_uid = ?`,
|
|
|
|
clock, kcUID)
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) getAccountsForKeycard(tx *sql.Tx, kcUID string) ([]types.Address, error) {
|
|
|
|
var accountAddresses []types.Address
|
|
|
|
if tx == nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return accountAddresses, errDbTransactionIsNil
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rows, err := tx.Query(`SELECT account_address FROM keycards_accounts WHERE keycard_uid = ?`, kcUID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var accAddress types.Address
|
|
|
|
err = rows.Scan(&accAddress)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
accountAddresses = append(accountAddresses, accAddress)
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
return accountAddresses, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) addAccounts(tx *sql.Tx, kcUID string, accountsAddresses []types.Address) (err error) {
|
|
|
|
if tx == nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return errDbTransactionIsNil
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
insertKcAcc, err := tx.Prepare(`
|
2023-01-13 17:12:46 +00:00
|
|
|
INSERT INTO
|
2023-02-14 13:06:59 +00:00
|
|
|
keycards_accounts
|
2022-09-06 07:10:40 +00:00
|
|
|
(
|
2023-01-13 17:12:46 +00:00
|
|
|
keycard_uid,
|
2023-02-14 13:06:59 +00:00
|
|
|
account_address
|
2023-01-13 17:12:46 +00:00
|
|
|
)
|
2022-09-06 07:10:40 +00:00
|
|
|
VALUES
|
2023-02-14 13:06:59 +00:00
|
|
|
(?, ?);
|
2022-09-06 07:10:40 +00:00
|
|
|
`)
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2022-09-06 07:10:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-02-14 13:06:59 +00:00
|
|
|
defer insertKcAcc.Close()
|
2022-09-06 07:10:40 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
for i := range accountsAddresses {
|
|
|
|
addr := accountsAddresses[i]
|
2022-09-06 07:10:40 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
_, err = insertKcAcc.Exec(kcUID, addr)
|
2022-09-06 07:10:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
|
2022-09-06 07:10:40 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
func (kp *KeyPairs) deleteKeycard(tx *sql.Tx, kcUID string) (err error) {
|
|
|
|
if tx == nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return errDbTransactionIsNil
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
delete, err := tx.Prepare(`
|
|
|
|
DELETE
|
|
|
|
FROM
|
|
|
|
keycards
|
|
|
|
WHERE
|
|
|
|
keycard_uid = ?
|
|
|
|
`)
|
2023-02-14 13:06:59 +00:00
|
|
|
if err != nil {
|
2023-02-21 09:50:48 +00:00
|
|
|
return err
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
defer delete.Close()
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
_, err = delete.Exec(kcUID)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) AddMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(keyPair KeyPair) (addedKc bool, addedAccs bool, err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
tx, proceed, err := kp.startTransactionAndCheckIfNeedToProceed(keyPair.KeycardUID, keyPair.LastUpdateClock)
|
|
|
|
defer func() {
|
|
|
|
if err == nil {
|
|
|
|
err = tx.Commit()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_ = tx.Rollback()
|
|
|
|
}()
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
if proceed {
|
|
|
|
// insert only if there is no such keycard, otherwise just add accounts
|
|
|
|
if err != nil && err == sql.ErrNoRows {
|
2023-02-21 09:50:48 +00:00
|
|
|
_, err = tx.Exec(`
|
|
|
|
INSERT INTO
|
|
|
|
keycards
|
|
|
|
(
|
|
|
|
keycard_uid,
|
|
|
|
keycard_name,
|
|
|
|
keycard_locked,
|
|
|
|
key_uid,
|
|
|
|
last_update_clock
|
|
|
|
)
|
|
|
|
VALUES
|
|
|
|
(?, ?, ?, ?, ?);`,
|
|
|
|
keyPair.KeycardUID, keyPair.KeycardName, keyPair.KeycardLocked, keyPair.KeyUID, keyPair.LastUpdateClock)
|
|
|
|
|
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return false, false, err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = kp.addAccounts(tx, keyPair.KeycardUID, keyPair.AccountsAddresses)
|
2023-02-21 12:35:26 +00:00
|
|
|
return err == nil, false, err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = kp.setLastUpdateClock(tx, keyPair.KeycardUID, keyPair.LastUpdateClock)
|
2023-02-14 13:06:59 +00:00
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return false, false, err
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
|
|
|
|
err = kp.addAccounts(tx, keyPair.KeycardUID, keyPair.AccountsAddresses)
|
2023-02-21 12:35:26 +00:00
|
|
|
return false, err == nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return false, false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (kp *KeyPairs) SyncKeycards(syncingClock uint64, keypairsToSync []*KeyPair) (err error) {
|
|
|
|
tx, err := kp.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
if err == nil {
|
|
|
|
err = tx.Commit()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_ = tx.Rollback()
|
|
|
|
}()
|
|
|
|
|
|
|
|
rows, err := tx.Query(`SELECT * FROM keycards`)
|
|
|
|
if err != nil && err != sql.ErrNoRows {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
var dbKeypairs []*KeyPair
|
|
|
|
for rows.Next() {
|
|
|
|
keyPair := &KeyPair{}
|
|
|
|
err := rows.Scan(&keyPair.KeycardUID, &keyPair.KeycardName, &keyPair.KeycardLocked, &keyPair.KeyUID,
|
|
|
|
&keyPair.LastUpdateClock)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
dbKeypairs = append(dbKeypairs, keyPair)
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
// apply those from `keypairsToSync` which are newer
|
|
|
|
for _, syncKp := range keypairsToSync {
|
|
|
|
foundAtIndex := -1
|
|
|
|
for i := range dbKeypairs {
|
|
|
|
if dbKeypairs[i].KeycardUID == syncKp.KeycardUID {
|
|
|
|
foundAtIndex = i
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
doInsertOrReplace := true
|
|
|
|
if foundAtIndex > -1 {
|
|
|
|
if dbKeypairs[foundAtIndex].LastUpdateClock > syncKp.LastUpdateClock {
|
|
|
|
doInsertOrReplace = false
|
|
|
|
}
|
|
|
|
dbKeypairs = removeElementAtIndex(dbKeypairs, foundAtIndex)
|
|
|
|
}
|
|
|
|
|
|
|
|
if doInsertOrReplace {
|
|
|
|
_, err = tx.Exec(`
|
|
|
|
INSERT OR REPLACE INTO
|
|
|
|
keycards
|
|
|
|
(
|
|
|
|
keycard_uid,
|
|
|
|
keycard_name,
|
|
|
|
keycard_locked,
|
|
|
|
key_uid,
|
|
|
|
last_update_clock
|
|
|
|
)
|
|
|
|
VALUES
|
|
|
|
(?, ?, ?, ?, ?);`,
|
|
|
|
syncKp.KeycardUID, syncKp.KeycardName, syncKp.KeycardLocked, syncKp.KeyUID, syncKp.LastUpdateClock)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = kp.addAccounts(tx, syncKp.KeycardUID, syncKp.AccountsAddresses)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove those from the db if they are not in `keypairsToSync` and if they are older than the moment `keypairsToSync` was created at
|
|
|
|
for _, dbKp := range dbKeypairs {
|
|
|
|
if dbKp.LastUpdateClock > syncingClock {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
err = kp.deleteKeycard(tx, dbKp.KeycardUID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
func (kp *KeyPairs) RemoveMigratedAccountsForKeycard(kcUID string, accountAddresses []types.Address,
|
2023-02-21 12:35:26 +00:00
|
|
|
clock uint64) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
tx, proceed, err := kp.startTransactionAndCheckIfNeedToProceed(kcUID, clock)
|
|
|
|
defer func() {
|
|
|
|
if err == nil {
|
|
|
|
err = tx.Commit()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_ = tx.Rollback()
|
|
|
|
}()
|
|
|
|
|
2023-02-14 13:06:59 +00:00
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
|
|
|
|
if proceed {
|
|
|
|
err = kp.setLastUpdateClock(tx, kcUID, clock)
|
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dbAccountAddresses, err := kp.getAccountsForKeycard(tx, kcUID)
|
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
|
|
|
deleteKeycard := true
|
|
|
|
for _, dbAddr := range dbAccountAddresses {
|
|
|
|
found := false
|
|
|
|
for _, addr := range accountAddresses {
|
|
|
|
if dbAddr == addr {
|
|
|
|
found = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
deleteKeycard = false
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
|
|
|
}
|
2023-02-21 09:50:48 +00:00
|
|
|
|
|
|
|
if deleteKeycard {
|
2023-02-21 12:35:26 +00:00
|
|
|
return kp.deleteKeycard(tx, kcUID)
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
inVector := strings.Repeat(",?", len(accountAddresses)-1)
|
|
|
|
query := `
|
|
|
|
DELETE
|
|
|
|
FROM
|
|
|
|
keycards_accounts
|
|
|
|
WHERE
|
|
|
|
keycard_uid = ?
|
|
|
|
AND
|
|
|
|
account_address IN (?` + inVector + `)
|
|
|
|
`
|
|
|
|
delete, err := tx.Prepare(query)
|
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2023-02-14 13:06:59 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
args := make([]interface{}, len(accountAddresses)+1)
|
|
|
|
args[0] = kcUID
|
|
|
|
for i, addr := range accountAddresses {
|
|
|
|
args[i+1] = addr
|
|
|
|
}
|
2023-01-06 09:57:22 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
defer delete.Close()
|
2023-01-06 09:57:22 +00:00
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
_, err = delete.Exec(args...)
|
2023-01-06 09:57:22 +00:00
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2023-01-06 09:57:22 +00:00
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-01-06 09:57:22 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) execUpdateQuery(kcUID string, clock uint64, field string, value interface{}) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
tx, proceed, err := kp.startTransactionAndCheckIfNeedToProceed(kcUID, clock)
|
|
|
|
defer func() {
|
|
|
|
if err == nil {
|
|
|
|
err = tx.Commit()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_ = tx.Rollback()
|
|
|
|
}()
|
2022-09-20 10:45:50 +00:00
|
|
|
|
2022-09-06 07:10:40 +00:00
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
if proceed {
|
|
|
|
sql := fmt.Sprintf(`UPDATE keycards SET %s = ?, last_update_clock = ? WHERE keycard_uid = ?`, field) // nolint: gosec
|
|
|
|
_, err = tx.Exec(sql, value, clock, kcUID)
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2022-09-06 07:10:40 +00:00
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
return nil
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) KeycardLocked(kcUID string, clock uint64) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
return kp.execUpdateQuery(kcUID, clock, "keycard_locked", true)
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) KeycardUnlocked(kcUID string, clock uint64) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
return kp.execUpdateQuery(kcUID, clock, "keycard_locked", false)
|
2022-09-20 10:45:50 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) UpdateKeycardUID(oldKcUID string, newKcUID string, clock uint64) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
return kp.execUpdateQuery(oldKcUID, clock, "keycard_uid", newKcUID)
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) SetKeycardName(kcUID string, kpName string, clock uint64) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
return kp.execUpdateQuery(kcUID, clock, "keycard_name", kpName)
|
2023-02-14 13:06:59 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
func (kp *KeyPairs) DeleteKeycard(kcUID string, clock uint64) (err error) {
|
2023-02-21 09:50:48 +00:00
|
|
|
tx, proceed, err := kp.startTransactionAndCheckIfNeedToProceed(kcUID, clock)
|
|
|
|
defer func() {
|
|
|
|
if err == nil {
|
|
|
|
err = tx.Commit()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_ = tx.Rollback()
|
|
|
|
}()
|
|
|
|
|
2022-09-06 07:10:40 +00:00
|
|
|
if err != nil {
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 09:50:48 +00:00
|
|
|
if proceed {
|
2023-02-21 12:35:26 +00:00
|
|
|
return kp.deleteKeycard(tx, kcUID)
|
2023-02-21 09:50:48 +00:00
|
|
|
}
|
2022-09-06 07:10:40 +00:00
|
|
|
|
2023-02-21 12:35:26 +00:00
|
|
|
return err
|
2022-09-06 07:10:40 +00:00
|
|
|
}
|
2023-01-25 10:18:28 +00:00
|
|
|
|
|
|
|
func (kp *KeyPairs) DeleteKeypair(keyUID string) (err error) {
|
|
|
|
delete, err := kp.db.Prepare(`
|
|
|
|
DELETE
|
|
|
|
FROM
|
2023-02-14 13:06:59 +00:00
|
|
|
keycards
|
2023-01-25 10:18:28 +00:00
|
|
|
WHERE
|
|
|
|
key_uid = ?
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer delete.Close()
|
|
|
|
_, err = delete.Exec(keyUID)
|
|
|
|
return err
|
|
|
|
}
|