From 64a4b5b873da83a8c25764b1572b730e7d94566c Mon Sep 17 00:00:00 2001 From: Firas Qutishat Date: Thu, 30 Jan 2020 10:55:13 -0500 Subject: [PATCH] fix: Store vc directly in indexeddb closes #43 Signed-off-by: Firas Qutishat --- ci/version_var.sh | 4 +-- pkg/store/vc/store.go | 54 ++++++++++++++++++++----------------- pkg/store/vc/store_test.go | 55 +++++++++++++------------------------- 3 files changed, 49 insertions(+), 64 deletions(-) diff --git a/ci/version_var.sh b/ci/version_var.sh index b33cf2bd..7ae0e1d1 100644 --- a/ci/version_var.sh +++ b/ci/version_var.sh @@ -7,8 +7,8 @@ # Release Parameters -BASE_VERSION=0.1.2 -IS_RELEASE=false +BASE_VERSION=0.1.1 +IS_RELEASE=true ARCH=$(go env GOARCH) diff --git a/pkg/store/vc/store.go b/pkg/store/vc/store.go index f7151b04..d9007a4a 100644 --- a/pkg/store/vc/store.go +++ b/pkg/store/vc/store.go @@ -9,13 +9,12 @@ SPDX-License-Identifier: Apache-2.0 package vc import ( + "encoding/json" "fmt" "strings" "syscall/js" - "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" "github.com/hyperledger/aries-framework-go/pkg/storage" - verifiablestore "github.com/hyperledger/aries-framework-go/pkg/store/verifiable" ) const ( @@ -26,24 +25,19 @@ type provider interface { StorageProvider() storage.Provider } -type vcStore interface { - SaveVC(vc *verifiable.Credential) error - GetVC(vcID string) (*verifiable.Credential, error) -} - // RegisterHandleJSCallback register handle vc store js callback func RegisterHandleJSCallback(ctx provider) error { - store, err := verifiablestore.New(ctx) + vcFriendlyNameStore, err := ctx.StorageProvider().OpenStore("vc-friendlyname") if err != nil { - return fmt.Errorf("failed to create new instance of verifiable store: %w", err) + return fmt.Errorf("failed to open vc frindly name store: %w", err) } - vcFriendlyNameStore, err := ctx.StorageProvider().OpenStore("vc-friendlyname") + vcStore, err := ctx.StorageProvider().OpenStore("verifiable") if err != nil { return fmt.Errorf("failed to open vc frindly name store: %w", err) } - c := callback{store: store, vcFriendlyNameStore: vcFriendlyNameStore, jsDoc: js.Global().Get("document")} + c := callback{vcStore: vcStore, vcFriendlyNameStore: vcFriendlyNameStore, jsDoc: js.Global().Get("document")} js.Global().Set("storeVC", js.FuncOf(c.storeVC)) js.Global().Set("populateVC", js.FuncOf(c.populateVC)) js.Global().Set("getVC", js.FuncOf(c.getVC)) @@ -52,7 +46,7 @@ func RegisterHandleJSCallback(ctx provider) error { } type callback struct { - store vcStore + vcStore storage.Store vcFriendlyNameStore storage.Store jsDoc js.Value } @@ -64,20 +58,28 @@ func (c *callback) storeVC(this js.Value, inputs []js.Value) interface{} { m["dataType"] = "Response" m["data"] = "success" vcData := inputs[0].Get("credential").Get("data").String() - vc, _, err := verifiable.NewCredential([]byte(vcData)) - if err != nil { - m["data"] = fmt.Sprintf("failed to create new credential: %s", err.Error()) + + var vcMap map[string]interface{} + if err := json.Unmarshal([]byte(vcData), &vcMap); err != nil { + m["data"] = fmt.Sprintf("failed to unmarshal vc json: %s", err.Error()) + inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m)) + return + } + + vcID := stringEntry(vcMap["id"]) + if vcID == "" { + m["data"] = fmt.Sprintf("vc id not exist") inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m)) return } - if err := c.store.SaveVC(vc); err != nil { + if err := c.vcStore.Put(vcID, []byte(vcData)); err != nil { m["data"] = fmt.Sprintf("failed to put in vc store: %s", err.Error()) inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m)) return } - if err := c.vcFriendlyNameStore.Put(friendlyNamePreFix+inputs[1].String(), []byte(vc.ID)); err != nil { + if err := c.vcFriendlyNameStore.Put(friendlyNamePreFix+inputs[1].String(), []byte(vcID)); err != nil { m["data"] = fmt.Sprintf("failed to put in vc friendly name store: %s", err.Error()) } @@ -116,23 +118,25 @@ func (c *callback) getVC(this js.Value, inputs []js.Value) interface{} { return } - vc, err := c.store.GetVC(string(vcID)) + vcBytes, err := c.vcStore.Get(string(vcID)) if err != nil { m["data"] = fmt.Sprintf("failed to get in vc store: %s", err.Error()) inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m)) return } - vcBytes, err := vc.MarshalJSON() - if err != nil { - m["data"] = fmt.Sprintf("failed to marshal vc: %s", err.Error()) - inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m)) - return - } - m["data"] = string(vcBytes) inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m)) }() return nil } + +// stringEntry +func stringEntry(entry interface{}) string { + if entry == nil { + return "" + } + + return entry.(string) +} diff --git a/pkg/store/vc/store_test.go b/pkg/store/vc/store_test.go index 012e7e57..2d996082 100644 --- a/pkg/store/vc/store_test.go +++ b/pkg/store/vc/store_test.go @@ -14,8 +14,8 @@ import ( "testing" "time" - "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" "github.com/hyperledger/aries-framework-go/pkg/storage" + "github.com/stretchr/testify/require" mockstorage "github.com/trustbloc/edge-agent/pkg/internal/mock/storage" ) @@ -54,23 +54,15 @@ var credential = ` func TestRegisterHandleInvitationJSCallback(t *testing.T) { t.Run("test success", func(t *testing.T) { - require.NoError(t, RegisterHandleJSCallback(&mockProvider{ - storageProviderValue: &mockstorage.MockStoreProvider{}})) + require.NoError(t, RegisterHandleJSCallback( + &mockProvider{storageProviderValue: &mockstorage.MockStoreProvider{}})) require.True(t, js.Global().Get("storeVC").Truthy()) }) - - t.Run("test error from open store", func(t *testing.T) { - err := RegisterHandleJSCallback(&mockProvider{ - storageProviderValue: &mockstorage.MockStoreProvider{ - ErrOpenStoreHandle: fmt.Errorf("open store error")}}) - require.Error(t, err) - require.Contains(t, err.Error(), "open store error") - }) } func TestStoreVC(t *testing.T) { t.Run("test error from new credential", func(t *testing.T) { - c := callback{store: &mockVCStore{}} + c := callback{vcStore: &mockstorage.MockStore{}} m := make(map[string]interface{}) m1 := make(map[string]interface{}) m1["data"] = "wrongVC" @@ -93,14 +85,14 @@ func TestStoreVC(t *testing.T) { select { case value := <-valueFlag: require.Equal(t, "Response", value.Get("dataType").String()) - require.Contains(t, value.Get("data").String(), "failed to create new credential") + require.Contains(t, value.Get("data").String(), "failed to unmarshal vc json") case <-time.After(2 * time.Second): require.Fail(t, "timeout waiting for response") } }) t.Run("test error from vc store", func(t *testing.T) { - c := callback{store: &mockVCStore{saveVCError: fmt.Errorf("put error")}} + c := callback{vcStore: &mockstorage.MockStore{ErrPut: fmt.Errorf("put error")}} m := make(map[string]interface{}) m1 := make(map[string]interface{}) m1["data"] = credential @@ -130,7 +122,8 @@ func TestStoreVC(t *testing.T) { }) t.Run("test error from vc friendly name store", func(t *testing.T) { - c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{ErrPut: fmt.Errorf("error put")}} + c := callback{vcStore: &mockstorage.MockStore{ + Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{ErrPut: fmt.Errorf("error put")}} m := make(map[string]interface{}) m1 := make(map[string]interface{}) m1["data"] = credential @@ -160,7 +153,8 @@ func TestStoreVC(t *testing.T) { }) t.Run("test success", func(t *testing.T) { - c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{ + c := callback{vcStore: &mockstorage.MockStore{ + Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{ Store: make(map[string][]byte)}} m := make(map[string]interface{}) m1 := make(map[string]interface{}) @@ -195,7 +189,8 @@ func TestPopulateVC(t *testing.T) { t.Run("test success", func(t *testing.T) { s := make(map[string][]byte) js.Global().Set("document1", make(map[string]interface{})) - c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{ + c := callback{vcStore: &mockstorage.MockStore{ + Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{ Store: s}, jsDoc: js.Global().Get("document")} c.jsDoc.Set("createElement", js.FuncOf(func(this js.Value, args []js.Value) interface{} { m := make(map[string]interface{}) @@ -225,7 +220,8 @@ func TestPopulateVC(t *testing.T) { func TestGetVC(t *testing.T) { t.Run("test error from vc friendly name store", func(t *testing.T) { - c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{ErrGet: fmt.Errorf("error get")}} + c := callback{vcStore: &mockstorage.MockStore{ + Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{ErrGet: fmt.Errorf("error get")}} m := make(map[string]interface{}) vcEvent := js.ValueOf(m) @@ -254,9 +250,7 @@ func TestGetVC(t *testing.T) { t.Run("test error from vc store", func(t *testing.T) { s := make(map[string][]byte) - c := callback{store: &mockVCStore{getVCFunc: func(vcID string) (v *verifiable.Credential, err error) { - return nil, fmt.Errorf("vc store error") - }}, + c := callback{vcStore: &mockstorage.MockStore{ErrGet: fmt.Errorf("vc store error")}, vcFriendlyNameStore: &mockstorage.MockStore{Store: s}} s[friendlyNamePreFix+"key"] = []byte("vcKey") @@ -288,11 +282,11 @@ func TestGetVC(t *testing.T) { t.Run("test success", func(t *testing.T) { s := make(map[string][]byte) - c := callback{store: &mockVCStore{getVCFunc: func(vcID string) (v *verifiable.Credential, err error) { - return &verifiable.Credential{ID: "vcID"}, nil - }}, + c := callback{vcStore: &mockstorage.MockStore{ + Store: s}, vcFriendlyNameStore: &mockstorage.MockStore{Store: s}} + s["vcKey"] = []byte("vcID") s[friendlyNamePreFix+"key"] = []byte("vcKey") m := make(map[string]interface{}) @@ -328,16 +322,3 @@ type mockProvider struct { func (m *mockProvider) StorageProvider() storage.Provider { return m.storageProviderValue } - -type mockVCStore struct { - saveVCError error - getVCFunc func(vcID string) (*verifiable.Credential, error) -} - -func (m *mockVCStore) SaveVC(vc *verifiable.Credential) error { - return m.saveVCError -} - -func (m *mockVCStore) GetVC(vcID string) (*verifiable.Credential, error) { - return m.getVCFunc(vcID) -}