diff --git a/cmd/aries-agent-mobile/go.sum b/cmd/aries-agent-mobile/go.sum index 04b5ff3494..9ae53c89a8 100644 --- a/cmd/aries-agent-mobile/go.sum +++ b/cmd/aries-agent-mobile/go.sum @@ -174,6 +174,7 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210422133815-2ef2d99cb692 h1:anEytYaCtUeVS4UpivolNp8S4ZPLIQaBrJAiZMh5CwE= github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210422133815-2ef2d99cb692/go.mod h1:Vw8AblyCa1h6mVbNvbMXeZdlXVGu6Cq+TXZhD4oqvwE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= diff --git a/cmd/aries-agent-rest/go.sum b/cmd/aries-agent-rest/go.sum index 7e0d2947a6..4108e5e81b 100644 --- a/cmd/aries-agent-rest/go.sum +++ b/cmd/aries-agent-rest/go.sum @@ -206,6 +206,7 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210422133815-2ef2d99cb692 h1:anEytYaCtUeVS4UpivolNp8S4ZPLIQaBrJAiZMh5CwE= github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210422133815-2ef2d99cb692/go.mod h1:Vw8AblyCa1h6mVbNvbMXeZdlXVGu6Cq+TXZhD4oqvwE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= diff --git a/cmd/aries-js-worker/go.sum b/cmd/aries-js-worker/go.sum index dd4daa3246..31f5ae2634 100644 --- a/cmd/aries-js-worker/go.sum +++ b/cmd/aries-js-worker/go.sum @@ -174,6 +174,7 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210422133815-2ef2d99cb692 h1:anEytYaCtUeVS4UpivolNp8S4ZPLIQaBrJAiZMh5CwE= github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20210422133815-2ef2d99cb692/go.mod h1:Vw8AblyCa1h6mVbNvbMXeZdlXVGu6Cq+TXZhD4oqvwE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= diff --git a/pkg/controller/command/vcwallet/command.go b/pkg/controller/command/vcwallet/command.go index 9359a21fb0..adaba1c705 100644 --- a/pkg/controller/command/vcwallet/command.go +++ b/pkg/controller/command/vcwallet/command.go @@ -22,6 +22,7 @@ import ( "github.com/hyperledger/aries-framework-go/pkg/crypto" "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr" "github.com/hyperledger/aries-framework-go/pkg/internal/logutil" + "github.com/hyperledger/aries-framework-go/pkg/kms/webkms" "github.com/hyperledger/aries-framework-go/pkg/wallet" "github.com/hyperledger/aries-framework-go/spi/storage" ) @@ -102,6 +103,28 @@ const ( emptyRawLength = 4 ) +// HTTPHeaderSigner is for http header signing, typically used for zcapld functionality. +type HTTPHeaderSigner interface { + // SignHeader header with capability. + SignHeader(req *http.Request, capabilityBytes []byte) (*http.Header, error) +} + +// Config contains properties to customize verifiable credential wallet controller. +// All properties of this config are optional, but they can be used to customize wallet's webkms and edv client's. +type Config struct { + // EDV header signer, typically used for introducing zcapld feature. + EdvAuthSigner HTTPHeaderSigner + // Web KMS header signer, typically used for introducing zcapld feature. + WebKMSAuthSigner HTTPHeaderSigner + // option is a performance optimization that speeds up queries by getting full documents from + // the EDV server instead of only document locations. + EDVReturnFullDocumentsOnQuery bool + // this EDV option is a performance optimization that allows for restStore.Batch to only require one REST call. + EDVBatchEndpointExtensionEnabled bool + // Aries Web KMS cache size configuration. + WebKMSCacheSize int +} + // provider contains dependencies for the verifiable credential wallet command controller // and is typically created by using aries.Context(). type provider interface { @@ -113,12 +136,19 @@ type provider interface { // Command contains operations provided by verifiable credential wallet controller. type Command struct { - ctx provider + ctx provider + config *Config } // New returns new verifiable credential wallet controller command instance. -func New(p provider) *Command { - return &Command{ctx: p} +func New(p provider, config *Config) *Command { + cmd := &Command{ctx: p, config: &Config{}} + + if config != nil { + cmd.config = config + } + + return cmd } // GetHandlers returns list of all commands supported by this controller command. @@ -218,7 +248,7 @@ func (o *Command) Open(rw io.Writer, req io.Reader) command.Error { return command.NewExecuteError(OpenWalletErrorCode, err) } - token, err := vcWallet.Open(prepareUnlockOptions(request)...) + token, err := vcWallet.Open(prepareUnlockOptions(request, o.config)...) if err != nil { logutil.LogInfo(logger, CommandName, OpenMethod, err.Error()) @@ -586,31 +616,67 @@ func prepareProfileOptions(rqst *CreateOrUpdateProfileRequest) []wallet.ProfileO } // prepareUnlockOptions prepares options for unlocking wallet. -func prepareUnlockOptions(rqst *UnlockWalletRequest) []wallet.UnlockOptions { +func prepareUnlockOptions(rqst *UnlockWalletRequest, conf *Config) []wallet.UnlockOptions { // nolint:funlen,gocyclo var options []wallet.UnlockOptions if rqst.LocalKMSPassphrase != "" { options = append(options, wallet.WithUnlockByPassphrase(rqst.LocalKMSPassphrase)) } - if rqst.WebKMSAuth != "" { - options = append(options, wallet.WithUnlockByAuthorizationToken(rqst.LocalKMSPassphrase)) + var webkmsOpts []webkms.Opt + + if rqst.WebKMSAuth != nil { + if rqst.WebKMSAuth.AuthToken != "" { + webkmsOpts = append(webkmsOpts, webkms.WithHeaders( + func(req *http.Request) (*http.Header, error) { + req.Header.Set("authorization", fmt.Sprintf("Bearer %s", rqst.EDVUnlock.AuthToken)) + + return &req.Header, nil + }, + )) + } else if rqst.WebKMSAuth.Capability != "" && conf.WebKMSAuthSigner != nil { + webkmsOpts = append(webkmsOpts, webkms.WithHeaders( + func(req *http.Request) (*http.Header, error) { + return conf.EdvAuthSigner.SignHeader(req, []byte(rqst.WebKMSAuth.Capability)) + }, + )) + } + } + + if conf.WebKMSCacheSize > 0 { + webkmsOpts = append(webkmsOpts, webkms.WithCache(conf.WebKMSCacheSize)) } - // TODO edv sign header function for zcap support #2433 + var edvOpts []edv.RESTProviderOption + if rqst.EDVUnlock != nil { if rqst.EDVUnlock.AuthToken != "" { - options = append(options, wallet.WithUnlockEDVOptions(edv.WithHeaders( + edvOpts = append(edvOpts, edv.WithHeaders( func(req *http.Request) (*http.Header, error) { req.Header.Set("authorization", fmt.Sprintf("Bearer %s", rqst.EDVUnlock.AuthToken)) return &req.Header, nil }, - ))) + )) + } else if rqst.EDVUnlock.Capability != "" && conf.EdvAuthSigner != nil { + edvOpts = append(edvOpts, edv.WithHeaders( + func(req *http.Request) (*http.Header, error) { + return conf.EdvAuthSigner.SignHeader(req, []byte(rqst.EDVUnlock.Capability)) + }, + )) } } - // TODO web kms sign header function for zcap support #2433 + if conf.EDVBatchEndpointExtensionEnabled { + edvOpts = append(edvOpts, edv.WithBatchEndpointExtension()) + } + + if conf.EDVReturnFullDocumentsOnQuery { + edvOpts = append(edvOpts, edv.WithFullDocumentsReturnedFromQueries()) + } + + options = append(options, wallet.WithUnlockWebKMSOptions(webkmsOpts...), wallet.WithUnlockEDVOptions(edvOpts...)) + return options } diff --git a/pkg/controller/command/vcwallet/command_test.go b/pkg/controller/command/vcwallet/command_test.go index fd964ad70d..6bbf73b851 100644 --- a/pkg/controller/command/vcwallet/command_test.go +++ b/pkg/controller/command/vcwallet/command_test.go @@ -42,6 +42,7 @@ const ( sampleEDVMacKID = "sample-edv-mac-kid" sampleCommandError = "sample-command-error-01" sampleFakeTkn = "sample-fake-token-01" + sampleFakeCapability = "sample-fake-capability-01" sampleDIDKey = "did:key:z6MknC1wwS6DEYwtGbZZo2QvjQjkh2qSBjb4GYmbye8dv4S5" sampleUDCVC = `{ "@context": [ @@ -233,7 +234,7 @@ const ( func TestNew(t *testing.T) { t.Run("successfully create new command instance", func(t *testing.T) { - cmd := New(newMockProvider(t)) + cmd := New(newMockProvider(t), &Config{}) require.NotNil(t, cmd) require.Len(t, cmd.GetHandlers(), 13) @@ -244,7 +245,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("successfully create a new wallet profile (localkms)", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) request := &CreateOrUpdateProfileRequest{ @@ -265,7 +266,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("successfully create a new wallet profile (webkms/remotekms)", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) request := &CreateOrUpdateProfileRequest{ @@ -286,7 +287,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("successfully create a new wallet profile with EDV configuration", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) // create with remote kms. @@ -333,7 +334,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("failed to create duplicate profile", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) request := &CreateOrUpdateProfileRequest{ @@ -360,7 +361,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("failed to create profile due to invalid settings", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) request := &CreateOrUpdateProfileRequest{ @@ -377,7 +378,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("failed to create profile due to invalid request", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) var b1 bytes.Buffer @@ -390,7 +391,7 @@ func TestCommand_CreateProfile(t *testing.T) { t.Run("failed to create profile due to EDV key set creation failure", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) mockStProv, ok := mockctx.StorageProviderValue.(*mockstorage.MockStoreProvider) @@ -420,7 +421,7 @@ func TestCommand_CreateProfile(t *testing.T) { func TestCommand_UpdateProfile(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) require.NotNil(t, cmd) createRqst := &CreateOrUpdateProfileRequest{ @@ -521,7 +522,7 @@ func TestCommand_OpenAndClose(t *testing.T) { }) t.Run("successfully unlock & lock wallet (local kms)", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) request := &UnlockWalletRequest{ UserID: sampleUser1, @@ -559,11 +560,51 @@ func TestCommand_OpenAndClose(t *testing.T) { }) t.Run("successfully unlock & lock wallet (remote kms)", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) request := &UnlockWalletRequest{ UserID: sampleUser2, - WebKMSAuth: sampleFakeTkn, + WebKMSAuth: &UnlockAuth{AuthToken: sampleFakeTkn}, + } + + // unlock wallet + var b bytes.Buffer + cmdErr := cmd.Open(&b, getReader(t, &request)) + require.NoError(t, cmdErr) + require.NotEmpty(t, getUnlockToken(t, b)) + b.Reset() + + // try again, should get error, wallet already unlocked + cmdErr = cmd.Open(&b, getReader(t, &request)) + require.Error(t, cmdErr) + require.Contains(t, cmdErr.Error(), wallet.ErrAlreadyUnlocked.Error()) + require.Empty(t, b.Len()) + b.Reset() + + // lock wallet + cmdErr = cmd.Close(&b, getReader(t, &LockWalletRequest{UserID: sampleUser2})) + require.NoError(t, cmdErr) + var lockResponse LockWalletResponse + require.NoError(t, json.NewDecoder(&b).Decode(&lockResponse)) + require.True(t, lockResponse.Closed) + b.Reset() + + // lock wallet again + cmdErr = cmd.Close(&b, getReader(t, &LockWalletRequest{UserID: sampleUser2})) + require.NoError(t, cmdErr) + require.NoError(t, json.NewDecoder(&b).Decode(&lockResponse)) + require.False(t, lockResponse.Closed) + b.Reset() + }) + + t.Run("successfully unlock & lock wallet (remote kms, capability)", func(t *testing.T) { + cmd := New(mockctx, &Config{ + WebKMSCacheSize: 99, + }) + + request := &UnlockWalletRequest{ + UserID: sampleUser2, + WebKMSAuth: &UnlockAuth{Capability: sampleFakeCapability}, } // unlock wallet @@ -597,12 +638,12 @@ func TestCommand_OpenAndClose(t *testing.T) { }) t.Run("successfully unlock & lock wallet (local kms, edv user)", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) request := &UnlockWalletRequest{ UserID: sampleUser3, LocalKMSPassphrase: samplePassPhrase, - EDVUnlock: &EDVUnlockRequest{ + EDVUnlock: &UnlockAuth{ AuthToken: sampleFakeTkn, }, } @@ -637,8 +678,52 @@ func TestCommand_OpenAndClose(t *testing.T) { b.Reset() }) + t.Run("successfully unlock & lock wallet (local kms, edv capability user)", func(t *testing.T) { + cmd := New(mockctx, &Config{ + EDVReturnFullDocumentsOnQuery: true, + EDVBatchEndpointExtensionEnabled: true, + }) + + request := &UnlockWalletRequest{ + UserID: sampleUser3, + LocalKMSPassphrase: samplePassPhrase, + EDVUnlock: &UnlockAuth{ + Capability: sampleFakeCapability, + }, + } + + // unlock wallet + var b bytes.Buffer + cmdErr := cmd.Open(&b, getReader(t, &request)) + require.NoError(t, cmdErr) + require.NotEmpty(t, getUnlockToken(t, b)) + b.Reset() + + // try again, should get error, wallet already unlocked + cmdErr = cmd.Open(&b, getReader(t, &request)) + require.Error(t, cmdErr) + require.Contains(t, cmdErr.Error(), wallet.ErrAlreadyUnlocked.Error()) + require.Empty(t, b.Len()) + b.Reset() + + // lock wallet + cmdErr = cmd.Close(&b, getReader(t, &LockWalletRequest{UserID: sampleUser3})) + require.NoError(t, cmdErr) + var lockResponse LockWalletResponse + require.NoError(t, json.NewDecoder(&b).Decode(&lockResponse)) + require.True(t, lockResponse.Closed) + b.Reset() + + // lock wallet again + cmdErr = cmd.Close(&b, getReader(t, &LockWalletRequest{UserID: sampleUser3})) + require.NoError(t, cmdErr) + require.NoError(t, json.NewDecoder(&b).Decode(&lockResponse)) + require.False(t, lockResponse.Closed) + b.Reset() + }) + t.Run("lock & unlock failures", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -696,13 +781,13 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { token2, lock2 := unlockWallet(t, mockctx, &UnlockWalletRequest{ UserID: sampleUser2, - WebKMSAuth: sampleFakeTkn, + WebKMSAuth: &UnlockAuth{AuthToken: sampleFakeTkn}, }) defer lock2() t.Run("add a credential to wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -715,7 +800,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("add a metadata to wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -728,7 +813,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("get a credential from wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -746,7 +831,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("get all credentials from wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) // save multiple credentials, one already saved const count = 6 @@ -778,7 +863,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("remove a credential from wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -791,7 +876,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("get a credential from different wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -804,7 +889,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("try content operations from invalid auth", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -840,7 +925,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("try content operations from invalid content type", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -879,7 +964,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("try content operations from invalid profile", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -915,7 +1000,7 @@ func TestCommand_AddRemoveGetGetAll(t *testing.T) { }) t.Run("try content operations from invalid request", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -967,7 +1052,7 @@ func TestCommand_Query(t *testing.T) { }) t.Run("successfully query credentials", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -993,7 +1078,7 @@ func TestCommand_Query(t *testing.T) { }) t.Run("query credentials with invalid auth", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1010,7 +1095,7 @@ func TestCommand_Query(t *testing.T) { }) t.Run("query credentials with invalid wallet profile", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1027,7 +1112,7 @@ func TestCommand_Query(t *testing.T) { }) t.Run("query credentials with invalid query type", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1044,7 +1129,7 @@ func TestCommand_Query(t *testing.T) { }) t.Run("query credentials with invalid request", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1090,7 +1175,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { var rawCredentialToVerify json.RawMessage t.Run("issue a credential", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1119,7 +1204,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("verify a credential from store", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1136,7 +1221,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("verify a raw credential", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1157,7 +1242,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { invalidVC := string(rawCredentialToVerify) invalidVC = strings.ReplaceAll(invalidVC, "Jayden Doe", "John Smith") - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1177,7 +1262,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { var presentation *verifiable.Presentation t.Run("prove credentials", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1220,7 +1305,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { vpBytes, err := presentation.MarshalJSON() require.NoError(t, err) - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1254,7 +1339,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("failed to prove a credential", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1269,7 +1354,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("failed to prove a credential", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1285,7 +1370,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("issue,prove,verify with invalid profile", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1320,7 +1405,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("issue,prove,verify with invalid auth", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1348,7 +1433,7 @@ func TestCommand_IssueProveVerify(t *testing.T) { }) t.Run("issue,prove,verify with invalid request", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1404,7 +1489,7 @@ func TestCommand_Derive(t *testing.T) { require.NoError(t, json.Unmarshal([]byte(sampleFrame), &frameDoc)) t.Run("derive a credential from stored credential", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1425,7 +1510,7 @@ func TestCommand_Derive(t *testing.T) { }) t.Run("derive a credential from raw credential", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1446,7 +1531,7 @@ func TestCommand_Derive(t *testing.T) { }) t.Run("derive a credential using invalid auth", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1463,7 +1548,7 @@ func TestCommand_Derive(t *testing.T) { }) t.Run("derive a credential using invalid profile", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1480,7 +1565,7 @@ func TestCommand_Derive(t *testing.T) { }) t.Run("derive a credential using invalid request", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &Config{}) var b bytes.Buffer @@ -1502,7 +1587,7 @@ func TestCommand_Derive(t *testing.T) { } func createSampleUserProfile(t *testing.T, ctx *mockprovider.Provider, request *CreateOrUpdateProfileRequest) { - cmd := New(ctx) + cmd := New(ctx, &Config{}) require.NotNil(t, cmd) var l bytes.Buffer @@ -1526,7 +1611,7 @@ func getUnlockToken(t *testing.T, b bytes.Buffer) string { } func unlockWallet(t *testing.T, ctx *mockprovider.Provider, request *UnlockWalletRequest) (string, func()) { - cmd := New(ctx) + cmd := New(ctx, nil) var b bytes.Buffer @@ -1542,7 +1627,7 @@ func unlockWallet(t *testing.T, ctx *mockprovider.Provider, request *UnlockWalle } func addContent(t *testing.T, ctx *mockprovider.Provider, request *AddContentRequest) { - cmd := New(ctx) + cmd := New(ctx, &Config{}) var b bytes.Buffer defer b.Reset() diff --git a/pkg/controller/command/vcwallet/models.go b/pkg/controller/command/vcwallet/models.go index f0a6675f1c..2329faaa59 100644 --- a/pkg/controller/command/vcwallet/models.go +++ b/pkg/controller/command/vcwallet/models.go @@ -60,23 +60,23 @@ type UnlockWalletRequest struct { // WebKMSAuth for authorizing acccess to web/remote kms. // Optional, to be used if profile for this wallet user is setup with web/remote KMS. - WebKMSAuth string `json:"webKMSAuth,omitempty"` + WebKMSAuth *UnlockAuth `json:"webKMSAuth,omitempty"` // Options for authorizing access to wallet's EDV content store. // Optional, to be used only if profile for this wallet user is setup to use EDV as content store. - EDVUnlock *EDVUnlockRequest `json:"edvUnlock,omitempty"` + EDVUnlock *UnlockAuth `json:"edvUnlock,omitempty"` } -// EDVUnlockRequest contains different options for authorizing access to wallet's EDV content store. -type EDVUnlockRequest struct { - // Capability if ZCAP sign header feature to be used for authorizing EDV access. - // Optional, can be used only if ZCAP sign header feature is configured with command controller - // TODO to be implemented #2433 - Capability string `json:"capability,omitempty"` - - // Authorization token to be used for authorizing EDV access. +// UnlockAuth contains different options for authorizing access to wallet's EDV content store & webkms. +type UnlockAuth struct { + // Http header 'authorization' bearer token to be used. // Optional, only if required by wallet user. AuthToken string `json:"authToken,omitempty"` + + // Capability if ZCAP sign header feature to be used for authorizing access. + // Optional, can be used only if ZCAP sign header feature is configured with command controller. + // Note: will not be considered When provided with `AuthToken` option. + Capability string `json:"capability,omitempty"` } // UnlockWalletResponse contains response for wallet unlock operation. diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index ec20e07c53..3c5f8f2f11 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -18,6 +18,7 @@ import ( messagingcmd "github.com/hyperledger/aries-framework-go/pkg/controller/command/messaging" outofbandcmd "github.com/hyperledger/aries-framework-go/pkg/controller/command/outofband" presentproofcmd "github.com/hyperledger/aries-framework-go/pkg/controller/command/presentproof" + vcwalletcmd "github.com/hyperledger/aries-framework-go/pkg/controller/command/vcwallet" vdrcmd "github.com/hyperledger/aries-framework-go/pkg/controller/command/vdr" "github.com/hyperledger/aries-framework-go/pkg/controller/command/verifiable" "github.com/hyperledger/aries-framework-go/pkg/controller/rest" @@ -29,6 +30,7 @@ import ( messagingrest "github.com/hyperledger/aries-framework-go/pkg/controller/rest/messaging" outofbandrest "github.com/hyperledger/aries-framework-go/pkg/controller/rest/outofband" presentproofrest "github.com/hyperledger/aries-framework-go/pkg/controller/rest/presentproof" + vcwalletrest "github.com/hyperledger/aries-framework-go/pkg/controller/rest/vcwallet" vdrrest "github.com/hyperledger/aries-framework-go/pkg/controller/rest/vdr" verifiablerest "github.com/hyperledger/aries-framework-go/pkg/controller/rest/verifiable" "github.com/hyperledger/aries-framework-go/pkg/controller/webnotifier" @@ -41,6 +43,7 @@ type allOpts struct { autoAccept bool msgHandler command.MessageHandler notifier command.Notifier + walletConf *vcwalletcmd.Config } const wsPath = "/ws" @@ -83,6 +86,13 @@ func WithMessageHandler(handler command.MessageHandler) Opt { } } +// WithWalletConfiguration is an option for customizing vcwallet controller. +func WithWalletConfiguration(conf *vcwalletcmd.Config) Opt { + return func(opts *allOpts) { + opts.walletConf = conf + } +} + // GetRESTHandlers returns all REST handlers provided by controller. func GetRESTHandlers(ctx *context.Provider, opts ...Opt) ([]rest.Handler, error) { // nolint: funlen,gocyclo restAPIOpts := &allOpts{} @@ -154,6 +164,9 @@ func GetRESTHandlers(ctx *context.Provider, opts ...Opt) ([]rest.Handler, error) // kms command operation kmscmd := kmsrest.New(ctx) + // vc wallet command controller + wallet := vcwalletrest.New(ctx, restAPIOpts.walletConf) + // creat handlers from all operations var allHandlers []rest.Handler allHandlers = append(allHandlers, exchangeOp.GetRESTHandlers()...) @@ -166,6 +179,7 @@ func GetRESTHandlers(ctx *context.Provider, opts ...Opt) ([]rest.Handler, error) allHandlers = append(allHandlers, introduceOp.GetRESTHandlers()...) allHandlers = append(allHandlers, outofbandOp.GetRESTHandlers()...) allHandlers = append(allHandlers, kmscmd.GetRESTHandlers()...) + allHandlers = append(allHandlers, wallet.GetRESTHandlers()...) nhp, ok := notifier.(handlerProvider) if ok { @@ -250,6 +264,9 @@ func GetCommandHandlers(ctx *context.Provider, opts ...Opt) ([]command.Handler, // kms command operation kmscmd := kms.New(ctx) + // vc wallet command controller + wallet := vcwalletcmd.New(ctx, cmdOpts.walletConf) + var allHandlers []command.Handler allHandlers = append(allHandlers, didexcmd.GetHandlers()...) allHandlers = append(allHandlers, vcmd.GetHandlers()...) @@ -261,6 +278,7 @@ func GetCommandHandlers(ctx *context.Provider, opts ...Opt) ([]command.Handler, allHandlers = append(allHandlers, presentproof.GetHandlers()...) allHandlers = append(allHandlers, introduce.GetHandlers()...) allHandlers = append(allHandlers, outofband.GetHandlers()...) + allHandlers = append(allHandlers, wallet.GetHandlers()...) return allHandlers, nil } diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 980891c0b7..9e1fbfd228 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/hyperledger/aries-framework-go/pkg/controller/command/vcwallet" "github.com/hyperledger/aries-framework-go/pkg/controller/internal/mocks/webhook" "github.com/hyperledger/aries-framework-go/pkg/framework/aries" "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api" @@ -151,3 +152,14 @@ func TestWithMessageHandler(t *testing.T) { require.NotNil(t, controllerOpts.msgHandler) } + +func TestWithWalletConfiguration(t *testing.T) { + controllerOpts := &allOpts{} + + opt := WithWalletConfiguration(&vcwallet.Config{WebKMSCacheSize: 99}) + + opt(controllerOpts) + + require.NotNil(t, controllerOpts.walletConf) + require.Equal(t, controllerOpts.walletConf.WebKMSCacheSize, 99) +} diff --git a/pkg/controller/rest/vcwallet/operation.go b/pkg/controller/rest/vcwallet/operation.go index 1f93fdfeef..2e2d0f5b3d 100644 --- a/pkg/controller/rest/vcwallet/operation.go +++ b/pkg/controller/rest/vcwallet/operation.go @@ -55,8 +55,8 @@ type Operation struct { } // New returns new verfiable credential wallet REST controller. -func New(p provider) *Operation { - cmd := vcwallet.New(p) +func New(p provider, config *vcwallet.Config) *Operation { + cmd := vcwallet.New(p, config) o := &Operation{command: cmd} diff --git a/pkg/controller/rest/vcwallet/operation_test.go b/pkg/controller/rest/vcwallet/operation_test.go index c0824a5256..8f60303ddc 100644 --- a/pkg/controller/rest/vcwallet/operation_test.go +++ b/pkg/controller/rest/vcwallet/operation_test.go @@ -235,7 +235,7 @@ const ( func TestNew(t *testing.T) { t.Run("successfully create rest command instance", func(t *testing.T) { - cmd := New(newMockProvider(t)) + cmd := New(newMockProvider(t), &vcwallet.Config{}) require.NotNil(t, cmd) require.Len(t, cmd.GetRESTHandlers(), 13) @@ -246,7 +246,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("successfully create a new wallet profile (localkms)", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) request := &vcwallet.CreateOrUpdateProfileRequest{ @@ -263,7 +263,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("successfully create a new wallet profile (webkms/remotekms)", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) request := &vcwallet.CreateOrUpdateProfileRequest{ @@ -280,7 +280,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("successfully create a new wallet profile with EDV configuration", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) // create with remote kms. @@ -324,7 +324,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("failed to create duplicate profile", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) request := &vcwallet.CreateOrUpdateProfileRequest{ @@ -351,7 +351,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("failed to create profile due to invalid settings", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) request := &vcwallet.CreateOrUpdateProfileRequest{ @@ -367,7 +367,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("failed to create profile due to invalid request", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) rq := httptest.NewRequest(http.MethodPost, CreateProfilePath, getReader(t, "--")) @@ -379,7 +379,7 @@ func TestOperation_CreateProfile(t *testing.T) { t.Run("failed to create profile due to EDV key set creation failure", func(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) mockStProv, ok := mockctx.StorageProviderValue.(*mockstorage.MockStoreProvider) @@ -407,7 +407,7 @@ func TestOperation_CreateProfile(t *testing.T) { func TestOperation_UpdateProfile(t *testing.T) { mockctx := newMockProvider(t) - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) require.NotNil(t, cmd) createRqst := &vcwallet.CreateOrUpdateProfileRequest{ @@ -499,7 +499,7 @@ func TestOperation_OpenAndClose(t *testing.T) { }) t.Run("successfully unlock & lock wallet (local kms)", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) request := &vcwallet.UnlockWalletRequest{ UserID: sampleUser1, @@ -537,11 +537,11 @@ func TestOperation_OpenAndClose(t *testing.T) { }) t.Run("successfully unlock & lock wallet (remote kms)", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) request := &vcwallet.UnlockWalletRequest{ UserID: sampleUser2, - WebKMSAuth: sampleFakeTkn, + WebKMSAuth: &vcwallet.UnlockAuth{AuthToken: sampleFakeTkn}, } // unlock wallet @@ -575,12 +575,12 @@ func TestOperation_OpenAndClose(t *testing.T) { }) t.Run("successfully unlock & lock wallet (local kms, edv user)", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) request := &vcwallet.UnlockWalletRequest{ UserID: sampleUser3, LocalKMSPassphrase: samplePassPhrase, - EDVUnlock: &vcwallet.EDVUnlockRequest{ + EDVUnlock: &vcwallet.UnlockAuth{ AuthToken: sampleFakeTkn, }, } @@ -616,7 +616,7 @@ func TestOperation_OpenAndClose(t *testing.T) { }) t.Run("lock & unlock failures", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) rq := httptest.NewRequest(http.MethodPost, OpenPath, getReader(t, vcwallet.UnlockWalletRequest{})) rw := httptest.NewRecorder() @@ -676,7 +676,7 @@ func TestOperation_AddRemoveGetGetAll(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, AddPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Add(rw, rq) require.Equal(t, rw.Code, http.StatusOK) }) @@ -691,7 +691,7 @@ func TestOperation_AddRemoveGetGetAll(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, AddPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Add(rw, rq) require.Equal(t, rw.Code, http.StatusOK) }) @@ -706,13 +706,13 @@ func TestOperation_AddRemoveGetGetAll(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, GetPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Get(rw, rq) require.Equal(t, rw.Code, http.StatusOK) }) t.Run("get all credentials from wallet", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) // save multiple credentials, one already saved const count = 6 @@ -755,7 +755,7 @@ func TestOperation_AddRemoveGetGetAll(t *testing.T) { WalletAuth: vcwallet.WalletAuth{UserID: sampleUser1, Auth: token1}, } - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) rq := httptest.NewRequest(http.MethodPost, RemovePath, getReader(t, request)) rw := httptest.NewRecorder() @@ -765,7 +765,7 @@ func TestOperation_AddRemoveGetGetAll(t *testing.T) { }) t.Run("try content operations from invalid auth", func(t *testing.T) { - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) const expectedErr = "invalid auth token" @@ -858,7 +858,7 @@ func TestOperation_Query(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, QueryPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Query(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -886,7 +886,7 @@ func TestOperation_Query(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, QueryPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Query(rw, rq) require.Equal(t, rw.Code, http.StatusInternalServerError) require.Contains(t, rw.Body.String(), "invalid auth token") @@ -910,7 +910,7 @@ func TestOperation_Query(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, QueryPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Query(rw, rq) require.Equal(t, rw.Code, http.StatusInternalServerError) require.Contains(t, rw.Body.String(), "unsupported query type") @@ -965,7 +965,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, IssuePath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Issue(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -992,7 +992,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, VerifyPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Verify(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1011,7 +1011,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, VerifyPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Verify(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1034,7 +1034,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, VerifyPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Verify(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1060,7 +1060,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, ProvePath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Prove(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1106,7 +1106,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, VerifyPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Verify(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1148,7 +1148,7 @@ func TestOperation_IssueProveVerify(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, ProvePath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Prove(rw, rq) require.Equal(t, rw.Code, http.StatusInternalServerError) require.Contains(t, rw.Body.String(), "invalid auth token") @@ -1212,7 +1212,7 @@ func TestOperation_Derive(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, DerivePath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Derive(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1235,7 +1235,7 @@ func TestOperation_Derive(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, DerivePath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Derive(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1258,7 +1258,7 @@ func TestOperation_Derive(t *testing.T) { rq := httptest.NewRequest(http.MethodPost, DerivePath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(mockctx) + cmd := New(mockctx, &vcwallet.Config{}) cmd.Derive(rw, rq) require.Equal(t, rw.Code, http.StatusInternalServerError) require.Contains(t, rw.Body.String(), "invalid auth token") @@ -1266,7 +1266,7 @@ func TestOperation_Derive(t *testing.T) { } func createSampleUserProfile(t *testing.T, ctx *mockprovider.Provider, request *vcwallet.CreateOrUpdateProfileRequest) { - cmd := New(ctx) + cmd := New(ctx, &vcwallet.Config{}) require.NotNil(t, cmd) rq := httptest.NewRequest(http.MethodPost, CreateProfilePath, getReader(t, request)) @@ -1294,7 +1294,7 @@ func unlockWallet(t *testing.T, ctx *mockprovider.Provider, request *vcwallet.Un rq := httptest.NewRequest(http.MethodPost, OpenPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(ctx) + cmd := New(ctx, &vcwallet.Config{}) cmd.Open(rw, rq) require.Equal(t, rw.Code, http.StatusOK) @@ -1310,7 +1310,7 @@ func addContent(t *testing.T, ctx *mockprovider.Provider, request *vcwallet.AddC rq := httptest.NewRequest(http.MethodPost, AddPath, getReader(t, request)) rw := httptest.NewRecorder() - cmd := New(ctx) + cmd := New(ctx, &vcwallet.Config{}) cmd.Add(rw, rq) require.Equal(t, rw.Code, http.StatusOK) }