Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
4076c6a918
commit
bc7221f5c5
@ -199,7 +199,7 @@ func (s *E2ETestSuite) TestQueryGranterGrantsGRPC() {
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.APIAddress, val.Address.String()),
|
||||
false,
|
||||
"",
|
||||
7,
|
||||
6,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
|
||||
@ -1,269 +0,0 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/codec/address"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||
authzclitestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil"
|
||||
)
|
||||
|
||||
func (s *E2ETestSuite) TestQueryAuthorizations() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
grantee := s.grantee[0]
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := authzclitestutil.CreateGrant(
|
||||
val.ClientCtx,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"Error: Invalid grantee",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
"invalid grantee",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed: invalid character in string: ' '",
|
||||
},
|
||||
{
|
||||
"Error: Invalid granter",
|
||||
[]string{
|
||||
"invalid granter",
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed: invalid character in string: ' '",
|
||||
},
|
||||
{
|
||||
"Valid txn (json)",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
``,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryGrants(address.NewBech32Codec("cosmos"))
|
||||
clientCtx := val.ClientCtx
|
||||
resp, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(string(resp.Bytes()), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
var grants authz.QueryGrantsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &grants)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestQueryAuthorization() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
grantee := s.grantee[0]
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := authzclitestutil.CreateGrant(
|
||||
val.ClientCtx,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expectedOutput string
|
||||
}{
|
||||
{
|
||||
"Error: Invalid grantee",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
"invalid grantee",
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Error: Invalid granter",
|
||||
[]string{
|
||||
"invalid granter",
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"no authorization found",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
grantee.String(),
|
||||
"typeMsgSend",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Valid txn (json)",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
`{"@type":"/cosmos.bank.v1beta1.SendAuthorization","spend_limit":[{"denom":"stake","amount":"100"}],"allow_list":[]}`,
|
||||
},
|
||||
{
|
||||
"Valid txn with allowed list (json)",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
s.grantee[3].String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
fmt.Sprintf(`{"@type":"/cosmos.bank.v1beta1.SendAuthorization","spend_limit":[{"denom":"stake","amount":"88"}],"allow_list":["%s"]}`, s.grantee[4]),
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryGrants(address.NewBech32Codec("cosmos"))
|
||||
clientCtx := val.ClientCtx
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().Contains(strings.TrimSpace(out.String()), tc.expectedOutput)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *E2ETestSuite) TestQueryGranterGrants() {
|
||||
val := s.network.Validators[0]
|
||||
grantee := s.grantee[0]
|
||||
require := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expectedErr string
|
||||
expItems int
|
||||
}{
|
||||
{
|
||||
"invalid address",
|
||||
[]string{
|
||||
"invalid-address",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed",
|
||||
0,
|
||||
},
|
||||
{
|
||||
"no authorization found",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
0,
|
||||
},
|
||||
{
|
||||
"valid case",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
7,
|
||||
},
|
||||
{
|
||||
"valid case with pagination",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
"--limit=2",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
2,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetQueryGranterGrants(address.NewBech32Codec("cosmos"))
|
||||
clientCtx := val.ClientCtx
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
require.Error(err)
|
||||
require.Contains(out.String(), tc.expectedErr)
|
||||
} else {
|
||||
require.NoError(err)
|
||||
var grants authz.QueryGranterGrantsResponse
|
||||
require.NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants))
|
||||
require.Len(grants.Grants, tc.expItems)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,195 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func GetQueryCmd(ac address.Codec) *cobra.Command {
|
||||
authorizationQueryCmd := &cobra.Command{
|
||||
Use: authz.ModuleName,
|
||||
Short: "Querying commands for the authz module",
|
||||
Long: "",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
authorizationQueryCmd.AddCommand(
|
||||
GetCmdQueryGrants(ac),
|
||||
GetQueryGranterGrants(ac),
|
||||
GetQueryGranteeGrants(ac),
|
||||
)
|
||||
|
||||
return authorizationQueryCmd
|
||||
}
|
||||
|
||||
// GetCmdQueryGrants implements the query authorization command.
|
||||
func GetCmdQueryGrants(ac address.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "grants [granter-addr] [grantee-addr] [msg-type-url]?",
|
||||
Args: cobra.RangeArgs(2, 3),
|
||||
Short: "query grants for a granter-grantee pair and optionally a msg-type-url",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query authorization grants for a granter-grantee pair. If msg-type-url
|
||||
is set, it will select grants only for that msg type.
|
||||
Examples:
|
||||
$ %s query %s grants cosmos1skj.. cosmos1skjwj..
|
||||
$ %s query %s grants cosmos1skjw.. cosmos1skjwj.. %s
|
||||
`,
|
||||
version.AppName, authz.ModuleName,
|
||||
version.AppName, authz.ModuleName, bank.SendAuthorization{}.MsgTypeURL()),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := authz.NewQueryClient(clientCtx)
|
||||
|
||||
_, err = ac.StringToBytes(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = ac.StringToBytes(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgAuthorized := ""
|
||||
if len(args) == 3 {
|
||||
msgAuthorized = args[2]
|
||||
}
|
||||
pageReq, err := client.ReadPageRequest(cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := queryClient.Grants(
|
||||
cmd.Context(),
|
||||
&authz.QueryGrantsRequest{
|
||||
Granter: args[0],
|
||||
Grantee: args[1],
|
||||
MsgTypeUrl: msgAuthorized,
|
||||
Pagination: pageReq,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
flags.AddPaginationFlagsToCmd(cmd, "grants")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetQueryGranterGrants returns cmd to query for all grants for a granter.
|
||||
func GetQueryGranterGrants(ac address.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "grants-by-granter [granter-addr]",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Short: "query authorization grants granted by granter",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query authorization grants granted by granter.
|
||||
Examples:
|
||||
$ %s q %s grants-by-granter cosmos1skj..
|
||||
`,
|
||||
version.AppName, authz.ModuleName),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = ac.StringToBytes(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pageReq, err := client.ReadPageRequest(cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := authz.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GranterGrants(
|
||||
cmd.Context(),
|
||||
&authz.QueryGranterGrantsRequest{
|
||||
Granter: args[0],
|
||||
Pagination: pageReq,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
flags.AddPaginationFlagsToCmd(cmd, "granter-grants")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetQueryGranteeGrants returns cmd to query for all grants for a grantee.
|
||||
func GetQueryGranteeGrants(ac address.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "grants-by-grantee [grantee-addr]",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Short: "query authorization grants granted to a grantee",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query authorization grants granted to a grantee.
|
||||
Examples:
|
||||
$ %s q %s grants-by-grantee cosmos1skj..
|
||||
`,
|
||||
version.AppName, authz.ModuleName),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = ac.StringToBytes(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pageReq, err := client.ReadPageRequest(cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := authz.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GranteeGrants(
|
||||
cmd.Context(),
|
||||
&authz.QueryGranteeGrantsRequest{
|
||||
Grantee: args[0],
|
||||
Pagination: pageReq,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
flags.AddPaginationFlagsToCmd(cmd, "grantee-grants")
|
||||
return cmd
|
||||
}
|
||||
@ -1,315 +0,0 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||
authzclitestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil"
|
||||
)
|
||||
|
||||
func (s *CLITestSuite) TestQueryAuthorizations() {
|
||||
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||
|
||||
grantee := s.grantee[0]
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := authzclitestutil.CreateGrant(
|
||||
s.clientCtx,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"Error: Invalid grantee",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
"invalid grantee",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed: invalid character in string: ' '",
|
||||
},
|
||||
{
|
||||
"Error: Invalid granter",
|
||||
[]string{
|
||||
"invalid granter",
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed: invalid character in string: ' '",
|
||||
},
|
||||
{
|
||||
"Valid txn (json)",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
``,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryGrants(addresscodec.NewBech32Codec("cosmos"))
|
||||
resp, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(string(resp.Bytes()), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
var grants authz.QueryGrantsResponse
|
||||
err = s.clientCtx.Codec.UnmarshalJSON(resp.Bytes(), &grants)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CLITestSuite) TestQueryAuthorization() {
|
||||
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||
|
||||
grantee := s.grantee[0]
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := authzclitestutil.CreateGrant(
|
||||
s.clientCtx,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"Error: Invalid grantee",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
"invalid grantee",
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Error: Invalid granter",
|
||||
[]string{
|
||||
"invalid granter",
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Valid txn (json)",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Valid txn with allowed list (json)",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
s.grantee[3].String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryGrants(addresscodec.NewBech32Codec("cosmos"))
|
||||
_, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CLITestSuite) TestQueryGranteeGrants() {
|
||||
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||
|
||||
grantee := s.grantee[0]
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
require := s.Require()
|
||||
|
||||
_, err := authzclitestutil.CreateGrant(
|
||||
s.clientCtx,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
"invalid address",
|
||||
[]string{
|
||||
"invalid-address",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed",
|
||||
},
|
||||
{
|
||||
"valid case",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid case with pagination",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"--limit=2",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetQueryGranteeGrants(addresscodec.NewBech32Codec("cosmos"))
|
||||
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
require.Error(err)
|
||||
require.Contains(out.String(), tc.expectedErr)
|
||||
} else {
|
||||
require.NoError(err)
|
||||
var grants authz.QueryGranteeGrantsResponse
|
||||
require.NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CLITestSuite) TestQueryGranterGrants() {
|
||||
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||
|
||||
grantee := s.grantee[0]
|
||||
require := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
"invalid address",
|
||||
[]string{
|
||||
"invalid-address",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed",
|
||||
},
|
||||
{
|
||||
"no authorization found",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid case",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid case with pagination",
|
||||
[]string{
|
||||
val[0].Address.String(),
|
||||
"--limit=2",
|
||||
fmt.Sprintf("--%s=json", flags.FlagOutput),
|
||||
},
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetQueryGranterGrants(addresscodec.NewBech32Codec("cosmos"))
|
||||
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
require.Error(err)
|
||||
require.Contains(out.String(), tc.expectedErr)
|
||||
} else {
|
||||
require.NoError(err)
|
||||
var grants authz.QueryGranterGrantsResponse
|
||||
require.NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,19 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() {
|
||||
func(require *require.Assertions, res *authz.QueryGrantsResponse) {},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
"authorization not found",
|
||||
func(require *require.Assertions) {
|
||||
req = &authz.QueryGrantsRequest{
|
||||
Granter: addrs[1].String(),
|
||||
Grantee: addrs[0].String(),
|
||||
MsgTypeUrl: banktypes.SendAuthorization{}.MsgTypeURL(),
|
||||
}
|
||||
},
|
||||
"authorization not found for /cosmos.bank.v1beta1.MsgSend",
|
||||
func(require *require.Assertions, res *authz.QueryGrantsResponse) {},
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func(require *require.Assertions) {
|
||||
expAuthorization = suite.createSendAuthorization(addrs[0], addrs[1])
|
||||
req = &authz.QueryGrantsRequest{
|
||||
@ -76,6 +88,28 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() {
|
||||
require.Equal(auth.String(), expAuthorization.String())
|
||||
},
|
||||
},
|
||||
{
|
||||
"success with allow list",
|
||||
func(require *require.Assertions) {
|
||||
expAuthorization = suite.createSendAuthorizationWithAllowList(addrs[0], addrs[1])
|
||||
require.Len(expAuthorization.(*banktypes.SendAuthorization).GetAllowList(), 1)
|
||||
req = &authz.QueryGrantsRequest{
|
||||
Granter: addrs[1].String(),
|
||||
Grantee: addrs[0].String(),
|
||||
MsgTypeUrl: expAuthorization.MsgTypeURL(),
|
||||
}
|
||||
},
|
||||
"",
|
||||
func(require *require.Assertions, res *authz.QueryGrantsResponse) {
|
||||
var auth authz.Authorization
|
||||
require.Equal(1, len(res.Grants))
|
||||
err := suite.encCfg.InterfaceRegistry.UnpackAny(res.Grants[0].Authorization, &auth)
|
||||
require.NoError(err)
|
||||
require.NotNil(auth)
|
||||
require.Equal(auth.String(), expAuthorization.String())
|
||||
require.Equal(auth.(*banktypes.SendAuthorization).GetAllowList(), expAuthorization.(*banktypes.SendAuthorization).GetAllowList())
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
@ -93,70 +127,6 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TestSuite) TestGRPCQueryAuthorizations() {
|
||||
queryClient, addrs := suite.queryClient, suite.addrs
|
||||
var (
|
||||
req *authz.QueryGrantsRequest
|
||||
expAuthorization authz.Authorization
|
||||
)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
postTest func(res *authz.QueryGrantsResponse)
|
||||
}{
|
||||
{
|
||||
"fail invalid granter addr",
|
||||
func() {
|
||||
req = &authz.QueryGrantsRequest{}
|
||||
},
|
||||
false,
|
||||
func(res *authz.QueryGrantsResponse) {},
|
||||
},
|
||||
{
|
||||
"fail invalid grantee addr",
|
||||
func() {
|
||||
req = &authz.QueryGrantsRequest{
|
||||
Granter: addrs[0].String(),
|
||||
}
|
||||
},
|
||||
false,
|
||||
func(res *authz.QueryGrantsResponse) {},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
func() {
|
||||
expAuthorization = suite.createSendAuthorization(addrs[0], addrs[1])
|
||||
req = &authz.QueryGrantsRequest{
|
||||
Granter: addrs[1].String(),
|
||||
Grantee: addrs[0].String(),
|
||||
}
|
||||
},
|
||||
true,
|
||||
func(res *authz.QueryGrantsResponse) {
|
||||
var auth authz.Authorization
|
||||
suite.Require().Equal(1, len(res.Grants))
|
||||
err := suite.encCfg.InterfaceRegistry.UnpackAny(res.Grants[0].Authorization, &auth)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(auth)
|
||||
suite.Require().Equal(auth.String(), expAuthorization.String())
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
|
||||
testCase.malleate()
|
||||
result, err := queryClient.Grants(gocontext.Background(), req)
|
||||
if testCase.expPass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
testCase.postTest(result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TestSuite) TestGRPCQueryGranterGrants() {
|
||||
require := suite.Require()
|
||||
queryClient, addrs := suite.queryClient, suite.addrs
|
||||
@ -312,3 +282,12 @@ func (suite *TestSuite) createSendAuthorization(grantee, granter sdk.AccAddress)
|
||||
suite.Require().NoError(err)
|
||||
return authorization
|
||||
}
|
||||
|
||||
func (suite *TestSuite) createSendAuthorizationWithAllowList(grantee, granter sdk.AccAddress) authz.Authorization {
|
||||
exp := suite.ctx.BlockHeader().Time.Add(time.Hour)
|
||||
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
|
||||
authorization := &banktypes.SendAuthorization{SpendLimit: newCoins, AllowList: []string{suite.addrs[5].String()}}
|
||||
err := suite.authzKeeper.SaveGrant(suite.ctx, grantee, granter, authorization, &exp)
|
||||
suite.Require().NoError(err)
|
||||
return authorization
|
||||
}
|
||||
|
||||
53
x/authz/module/autocli.go
Normal file
53
x/authz/module/autocli.go
Normal file
@ -0,0 +1,53 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
authzv1beta1 "cosmossdk.io/api/cosmos/authz/v1beta1"
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
|
||||
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
|
||||
return &autocliv1.ModuleOptions{
|
||||
Query: &autocliv1.ServiceCommandDescriptor{
|
||||
Service: authzv1beta1.Query_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Grants",
|
||||
Use: "grants [granter-addr] [grantee-addr] <msg-type-url>",
|
||||
Short: "Query grants for a granter-grantee pair and optionally a msg-type-url",
|
||||
Long: "Query authorization grants for a granter-grantee pair. If msg-type-url is set, it will select grants only for that msg type.",
|
||||
Example: fmt.Sprintf("%s query authz grants cosmos1skj.. cosmos1skjwj.. %s", version.AppName, bank.SendAuthorization{}.MsgTypeURL()),
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{ProtoField: "granter"},
|
||||
{ProtoField: "grantee"},
|
||||
{ProtoField: "msg_type_url", Optional: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
RpcMethod: "GranterGrants",
|
||||
Use: "grants-by-granter [granter-addr]",
|
||||
Short: "Query authorization grants granted by granter",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{ProtoField: "granter"},
|
||||
},
|
||||
},
|
||||
{
|
||||
RpcMethod: "GranteeGrants",
|
||||
Use: "grants-by-grantee [grantee-addr]",
|
||||
Short: "Query authorization grants granted to a grantee",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{ProtoField: "grantee"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Tx: &autocliv1.ServiceCommandDescriptor{
|
||||
Service: authzv1beta1.Msg_ServiceDesc.ServiceName,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -90,11 +90,6 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux
|
||||
}
|
||||
}
|
||||
|
||||
// GetQueryCmd returns the cli query commands for the authz module
|
||||
func (ab AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd(ab.ac)
|
||||
}
|
||||
|
||||
// GetTxCmd returns the transaction commands for the authz module
|
||||
func (ab AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.GetTxCmd(ab.ac)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user