diff --git a/cmd/adapter-rest/startcmd/start.go b/cmd/adapter-rest/startcmd/start.go index 84d7f2d5..734392fb 100644 --- a/cmd/adapter-rest/startcmd/start.go +++ b/cmd/adapter-rest/startcmd/start.go @@ -53,7 +53,6 @@ import ( tlsutils "github.com/trustbloc/edge-core/pkg/utils/tls" "github.com/trustbloc/edge-adapter/pkg/did" - "github.com/trustbloc/edge-adapter/pkg/governance" "github.com/trustbloc/edge-adapter/pkg/hydra" "github.com/trustbloc/edge-adapter/pkg/ld" "github.com/trustbloc/edge-adapter/pkg/presentationex" @@ -180,10 +179,6 @@ const ( " Alternatively, this can be set with the following environment variable: " + logLevelEnvKey logLevelEnvKey = "ADAPTER_REST_LOGLEVEL" - governanceVCSURLFlagName = "governance-vcs-url" - governanceVCSURLFlagUsage = "Governance VCS instance is running on. Format: HostName:Port." - governanceVCSURLEnvKey = "ADAPTER_REST_GOVERNANCE_VCS_URL" - requestTokensFlagName = "request-tokens" requestTokensEnvKey = "ADAPTER_REST_REQUEST_TOKENS" // nolint: gosec requestTokensFlagUsage = "Tokens used for http request " + @@ -306,7 +301,6 @@ type adapterRestParameters struct { didCommParameters *didCommParameters // didcomm trustblocDomain string universalResolverURL string - governanceVCSURL string requestTokens map[string]string walletAppURL string oidcClientDBKeyPath string @@ -316,12 +310,6 @@ type adapterRestParameters struct { cmOutputDescriptorsFilePath string } -// governanceProvider governance provider. -type governanceProvider interface { - IssueCredential(didID, profileID string) ([]byte, error) - GetCredential(profileID string) ([]byte, error) -} - type server interface { ListenAndServe(host, certFile, keyFile string, router http.Handler) error } @@ -442,12 +430,6 @@ func getAdapterRestParameters(cmd *cobra.Command) (*adapterRestParameters, error return nil, fmt.Errorf(confErrMsg, err) } - governanceVCSURL, err := cmdutils.GetUserSetVarFromString(cmd, governanceVCSURLFlagName, - governanceVCSURLEnvKey, true) - if err != nil { - return nil, fmt.Errorf(confErrMsg, err) - } - requestTokens, err := getRequestTokens(cmd) if err != nil { return nil, fmt.Errorf(confErrMsg, err) @@ -485,7 +467,6 @@ func getAdapterRestParameters(cmd *cobra.Command) (*adapterRestParameters, error didCommParameters: didCommParameters, trustblocDomain: trustblocDomain, universalResolverURL: universalResolverURL, - governanceVCSURL: governanceVCSURL, requestTokens: requestTokens, walletAppURL: walletAppURL, oidcClientDBKeyPath: issuerOIDCKeyPath, @@ -650,7 +631,6 @@ func createFlags(startCmd *cobra.Command) { startCmd.Flags().StringP(presentationDefinitionsFlagName, "", "", presentationDefinitionsFlagUsage) startCmd.Flags().StringP(hydraURLFlagName, "", "", hydraURLFlagUsage) startCmd.Flags().StringP(modeFlagName, "", "", modeFlagUsage) - startCmd.Flags().StringP(governanceVCSURLFlagName, "", "", governanceVCSURLFlagUsage) startCmd.Flags().StringArrayP(requestTokensFlagName, "", []string{}, requestTokensFlagUsage) // didcomm @@ -773,18 +753,6 @@ func addRPHandlers(parameters *adapterRestParameters, framework *aries.Aries, ro return fmt.Errorf("failed to init edge storage: %w", err) } - var governanceProv governanceProvider - - if parameters.governanceVCSURL != "" { - var errNew error - - governanceProv, errNew = newGovernanceProvider(parameters.governanceVCSURL, rootCAs, store, - parameters.requestTokens, parameters.trustblocDomain) - if errNew != nil { - return fmt.Errorf("failed to create governance provider: %w", errNew) - } - } - // TODO init OIDC stuff in iteration 2 - https://github.com/trustbloc/edge-adapter/issues/24 didCreator, err := did.NewTrustblocDIDCreator( @@ -814,7 +782,6 @@ func addRPHandlers(parameters *adapterRestParameters, framework *aries.Aries, ro AriesContextProvider: ctx, AriesMessenger: framework.Messenger(), MsgRegistrar: msgRegistrar, - GovernanceProvider: governanceProv, PresentProofClient: presentProofClient, WalletBridgeAppURL: parameters.walletAppURL, JSONLDDocumentLoader: ctx.JSONLDDocumentLoader(), @@ -844,7 +811,7 @@ func addRPHandlers(parameters *adapterRestParameters, framework *aries.Aries, ro return nil } -// nolint:funlen,gocyclo,cyclop +// nolint:funlen func addIssuerHandlers(parameters *adapterRestParameters, framework *aries.Aries, router *mux.Router, rootCAs *x509.CertPool, msgRegistrar *msghandler.Registrar) error { store, err := initStore(parameters.dsnParams.dsn, parameters.dsnParams.timeout, issuerAdapterStorePrefix) @@ -852,18 +819,6 @@ func addIssuerHandlers(parameters *adapterRestParameters, framework *aries.Aries return fmt.Errorf("failed to init storage provider : %w", err) } - var governanceProv governanceProvider - - if parameters.governanceVCSURL != "" { - var errNew error - - governanceProv, errNew = newGovernanceProvider(parameters.governanceVCSURL, rootCAs, store, - parameters.requestTokens, parameters.trustblocDomain) - if errNew != nil { - return fmt.Errorf("failed to init governance provider: %w", errNew) - } - } - ariesCtx, err := framework.Context() if err != nil { return fmt.Errorf("aries-framework - failed to get aries context : %w", err) @@ -902,7 +857,6 @@ func addIssuerHandlers(parameters *adapterRestParameters, framework *aries.Aries StoreProvider: store, PublicDIDCreator: didCreator, TLSConfig: &tls.Config{RootCAs: rootCAs, MinVersion: tls.VersionTLS12}, - GovernanceProvider: governanceProv, OIDCClientStoreKey: clientStoreKey, ExternalURL: parameters.externalURL, DidDomain: parameters.trustblocDomain, @@ -941,12 +895,6 @@ func getIssuerOIDCClientStoreKey(keyPath string) ([]byte, error) { return bytes, nil } -func newGovernanceProvider(governanceVCSURL string, rootCAs *x509.CertPool, - store storage.Provider, requestTokens map[string]string, domain string) (*governance.Provider, error) { - return governance.New(governanceVCSURL, &tls.Config{RootCAs: rootCAs}, store, // nolint:gosec,wrapcheck - requestTokens, domain) -} - func uiHandler( basePath string, fileServer func(http.ResponseWriter, *http.Request, string)) func(http.ResponseWriter, *http.Request) { diff --git a/cmd/adapter-rest/startcmd/start_test.go b/cmd/adapter-rest/startcmd/start_test.go index 58517911..207e0496 100644 --- a/cmd/adapter-rest/startcmd/start_test.go +++ b/cmd/adapter-rest/startcmd/start_test.go @@ -390,7 +390,6 @@ func TestAdapterModes(t *testing.T) { // nolint:paralleltest // shared environme "--" + didCommInboundHostFlagName, randomURL(), "--" + datasourceNameFlagName, "mem://test", "--" + datasourceTimeoutFlagName, "30", - "--" + governanceVCSURLFlagName, "http://example.vcs.com", } startCmd.SetArgs(args) @@ -421,7 +420,6 @@ func TestAdapterModes(t *testing.T) { // nolint:paralleltest // shared environme "--" + didCommInboundHostFlagName, testInboundHostURL, "--" + datasourceNameFlagName, "mem://test", "--" + datasourceTimeoutFlagName, "30", - "--" + governanceVCSURLFlagName, "http://example.vcs.com", "--" + issuerOIDCClientStoreKeyFlagName, file.Name(), "--" + cmOutputDescriptorsFilePathFlagName, "./testdata/outputdescriptors.json", } @@ -509,7 +507,6 @@ func TestAdapterModes(t *testing.T) { // nolint:paralleltest // shared environme "--" + didCommInboundHostFlagName, testInboundHostURL, "--" + datasourceNameFlagName, "mem://test", "--" + datasourceTimeoutFlagName, "30", - "--" + governanceVCSURLFlagName, "http://example.vcs.com", "--" + issuerOIDCClientStoreKeyFlagName, file.Name() + "-nonexistent", "--" + cmOutputDescriptorsFilePathFlagName, "./testdata/outputdescriptors.json", } @@ -536,7 +533,6 @@ func TestAdapterModes(t *testing.T) { // nolint:paralleltest // shared environme "--" + didCommInboundHostFlagName, testInboundHostURL, "--" + datasourceNameFlagName, "mem://test", "--" + datasourceTimeoutFlagName, "30", - "--" + governanceVCSURLFlagName, "http://example.vcs.com", "--" + issuerOIDCClientStoreKeyFlagName, file.Name() + "-nonexistent", "--" + cmOutputDescriptorsFilePathFlagName, file.Name(), } diff --git a/pkg/governance/provider.go b/pkg/governance/provider.go deleted file mode 100644 index 2b041e6e..00000000 --- a/pkg/governance/provider.go +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright SecureKey Technologies Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package governance - -import ( - "bytes" - "crypto/tls" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "strings" - - "github.com/hyperledger/aries-framework-go/spi/storage" - "github.com/trustbloc/edge-core/pkg/log" -) - -var logger = log.New("edge-adapter/governance") - -const ( - governanceProfileName = "governance" // TODO make it configurable - issueCredentialURLFormat = "%s/governance/%s" + "/issueCredential" - storeName = "governance" - governanceVCKey = "%s_governance_vc" - vcsGovernanceRequestTokenName = "vcs_governance" //nolint: gosec - didParts = 4 -) - -type httpClient interface { - Do(req *http.Request) (*http.Response, error) -} - -// issueCredentialRequest request for issuing credential. -type issueCredentialRequest struct { - DID string `json:"did,omitempty"` -} - -// Provider provide governance operation. -type Provider struct { - governanceVCSUrl string - httpClient httpClient - store storage.Store - requestTokens map[string]string - domain string -} - -// New return new provider for governance provider. -func New(governanceVCSUrl string, tlsConfig *tls.Config, s storage.Provider, - requestTokens map[string]string, domain string) (*Provider, error) { - store, err := s.OpenStore(storeName) - if err != nil { - return nil, fmt.Errorf("failed to open store : %w", err) - } - - return &Provider{ - governanceVCSUrl: governanceVCSUrl, - httpClient: &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}, store: store, - requestTokens: requestTokens, domain: domain, - }, nil -} - -// IssueCredential issue credential. -func (p *Provider) IssueCredential(didID, profileID string) ([]byte, error) { - _, err := p.GetCredential(profileID) - if err != nil { - if errors.Is(err, storage.ErrDataNotFound) { - return p.issueCredential(p.replaceCanonicalDIDWithDomainDID(didID), profileID) - } - - return nil, err - } - - return nil, fmt.Errorf("governance vc already issued") -} - -func (p *Provider) replaceCanonicalDIDWithDomainDID(didID string) string { - if strings.HasPrefix(didID, "did:trustbloc") { - split := strings.Split(didID, ":") - if len(split) == didParts { - domainDIDID := fmt.Sprintf("%s:%s:%s:%s", split[0], split[1], p.domain, split[3]) - - return domainDIDID - } - } - - return didID -} - -func (p *Provider) issueCredential(didID, profileID string) ([]byte, error) { - req := &issueCredentialRequest{DID: didID} - - reqBytes, err := json.Marshal(req) - if err != nil { - return nil, fmt.Errorf("failed to marshal request: %w", err) - } - - endpointURL := fmt.Sprintf(issueCredentialURLFormat, p.governanceVCSUrl, governanceProfileName) - - httpReq, err := http.NewRequest(http.MethodPost, endpointURL, bytes.NewBuffer(reqBytes)) - if err != nil { - return nil, fmt.Errorf("failed to create new http request: %w", err) - } - - data, err := sendHTTPRequest(httpReq, p.httpClient, http.StatusCreated, - p.requestTokens[vcsGovernanceRequestTokenName]) - if err != nil { - return nil, fmt.Errorf("failed to execute http request: %w", err) - } - - if err := p.store.Put(fmt.Sprintf(governanceVCKey, profileID), data); err != nil { - return nil, fmt.Errorf("failed to store profile data: %w", err) - } - - return data, nil -} - -// GetCredential get governance credential. -func (p *Provider) GetCredential(profileID string) ([]byte, error) { - return p.store.Get(fmt.Sprintf(governanceVCKey, profileID)) // nolint:wrapcheck // reduce cyclo -} - -func sendHTTPRequest(req *http.Request, client httpClient, status int, bearerToken string) ([]byte, error) { - if bearerToken != "" { - req.Header.Add("Authorization", "Bearer "+bearerToken) - } - - resp, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("http request : %w", err) - } - - defer func() { - err = resp.Body.Close() - if err != nil { - logger.Warnf("failed to close response body") - } - }() - - if resp.StatusCode != status { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Warnf("failed to read response body for status: %d", resp.StatusCode) - } - - return nil, fmt.Errorf("http request: %d %s", resp.StatusCode, string(body)) - } - - return ioutil.ReadAll(resp.Body) // nolint:wrapcheck // reduce cyclo -} diff --git a/pkg/governance/provider_test.go b/pkg/governance/provider_test.go deleted file mode 100644 index c203778b..00000000 --- a/pkg/governance/provider_test.go +++ /dev/null @@ -1,159 +0,0 @@ -/* -Copyright SecureKey Technologies Inc. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 -*/ - -package governance - -import ( - "bytes" - "fmt" - "io/ioutil" - "net/http" - "testing" - - "github.com/hyperledger/aries-framework-go/component/storageutil/mem" - mockstorage "github.com/hyperledger/aries-framework-go/component/storageutil/mock" - "github.com/hyperledger/aries-framework-go/spi/storage" - "github.com/stretchr/testify/require" -) - -func TestNew(t *testing.T) { - t.Parallel() - - t.Run("test success", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, mem.NewProvider(), nil, "") - require.NoError(t, err) - require.NotNil(t, p) - }) - - t.Run("test failed to open store", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, &mockstorage.Provider{ - ErrOpenStore: fmt.Errorf("failed to open store"), - }, nil, "") - require.Error(t, err) - require.Contains(t, err.Error(), "failed to open store") - require.Nil(t, p) - }) -} - -func TestProvider_IssueCredential(t *testing.T) { - t.Parallel() - - t.Run("test error governance vc already issued", func(t *testing.T) { - t.Parallel() - - memProvider := mem.NewProvider() - - store, err := memProvider.OpenStore(storeName) - require.NoError(t, err) - - err = store.Put(fmt.Sprintf(governanceVCKey, "p1"), []byte("value")) - require.NoError(t, err) - - p, err := New("", nil, memProvider, nil, "") - require.NoError(t, err) - - _, err = p.IssueCredential("did:example:123", "p1") - require.Error(t, err) - require.Contains(t, err.Error(), "governance vc already issued") - }) - - t.Run("test failed to get governance vc from store", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, &mockstorage.Provider{ - OpenStoreReturn: &mockstorage.Store{ErrGet: fmt.Errorf("failed to get")}, - }, - nil, "") - require.NoError(t, err) - - _, err = p.IssueCredential("did:example:123", "p1") - require.Error(t, err) - require.Contains(t, err.Error(), "failed to get") - }) - - t.Run("test failed to send http request", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, mem.NewProvider(), - map[string]string{vcsGovernanceRequestTokenName: "token"}, "") - require.NoError(t, err) - - p.httpClient = &mockHTTPClient{respErr: fmt.Errorf("failed to send http request")} - - _, err = p.IssueCredential("did:example:123", "p1") - require.Error(t, err) - require.Contains(t, err.Error(), "failed to send http request") - }) - - t.Run("test vcs return 500 status code", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, mem.NewProvider(), - map[string]string{vcsGovernanceRequestTokenName: "token"}, "") - require.NoError(t, err) - - p.httpClient = &mockHTTPClient{respValue: &http.Response{ - StatusCode: http.StatusInternalServerError, - Body: ioutil.NopCloser(bytes.NewReader([]byte("failed ot issue vc"))), - }} - - _, err = p.IssueCredential("did:example:123", "p1") - require.Error(t, err) - require.Contains(t, err.Error(), "http request: 500 failed ot issue vc") - }) - - t.Run("test put vc in db", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, &mockstorage.Provider{ - OpenStoreReturn: &mockstorage.Store{ErrGet: storage.ErrDataNotFound, ErrPut: fmt.Errorf("error put")}, - }, - map[string]string{vcsGovernanceRequestTokenName: "token"}, "") - require.NoError(t, err) - - p.httpClient = &mockHTTPClient{respValue: &http.Response{ - StatusCode: http.StatusCreated, - Body: ioutil.NopCloser(bytes.NewReader([]byte("vc success"))), - }} - - _, err = p.IssueCredential("did:example:123", "p1") - require.Error(t, err) - require.Contains(t, err.Error(), "error put") - }) - - t.Run("test success", func(t *testing.T) { - t.Parallel() - - p, err := New("", nil, mem.NewProvider(), - map[string]string{vcsGovernanceRequestTokenName: "token"}, "") - require.NoError(t, err) - - p.httpClient = &mockHTTPClient{respValue: &http.Response{ - StatusCode: http.StatusCreated, - Body: ioutil.NopCloser(bytes.NewReader([]byte("vc success"))), - }} - - data, err := p.IssueCredential("did:example:123", "p1") - require.NoError(t, err) - require.Equal(t, []byte("vc success"), data) - }) -} - -type mockHTTPClient struct { - respValue *http.Response - respErr error -} - -func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) { - if m.respErr != nil { - return nil, m.respErr - } - - return m.respValue, nil -} diff --git a/pkg/internal/mock/governance/provider.go b/pkg/internal/mock/governance/provider.go deleted file mode 100644 index 13081903..00000000 --- a/pkg/internal/mock/governance/provider.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright SecureKey Technologies Inc. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package governance - -// MockProvider is a mock used in tests. -type MockProvider struct { - IssueCredentialFunc func(didID, profileID string) ([]byte, error) - GetCredentialFunc func(profileID string) ([]byte, error) -} - -// IssueCredential issue credential. -func (s *MockProvider) IssueCredential(didID, profileID string) ([]byte, error) { - if s.IssueCredentialFunc != nil { - return s.IssueCredentialFunc(didID, profileID) - } - - return nil, nil -} - -// GetCredential get credential. -func (s *MockProvider) GetCredential(profileID string) ([]byte, error) { - if s.GetCredentialFunc != nil { - return s.GetCredentialFunc(profileID) - } - - return nil, nil -} diff --git a/pkg/internal/testutil/contexts/governance.jsonld b/pkg/internal/testutil/contexts/governance.jsonld deleted file mode 100644 index 6bd33cc4..00000000 --- a/pkg/internal/testutil/contexts/governance.jsonld +++ /dev/null @@ -1,70 +0,0 @@ -{ - "@context": { - "@version": 1.1, - "@protected": true, - "xsd":"http://www.w3.org/2001/XMLSchema#", - "ex": "https://example.org/examples#", - - "GovernanceCredential": "ex:GovernanceCredential", - "name": "http://schema.org/name", - "version": "http://schema.org/version", - "logo": "http://schema.org/logo", - "description": "http://schema.org/description", - "docs_uri": "http://schema.org/url", - "data_uri": "http://schema.org/url", - "topics": "xsd:string", - "geos": "xsd:string", - "jurisdictions": "xsd:string", - "roles": "xsd:string", - "privileges": { - "@id": "ex:privileges", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "uri": "http://schema.org/url" - } - }, - "duties": { - "@id": "ex:duties", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "uri": "http://schema.org/url" - } - }, - "define": { - "@id": "ex:define", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "id": "@id" - } - }, - "rules": { - "@id": "ex:rules", - "@context": { - "@version": 1.1, - "@protected": true, - - "grant": "xsd:string", - "duties": "xsd:string", - "thus": "xsd:string", - "when": { - "@id": "ex:when", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name" - } - } - } - } - } -} diff --git a/pkg/internal/testutil/document_loader.go b/pkg/internal/testutil/document_loader.go index b6ad42e8..0c60a89f 100644 --- a/pkg/internal/testutil/document_loader.go +++ b/pkg/internal/testutil/document_loader.go @@ -35,8 +35,6 @@ var ( mdlV1Vocab []byte //go:embed contexts/issuer-manifest-credential-v1.jsonld issuerManifestV1Vocab []byte - //go:embed contexts/governance.jsonld - governanceVocab []byte //go:embed contexts/credit-card-v1.jsonld creditCardV1Vocab []byte //go:embed contexts/credit-score-v1.jsonld @@ -89,10 +87,6 @@ var contextDocuments = []ldcontext.Document{ URL: "https://trustbloc.github.io/context/vc/issuer-manifest-credential-v1.jsonld", Content: issuerManifestV1Vocab, }, - { - URL: "https://trustbloc.github.io/context/governance/context.jsonld", - Content: governanceVocab, - }, { URL: "https://trustbloc.github.io/context/vc/examples/credit-card-v1.jsonld", Content: creditCardV1Vocab, diff --git a/pkg/restapi/issuer/operation/operations.go b/pkg/restapi/issuer/operation/operations.go index 2fda86c0..1233a7f0 100644 --- a/pkg/restapi/issuer/operation/operations.go +++ b/pkg/restapi/issuer/operation/operations.go @@ -120,12 +120,6 @@ type PublicDIDCreator interface { Create() (*did.Doc, error) } -// GovernanceProvider governance provider. -type GovernanceProvider interface { - IssueCredential(didID, profileID string) ([]byte, error) - GetCredential(profileID string) ([]byte, error) -} - type mediatorClientProvider interface { Service(id string) (interface{}, error) } @@ -151,7 +145,6 @@ type Config struct { StoreProvider storage.Provider PublicDIDCreator PublicDIDCreator TLSConfig *tls.Config - GovernanceProvider GovernanceProvider WalletBridgeAppURL string OIDCClientStoreKey []byte ExternalURL string @@ -278,7 +271,6 @@ func New(config *Config) (*Operation, error) { // nolint:funlen,gocyclo,cyclop serviceEndpoint: config.AriesCtx.ServiceEndpoint(), vccrypto: vccrypto, publicDIDCreator: config.PublicDIDCreator, - governanceProvider: config.GovernanceProvider, httpClient: &http.Client{Transport: &http.Transport{TLSClientConfig: config.TLSConfig}}, routeSvc: routeSvc, messenger: config.AriesMessenger, @@ -330,7 +322,6 @@ type Operation struct { serviceEndpoint string publicDIDCreator PublicDIDCreator httpClient httpClient - governanceProvider GovernanceProvider routeSvc routeService messenger service.Messenger walletBridge *walletops.Operation @@ -409,18 +400,6 @@ func (o *Operation) createIssuerProfileHandler(rw http.ResponseWriter, req *http return } - if o.governanceProvider != nil { - didID := newDidDoc.ID - - _, err = o.governanceProvider.IssueCredential(didID, data.ID) - if err != nil { - commhttp.WriteErrorResponseWithLog(rw, http.StatusInternalServerError, - fmt.Sprintf("failed to issue governance vc: %s", err.Error()), profileEndpoint, logger) - - return - } - } - rw.WriteHeader(http.StatusCreated) commhttp.WriteResponseWithLog(rw, profileData, profileEndpoint, logger) } @@ -963,20 +942,6 @@ func (o *Operation) getCredentialInteractionRequestHandler(rw http.ResponseWrite credentials = append(credentials, vcBytes) } - if o.governanceProvider != nil { - governanceVC, err := o.governanceProvider.GetCredential(profile.ID) - if err != nil { - commhttp.WriteErrorResponseWithLog(rw, http.StatusInternalServerError, - fmt.Sprintf("error retrieving governance vc : %s", err.Error()), - getCredentialInteractionRequestEndpoint, logger) - - return - } - - // append governance credential - credentials = append(credentials, governanceVC) - } - commhttp.WriteResponseWithLog(rw, &CredentialHandlerRequest{ Query: &CHAPIQuery{Type: DIDConnectCHAPIQueryType}, DIDCommInvitation: txnData.DIDCommInvitation, diff --git a/pkg/restapi/issuer/operation/operations_test.go b/pkg/restapi/issuer/operation/operations_test.go index 28373d56..1c60b464 100644 --- a/pkg/restapi/issuer/operation/operations_test.go +++ b/pkg/restapi/issuer/operation/operations_test.go @@ -47,7 +47,6 @@ import ( mockconn "github.com/trustbloc/edge-adapter/pkg/internal/mock/connection" mockdiddoc "github.com/trustbloc/edge-adapter/pkg/internal/mock/diddoc" mockdidexchange "github.com/trustbloc/edge-adapter/pkg/internal/mock/didexchange" - mockgovernance "github.com/trustbloc/edge-adapter/pkg/internal/mock/governance" "github.com/trustbloc/edge-adapter/pkg/internal/mock/issuecredential" "github.com/trustbloc/edge-adapter/pkg/internal/mock/messenger" mockoutofband "github.com/trustbloc/edge-adapter/pkg/internal/mock/outofband" @@ -551,39 +550,6 @@ func TestCreateProfile(t *testing.T) { require.Equal(t, vReq.SupportsAssuranceCredential, profileRes.SupportsAssuranceCredential) }) - t.Run("create profile - failed to issue governance vc", func(t *testing.T) { - t.Parallel() - - op2, err := New(config(t)) - require.NoError(t, err) - - op2.createOIDCClientFunc = func(*issuer.ProfileData) (oidcClient, error) { - return &mockOIDC, nil - } - - op2.getOIDCClientFunc = func(string, string) (oidcClient, error) { - return &mockOIDC, nil - } - - op2.governanceProvider = &mockgovernance.MockProvider{ - IssueCredentialFunc: func(didID, profileID string) ([]byte, error) { - return nil, fmt.Errorf("failed to issue governance vc") - }, - } - - h := getHandler(t, op2, endpoint) - - vReq := createProfileData(uuid.New().String()) - - vReqBytes, err := json.Marshal(vReq) - require.NoError(t, err) - - rr := serveHTTP(t, h.Handle(), http.MethodPost, endpoint, vReqBytes) - - require.Equal(t, http.StatusInternalServerError, rr.Code) - require.Contains(t, rr.Body.String(), "failed to issue governance vc") - }) - t.Run("create profile - invalid request", func(t *testing.T) { t.Parallel() @@ -1964,10 +1930,6 @@ func TestCredentialInteractionRequest(t *testing.T) { c, e := New(config(t)) require.NoError(t, e) - c.governanceProvider = &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return []byte(`{"key":"value"}`), nil - }} - t.Run("without assurance support", func(t *testing.T) { t.Parallel() @@ -1991,8 +1953,7 @@ func TestCredentialInteractionRequest(t *testing.T) { require.NoError(t, err) require.Equal(t, DIDConnectCHAPIQueryType, chapiReq.Query.Type) require.Equal(t, "https://didcomm.org/out-of-band/1.0/invitation", chapiReq.DIDCommInvitation.Type) - require.Equal(t, `{"key":"value"}`, string(chapiReq.Credentials[1])) - require.Equal(t, 2, len(chapiReq.Credentials)) + require.Equal(t, 1, len(chapiReq.Credentials)) }) t.Run("with assurance support", func(t *testing.T) { @@ -2024,8 +1985,7 @@ func TestCredentialInteractionRequest(t *testing.T) { require.NoError(t, err) require.Equal(t, DIDConnectCHAPIQueryType, chapiReq.Query.Type) require.Equal(t, "https://didcomm.org/out-of-band/1.0/invitation", chapiReq.DIDCommInvitation.Type) - require.Equal(t, `{"key":"value"}`, string(chapiReq.Credentials[2])) - require.Equal(t, 3, len(chapiReq.Credentials)) + require.Equal(t, 2, len(chapiReq.Credentials)) }) t.Run("with assurance credential using oidc", func(t *testing.T) { @@ -2071,8 +2031,7 @@ func TestCredentialInteractionRequest(t *testing.T) { require.NoError(t, err) require.Equal(t, DIDConnectCHAPIQueryType, chapiReq.Query.Type) require.Equal(t, "https://didcomm.org/out-of-band/1.0/invitation", chapiReq.DIDCommInvitation.Type) - require.Equal(t, `{"key":"value"}`, string(chapiReq.Credentials[2])) - require.Equal(t, 3, len(chapiReq.Credentials)) + require.Equal(t, 2, len(chapiReq.Credentials)) }) }) @@ -2082,10 +2041,6 @@ func TestCredentialInteractionRequest(t *testing.T) { c, e := New(config(t)) require.NoError(t, e) - c.governanceProvider = &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return []byte(`{"key":"value"}`), nil - }} - t.Run("without linked wallet", func(t *testing.T) { t.Parallel() @@ -2146,33 +2101,6 @@ func TestCredentialInteractionRequest(t *testing.T) { }) }) - t.Run("test get governance - failed", func(t *testing.T) { - t.Parallel() - - c, err := New(config(t)) - require.NoError(t, err) - - c.governanceProvider = &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return nil, fmt.Errorf("failed to get vc") - }} - - profile := createProfileData("profile1") - - err = c.profileStore.SaveProfile(profile) - require.NoError(t, err) - - txnID, err := c.createTxn(profile, uuid.New().String(), uuid.New().String()) - require.NoError(t, err) - - getCHAPIRequestHandler := getHandler(t, c, getCredentialInteractionRequestEndpoint) - - rr := serveHTTP(t, getCHAPIRequestHandler.Handle(), http.MethodGet, - getCredentialInteractionRequestEndpoint+"?"+txnIDQueryParam+"="+txnID, nil) - - require.Equal(t, http.StatusInternalServerError, rr.Code) - require.Contains(t, rr.Body.String(), "error retrieving governance vc : failed to get vc") - }) - t.Run("test fetch invitation - no txnID in the url query", func(t *testing.T) { t.Parallel() diff --git a/pkg/restapi/issuer/operation/support_test.go b/pkg/restapi/issuer/operation/support_test.go index 068d849d..f6fe27b1 100644 --- a/pkg/restapi/issuer/operation/support_test.go +++ b/pkg/restapi/issuer/operation/support_test.go @@ -43,7 +43,6 @@ import ( "github.com/trustbloc/edge-adapter/pkg/aries" mockdiddoc "github.com/trustbloc/edge-adapter/pkg/internal/mock/diddoc" - mockgovernance "github.com/trustbloc/edge-adapter/pkg/internal/mock/governance" "github.com/trustbloc/edge-adapter/pkg/internal/mock/issuecredential" "github.com/trustbloc/edge-adapter/pkg/internal/mock/messenger" mockoutofband "github.com/trustbloc/edge-adapter/pkg/internal/mock/outofband" @@ -93,7 +92,6 @@ func config(t *testing.T) *Config { MsgRegistrar: msghandler.NewRegistrar(), AriesMessenger: &messenger.MockMessenger{}, PublicDIDCreator: &stubPublicDIDCreator{createValue: mockdiddoc.GetMockDIDDoc("did:example:def567")}, - GovernanceProvider: &mockgovernance.MockProvider{}, OIDCClientStoreKey: oidcClientStoreKey, JSONLDDocumentLoader: testutil.DocumentLoader(t), } diff --git a/pkg/restapi/rp/operation/models.go b/pkg/restapi/rp/operation/models.go index e060f9f3..5e6a665f 100644 --- a/pkg/restapi/rp/operation/models.go +++ b/pkg/restapi/rp/operation/models.go @@ -16,22 +16,20 @@ import ( // gprrPartialMarshal is a GetPresentationRequestResponse, but with the invitation marshalled already, // for more efficient sending logic. type gprrPartialMarshal struct { - PD *presexch.PresentationDefinition `json:"pd,omitempty"` - Inv json.RawMessage `json:"invitation"` - Credentials []json.RawMessage `json:"credentials,omitempty"` - CredentialGovernance json.RawMessage `json:"credentialGovernance,omitempty"` - WACI bool `json:"waci,omitempty"` - WalletRedirect string `json:"walletRedirect,omitempty"` + PD *presexch.PresentationDefinition `json:"pd,omitempty"` + Inv json.RawMessage `json:"invitation"` + Credentials []json.RawMessage `json:"credentials,omitempty"` + WACI bool `json:"waci,omitempty"` + WalletRedirect string `json:"walletRedirect,omitempty"` } // GetPresentationRequestResponse API response of getPresentationRequest. type GetPresentationRequestResponse struct { - PD *presexch.PresentationDefinition `json:"pd,omitempty"` - Inv *wallet.GenericInvitation `json:"invitation"` - Credentials []json.RawMessage `json:"credentials,omitempty"` - CredentialGovernance json.RawMessage `json:"credentialGovernance,omitempty"` - WACI bool `json:"waci,omitempty"` - WalletRedirect string `json:"walletRedirect,omitempty"` + PD *presexch.PresentationDefinition `json:"pd,omitempty"` + Inv *wallet.GenericInvitation `json:"invitation"` + Credentials []json.RawMessage `json:"credentials,omitempty"` + WACI bool `json:"waci,omitempty"` + WalletRedirect string `json:"walletRedirect,omitempty"` } // CreateRPTenantRequest API request body to register an RP tenant. diff --git a/pkg/restapi/rp/operation/operations.go b/pkg/restapi/rp/operation/operations.go index 2baa81a5..ea77f631 100644 --- a/pkg/restapi/rp/operation/operations.go +++ b/pkg/restapi/rp/operation/operations.go @@ -157,12 +157,6 @@ type connectionRecorder interface { GetConnectionRecordByDIDs(myDID, theirDID string) (*connection.Record, error) } -// GovernanceProvider governance provider. -type GovernanceProvider interface { - IssueCredential(didID, profileID string) ([]byte, error) - GetCredential(profileID string) ([]byte, error) -} - // AriesContextProvider is the dependency interface for the connection.Recorder. type AriesContextProvider interface { StorageProvider() storage.Provider @@ -223,7 +217,6 @@ func New(config *Config) (*Operation, error) { // nolint:funlen,gocyclo,cyclop publicDIDCreator: config.PublicDIDCreator, ppClient: config.PresentProofClient, vdrReg: config.AriesContextProvider.VDRegistry(), - governanceProvider: config.GovernanceProvider, km: config.AriesContextProvider.KMS(), ariesCrypto: config.AriesContextProvider.Crypto(), messenger: config.AriesMessenger, @@ -320,7 +313,6 @@ type Config struct { AriesContextProvider AriesContextProvider PresentProofClient PresentProofClient Storage *Storage - GovernanceProvider GovernanceProvider AriesMessenger service.Messenger MsgRegistrar *msghandler.Registrar WalletBridgeAppURL string @@ -353,7 +345,6 @@ type Operation struct { vdrReg vdrapi.Registry transientStore storage.Store persistenceStore storage.Store - governanceProvider GovernanceProvider km kms.KeyManager ariesCrypto ariescrypto.Crypto routeSvc routeService @@ -831,24 +822,10 @@ func (o *Operation) getPresentationsRequest(w http.ResponseWriter, r *http.Reque return } - var governanceVC []byte - - if o.governanceProvider != nil { - var err error - governanceVC, err = o.governanceProvider.GetCredential(cr.CR.GetPayload().Client.ClientID) - - if err != nil { - handleError(w, http.StatusInternalServerError, - fmt.Sprintf("error retrieving governance vc : %s", err)) - - return - } - } - response := &gprrPartialMarshal{ PD: cr.PD, Inv: invBytes, - Credentials: []json.RawMessage{governanceVC}, + Credentials: []json.RawMessage{}, } w.WriteHeader(http.StatusOK) @@ -1660,7 +1637,7 @@ func testResponse(w io.Writer) { } } -//nolint:funlen,gocyclo,cyclop +//nolint:funlen func (o *Operation) createRPTenant(w http.ResponseWriter, r *http.Request) { request := &CreateRPTenantRequest{} @@ -1722,17 +1699,6 @@ func (o *Operation) createRPTenant(w http.ResponseWriter, r *http.Request) { didID := publicDID.ID - if o.governanceProvider != nil { - _, err = o.governanceProvider.IssueCredential(didID, created.Payload.ClientID) - if err != nil { - msg := fmt.Sprintf("failed to issue governance vc : %s", err) - logger.Errorf(msg) - commhttp.WriteErrorResponse(w, http.StatusInternalServerError, msg) - - return - } - } - // RP not found - we're good to go err = o.rpStore.SaveRP(&rp.Tenant{ ClientID: created.Payload.ClientID, diff --git a/pkg/restapi/rp/operation/operations_test.go b/pkg/restapi/rp/operation/operations_test.go index 528db180..a9f8a027 100644 --- a/pkg/restapi/rp/operation/operations_test.go +++ b/pkg/restapi/rp/operation/operations_test.go @@ -55,7 +55,6 @@ import ( "github.com/trustbloc/edge-adapter/pkg/db/rp" mockconn "github.com/trustbloc/edge-adapter/pkg/internal/mock/connection" mockdidexchange "github.com/trustbloc/edge-adapter/pkg/internal/mock/didexchange" - mockgovernance "github.com/trustbloc/edge-adapter/pkg/internal/mock/governance" "github.com/trustbloc/edge-adapter/pkg/internal/mock/messenger" mockoutofband "github.com/trustbloc/edge-adapter/pkg/internal/mock/outofband" mockoutofbandv2 "github.com/trustbloc/edge-adapter/pkg/internal/mock/outofbandv2" @@ -1502,11 +1501,8 @@ func TestGetPresentationsRequest(t *testing.T) { }, AriesContextProvider: agent(t), PresentProofClient: &mockpresentproof.MockClient{}, - GovernanceProvider: &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return []byte(`{"key":"value"}`), nil - }}, - MsgRegistrar: msghandler.NewRegistrar(), - AriesMessenger: &messenger.MockMessenger{}, + MsgRegistrar: msghandler.NewRegistrar(), + AriesMessenger: &messenger.MockMessenger{}, }) require.NoError(t, err) @@ -1533,8 +1529,7 @@ func TestGetPresentationsRequest(t *testing.T) { require.NotNil(t, resp.Inv) require.Len(t, resp.Inv.Services, 1) require.Equal(t, rpPublicDID.String(), resp.Inv.Services[0]) - require.Len(t, resp.Credentials, 1) - require.Equal(t, `{"key":"value"}`, string(resp.Credentials[0])) + require.Len(t, resp.Credentials, 0) }) t.Run("test waci success", func(t *testing.T) { @@ -1588,9 +1583,7 @@ func TestGetPresentationsRequest(t *testing.T) { }, AriesContextProvider: agent(t), PresentProofClient: &mockpresentproof.MockClient{}, - GovernanceProvider: &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return []byte(`{"key":"value"}`), nil - }}, + MsgRegistrar: msghandler.NewRegistrar(), AriesMessenger: &messenger.MockMessenger{}, }) @@ -1676,9 +1669,7 @@ func TestGetPresentationsRequest(t *testing.T) { }, AriesContextProvider: agent(t), PresentProofClient: &mockpresentproof.MockClient{}, - GovernanceProvider: &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return []byte(`{"key":"value"}`), nil - }}, + MsgRegistrar: msghandler.NewRegistrar(), AriesMessenger: &messenger.MockMessenger{}, }) @@ -1713,83 +1704,6 @@ func TestGetPresentationsRequest(t *testing.T) { require.Equal(t, rpPublicDID.String(), res.Inv.From) }) - t.Run("test get governance - failed", func(t *testing.T) { - t.Parallel() - userSubject := uuid.New().String() - rpClientID := uuid.New().String() - rpPublicDID := newDID(t) - handle := uuid.New().String() - presDefs := &presexch.PresentationDefinition{ - InputDescriptors: []*presexch.InputDescriptor{{ID: uuid.New().String()}}, - } - store := mem.NewProvider() - saveUserConn(t, store, &rp.UserConnection{ - User: &rp.User{Subject: userSubject}, - RP: &rp.Tenant{ClientID: rpClientID}, - Request: &rp.DataRequest{}, - }) - - c, err := New(&Config{ - PresentationExProvider: &mockPresentationExProvider{createValue: presDefs}, - OOBClient: &mockoutofband.MockClient{ - CreateInvVal: &outofband.Invitation{ - ID: uuid.New().String(), - Type: outofband.InvitationMsgType, - Label: "test-label", - Services: []interface{}{rpPublicDID.String()}, - Protocols: []string{didexchangesvc.PIURI}, - }, - }, - OOBV2Client: &mockoutofbandv2.MockClient{ - CreateInvVal: &outofbandv2.Invitation{ - ID: uuid.NewString(), - Type: outofbandv2.InvitationMsgType, - Label: "test-label", - From: rpPublicDID.String(), - }, - }, - DIDExchClient: &mockdidexchange.MockClient{ - CreateInvWithDIDFunc: func(label, didID string) (*didexchange.Invitation, error) { - return &didexchange.Invitation{Invitation: &didexchangesvc.Invitation{ - ID: uuid.New().String(), - Type: didexchange.InvitationMsgType, - Label: "test-label", - DID: rpPublicDID.String(), - }}, nil - }, - }, - Storage: &Storage{ - Persistent: store, - Transient: mem.NewProvider(), - }, - AriesContextProvider: agent(t), - PresentProofClient: &mockpresentproof.MockClient{}, - GovernanceProvider: &mockgovernance.MockProvider{GetCredentialFunc: func(profileID string) ([]byte, error) { - return nil, fmt.Errorf("failed to get vc") - }}, - MsgRegistrar: msghandler.NewRegistrar(), - AriesMessenger: &messenger.MockMessenger{}, - }) - require.NoError(t, err) - - storePut(t, c.transientStore, handle, &consentRequestCtx{ - PD: presDefs, - CR: &admin.GetConsentRequestOK{ - Payload: &models.ConsentRequest{ - Subject: userSubject, - Client: &models.OAuth2Client{ClientID: rpClientID}, - }, - }, - RPPublicDID: rpPublicDID.String(), - }) - - r := httptest.NewRecorder() - c.getPresentationsRequest(r, newCreatePresentationDefinitionRequest(t, handle)) - - require.Equal(t, http.StatusInternalServerError, r.Code) - require.Contains(t, r.Body.String(), "error retrieving governance vc : failed to get vc") - }) - t.Run("bad request if handle is invalid", func(t *testing.T) { t.Parallel() c, err := New(config(t)) @@ -3218,7 +3132,6 @@ func TestCreateRPTenant(t *testing.T) { }, PublicDIDCreator: &stubPublicDIDCreator{createValue: &did.Doc{ID: expected.PublicDID}}, PresentProofClient: &mockpresentproof.MockClient{}, - GovernanceProvider: &mockgovernance.MockProvider{}, MsgRegistrar: msghandler.NewRegistrar(), AriesMessenger: &messenger.MockMessenger{}, }) @@ -3468,63 +3381,6 @@ func TestCreateRPTenant(t *testing.T) { })) require.Equal(t, http.StatusInternalServerError, w.Code) }) - - t.Run("failed to issue governance vc", func(t *testing.T) { - t.Parallel() - - callback := "http://test.example.com" - expected := &rp.Tenant{ - ClientID: uuid.New().String(), - PublicDID: newDID(t).String(), - Label: "test label", - Scopes: []string{creditCardStatementScope}, - } - clientSecret := uuid.New().String() - - store := mem.NewProvider() - o, err := New(&Config{ - DIDExchClient: &mockdidexchange.MockClient{}, - Storage: &Storage{ - Persistent: store, - Transient: mem.NewProvider(), - }, - AriesContextProvider: agent(t), - Hydra: &stubHydra{ - createOauth2ClientFunc: func(params *admin.CreateOAuth2ClientParams) (*admin.CreateOAuth2ClientCreated, error) { - require.Contains(t, strings.Split(params.Body.Scope, " "), oidc.ScopeOpenID) - require.Contains(t, strings.Split(params.Body.Scope, " "), creditCardStatementScope) - require.Contains(t, params.Body.RedirectUris, callback) - return &admin.CreateOAuth2ClientCreated{ - Payload: &models.OAuth2Client{ - ClientID: expected.ClientID, - ClientSecret: clientSecret, - RequestUris: []string{callback}, - Scope: strings.Join([]string{oidc.ScopeOpenID, creditCardStatementScope}, " "), - }, - }, nil - }, - }, - PublicDIDCreator: &stubPublicDIDCreator{createValue: &did.Doc{ID: expected.PublicDID}}, - PresentProofClient: &mockpresentproof.MockClient{}, - GovernanceProvider: &mockgovernance.MockProvider{ - IssueCredentialFunc: func(didID, profileID string) ([]byte, error) { - return nil, fmt.Errorf("failed to issue governance vc") - }, - }, - MsgRegistrar: msghandler.NewRegistrar(), - AriesMessenger: &messenger.MockMessenger{}, - }) - require.NoError(t, err) - - w := httptest.NewRecorder() - o.createRPTenant(w, newCreateRPRequest(t, &CreateRPTenantRequest{ - Label: expected.Label, - Callback: callback, - Scopes: []string{creditCardStatementScope}, - })) - require.Equal(t, http.StatusInternalServerError, w.Code) - require.Contains(t, w.Body.String(), "failed to issue governance vc") - }) } func TestRemoveOIDCScope(t *testing.T) { diff --git a/test/bdd/fixtures/adapter-rest/docker-compose.yml b/test/bdd/fixtures/adapter-rest/docker-compose.yml index 6c8e00dc..21871ba9 100644 --- a/test/bdd/fixtures/adapter-rest/docker-compose.yml +++ b/test/bdd/fixtures/adapter-rest/docker-compose.yml @@ -12,7 +12,6 @@ services: image: ${ISSUER_ADAPTER_REST_IMAGE}:latest environment: - ADAPTER_REST_HOST_URL=0.0.0.0:9070 - - ADAPTER_REST_GOVERNANCE_VCS_URL=http://governance.vcs.example.com:8066 - ADAPTER_REST_TLS_CACERTS=/etc/tls/ec-cacert.pem - ADAPTER_REST_TLS_SYSTEMCERTPOOL=true - ADAPTER_REST_TLS_SERVE_CERT=/etc/tls/ec-pubCert.pem @@ -36,7 +35,7 @@ services: - 9070:9070 - 9071:9071 entrypoint: "" - command: /bin/sh -c "adapter-rest start" + command: /bin/sh -c "adapter-rest start" volumes: - ../keys/tls:/etc/tls - ../keys/issuer-stores:/etc/store-keys @@ -52,7 +51,6 @@ services: environment: - ADAPTER_REST_HOST_URL=0.0.0.0:8070 - ADAPTER_REST_TLS_CACERTS=/etc/tls/ec-cacert.pem - - ADAPTER_REST_GOVERNANCE_VCS_URL=http://governance.vcs.example.com:8066 - ADAPTER_REST_TLS_SYSTEMCERTPOOL=true - ADAPTER_REST_TLS_SERVE_CERT=/etc/tls/ec-pubCert.pem - ADAPTER_REST_TLS_SERVE_KEY=/etc/tls/ec-key.pem @@ -75,7 +73,7 @@ services: ports: - 8070:8070 entrypoint: "" - command: /bin/sh -c "adapter-rest start" + command: /bin/sh -c "adapter-rest start" volumes: - ../keys/tls:/etc/tls - ../testdata:/etc/testdata @@ -104,7 +102,7 @@ services: ports: - "4444:4444" # Public port - "4445:4445" # Admin port - command: /bin/sh -c "hydra migrate sql --read-from-env --yes; hydra serve all" + command: /bin/sh -c "hydra migrate sql --read-from-env --yes; hydra serve all" entrypoint: "" environment: - DSN=mysql://rpadapterhydra:rpadapterhydra-secret-pw@tcp(mysql:3306)/rpadapterhydra?max_conns=20&max_idle_conns=4 @@ -130,7 +128,7 @@ services: ports: - "9044:9044" # Public port - "9045:9045" # Admin port - command: /bin/sh -c "hydra migrate sql --read-from-env --yes; hydra serve all" + command: /bin/sh -c "hydra migrate sql --read-from-env --yes; hydra serve all" entrypoint: "" environment: - SERVE_PUBLIC_PORT=9044 diff --git a/test/bdd/fixtures/integration/docker-compose.yml b/test/bdd/fixtures/integration/docker-compose.yml index 1a18d304..8695280e 100644 --- a/test/bdd/fixtures/integration/docker-compose.yml +++ b/test/bdd/fixtures/integration/docker-compose.yml @@ -114,37 +114,6 @@ services: aliases: - mock-issuer.com - governance.vcs.example.com: - container_name: governance.vcs.example.com - image: ${VCS_IMAGE}:${VCS_IMAGE_TAG} - environment: - - VC_REST_HOST_URL=0.0.0.0:8066 - - VC_REST_HOST_URL_EXTERNAL=http://governance.vcs.example.com:8066 - - EDV_REST_HOST_URL=${EDV_HOST}:${EDV_PORT}${EDV_ROOT_ENDPOINT} - - UNIVERSAL_RESOLVER_HOST_URL=http://did.rest.example.com:8072/1.0/identifiers - - BLOC_DOMAIN=${BLOC_DOMAIN} - - VC_REST_MODE=governance - - DATABASE_TYPE=mem - - KMSSECRETS_DATABASE_TYPE=mem - - VC_REST_TLS_CACERTS=/etc/tls/ec-cacert.pem - - VC_REST_TLS_SYSTEMCERTPOOL=true - - VC_REST_GOVERNANCE_CLAIMS_FILE=/etc/governance_claims.json - - VC_REST_DID_ANCHOR_ORIGIN=https://testnet.orb.local - ports: - - 8066:8066 - entrypoint: "" - command: /bin/sh -c "/tmp/governance-vcs-profiles.sh& vc-rest start" - volumes: - - ./governance-vcs-profiles.sh/:/tmp/governance-vcs-profiles.sh - - ../keys/tls:/etc/tls - - ./governance_claims.json:/etc/governance_claims.json - depends_on: - - edv.rest.example.com - networks: - adapter-rest_bdd_net: - aliases: - - governance.vcs.example.com - edv.rest.example.com: container_name: edv.rest.example.com image: ${EDV_REST_IMAGE}:${EDV_REST_IMAGE_TAG} diff --git a/test/bdd/fixtures/integration/governance-vcs-profiles.sh b/test/bdd/fixtures/integration/governance-vcs-profiles.sh deleted file mode 100755 index 7a4b6925..00000000 --- a/test/bdd/fixtures/integration/governance-vcs-profiles.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -# -# Copyright SecureKey Technologies Inc. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# - - -apk --no-cache add curl jq - - -echo "Adding governance profiles" - - -n=0 -maxAttempts=30 -while true -do - responseCreatedTime=$(curl --header "Content-Type: application/json" --header "Authorization: Bearer vcs_issuer_rw_token" \ - --request POST \ - --data '{"name":"governance", "uri":"http://example.com", "signatureType":"Ed25519Signature2018", "signatureRepresentation":1,"didKeyType":"Ed25519"}' \ - http://governance.vcs.example.com:8066/governance/profile | jq -r '.created' 2>/dev/null) - echo "'created' field from profile governance response is: $responseCreatedTime" - - if [ -n "$responseCreatedTime" ] && [ "$responseCreatedTime" != "null" ] - then - break - fi - echo "Invalid 'created' field from governance response when trying to create a profile (attempt $((n+1))/$maxAttempts)." - - - n=$((n+1)) - if [ $n -eq $maxAttempts ] - then - echo "failed to create governance profile" - exit 1 - fi - sleep 5 -done diff --git a/test/bdd/fixtures/integration/governance_claims.json b/test/bdd/fixtures/integration/governance_claims.json deleted file mode 100644 index eac9e0bb..00000000 --- a/test/bdd/fixtures/integration/governance_claims.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "trustbloc", - "version": "1.0", - "logo": "https://example.com/logo", - "description": "Trustbloc Governs.", - "docs_uri": "https://example.com/docs", - "data_uri": "https://example.com/data.json", - "topics": ["banking"], - "jurisdictions": ["ca"], - "geos": ["Canadian"], - "roles": ["accreditor"], - "privileges": [ - {"name": "accredit", "uri": "https://example.com/accredit"} - ], - "duties": [ - {"name": "safe-accredit", "uri": "https://example.com/responsible-accredit"} - ], - "define": [ - {"name": "DID", "id": "$DID"} - ] -} diff --git a/test/bdd/fixtures/testdata/contexts/test-contexts.json b/test/bdd/fixtures/testdata/contexts/test-contexts.json index 5f81647f..2080260d 100644 --- a/test/bdd/fixtures/testdata/contexts/test-contexts.json +++ b/test/bdd/fixtures/testdata/contexts/test-contexts.json @@ -1,131 +1,61 @@ { "documents": [ - { - "url": "https://trustbloc.github.io/context/governance/context.jsonld", - "content": { - "@context": { - "@version": 1.1, - "@protected": true, - "xsd":"http://www.w3.org/2001/XMLSchema#", - "ex": "https://example.org/examples#", - - "GovernanceCredential": "ex:GovernanceCredential", - "name": "http://schema.org/name", - "version": "http://schema.org/version", - "logo": "http://schema.org/logo", - "description": "http://schema.org/description", - "docs_uri": "http://schema.org/url", - "data_uri": "http://schema.org/url", - "topics": "xsd:string", - "geos": "xsd:string", - "jurisdictions": "xsd:string", - "roles": "xsd:string", - "privileges": { - "@id": "ex:privileges", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "uri": "http://schema.org/url" - } - }, - "duties": { - "@id": "ex:duties", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "uri": "http://schema.org/url" - } - }, - "define": { - "@id": "ex:define", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "id": "@id" - } - }, - "rules": { - "@id": "ex:rules", - "@context": { - "@version": 1.1, - "@protected": true, - - "grant": "xsd:string", - "duties": "xsd:string", - "thus": "xsd:string", - "when": { - "@id": "ex:when", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name" - } - } - } - } - } - } - }, { "url": "https://trustbloc.github.io/context/vc/examples/citizenship-v1.jsonld", "content": { "@context": { "@version": 1.1, "@protected": true, - "name": "http://schema.org/name", "description": "http://schema.org/description", "identifier": "http://schema.org/identifier", - "image": {"@id": "http://schema.org/image", "@type": "@id"}, - + "image": { + "@id": "http://schema.org/image", + "@type": "@id" + }, "PermanentResidentCard": { "@id": "https://w3id.org/citizenship#PermanentResidentCard", "@context": { "@version": 1.1, "@protected": true, - "id": "@id", "type": "@type", - "description": "http://schema.org/description", "name": "http://schema.org/name", "identifier": "http://schema.org/identifier", - "image": {"@id": "http://schema.org/image", "@type": "@id"} + "image": { + "@id": "http://schema.org/image", + "@type": "@id" + } } }, - "PermanentResident": { "@id": "https://w3id.org/citizenship#PermanentResident", "@context": { "@version": 1.1, "@protected": true, - "id": "@id", "type": "@type", - "ctzn": "https://w3id.org/citizenship#", "schema": "http://schema.org/", "xsd": "http://www.w3.org/2001/XMLSchema#", - "birthCountry": "ctzn:birthCountry", - "birthDate": {"@id": "schema:birthDate", "@type": "xsd:dateTime"}, + "birthDate": { + "@id": "schema:birthDate", + "@type": "xsd:dateTime" + }, "commuterClassification": "ctzn:commuterClassification", "familyName": "schema:familyName", "gender": "schema:gender", "givenName": "schema:givenName", "lprCategory": "ctzn:lprCategory", "lprNumber": "ctzn:lprNumber", - "residentSince": {"@id": "ctzn:residentSince", "@type": "xsd:dateTime"} + "residentSince": { + "@id": "ctzn:residentSince", + "@type": "xsd:dateTime" + } } }, - "Person": "http://schema.org/Person" } } @@ -133,27 +63,26 @@ { "url": "https://trustbloc.github.io/context/vc/examples/credit-card-v1.jsonld", "content": { - "@context":{ - "@version":1.1, - "id":"@id", - "type":"@type", - "ex":"https://example.org/examples#", - "name":"http://schema.org/name", - "description":"http://schema.org/description", - - "CreditCardStatement":{ - "@id":"ex:CreditCardStatement", - "@context":{ - "@version":1.1, - "id":"@id", - "type":"@type", - "ex":"https://example.org/examples#", - "credentialSubject":{ - "@id":"ex:credentialSubject", - "@context":{ - "@version":1.1, - "@protected":true, - "stmt":"schema:Invoice" + "@context": { + "@version": 1.1, + "id": "@id", + "type": "@type", + "ex": "https://example.org/examples#", + "name": "http://schema.org/name", + "description": "http://schema.org/description", + "CreditCardStatement": { + "@id": "ex:CreditCardStatement", + "@context": { + "@version": 1.1, + "id": "@id", + "type": "@type", + "ex": "https://example.org/examples#", + "credentialSubject": { + "@id": "ex:credentialSubject", + "@context": { + "@version": 1.1, + "@protected": true, + "stmt": "schema:Invoice" } } } @@ -170,7 +99,6 @@ "type": "@type", "xsd": "http://www.w3.org/2001/XMLSchema#", "ex": "https://example.org/examples#", - "DrivingLicenseEvidence": { "@id": "ex:DrivingLicenseEvidence", "@context": { @@ -178,10 +106,8 @@ "@protected": true, "id": "@id", "type": "@type", - "name": "http://schema.org/name", "description": "http://schema.org/description", - "document_number": { "@id": "ex:document_number", "@type": "xsd:string" @@ -202,54 +128,114 @@ { "url": "https://trustbloc.github.io/context/vc/examples/mdl-v1.jsonld", "content": { - "@context":{ - "@version":1.1, - "id":"@id", - "type":"@type", - "name":"http://schema.org/name", - "description":"http://schema.org/description", - - "mDL":{ - "@id":"ex:mDL", - "@context":{ - "@version":1.1, - "@protected":true, - "id":"@id", - "type":"@type", - "xsd":"http://www.w3.org/2001/XMLSchema#", - "ex":"https://example.org/examples#", - - "family_name":{ "@id":"ex:family_name" }, - "given_name":{ "@id":"ex:given_name" }, - "birthdate":{ "@id":"ex:birthdate" }, - "issue_date":{ "@id":"ex:issue_date" }, - "expiry_date":{ "@id":"ex:expiry_date" }, - "issuing_country":{ "@id":"ex:issuing_country" }, - "issuing_authority":{ "@id":"ex:issuing_authority" }, - "document_number":{ "@id":"ex:document_number" }, - "driving_privileges":{ "@id":"ex:driving_privileges" }, - "portrait":{ "@id":"ex:portrait" }, - "administrative_number":{ "@id":"ex:administrative_number" }, - "gender":{ "@id":"ex:gender" }, - "height":{ "@id":"ex:height" }, - "weight":{ "@id":"ex:weight" }, - "eye_color":{ "@id":"ex:eye_color" }, - "hair_color":{ "@id":"ex:hair_color" }, - "birthplace":{ "@id":"ex:birthplace" }, - "resident_address":{ "@id":"ex:resident_address" }, - "portrait_capture_date":{ "@id":"ex:portrait_capture_date" }, - "age_in_years":{ "@id":"ex:age_in_years" }, - "age_birth_year":{ "@id":"ex:age_birth_year" }, - "issuing_jurisdiction":{ "@id":"ex:issuing_jurisdiction" }, - "nationality":{ "@id":"ex:nationality" }, - "resident_city":{ "@id":"ex:resident_city" }, - "resident_state":{ "@id":"ex:resident_state" }, - "resident_postal_code":{ "@id":"ex:resident_postal_code" }, - "biometric_template_xx":{ "@id":"ex:biometric_template_xx" }, - "name_nat_char":{ "@id":"ex:name_nat_char" }, - "mgmt_lastupdate":{ "@id":"ex:mgmt_lastupdate" }, - "mgmt_validity":{ "@id":"ex:mgmt_validity" }, - "mgmt_nextupdate":{ "@id":"ex:mgmt_nextupdate" } + "@context": { + "@version": 1.1, + "id": "@id", + "type": "@type", + "name": "http://schema.org/name", + "description": "http://schema.org/description", + "mDL": { + "@id": "ex:mDL", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "ex": "https://example.org/examples#", + "family_name": { + "@id": "ex:family_name" + }, + "given_name": { + "@id": "ex:given_name" + }, + "birthdate": { + "@id": "ex:birthdate" + }, + "issue_date": { + "@id": "ex:issue_date" + }, + "expiry_date": { + "@id": "ex:expiry_date" + }, + "issuing_country": { + "@id": "ex:issuing_country" + }, + "issuing_authority": { + "@id": "ex:issuing_authority" + }, + "document_number": { + "@id": "ex:document_number" + }, + "driving_privileges": { + "@id": "ex:driving_privileges" + }, + "portrait": { + "@id": "ex:portrait" + }, + "administrative_number": { + "@id": "ex:administrative_number" + }, + "gender": { + "@id": "ex:gender" + }, + "height": { + "@id": "ex:height" + }, + "weight": { + "@id": "ex:weight" + }, + "eye_color": { + "@id": "ex:eye_color" + }, + "hair_color": { + "@id": "ex:hair_color" + }, + "birthplace": { + "@id": "ex:birthplace" + }, + "resident_address": { + "@id": "ex:resident_address" + }, + "portrait_capture_date": { + "@id": "ex:portrait_capture_date" + }, + "age_in_years": { + "@id": "ex:age_in_years" + }, + "age_birth_year": { + "@id": "ex:age_birth_year" + }, + "issuing_jurisdiction": { + "@id": "ex:issuing_jurisdiction" + }, + "nationality": { + "@id": "ex:nationality" + }, + "resident_city": { + "@id": "ex:resident_city" + }, + "resident_state": { + "@id": "ex:resident_state" + }, + "resident_postal_code": { + "@id": "ex:resident_postal_code" + }, + "biometric_template_xx": { + "@id": "ex:biometric_template_xx" + }, + "name_nat_char": { + "@id": "ex:name_nat_char" + }, + "mgmt_lastupdate": { + "@id": "ex:mgmt_lastupdate" + }, + "mgmt_validity": { + "@id": "ex:mgmt_validity" + }, + "mgmt_nextupdate": { + "@id": "ex:mgmt_nextupdate" + } } } } diff --git a/test/bdd/pkg/agent/agent_controller_steps.go b/test/bdd/pkg/agent/agent_controller_steps.go index 5eea19c3..1f96a1cc 100644 --- a/test/bdd/pkg/agent/agent_controller_steps.go +++ b/test/bdd/pkg/agent/agent_controller_steps.go @@ -94,9 +94,6 @@ const ( pullTopicsWaitInMilliSec = 200 pullTopicsAttemptsBeforeFail = 500 / pullTopicsWaitInMilliSec - governanceCtx = "https://trustbloc.github.io/context/governance/context.jsonld" - governanceVCCTXSize = 3 - stateCompleteMsgType = "https://trustbloc.dev/didexchange/1.0/state-complete" ) @@ -274,12 +271,12 @@ func (a *Steps) handleDIDCommConnectRequest(agentID, supportedVCContexts, issuer return fmt.Errorf("parse failure: %w", err) } - if supportsAssuranceCred && len(request.Credentials) != 3 { - return fmt.Errorf("invalid number of credential in chapi request: "+ - "expected=%d actual=%d", 3, len(request.Credentials)) - } else if !supportsAssuranceCred && len(request.Credentials) != 2 { + if supportsAssuranceCred && len(request.Credentials) != 2 { return fmt.Errorf("invalid number of credential in chapi request: "+ "expected=%d actual=%d", 2, len(request.Credentials)) + } else if !supportsAssuranceCred && len(request.Credentials) != 1 { + return fmt.Errorf("invalid number of credential in chapi request: "+ + "expected=%d actual=%d", 1, len(request.Credentials)) } err = validateManifestCred(request.Credentials[0], supportedVCContexts) @@ -296,16 +293,6 @@ func (a *Steps) handleDIDCommConnectRequest(agentID, supportedVCContexts, issuer a.refCredentials[agentID] = vc } - if supportsAssuranceCred { - err = validateGovernance(request.Credentials[2]) - } else { - err = validateGovernance(request.Credentials[1]) - } - - if err != nil { - return fmt.Errorf("failed to parse governance credential : %w", err) - } - err = UnregisterAllMsgServices(a.ControllerURLs[agentID]) if err != nil { return fmt.Errorf("failed to unregister msg svcs: %w", err) @@ -1571,40 +1558,6 @@ func validateManifestCred(manifestVCBytes []byte, supportedVCContexts string) er return nil } -func validateGovernance(governanceVCBytes json.RawMessage) error { - l, err := bddutil.DocumentLoader() - if err != nil { - return fmt.Errorf("failed to init document loader: %w", err) - } - - governanceVC, err := verifiable.ParseCredential( - governanceVCBytes, - verifiable.WithDisabledProofCheck(), - verifiable.WithJSONLDDocumentLoader(l), - ) - if err != nil { - return fmt.Errorf("failed to parse VC: %w", err) - } - - if len(governanceVC.Context) != governanceVCCTXSize { - return fmt.Errorf("governance vc context not equal 3") - } - - exist := false - - for _, v := range governanceVC.Context { - if v == governanceCtx { - exist = true - } - } - - if !exist { - return fmt.Errorf("governance vc context %s not exist", governanceCtx) - } - - return nil -} - func validateAndGetReferenceCred(vcBytes []byte, vcType string, vdriReg vdriapi.Registry) (*verifiable.Credential, error) { l, err := bddutil.DocumentLoader() diff --git a/test/bdd/pkg/bddutil/contexts/governance.jsonld b/test/bdd/pkg/bddutil/contexts/governance.jsonld deleted file mode 100644 index 3c06cd14..00000000 --- a/test/bdd/pkg/bddutil/contexts/governance.jsonld +++ /dev/null @@ -1,70 +0,0 @@ -{ - "@context": { - "@version": 1.1, - "@protected": true, - "xsd":"http://www.w3.org/2001/XMLSchema#", - "ex": "https://example.org/examples#", - - "GovernanceCredential": "ex:GovernanceCredential", - "name": "http://schema.org/name", - "version": "http://schema.org/version", - "logo": "http://schema.org/logo", - "description": "http://schema.org/description", - "docs_uri": "http://schema.org/url", - "data_uri": "http://schema.org/url", - "topics": "xsd:string", - "geos": "xsd:string", - "jurisdictions": "xsd:string", - "roles": "xsd:string", - "privileges": { - "@id": "ex:privileges", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "uri": "http://schema.org/url" - } - }, - "duties": { - "@id": "ex:duties", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "uri": "http://schema.org/url" - } - }, - "define": { - "@id": "ex:define", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name", - "id": "@id" - } - }, - "rules": { - "@id": "ex:rules", - "@context": { - "@version": 1.1, - "@protected": true, - - "grant": "xsd:string", - "duties": "xsd:string", - "thus": "xsd:string", - "when": { - "@id": "ex:when", - "@context": { - "@version": 1.1, - "@protected": true, - - "name": "http://schema.org/name" - } - } - } - } - } -} \ No newline at end of file diff --git a/test/bdd/pkg/bddutil/util.go b/test/bdd/pkg/bddutil/util.go index 070955de..be7ae0c8 100644 --- a/test/bdd/pkg/bddutil/util.go +++ b/test/bdd/pkg/bddutil/util.go @@ -264,8 +264,6 @@ var ( creditCardV1Vocab []byte //go:embed contexts/driver-license-evidence-v1.jsonld driverLicenseEvidenceV1Vocab []byte - //go:embed contexts/governance.jsonld - governanceVocab []byte //go:embed contexts/mdl-v1.jsonld mdlV1Vocab []byte //go:embed contexts/issuer-manifest-credential-v1.jsonld @@ -287,10 +285,6 @@ var extraContexts = []ldcontext.Document{ //nolint:gochecknoglobals URL: "https://trustbloc.github.io/context/vc/issuer-manifest-credential-v1.jsonld", Content: issuerManifestV1Vocab, }, - { - URL: "https://trustbloc.github.io/context/governance/context.jsonld", - Content: governanceVocab, - }, { URL: "https://trustbloc.github.io/context/vc/examples/citizenship-v1.jsonld", Content: citizenshipV1Vocab, diff --git a/test/bdd/pkg/rp/rp_steps.go b/test/bdd/pkg/rp/rp_steps.go index 297c3b24..e86b7335 100644 --- a/test/bdd/pkg/rp/rp_steps.go +++ b/test/bdd/pkg/rp/rp_steps.go @@ -58,10 +58,8 @@ const ( // AdapterURL is RP adapter endpoint. AdapterURL = "https://localhost:8070" - hydraAdminURL = "https://localhost:4445/" - hydraPublicURL = "https://localhost:4444/" - governanceCtx = "https://trustbloc.github.io/context/governance/context.jsonld" - governanceVCCTXSize = 3 + hydraAdminURL = "https://localhost:4445/" + hydraPublicURL = "https://localhost:4444/" trustblocDIDMethodDomain = "testnet.orb.local" ) @@ -534,11 +532,6 @@ func (s *Steps) sendCHAPIRequestToWallet(tenantID, walletID string) error { return fmt.Errorf("failed to validate presentation definitions for '%s': %w", tenantID, err) } - err = validateGovernance(result.Credentials[0]) - if err != nil { - return fmt.Errorf("failed to parse governance credential : %w", err) - } - tenant.invitationID = result.Inv.ID tenant.presDefs = result.PD s.context.Store[bddutil.GetDIDConnectRequestKey(tenantID, walletID)] = string(bits) @@ -639,40 +632,6 @@ func validatePresentationDefinitions(pd *presexch.PresentationDefinition, scope return nil } -func validateGovernance(governanceVCBytes []byte) error { - l, err := bddutil.DocumentLoader() - if err != nil { - return fmt.Errorf("failed to init document loader: %w", err) - } - - governanceVC, err := verifiable.ParseCredential( - governanceVCBytes, - verifiable.WithDisabledProofCheck(), - verifiable.WithJSONLDDocumentLoader(l), - ) - if err != nil { - return fmt.Errorf("failed to parse VC: %w", err) - } - - if len(governanceVC.Context) != governanceVCCTXSize { - return fmt.Errorf("governance vc context not equal 2") - } - - exist := false - - for _, v := range governanceVC.Context { - if v == governanceCtx { - exist = true - } - } - - if !exist { - return fmt.Errorf("governance vc context %s not exist", governanceCtx) - } - - return nil -} - func (s *Steps) walletAcceptsDIDCommInvitation(walletID, tenantID string) error { marshalled, found := s.context.GetString(bddutil.GetDIDConnectRequestKey(tenantID, walletID)) if !found {