Skip to content

Commit

Permalink
feat: trustbloc#19 prepare bootstrap data in oidc callback
Browse files Browse the repository at this point in the history
Signed-off-by: George Aristy <george.aristy@securekey.com>
  • Loading branch information
George Aristy committed Jul 23, 2020
1 parent eea0e67 commit 0c709c8
Show file tree
Hide file tree
Showing 5 changed files with 449 additions and 48 deletions.
59 changes: 59 additions & 0 deletions pkg/bootstrap/user/userprofile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package user

import (
"encoding/json"
"fmt"

"github.com/trustbloc/edge-core/pkg/storage"
)

// Profile is the user's bootstrap profile.
type Profile struct {
Sub string
SDSPrimaryVaultID string
KeyStoreIDs []string
}

// ProfileStore is the user Profile CRUD API.
type ProfileStore struct {
s storage.Store
}

// NewStore returns a new ProfileStore.
func NewStore(s storage.Store) *ProfileStore {
return &ProfileStore{s: s}
}

// Save saves the user Profile.
func (ps *ProfileStore) Save(p *Profile) error {
bits, err := json.Marshal(p)

if err != nil {
return fmt.Errorf("failed to marshal user profile : %w", err)
}

err = ps.s.Put(p.Sub, bits)
if err != nil {
return fmt.Errorf("failed to save user profile : %w", err)
}

return nil
}

// Get fetches the user Profile.
func (ps *ProfileStore) Get(sub string) (*Profile, error) {
bits, err := ps.s.Get(sub)
if err != nil {
return nil, fmt.Errorf("failed to fetch user profile : %w", err)
}

p := &Profile{}

return p, json.Unmarshal(bits, p)
}
92 changes: 92 additions & 0 deletions pkg/bootstrap/user/userprofile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package user

import (
"encoding/json"
"errors"
"testing"

"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/trustbloc/edge-core/pkg/storage/mockstore"
)

func TestNewStore(t *testing.T) {
p := NewStore(&mockstore.MockStore{})
require.NotNil(t, p)
}

func TestSave(t *testing.T) {
t.Run("saves profile", func(t *testing.T) {
expected := &Profile{
Sub: uuid.New().String(),
SDSPrimaryVaultID: uuid.New().String(),
KeyStoreIDs: []string{uuid.New().String()},
}

store := &mockstore.MockStore{
Store: make(map[string][]byte),
}

err := NewStore(store).Save(expected)
require.NoError(t, err)
result := &Profile{}
err = json.Unmarshal(store.Store[expected.Sub], result)
require.NoError(t, err)
require.Equal(t, expected, result)
})

t.Run("wraps store error", func(t *testing.T) {
expected := errors.New("test")
store := &mockstore.MockStore{
Store: make(map[string][]byte),
ErrPut: expected,
}
err := NewStore(store).Save(&Profile{Sub: "test"})
require.True(t, errors.Is(err, expected))
})
}

func TestGet(t *testing.T) {
t.Run("fetches profile", func(t *testing.T) {
expected := &Profile{
Sub: uuid.New().String(),
SDSPrimaryVaultID: uuid.New().String(),
KeyStoreIDs: []string{uuid.New().String()},
}
store := &mockstore.MockStore{
Store: map[string][]byte{
expected.Sub: toBytes(t, expected),
},
}
result, err := NewStore(store).Get(expected.Sub)
require.NoError(t, err)
require.Equal(t, expected, result)
})

t.Run("wraps store error", func(t *testing.T) {
expected := errors.New("test")
store := &mockstore.MockStore{
Store: map[string][]byte{
"test": {},
},
ErrGet: expected,
}
_, err := NewStore(store).Get("test")
require.True(t, errors.Is(err, expected))
})
}

func toBytes(t *testing.T, v interface{}) []byte {
t.Helper()

bits, err := json.Marshal(v)
require.NoError(t, err)

return bits
}
109 changes: 109 additions & 0 deletions pkg/internal/common/mockstorage/storage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package mockstorage

import (
"errors"
"fmt"
"sync"

"github.com/trustbloc/edge-core/pkg/storage"
)

// Provider mock store provider.
type Provider struct {
Stores map[string]storage.Store
Store *MockStore
ErrCreateStore error
ErrOpenStoreHandle error
FailNameSpace string
}

// NewMockStoreProvider new store provider instance.
func NewMockStoreProvider() *Provider {
return &Provider{
Stores: make(map[string]storage.Store),
Store: &MockStore{
Store: make(map[string][]byte),
},
}
}

// CreateStore creates a new store with the given name.
func (p *Provider) CreateStore(name string) error {
return p.ErrCreateStore
}

// OpenStore opens and returns a store for given name space.
func (p *Provider) OpenStore(name string) (storage.Store, error) {
if name == p.FailNameSpace {
return nil, fmt.Errorf("failed to open store for name space %s", name)
}

if s, ok := p.Stores[name]; ok {
return s, nil
}

return p.Store, p.ErrOpenStoreHandle
}

// Close closes all stores created under this store provider.
func (p *Provider) Close() error {
return nil
}

// CloseStore closes store for given name space.
func (p *Provider) CloseStore(name string) error {
return nil
}

// MockStore represents a mock store.
type MockStore struct {
Store map[string][]byte
lock sync.RWMutex
ErrPut error
ErrGet error
ErrCreateIndex error
ErrQuery error
ResultsIteratorToReturn storage.ResultsIterator
}

// Put stores the key-value pair.
func (s *MockStore) Put(k string, v []byte) error {
if k == "" {
return errors.New("key is mandatory")
}

s.lock.Lock()
s.Store[k] = v
s.lock.Unlock()

return s.ErrPut
}

// Get fetches the value associated with the given key.
func (s *MockStore) Get(k string) ([]byte, error) {
s.lock.RLock()
defer s.lock.RUnlock()

val, ok := s.Store[k]
if !ok {
return nil, storage.ErrValueNotFound
}

return val, s.ErrGet
}

// CreateIndex returns a mocked error.
func (s *MockStore) CreateIndex(createIndexRequest storage.CreateIndexRequest) error {
return s.ErrCreateIndex
}

// Query returns a mocked error.
func (s *MockStore) Query(query string) (storage.ResultsIterator, error) {
return s.ResultsIteratorToReturn, s.ErrQuery
}
Loading

0 comments on commit 0c709c8

Please sign in to comment.