From 90084f780af4ef89b55fc9c98a2b8c19b78ded3c Mon Sep 17 00:00:00 2001 From: Bob Stasyszyn Date: Wed, 10 Nov 2021 16:19:06 -0500 Subject: [PATCH] feat: Added 'accept list' management command to orb-cli Added an 'acceptlist' command to orb-cli that manages accept lists that are used by the 'Follow' and 'Invite' witness authorization handlers. The command has three sub-commands: - add - Adds one or more actor URIs to the accept list of a given type (follow or invite-witness) - remove - Removes one or more actor URIs from the accept list of a given type (follow or invite-witness) - get - Retrieves all accept lists or an accept list of a specified type (follow or invite-witness) closes #865 Signed-off-by: Bob Stasyszyn --- cmd/orb-cli/acceptlistcmd/acceptlist.go | 50 ++++++ cmd/orb-cli/acceptlistcmd/acceptlist_test.go | 21 +++ cmd/orb-cli/acceptlistcmd/getcmd.go | 66 ++++++++ cmd/orb-cli/acceptlistcmd/getcmd_test.go | 62 +++++++ cmd/orb-cli/acceptlistcmd/updatecmd.go | 125 ++++++++++++++ cmd/orb-cli/acceptlistcmd/updatecmd_test.go | 152 ++++++++++++++++++ cmd/orb-cli/common/common.go | 95 +++++++++++ cmd/orb-cli/common/common_test.go | 31 ++++ cmd/orb-cli/main.go | 2 + .../service/acceptlist/acceptlist.go | 2 - test/bdd/cli_steps.go | 23 +++ test/bdd/common_steps.go | 1 + test/bdd/features/orb-cli.feature | 38 ++++- test/bdd/features/orb-driver.feature | 8 +- test/bdd/features/orb-stress.feature | 8 +- 15 files changed, 663 insertions(+), 21 deletions(-) create mode 100644 cmd/orb-cli/acceptlistcmd/acceptlist.go create mode 100644 cmd/orb-cli/acceptlistcmd/acceptlist_test.go create mode 100644 cmd/orb-cli/acceptlistcmd/getcmd.go create mode 100644 cmd/orb-cli/acceptlistcmd/getcmd_test.go create mode 100644 cmd/orb-cli/acceptlistcmd/updatecmd.go create mode 100644 cmd/orb-cli/acceptlistcmd/updatecmd_test.go diff --git a/cmd/orb-cli/acceptlistcmd/acceptlist.go b/cmd/orb-cli/acceptlistcmd/acceptlist.go new file mode 100644 index 000000000..4dd5907d8 --- /dev/null +++ b/cmd/orb-cli/acceptlistcmd/acceptlist.go @@ -0,0 +1,50 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package acceptlistcmd + +import ( + "errors" + + "github.com/spf13/cobra" +) + +const ( + urlFlagName = "url" + urlFlagUsage = "The URL of the accept list REST endpoint." + + " Alternatively, this can be set with the following environment variable: " + urlEnvKey + urlEnvKey = "ORB_CLI_URL" + + actorFlagName = "actor" + actorFlagUsage = "A comma-separated list of service URIs to add to/remove from the accept list." + + " Alternatively, this can be set with the following environment variable: " + actorEnvKey + actorEnvKey = "ORB_CLI_ACTOR" + + typeFlagName = "type" + typeFlagUsage = "Accept list type (follow or invite-witness)." + + " Alternatively, this can be set with the following environment variable: " + typeEnvKey + typeEnvKey = "ORB_CLI_ACCEPT_TYPE" +) + +// GetCmd returns the Cobra acceptlist command. +func GetCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "acceptlist", + Short: "Manages accept lists.", + Long: "Manages accept lists for 'Follow' and 'Invite' witness authorization handlers.", + RunE: func(cmd *cobra.Command, args []string) error { + return errors.New("expecting subcommand add, remove, or get") + }, + } + + cmd.AddCommand( + newAddCmd(), + newRemoveCmd(), + newGetCmd(), + ) + + return cmd +} diff --git a/cmd/orb-cli/acceptlistcmd/acceptlist_test.go b/cmd/orb-cli/acceptlistcmd/acceptlist_test.go new file mode 100644 index 000000000..0234778fe --- /dev/null +++ b/cmd/orb-cli/acceptlistcmd/acceptlist_test.go @@ -0,0 +1,21 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package acceptlistcmd + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAcceptListCmd(t *testing.T) { + t.Run("test missing subcommand", func(t *testing.T) { + err := GetCmd().Execute() + require.Error(t, err) + require.Contains(t, err.Error(), "expecting subcommand add, remove, or get") + }) +} diff --git a/cmd/orb-cli/acceptlistcmd/getcmd.go b/cmd/orb-cli/acceptlistcmd/getcmd.go new file mode 100644 index 000000000..03bb44744 --- /dev/null +++ b/cmd/orb-cli/acceptlistcmd/getcmd.go @@ -0,0 +1,66 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package acceptlistcmd + +import ( + "fmt" + "net/http" + "net/url" + + "github.com/spf13/cobra" + cmdutils "github.com/trustbloc/edge-core/pkg/utils/cmd" + + "github.com/trustbloc/orb/cmd/orb-cli/common" +) + +func newGetCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "get", + Short: "Retrieves accept lists.", + Long: "Retrieves accept lists used by the 'Follow' and 'Invite' witness authorization handlers.", + RunE: func(cmd *cobra.Command, args []string) error { + return executeGet(cmd) + }, + } + + common.AddCommonFlags(cmd) + + cmd.Flags().StringP(urlFlagName, "", "", urlFlagUsage) + cmd.Flags().StringP(typeFlagName, "", "", typeFlagUsage) + + return cmd +} + +func executeGet(cmd *cobra.Command) error { + u, err := cmdutils.GetUserSetVarFromString(cmd, urlFlagName, urlEnvKey, false) + if err != nil { + return err + } + + _, err = url.Parse(u) + if err != nil { + return fmt.Errorf("invalid URL %s: %w", u, err) + } + + acceptType, err := cmdutils.GetUserSetVarFromString(cmd, typeFlagName, typeEnvKey, true) + if err != nil { + return err + } + + if acceptType != "" { + u = fmt.Sprintf("%s?type=%s", u, acceptType) + } + + resp, err := common.SendHTTPRequest(cmd, nil, http.MethodGet, u) + if err != nil { + return err + } + + fmt.Println(string(resp)) + + return nil +} diff --git a/cmd/orb-cli/acceptlistcmd/getcmd_test.go b/cmd/orb-cli/acceptlistcmd/getcmd_test.go new file mode 100644 index 000000000..e7d6c8ed0 --- /dev/null +++ b/cmd/orb-cli/acceptlistcmd/getcmd_test.go @@ -0,0 +1,62 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package acceptlistcmd + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetCmd(t *testing.T) { + t.Run("test missing url arg", func(t *testing.T) { + cmd := GetCmd() + cmd.SetArgs([]string{"get"}) + + err := cmd.Execute() + + require.Error(t, err) + require.Equal(t, + "Neither url (command line flag) nor ORB_CLI_URL (environment variable) have been set.", + err.Error()) + }) + + t.Run("test invalid url arg", func(t *testing.T) { + cmd := GetCmd() + + args := []string{"get"} + args = append(args, urlArg(":invalid")...) + cmd.SetArgs(args) + + err := cmd.Execute() + + require.Error(t, err) + require.Contains(t, err.Error(), "invalid URL") + }) + + t.Run("success", func(t *testing.T) { + serv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := fmt.Fprint(w, "d1") + require.NoError(t, err) + })) + + cmd := GetCmd() + + args := []string{"get"} + args = append(args, urlArg(serv.URL)...) + args = append(args, typeArg("follow")...) + cmd.SetArgs(args) + + cmd.SetArgs(args) + err := cmd.Execute() + + require.NoError(t, err) + }) +} diff --git a/cmd/orb-cli/acceptlistcmd/updatecmd.go b/cmd/orb-cli/acceptlistcmd/updatecmd.go new file mode 100644 index 000000000..f8c3db337 --- /dev/null +++ b/cmd/orb-cli/acceptlistcmd/updatecmd.go @@ -0,0 +1,125 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package acceptlistcmd + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/spf13/cobra" + cmdutils "github.com/trustbloc/edge-core/pkg/utils/cmd" + + "github.com/trustbloc/orb/cmd/orb-cli/common" +) + +func newAddCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "add", + Short: "Adds actors to an accept list.", + Long: "Adds actors to an accept list used by the 'Follow' and 'Invite' witness authorization handlers.", + RunE: func(cmd *cobra.Command, args []string) error { + return executeUpdate(cmd, true) + }, + } + + addUpdateFlags(cmd) + + return cmd +} + +func newRemoveCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "remove", + Short: "Removes actors from an accept list.", + Long: "Removes actors from an accept list used by the 'Follow' and 'Invite' witness authorization handlers.", + RunE: func(cmd *cobra.Command, args []string) error { + return executeUpdate(cmd, false) + }, + } + + addUpdateFlags(cmd) + + return cmd +} + +func executeUpdate(cmd *cobra.Command, isAdd bool) error { + u, acceptType, actors, err := getUpdateArgs(cmd) + if err != nil { + return err + } + + req := acceptListRequest{ + Type: acceptType, + } + + if isAdd { + req.Add = actors + } else { + req.Remove = actors + } + + reqBytes, err := json.Marshal([]acceptListRequest{req}) + if err != nil { + return err + } + + _, err = common.SendHTTPRequest(cmd, reqBytes, http.MethodPost, u) + if err != nil { + return err + } + + fmt.Println("Accept list has successfully been updated.") + + return nil +} + +func addUpdateFlags(cmd *cobra.Command) { + common.AddCommonFlags(cmd) + + cmd.Flags().StringP(urlFlagName, "", "", urlFlagUsage) + cmd.Flags().StringArrayP(actorFlagName, "", nil, actorFlagUsage) + cmd.Flags().StringP(typeFlagName, "", "", typeFlagUsage) +} + +func getUpdateArgs(cmd *cobra.Command) (u, acceptType string, actors []string, err error) { + u, err = cmdutils.GetUserSetVarFromString(cmd, urlFlagName, urlEnvKey, false) + if err != nil { + return "", "", nil, err + } + + _, err = url.Parse(u) + if err != nil { + return "", "", nil, fmt.Errorf("invalid URL %s: %w", u, err) + } + + acceptType, err = cmdutils.GetUserSetVarFromString(cmd, typeFlagName, typeEnvKey, false) + if err != nil { + return "", "", nil, err + } + + actors, err = cmdutils.GetUserSetVarFromArrayString(cmd, actorFlagName, actorEnvKey, false) + if err != nil { + return "", "", nil, err + } + + for _, actor := range actors { + _, err = url.Parse(actor) + if err != nil { + return "", "", nil, fmt.Errorf("invalid actor URL %s: %w", u, err) + } + } + + return u, acceptType, actors, nil +} + +type acceptListRequest struct { + Type string `json:"type"` + Add []string `json:"add,omitempty"` + Remove []string `json:"remove,omitempty"` +} diff --git a/cmd/orb-cli/acceptlistcmd/updatecmd_test.go b/cmd/orb-cli/acceptlistcmd/updatecmd_test.go new file mode 100644 index 000000000..da66e071e --- /dev/null +++ b/cmd/orb-cli/acceptlistcmd/updatecmd_test.go @@ -0,0 +1,152 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +package acceptlistcmd + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/trustbloc/orb/cmd/orb-cli/common" +) + +const ( + flag = "--" +) + +func TestUpdateCmd(t *testing.T) { + t.Run("test missing url arg", func(t *testing.T) { + cmd := GetCmd() + cmd.SetArgs([]string{"add"}) + + err := cmd.Execute() + + require.Error(t, err) + require.Equal(t, + "Neither url (command line flag) nor ORB_CLI_URL (environment variable) have been set.", + err.Error()) + }) + + t.Run("test invalid url arg", func(t *testing.T) { + cmd := GetCmd() + + args := []string{"add"} + args = append(args, urlArg(":invalid")...) + cmd.SetArgs(args) + + err := cmd.Execute() + + require.Error(t, err) + require.Contains(t, err.Error(), "invalid URL") + }) + + t.Run("test missing type arg", func(t *testing.T) { + cmd := GetCmd() + + args := []string{"add"} + args = append(args, urlArg("localhost:8080")...) + cmd.SetArgs(args) + + err := cmd.Execute() + + require.Error(t, err) + require.Equal(t, + "Neither type (command line flag) nor ORB_CLI_ACCEPT_TYPE (environment variable) have been set.", + err.Error()) + }) + + t.Run("test missing actorArg arg", func(t *testing.T) { + cmd := GetCmd() + + args := []string{"add"} + args = append(args, urlArg("localhost:8080")...) + args = append(args, typeArg("follow")...) + cmd.SetArgs(args) + + err := cmd.Execute() + + require.Error(t, err) + require.Equal(t, + "Neither actor (command line flag) nor ORB_CLI_ACTOR (environment variable) have been set.", + err.Error()) + }) + + t.Run("test invalid actorArg arg", func(t *testing.T) { + cmd := GetCmd() + + args := []string{"add"} + args = append(args, urlArg("localhost:8080")...) + args = append(args, typeArg("follow")...) + args = append(args, actorArg(":invalid")...) + cmd.SetArgs(args) + + err := cmd.Execute() + + require.Error(t, err) + require.Contains(t, err.Error(), "invalid actor URL") + }) + + t.Run("add -> success", func(t *testing.T) { + serv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := fmt.Fprint(w, "d1") + require.NoError(t, err) + })) + + cmd := GetCmd() + + args := []string{"add"} + args = append(args, urlArg(serv.URL)...) + args = append(args, typeArg("follow")...) + args = append(args, actorArg("localhost:8080")...) + args = append(args, authTokenArg("ADMIN_TOKEN")...) + cmd.SetArgs(args) + + cmd.SetArgs(args) + err := cmd.Execute() + + require.NoError(t, err) + }) + + t.Run("remove -> success", func(t *testing.T) { + serv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := fmt.Fprint(w, "d1") + require.NoError(t, err) + })) + + cmd := GetCmd() + + args := []string{"remove"} + args = append(args, urlArg(serv.URL)...) + args = append(args, typeArg("follow")...) + args = append(args, actorArg("localhost:8080")...) + args = append(args, authTokenArg("ADMIN_TOKEN")...) + cmd.SetArgs(args) + + cmd.SetArgs(args) + err := cmd.Execute() + + require.NoError(t, err) + }) +} + +func urlArg(value string) []string { + return []string{flag + urlFlagName, value} +} + +func actorArg(value string) []string { + return []string{flag + actorFlagName, value} +} + +func typeArg(value string) []string { + return []string{flag + typeFlagName, value} +} + +func authTokenArg(value string) []string { + return []string{flag + common.AuthTokenFlagName, value} +} diff --git a/cmd/orb-cli/common/common.go b/cmd/orb-cli/common/common.go index 9de73170b..20ec6e862 100644 --- a/cmd/orb-cli/common/common.go +++ b/cmd/orb-cli/common/common.go @@ -11,6 +11,7 @@ import ( "crypto" "crypto/ecdsa" "crypto/ed25519" + "crypto/tls" "crypto/x509" "encoding/json" "encoding/pem" @@ -19,6 +20,7 @@ import ( "io/ioutil" "net/http" "path/filepath" + "strconv" "github.com/btcsuite/btcutil/base58" "github.com/hyperledger/aries-framework-go-ext/component/vdr/sidetree/doc" @@ -27,10 +29,38 @@ import ( "github.com/spf13/cobra" "github.com/trustbloc/edge-core/pkg/log" cmdutils "github.com/trustbloc/edge-core/pkg/utils/cmd" + tlsutils "github.com/trustbloc/edge-core/pkg/utils/tls" ) var logger = log.New("orb-cli") +const ( + // TLSSystemCertPoolFlagName defines the flag for the system certificate pool. + TLSSystemCertPoolFlagName = "tls-systemcertpool" + // TLSSystemCertPoolFlagUsage defines the usage of the system certificate pool flag. + TLSSystemCertPoolFlagUsage = "Use system certificate pool." + + " Possible values [true] [false]. Defaults to false if not set." + + " Alternatively, this can be set with the following environment variable: " + TLSSystemCertPoolEnvKey + // TLSSystemCertPoolEnvKey defines the environment variable for the system certificate pool flag. + TLSSystemCertPoolEnvKey = "ORB_CLI_TLS_SYSTEMCERTPOOL" + + // TLSCACertsFlagName defines the flag for the CA certs flag. + TLSCACertsFlagName = "tls-cacerts" + // TLSCACertsFlagUsage defines the usage of the CA certs flag. + TLSCACertsFlagUsage = "Comma-separated list of ca certs path." + + " Alternatively, this can be set with the following environment variable: " + TLSCACertsEnvKey + // TLSCACertsEnvKey defines the environment variable for the CA certs flag. + TLSCACertsEnvKey = "ORB_CLI_TLS_CACERTS" + + // AuthTokenFlagName defines the flag for the authorization bearer token. + AuthTokenFlagName = "auth-token" + // AuthTokenFlagUsage defines the usage of the authorization bearer token flag. + AuthTokenFlagUsage = "Auth token." + + " Alternatively, this can be set with the following environment variable: " + AuthTokenEnvKey + // AuthTokenEnvKey defines the environment variable for the authorization bearer token flag. + AuthTokenEnvKey = "ORB_CLI_AUTH_TOKEN" //nolint:gosec +) + // PublicKey struct. type PublicKey struct { ID string `json:"id,omitempty"` @@ -284,8 +314,73 @@ func SendRequest(httpClient *http.Client, req []byte, headers map[string]string, return responseBytes, nil } +// SendHTTPRequest sends the given HTTP request using the options provided on the command-line. +func SendHTTPRequest(cmd *cobra.Command, reqBytes []byte, method, endpointURL string) ([]byte, error) { + client, err := newHTTPClient(cmd) + if err != nil { + return nil, err + } + + return SendRequest(client, reqBytes, newAuthTokenHeader(cmd), method, endpointURL) +} + func closeResponseBody(respBody io.Closer) { if err := respBody.Close(); err != nil { logger.Errorf("Failed to close response body: %v", err) } } + +func newHTTPClient(cmd *cobra.Command) (*http.Client, error) { + rootCAs, err := getRootCAs(cmd) + if err != nil { + return nil, err + } + + return &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: rootCAs, + MinVersion: tls.VersionTLS12, + }, + }, + }, nil +} + +func getRootCAs(cmd *cobra.Command) (*x509.CertPool, error) { + tlsSystemCertPoolString := cmdutils.GetUserSetOptionalVarFromString(cmd, TLSSystemCertPoolFlagName, + TLSSystemCertPoolEnvKey) + + tlsSystemCertPool := false + + if tlsSystemCertPoolString != "" { + var err error + tlsSystemCertPool, err = strconv.ParseBool(tlsSystemCertPoolString) + + if err != nil { + return nil, err + } + } + + tlsCACerts := cmdutils.GetUserSetOptionalVarFromArrayString(cmd, TLSCACertsFlagName, + TLSCACertsEnvKey) + + return tlsutils.GetCertPool(tlsSystemCertPool, tlsCACerts) +} + +func newAuthTokenHeader(cmd *cobra.Command) map[string]string { + headers := make(map[string]string) + + authToken := cmdutils.GetUserSetOptionalVarFromString(cmd, AuthTokenFlagName, AuthTokenEnvKey) + if authToken != "" { + headers["Authorization"] = "Bearer " + authToken + } + + return headers +} + +// AddCommonFlags adds common flags to the given command. +func AddCommonFlags(cmd *cobra.Command) { + cmd.Flags().StringP(TLSSystemCertPoolFlagName, "", "", TLSSystemCertPoolFlagUsage) + cmd.Flags().StringArrayP(TLSCACertsFlagName, "", nil, TLSCACertsFlagUsage) + cmd.Flags().StringP(AuthTokenFlagName, "", "", AuthTokenFlagUsage) +} diff --git a/cmd/orb-cli/common/common_test.go b/cmd/orb-cli/common/common_test.go index 05ee70bcd..1596e0458 100644 --- a/cmd/orb-cli/common/common_test.go +++ b/cmd/orb-cli/common/common_test.go @@ -308,6 +308,26 @@ func TestSendRequest(t *testing.T) { }) } +func TestSendHTTPRequest(t *testing.T) { + t.Run("test error 500", func(t *testing.T) { + serv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + + cmd := newMockCmd(func(cmd *cobra.Command, args []string) error { + _, err := SendHTTPRequest(cmd, nil, http.MethodGet, serv.URL) + + return err + }) + + cmd.SetArgs([]string{"--" + AuthTokenFlagName, "ADMIN_TOKEN"}) + + err := cmd.Execute() + require.Error(t, err) + require.Contains(t, err.Error(), "got unexpected response from") + }) +} + func TestGetVDRPublicKeys(t *testing.T) { t.Run("test public key invalid path", func(t *testing.T) { _, err := GetVDRPublicKeysFromFile("./wrongfile") @@ -407,3 +427,14 @@ func TestGetVDRPublicKeys(t *testing.T) { require.Equal(t, len(didDoc.Authentication), 2) }) } + +func newMockCmd(runFUnc func(cmd *cobra.Command, args []string) error) *cobra.Command { + cmd := &cobra.Command{ + Use: "mock", + RunE: runFUnc, + } + + AddCommonFlags(cmd) + + return cmd +} diff --git a/cmd/orb-cli/main.go b/cmd/orb-cli/main.go index a70bd918c..f92adfd5c 100644 --- a/cmd/orb-cli/main.go +++ b/cmd/orb-cli/main.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cobra" "github.com/trustbloc/edge-core/pkg/log" + "github.com/trustbloc/orb/cmd/orb-cli/acceptlistcmd" "github.com/trustbloc/orb/cmd/orb-cli/createdidcmd" "github.com/trustbloc/orb/cmd/orb-cli/deactivatedidcmd" "github.com/trustbloc/orb/cmd/orb-cli/followcmd" @@ -58,6 +59,7 @@ func main() { rootCmd.AddCommand(ipfsCmd) rootCmd.AddCommand(followcmd.GetCmd()) rootCmd.AddCommand(witnesscmd.GetCmd()) + rootCmd.AddCommand(acceptlistcmd.GetCmd()) if err := rootCmd.Execute(); err != nil { logger.Fatalf("Failed to run orb-cli: %s", err.Error()) diff --git a/pkg/activitypub/service/acceptlist/acceptlist.go b/pkg/activitypub/service/acceptlist/acceptlist.go index 223f2aa02..9d080283b 100644 --- a/pkg/activitypub/service/acceptlist/acceptlist.go +++ b/pkg/activitypub/service/acceptlist/acceptlist.go @@ -146,8 +146,6 @@ func (m *Manager) queryByType(acceptType string) ([]*spi.AcceptList, error) { acceptLists = append(acceptLists, list) } - logger.Debugf("Loaded accept lists for type [%s]: %s", acceptType, acceptLists) - return acceptLists, nil } diff --git a/test/bdd/cli_steps.go b/test/bdd/cli_steps.go index 59d1e126d..c3ce4231a 100644 --- a/test/bdd/cli_steps.go +++ b/test/bdd/cli_steps.go @@ -20,6 +20,8 @@ import ( // Steps is steps for cli BDD tests. type Steps struct { bddContext *BDDContext + state *state + cliValue string createdDID *ariesdid.Doc httpClient *httpClient @@ -29,6 +31,7 @@ type Steps struct { func NewCLISteps(ctx *BDDContext, state *state) *Steps { return &Steps{ bddContext: ctx, + state: state, httpClient: newHTTPClient(state, ctx), } } @@ -45,6 +48,7 @@ func (e *Steps) RegisterSteps(s *godog.Suite) { s.Step(`^check cli deactivated DID$`, e.checkDeactivatedDID) s.Step(`^check cli updated DID$`, e.checkUpdatedDID) s.Step(`^user create "([^"]*)" activity with outbox-url "([^"]*)" actor "([^"]*)" to "([^"]*)" action "([^"]*)"$`, e.createActivity) + s.Step(`^orb-cli is executed with args '([^']*)'$`, e.execute) } func (e *Steps) checkCreatedDID() error { @@ -411,6 +415,25 @@ func (e *Steps) createDID() error { return nil } +func (e *Steps) execute(argsStr string) error { + var args []string + + for _, arg := range strings.Split(argsStr, " ") { + args = append(args, arg) + } + + value, err := execCMD(args...) + if err != nil { + return err + } + + logger.Infof("Response from CLI: %s", value) + + e.state.setResponse(value) + + return nil +} + func execCMD(args ...string) (string, error) { cmd := exec.Command(fmt.Sprintf("../../.build/extract/orb-cli-%s-amd64", runtime.GOOS), args...) // nolint: gosec diff --git a/test/bdd/common_steps.go b/test/bdd/common_steps.go index 8c16ebfab..62de3e87a 100644 --- a/test/bdd/common_steps.go +++ b/test/bdd/common_steps.go @@ -934,6 +934,7 @@ func (d *CommonSteps) RegisterSteps(s *godog.Suite) { s.Step(`^the JSON path '([^']*)' of the response contains "([^"]*)"$`, d.jsonPathOfResponseContains) s.Step(`^the JSON path "([^"]*)" of the response contains expression "([^"]*)"$`, d.jsonPathOfResponseContainsRegEx) s.Step(`^the JSON path "([^"]*)" of the response does not contain "([^"]*)"$`, d.jsonPathOfResponseNotContains) + s.Step(`^the JSON path '([^']*)' of the response does not contain "([^"]*)"$`, d.jsonPathOfResponseNotContains) s.Step(`^the JSON path "([^"]*)" of the response does not contain expression "([^"]*)"$`, d.jsonPathOfResponseNotContainsRegEx) s.Step(`^the JSON path "([^"]*)" of the response is saved to variable "([^"]*)"$`, d.jsonPathOfResponseSavedToVar) s.Step(`^the JSON path '([^']*)' of the response is saved to variable "([^"]*)"$`, d.jsonPathOfResponseSavedToVar) diff --git a/test/bdd/features/orb-cli.feature b/test/bdd/features/orb-cli.feature index 68283600c..9c6fbab64 100644 --- a/test/bdd/features/orb-cli.feature +++ b/test/bdd/features/orb-cli.feature @@ -9,14 +9,9 @@ @orb_cli Feature: Using Orb CLI Background: Setup - # TODO: Replace this configuration to use the Orb CLI to update the accept list - Issue #865. - Given the authorization bearer token for "POST" requests to path "/services/orb/acceptlist" is set to "ADMIN_TOKEN" - Given variable "domain1AcceptList" is assigned the JSON value '[{"type":"follow","add":["https://orb.domain2.com/services/orb"]}]' - Then an HTTP POST is sent to "https://localhost:48326/services/orb/acceptlist" with content "${domain1AcceptList}" of type "application/json" - Given variable "domain2AcceptList" is assigned the JSON value '[{"type":"invite-witness","add":["https://orb.domain1.com/services/orb"]}]' - Then an HTTP POST is sent to "https://localhost:48426/services/orb/acceptlist" with content "${domain2AcceptList}" of type "application/json" - Given the authorization bearer token for "GET" requests to path "/sidetree/v1/identifiers" is set to "READ_TOKEN" + And orb-cli is executed with args 'acceptlist add --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domain2.com/services/orb --type follow --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + And orb-cli is executed with args 'acceptlist add --url https://localhost:48426/services/orb/acceptlist --actor https://orb.domain1.com/services/orb --type invite-witness --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' @orb_cli_did Scenario: test create and update did doc using cli @@ -45,3 +40,32 @@ Feature: Using Orb CLI When user create "witness" activity with outbox-url "https://localhost:48426/services/orb/outbox" actor "https://orb.domain2.com/services/orb" to "https://orb.domain1.com/services/orb" action "InviteWitness" Then we wait 3 seconds When user create "witness" activity with outbox-url "https://localhost:48426/services/orb/outbox" actor "https://orb.domain2.com/services/orb" to "https://orb.domain1.com/services/orb" action "Undo" + + @orb_cli_acceptlist + Scenario: test accept list management using cli + # Add actors to the 'follow' accept list. + When orb-cli is executed with args 'acceptlist add --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domainx.com/services/orb --actor https://orb.domainy.com/services/orb --type follow --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + # Add actors to the 'invite-witness' accept list. + Then orb-cli is executed with args 'acceptlist add --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domainz.com/services/orb --type invite-witness --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + + When orb-cli is executed with args 'acceptlist get --url https://localhost:48326/services/orb/acceptlist --type follow --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token READ_TOKEN' + Then the JSON path "url" of the response contains "https://orb.domainx.com/services/orb" + Then the JSON path "url" of the response contains "https://orb.domainy.com/services/orb" + + And orb-cli is executed with args 'acceptlist get --url https://localhost:48326/services/orb/acceptlist --type invite-witness --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token READ_TOKEN' + Then the JSON path "url" of the response contains "https://orb.domainz.com/services/orb" + + And orb-cli is executed with args 'acceptlist get --url https://localhost:48326/services/orb/acceptlist --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token READ_TOKEN' + Then the JSON path '#(type="follow").url' of the response contains "https://orb.domainx.com/services/orb" + And the JSON path '#(type="follow").url' of the response contains "https://orb.domainx.com/services/orb" + And the JSON path '#(type="invite-witness").url' of the response contains "https://orb.domainz.com/services/orb" + + # Remove actors from the 'follow' accept list. + When orb-cli is executed with args 'acceptlist remove --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domainx.com/services/orb --actor https://orb.domainy.com/services/orb --type follow --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + # Remove actors from the 'invite-witness' accept list. + Then orb-cli is executed with args 'acceptlist remove --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domainz.com/services/orb --type invite-witness --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + + And orb-cli is executed with args 'acceptlist get --url https://localhost:48326/services/orb/acceptlist --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token READ_TOKEN' + Then the JSON path '#(type="follow").url' of the response does not contain "https://orb.domainx.com/services/orb" + And the JSON path '#(type="follow").url' of the response does not contain "https://orb.domainx.com/services/orb" + And the JSON path '#(type="invite-witness").url' of the response does not contain "https://orb.domainz.com/services/orb" diff --git a/test/bdd/features/orb-driver.feature b/test/bdd/features/orb-driver.feature index 4a7c54dc5..244d726d5 100644 --- a/test/bdd/features/orb-driver.feature +++ b/test/bdd/features/orb-driver.feature @@ -9,12 +9,8 @@ @orb_driver Feature: Using Orb driver Background: Setup - # TODO: Replace this configuration to use the Orb CLI to update the accept list - Issue #865. - Given the authorization bearer token for "POST" requests to path "/services/orb/acceptlist" is set to "ADMIN_TOKEN" - Given variable "domain1AcceptList" is assigned the JSON value '[{"type":"follow","add":["https://orb.domain2.com/services/orb"]}]' - Then an HTTP POST is sent to "https://localhost:48326/services/orb/acceptlist" with content "${domain1AcceptList}" of type "application/json" - Given variable "domain2AcceptList" is assigned the JSON value '[{"type":"invite-witness","add":["https://orb.domain1.com/services/orb"]}]' - Then an HTTP POST is sent to "https://localhost:48426/services/orb/acceptlist" with content "${domain2AcceptList}" of type "application/json" + Given orb-cli is executed with args 'acceptlist add --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domain2.com/services/orb --type follow --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + And orb-cli is executed with args 'acceptlist add --url https://localhost:48426/services/orb/acceptlist --actor https://orb.domain1.com/services/orb --type invite-witness --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' @orb_driver_e2e Scenario: test resolve did through driver diff --git a/test/bdd/features/orb-stress.feature b/test/bdd/features/orb-stress.feature index d00699ae4..c28345f72 100644 --- a/test/bdd/features/orb-stress.feature +++ b/test/bdd/features/orb-stress.feature @@ -9,12 +9,8 @@ @orb_stress Feature: Using Orb stress test Background: Setup - # TODO: Replace this configuration to use the Orb CLI to update the accept list - Issue #865. - Given the authorization bearer token for "POST" requests to path "/services/orb/acceptlist" is set to "ADMIN_TOKEN" - Given variable "domain1AcceptList" is assigned the JSON value '[{"type":"follow","add":["https://orb.domain2.com/services/orb"]}]' - Then an HTTP POST is sent to "https://localhost:48326/services/orb/acceptlist" with content "${domain1AcceptList}" of type "application/json" - Given variable "domain2AcceptList" is assigned the JSON value '[{"type":"invite-witness","add":["https://orb.domain1.com/services/orb"]}]' - Then an HTTP POST is sent to "https://localhost:48426/services/orb/acceptlist" with content "${domain2AcceptList}" of type "application/json" + Given orb-cli is executed with args 'acceptlist add --url https://localhost:48326/services/orb/acceptlist --actor https://orb.domain2.com/services/orb --type follow --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' + And orb-cli is executed with args 'acceptlist add --url https://localhost:48426/services/orb/acceptlist --actor https://orb.domain1.com/services/orb --type invite-witness --tls-cacerts fixtures/keys/tls/ec-cacert.pem --auth-token ADMIN_TOKEN' @orb_did_stress_test_setup Scenario: