package client // // Storage // import ( "crypto/sha256" "encoding/json" "path/filepath" "forge.redroom.link/yves/meowlib" "github.com/dgraph-io/badger" ) type PeerStorage struct { DbFile string `json:"db_file,omitempty"` db *badger.DB } // Open a badger database from struct PeerStorage func (ps *PeerStorage) open() error { opts := badger.DefaultOptions(filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, ps.DbFile)) opts.Logger = nil var err error ps.db, err = badger.Open(opts) if err != nil { return err } return nil } // Store function StorePeer stores a peer in a badger database with Peer.Uid as key func (ps *PeerStorage) StorePeer(peer *Peer) error { err := ps.open() if err != nil { return err } defer ps.close() // first marshal the Peer to bytes with protobuf jsonsrv, err := json.Marshal(peer) if err != nil { return err } password := GetConfig().memoryPassword if peer.dbPassword != "" { password = peer.dbPassword } data, err := meowlib.SymEncrypt(password, jsonsrv) if err != nil { return err } shakey := sha256.Sum256([]byte(peer.Uid)) key := shakey[:] // then store it in the database return ps.db.Update(func(txn *badger.Txn) error { return txn.Set(key, data) }) } // LoadPeer function loads a Peer from a badger database with Peer.GetUid() as key func (ps *PeerStorage) LoadPeer(uid string, password string) (*Peer, error) { var peer Peer err := ps.open() if err != nil { return nil, err } defer ps.close() shakey := sha256.Sum256([]byte(uid)) key := shakey[:] err = ps.db.View(func(txn *badger.Txn) error { item, err := txn.Get(key) if err != nil { return err } return item.Value(func(val []byte) error { jsonsrv, err := meowlib.SymDecrypt(password, val) if err != nil { return err } return json.Unmarshal(jsonsrv, &peer) }) }) return &peer, err } // DeletePeer function deletes a Peer from a badger database with Peer.GetUid() as key func (ps *PeerStorage) DeletePeer(uid string) error { err := ps.open() if err != nil { return err } defer ps.close() shakey := sha256.Sum256([]byte(uid)) key := shakey[:] return ps.db.Update(func(txn *badger.Txn) error { return txn.Delete(key) }) } // LoadAllPeers function loads all Peers from a badger database func (ps *PeerStorage) LoadAllPeers(password string) ([]*Peer, error) { var peers []*Peer err := ps.open() if err != nil { return nil, err } defer ps.close() err = ps.db.View(func(txn *badger.Txn) error { opts := badger.DefaultIteratorOptions opts.PrefetchSize = 10 it := txn.NewIterator(opts) defer it.Close() for it.Rewind(); it.Valid(); it.Next() { item := it.Item() var sc Peer err := item.Value(func(val []byte) error { jsonsrv, err := meowlib.SymDecrypt(password, val) if err != nil { return err } return json.Unmarshal(jsonsrv, &sc) }) if err != nil { peers = append(peers, &sc) } } return nil }) return peers, err } // LoadPeersFromUids function loads Peers with id in []Uid parameter from a badger database func (ps *PeerStorage) LoadPeersFromUids(uids []string, password string) ([]*Peer, error) { var peers []*Peer err := ps.open() if err != nil { return nil, err } defer ps.close() err = ps.db.View(func(txn *badger.Txn) error { for _, uid := range uids { shakey := sha256.Sum256([]byte(uid)) key := shakey[:] item, err := txn.Get(key) if err != nil { return err } var sc Peer err = item.Value(func(val []byte) error { jsonsrv, err := meowlib.SymDecrypt(password, val) if err != nil { return err } return json.Unmarshal(jsonsrv, &sc) }) if err == nil { peers = append(peers, &sc) } } return nil }) return peers, err } // close a badger database func (ps *PeerStorage) close() { ps.db.Close() }