-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <Bob.Stasyszyn@securekey.com>
- Loading branch information
1 parent
ecebebb
commit 90084f7
Showing
15 changed files
with
663 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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") | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"` | ||
} |
Oops, something went wrong.