summaryrefslogtreecommitdiff
path: root/internal/storer
diff options
context:
space:
mode:
authorAlexander Kiryukhin <a.kiryukhin@mail.ru>2021-03-18 02:06:42 +0300
committerAlexander Kiryukhin <a.kiryukhin@mail.ru>2021-03-18 02:06:42 +0300
commit6f31f35c7b38fbf63d7a0c9322458e0b75828495 (patch)
tree2fcb8cb31bb6604e85cf390dbc01f2e9a8b26ee7 /internal/storer
Initial
Diffstat (limited to 'internal/storer')
-rw-r--r--internal/storer/storer.go124
1 files changed, 124 insertions, 0 deletions
diff --git a/internal/storer/storer.go b/internal/storer/storer.go
new file mode 100644
index 0000000..b8b4ffd
--- /dev/null
+++ b/internal/storer/storer.go
@@ -0,0 +1,124 @@
+package storer
+
+import (
+ "bytes"
+ "encoding/gob"
+ "time"
+
+ "github.com/dgraph-io/badger"
+ "github.com/neonxp/sendsafe/internal/encryption"
+ "github.com/rs/xid"
+)
+
+type Store struct {
+ db *badger.DB
+}
+
+func New(dbFile string) (*Store, error) {
+ db, err := badger.Open(badger.DefaultOptions(dbFile))
+ if err != nil {
+ return nil, err
+ }
+
+ return &Store{
+ db: db,
+ }, nil
+}
+
+func (s *Store) Save(text string, pin string, ttl int) (string, error) {
+ var err error
+
+ encrypted := false
+
+ if pin != "" {
+ text, err = encryption.Encrypt([]byte(pin), text)
+ if err != nil {
+ return "", err
+ }
+
+ encrypted = true
+ }
+
+ record := memo{
+ Text: text,
+ Encrypted: encrypted,
+ }
+
+ buf := bytes.NewBuffer([]byte{})
+ if err := gob.NewEncoder(buf).Encode(record); err != nil {
+ return "", err
+ }
+
+ id := xid.New()
+ err = s.db.Update(func(txn *badger.Txn) error {
+ return txn.SetEntry(&badger.Entry{
+ Key: id.Bytes(),
+ Value: buf.Bytes(),
+ ExpiresAt: uint64(time.Now().Add(time.Duration(ttl) * time.Minute).Unix()),
+ })
+ })
+
+ return id.String(), err
+}
+
+func (s *Store) IsEncrypted(id string) (bool, error) {
+ var encrypted bool
+
+ return encrypted, s.db.View(func(txn *badger.Txn) error {
+ value, err := txn.Get([]byte(id))
+ if err != nil {
+ return err
+ }
+ record := new(memo)
+ return value.Value(func(val []byte) error {
+ if err := gob.NewDecoder(bytes.NewBuffer(val)).Decode(record); err != nil {
+ return err
+ }
+ encrypted = record.Encrypted
+ return nil
+ })
+ })
+}
+
+func (s *Store) Get(id string, pin string) (string, error) {
+ var text string
+
+ return text, s.db.Update(func(txn *badger.Txn) error {
+ uid, err := xid.FromString(id)
+ if err != nil {
+ return err
+ }
+ value, err := txn.Get(uid.Bytes())
+ if err != nil {
+ return err
+ }
+ record := new(memo)
+ err = value.Value(func(val []byte) error {
+ if err := gob.NewDecoder(bytes.NewBuffer(val)).Decode(record); err != nil {
+ return err
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ text = record.Text
+ if record.Encrypted {
+ text, err = encryption.Decrypt([]byte(pin), text)
+ if err != nil {
+ return err
+ }
+ }
+ return txn.Delete(uid.Bytes())
+ })
+}
+
+func init() {
+ gob.Register(memo{})
+}
+
+type memo struct {
+ Text string
+ Encrypted bool
+}