diff --git a/go.mod b/go.mod index f8746dd..4a7cc94 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/sirupsen/logrus v1.6.0 github.com/stretchr/testify v1.6.1 github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect diff --git a/go.sum b/go.sum index 40b19a8..8ca2daf 100644 --- a/go.sum +++ b/go.sum @@ -120,6 +120,8 @@ github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -175,6 +177,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I= github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE= @@ -228,6 +232,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c= diff --git a/keychain/leveldb/store.go b/keychain/leveldb/store.go new file mode 100644 index 0000000..6ea56f0 --- /dev/null +++ b/keychain/leveldb/store.go @@ -0,0 +1,76 @@ +package leveldb + +import ( + "encoding/json" + "errors" + + "github.com/DE-labtory/zulu/db/leveldb" + "github.com/DE-labtory/zulu/keychain" + "github.com/sirupsen/logrus" +) + +func NewKeyStore(handle *leveldb.DBHandle) *KeyStore { + return &KeyStore{handle: handle} +} + +type KeyStore struct { + handle *leveldb.DBHandle +} + +func (ks *KeyStore) Store(k keychain.Key) error { + rawData, err := json.Marshal(k) + if err != nil { + return err + } + err = ks.handle.Put([]byte(k.ID), rawData, true) + if err != nil { + return err + } + return nil +} + +func (ks *KeyStore) Get(id string) (keychain.Key, error) { + var k keychain.Key + rawData, err := ks.handle.Get([]byte(id)) + + // check leveldb error + if err != nil { + logrus.Error("error while find key :" + id + ", in level db key store") + return k, err + } + + // check empty data + if rawData == nil { + return k, errors.New("key not found") + } + + // check unmarshal data + err = json.Unmarshal(rawData, &k) + if err != nil { + logrus.Error("error while unmarshal key :" + id + ", in level db key store") + return k, err + } + + // with no err + return k, nil +} + +func (ks *KeyStore) GetAll() ([]keychain.Key, error) { + keys := make([]keychain.Key, 0) + iter := ks.handle.GetIteratorWithPrefix() + for iter.Next() { + key := iter.Key() + rawData := iter.Value() + + var k keychain.Key + err := json.Unmarshal(rawData, &k) + if err != nil { + logrus.Error("error while unmarshal key :" + string(key) + ", in level db key store") + continue + } + + keys = append(keys, k) + } + + return keys, nil +} diff --git a/keychain/leveldb/store_test.go b/keychain/leveldb/store_test.go new file mode 100644 index 0000000..894a868 --- /dev/null +++ b/keychain/leveldb/store_test.go @@ -0,0 +1,146 @@ +package leveldb + +import ( + "encoding/json" + "os" + "testing" + + "github.com/DE-labtory/zulu/db/leveldb" + "github.com/DE-labtory/zulu/keychain" + "github.com/stretchr/testify/assert" +) + +const TestDbPath = "./test_db_path" + +var gracefulTestDown = func(t *testing.T, provider *leveldb.DBProvider) { + provider.Close() + err := os.RemoveAll(TestDbPath) + if err != nil { + t.Log(err.Error()) + } +} + +func TestKeyStore_Get(t *testing.T) { + // set + dbProvider := leveldb.CreateNewDBProvider(TestDbPath) + defer gracefulTestDown(t, dbProvider) + keyStoreHandle := dbProvider.GetDBHandle("keystore") + + // given + keyId := "testKeyId" + keyData := keychain.Key{ + ID: keyId, + PrivateKey: []byte("testPrivateKey"), + PublicKey: []byte("testPublicKey"), + } + rawData, err := json.Marshal(keyData) + assert.NoError(t, err) + + err = keyStoreHandle.Put([]byte(keyId), rawData, true) + assert.NoError(t, err) + + keyStore := NewKeyStore(keyStoreHandle) + + // when + retrieveKey, err := keyStore.Get(keyId) + + // then + assert.NoError(t, err) + assert.Equal(t, keyData, retrieveKey) +} + +func TestKeyStore_GetNotFound(t *testing.T) { + // set + dbProvider := leveldb.CreateNewDBProvider(TestDbPath) + defer gracefulTestDown(t, dbProvider) + keyStoreHandle := dbProvider.GetDBHandle("keystore") + + // given + keyId := "testKeyId" + keyData := keychain.Key{ + ID: keyId, + PrivateKey: []byte("testPrivateKey"), + PublicKey: []byte("testPublicKey"), + } + rawData, err := json.Marshal(keyData) + assert.NoError(t, err) + + err = keyStoreHandle.Put([]byte(keyId), rawData, true) + assert.NoError(t, err) + + keyStore := NewKeyStore(keyStoreHandle) + + // when + retrieveKey, err := keyStore.Get(keyId + "NOT_FOUND") + + // then + assert.Error(t, err) + assert.Equal(t, keychain.Key{}, retrieveKey) +} + +func TestKeyStore_Store(t *testing.T) { + // set + dbProvider := leveldb.CreateNewDBProvider(TestDbPath) + defer gracefulTestDown(t, dbProvider) + keyStoreHandle := dbProvider.GetDBHandle("keystore") + + // given + keyId := "testKeyId" + keyData := keychain.Key{ + ID: keyId, + PrivateKey: []byte("testPrivateKey"), + PublicKey: []byte("testPublicKey"), + } + rawData, err := json.Marshal(keyData) + assert.NoError(t, err) + + keyStore := NewKeyStore(keyStoreHandle) + + // when + err = keyStore.Store(keyData) + + // then + assert.NoError(t, err) + + d, err := keyStoreHandle.Get([]byte(keyId)) + assert.NoError(t, err) + assert.Equal(t, rawData, d) + +} + +func TestKeyStore_GetAll(t *testing.T) { + // set + dbProvider := leveldb.CreateNewDBProvider(TestDbPath) + defer gracefulTestDown(t, dbProvider) + keyStoreHandle := dbProvider.GetDBHandle("keystore") + + // given + keyId1 := "testKeyId1" + keyData1 := keychain.Key{ + ID: keyId1, + PrivateKey: []byte("testPrivateKey1"), + PublicKey: []byte("testPublicKey1"), + } + + keyId2 := "testKeyId2" + keyData2 := keychain.Key{ + ID: keyId2, + PrivateKey: []byte("testPrivateKey2"), + PublicKey: []byte("testPublicKey2"), + } + + keyStore := NewKeyStore(keyStoreHandle) + err := keyStore.Store(keyData1) + assert.NoError(t, err) + + err = keyStore.Store(keyData2) + assert.NoError(t, err) + + // when + loadKeys, err := keyStore.GetAll() + + // then + assert.NoError(t, err) + assert.Len(t, loadKeys, 2) + +}