Parse any of address in CLI; more tests
This commit is contained in:
@@ -73,6 +73,7 @@ func GenesisStoreCodeCmd(defaultNodeHome string, genesisMutator GenesisMutator)
|
||||
cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional")
|
||||
cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional")
|
||||
cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional")
|
||||
cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional")
|
||||
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
|
||||
@@ -597,27 +597,33 @@ func ProposalUnpinCodesCmd() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func parseAccessConfig(config string) (types.AccessConfig, error) {
|
||||
switch config {
|
||||
func parseAccessConfig(raw string) (types.AccessConfig, error) {
|
||||
switch raw {
|
||||
case "nobody":
|
||||
return types.AllowNobody, nil
|
||||
case "everybody":
|
||||
return types.AllowEverybody, nil
|
||||
default:
|
||||
address, err := sdk.AccAddressFromBech32(config)
|
||||
if err != nil {
|
||||
return types.AccessConfig{}, fmt.Errorf("unable to parse address %s", config)
|
||||
parts := strings.Split(raw, ",")
|
||||
addrs := make([]sdk.AccAddress, len(parts))
|
||||
for i, v := range parts {
|
||||
addr, err := sdk.AccAddressFromBech32(v)
|
||||
if err != nil {
|
||||
return types.AccessConfig{}, fmt.Errorf("unable to parse address %q: %s", v, err)
|
||||
}
|
||||
addrs[i] = addr
|
||||
}
|
||||
return types.AccessTypeOnlyAddress.With(address), nil
|
||||
cfg := types.AccessTypeAnyOfAddresses.With(addrs...)
|
||||
return cfg, cfg.ValidateBasic()
|
||||
}
|
||||
}
|
||||
|
||||
func parseAccessConfigUpdates(args []string) ([]types.AccessConfigUpdate, error) {
|
||||
updates := make([]types.AccessConfigUpdate, len(args))
|
||||
for i, c := range args {
|
||||
// format: code_id,access_config
|
||||
// access_config: nobody|everybody|address
|
||||
parts := strings.Split(c, ",")
|
||||
// format: code_id:access_config
|
||||
// access_config: nobody|everybody|address(es)
|
||||
parts := strings.Split(c, ":")
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("invalid format")
|
||||
}
|
||||
@@ -642,15 +648,15 @@ func parseAccessConfigUpdates(args []string) ([]types.AccessConfigUpdate, error)
|
||||
func ProposalUpdateInstantiateConfigCmd() *cobra.Command {
|
||||
bech32Prefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
|
||||
cmd := &cobra.Command{
|
||||
Use: "update-instantiate-config [code-id,permission]...",
|
||||
Use: "update-instantiate-config [code-id:permission]...",
|
||||
Short: "Submit an update instantiate config proposal.",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Submit an update instantiate config proposal for multiple code ids.
|
||||
|
||||
Example:
|
||||
$ %s tx gov submit-proposal update-instantiate-config 1,nobody 2,everybody 3,%s1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm
|
||||
`, version.AppName, bech32Prefix)),
|
||||
$ %s tx gov submit-proposal update-instantiate-config 1:nobody 2:everybody 3:%s1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm,%s1vx8knpllrj7n963p9ttd80w47kpacrhuts497x
|
||||
`, version.AppName, bech32Prefix, bech32Prefix)),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
|
||||
85
x/wasm/client/cli/gov_tx_test.go
Normal file
85
x/wasm/client/cli/gov_tx_test.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
func TestParseAccessConfigUpdates(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
src []string
|
||||
exp []types.AccessConfigUpdate
|
||||
expErr bool
|
||||
}{
|
||||
"nobody": {
|
||||
src: []string{"1:nobody"},
|
||||
exp: []types.AccessConfigUpdate{{
|
||||
CodeID: 1,
|
||||
InstantiatePermission: types.AccessConfig{Permission: types.AccessTypeNobody},
|
||||
}},
|
||||
},
|
||||
"everybody": {
|
||||
src: []string{"1:everybody"},
|
||||
exp: []types.AccessConfigUpdate{{
|
||||
CodeID: 1,
|
||||
InstantiatePermission: types.AccessConfig{Permission: types.AccessTypeEverybody},
|
||||
}},
|
||||
},
|
||||
"any of addresses - single": {
|
||||
src: []string{"1:cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x"},
|
||||
exp: []types.AccessConfigUpdate{
|
||||
{
|
||||
CodeID: 1,
|
||||
InstantiatePermission: types.AccessConfig{
|
||||
Permission: types.AccessTypeAnyOfAddresses,
|
||||
Addresses: []string{"cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"any of addresses - multiple": {
|
||||
src: []string{"1:cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x,cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr"},
|
||||
exp: []types.AccessConfigUpdate{
|
||||
{
|
||||
CodeID: 1,
|
||||
InstantiatePermission: types.AccessConfig{
|
||||
Permission: types.AccessTypeAnyOfAddresses,
|
||||
Addresses: []string{"cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x", "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"multiple code ids with different permissions": {
|
||||
src: []string{"1:cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x,cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr", "2:nobody"},
|
||||
exp: []types.AccessConfigUpdate{
|
||||
{
|
||||
CodeID: 1,
|
||||
InstantiatePermission: types.AccessConfig{
|
||||
Permission: types.AccessTypeAnyOfAddresses,
|
||||
Addresses: []string{"cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x", "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr"},
|
||||
},
|
||||
}, {
|
||||
CodeID: 2,
|
||||
InstantiatePermission: types.AccessConfig{
|
||||
Permission: types.AccessTypeNobody,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
got, gotErr := parseAccessConfigUpdates(spec.src)
|
||||
if spec.expErr {
|
||||
require.Error(t, gotErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -19,15 +19,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
flagAmount = "amount"
|
||||
flagLabel = "label"
|
||||
flagAdmin = "admin"
|
||||
flagNoAdmin = "no-admin"
|
||||
flagRunAs = "run-as"
|
||||
flagInstantiateByEverybody = "instantiate-everybody"
|
||||
flagInstantiateNobody = "instantiate-nobody"
|
||||
flagInstantiateByAddress = "instantiate-only-address"
|
||||
flagUnpinCode = "unpin-code"
|
||||
flagAmount = "amount"
|
||||
flagLabel = "label"
|
||||
flagAdmin = "admin"
|
||||
flagNoAdmin = "no-admin"
|
||||
flagRunAs = "run-as"
|
||||
flagInstantiateByEverybody = "instantiate-everybody"
|
||||
flagInstantiateNobody = "instantiate-nobody"
|
||||
flagInstantiateByAddress = "instantiate-only-address"
|
||||
flagInstantiateByAnyOfAddress = "instantiate-anyof-addresses"
|
||||
flagUnpinCode = "unpin-code"
|
||||
)
|
||||
|
||||
// GetTxCmd returns the transaction commands for this module
|
||||
@@ -75,7 +76,8 @@ func StoreCodeCmd() *cobra.Command {
|
||||
|
||||
cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional")
|
||||
cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional")
|
||||
cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional")
|
||||
cmd.Flags().String(flagInstantiateByAddress, "", "Deprecated: Only this address can instantiate a contract from the code, optional")
|
||||
cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional")
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
@@ -97,47 +99,9 @@ func parseStoreCodeArgs(file string, sender sdk.AccAddress, flags *flag.FlagSet)
|
||||
return types.MsgStoreCode{}, fmt.Errorf("invalid input file. Use wasm binary or gzip")
|
||||
}
|
||||
|
||||
var perm *types.AccessConfig
|
||||
onlyAddrStr, err := flags.GetString(flagInstantiateByAddress)
|
||||
perm, err := parseAccessConfigFlags(flags)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("instantiate by address: %s", err)
|
||||
}
|
||||
if onlyAddrStr != "" {
|
||||
allowedAddr, err := sdk.AccAddressFromBech32(onlyAddrStr)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, sdkerrors.Wrap(err, flagInstantiateByAddress)
|
||||
}
|
||||
x := types.AccessTypeOnlyAddress.With(allowedAddr)
|
||||
perm = &x
|
||||
} else {
|
||||
everybodyStr, err := flags.GetString(flagInstantiateByEverybody)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("instantiate by everybody: %s", err)
|
||||
}
|
||||
if everybodyStr != "" {
|
||||
ok, err := strconv.ParseBool(everybodyStr)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("boolean value expected for instantiate by everybody: %s", err)
|
||||
}
|
||||
if ok {
|
||||
perm = &types.AllowEverybody
|
||||
}
|
||||
}
|
||||
|
||||
nobodyStr, err := flags.GetString(flagInstantiateNobody)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("instantiate by nobody: %s", err)
|
||||
}
|
||||
if nobodyStr != "" {
|
||||
ok, err := strconv.ParseBool(nobodyStr)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("boolean value expected for instantiate by nobody: %s", err)
|
||||
}
|
||||
if ok {
|
||||
perm = &types.AllowNobody
|
||||
}
|
||||
}
|
||||
|
||||
return types.MsgStoreCode{}, err
|
||||
}
|
||||
|
||||
msg := types.MsgStoreCode{
|
||||
@@ -148,6 +112,65 @@ func parseStoreCodeArgs(file string, sender sdk.AccAddress, flags *flag.FlagSet)
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func parseAccessConfigFlags(flags *flag.FlagSet) (*types.AccessConfig, error) {
|
||||
addrs, err := flags.GetStringSlice(flagInstantiateByAnyOfAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("flag any of: %s", err)
|
||||
}
|
||||
if len(addrs) != 0 {
|
||||
acceptedAddrs := make([]sdk.AccAddress, len(addrs))
|
||||
for i, v := range addrs {
|
||||
acceptedAddrs[i], err = sdk.AccAddressFromBech32(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse %q: %w", v, err)
|
||||
}
|
||||
}
|
||||
x := types.AccessTypeAnyOfAddresses.With(acceptedAddrs...)
|
||||
return &x, nil
|
||||
}
|
||||
|
||||
onlyAddrStr, err := flags.GetString(flagInstantiateByAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("instantiate by address: %s", err)
|
||||
}
|
||||
if onlyAddrStr != "" {
|
||||
allowedAddr, err := sdk.AccAddressFromBech32(onlyAddrStr)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, flagInstantiateByAddress)
|
||||
}
|
||||
x := types.AccessTypeOnlyAddress.With(allowedAddr)
|
||||
return &x, nil
|
||||
}
|
||||
everybodyStr, err := flags.GetString(flagInstantiateByEverybody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("instantiate by everybody: %s", err)
|
||||
}
|
||||
if everybodyStr != "" {
|
||||
ok, err := strconv.ParseBool(everybodyStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("boolean value expected for instantiate by everybody: %s", err)
|
||||
}
|
||||
if ok {
|
||||
return &types.AllowEverybody, nil
|
||||
}
|
||||
}
|
||||
|
||||
nobodyStr, err := flags.GetString(flagInstantiateNobody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("instantiate by nobody: %s", err)
|
||||
}
|
||||
if nobodyStr != "" {
|
||||
ok, err := strconv.ParseBool(nobodyStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("boolean value expected for instantiate by nobody: %s", err)
|
||||
}
|
||||
if ok {
|
||||
return &types.AllowNobody, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// InstantiateContractCmd will instantiate a contract from previously uploaded code.
|
||||
func InstantiateContractCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
|
||||
59
x/wasm/client/cli/tx_test.go
Normal file
59
x/wasm/client/cli/tx_test.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
func TestParseAccessConfigFlags(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
args []string
|
||||
expCfg *types.AccessConfig
|
||||
expErr bool
|
||||
}{
|
||||
"nobody": {
|
||||
args: []string{"--instantiate-nobody=true"},
|
||||
expCfg: &types.AccessConfig{Permission: types.AccessTypeNobody},
|
||||
},
|
||||
"everybody": {
|
||||
args: []string{"--instantiate-everybody=true"},
|
||||
expCfg: &types.AccessConfig{Permission: types.AccessTypeEverybody},
|
||||
},
|
||||
"only address": {
|
||||
args: []string{"--instantiate-only-address=cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x"},
|
||||
expCfg: &types.AccessConfig{Permission: types.AccessTypeOnlyAddress, Address: "cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x"},
|
||||
},
|
||||
"only address - invalid": {
|
||||
args: []string{"--instantiate-only-address=foo"},
|
||||
expErr: true,
|
||||
},
|
||||
"any of address": {
|
||||
args: []string{"--instantiate-anyof-addresses=cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x,cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr"},
|
||||
expCfg: &types.AccessConfig{Permission: types.AccessTypeAnyOfAddresses, Addresses: []string{"cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x", "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr"}},
|
||||
},
|
||||
"any of address - invalid": {
|
||||
args: []string{"--instantiate-anyof-addresses=cosmos1vx8knpllrj7n963p9ttd80w47kpacrhuts497x,foo"},
|
||||
expErr: true,
|
||||
},
|
||||
"not set": {
|
||||
args: []string{},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
flags := StoreCodeCmd().Flags()
|
||||
require.NoError(t, flags.Parse(spec.args))
|
||||
gotCfg, gotErr := parseAccessConfigFlags(flags)
|
||||
if spec.expErr {
|
||||
require.Error(t, gotErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, gotErr)
|
||||
assert.Equal(t, spec.expCfg, gotCfg)
|
||||
})
|
||||
}
|
||||
}
|
||||
311
x/wasm/keeper/authz_policy_test.go
Normal file
311
x/wasm/keeper/authz_policy_test.go
Normal file
@@ -0,0 +1,311 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
func TestDefaultAuthzPolicyCanCreateCode(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
specs := map[string]struct {
|
||||
config types.AccessConfig
|
||||
actor sdk.AccAddress
|
||||
exp bool
|
||||
panics bool
|
||||
}{
|
||||
"nobody": {
|
||||
config: types.AllowNobody,
|
||||
exp: false,
|
||||
},
|
||||
"everybody": {
|
||||
config: types.AllowEverybody,
|
||||
exp: true,
|
||||
},
|
||||
"only address - same": {
|
||||
config: types.AccessTypeOnlyAddress.With(myActorAddress),
|
||||
exp: true,
|
||||
},
|
||||
"only address - different": {
|
||||
config: types.AccessTypeOnlyAddress.With(otherAddress),
|
||||
exp: false,
|
||||
},
|
||||
"any address - included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress),
|
||||
exp: true,
|
||||
},
|
||||
"any address - not included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress),
|
||||
exp: false,
|
||||
},
|
||||
"undefined config - panics": {
|
||||
config: types.AccessConfig{},
|
||||
panics: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := DefaultAuthorizationPolicy{}
|
||||
if !spec.panics {
|
||||
got := policy.CanCreateCode(spec.config, myActorAddress)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
return
|
||||
}
|
||||
assert.Panics(t, func() {
|
||||
policy.CanCreateCode(spec.config, myActorAddress)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAuthzPolicyCanInstantiateContract(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
specs := map[string]struct {
|
||||
config types.AccessConfig
|
||||
actor sdk.AccAddress
|
||||
exp bool
|
||||
panics bool
|
||||
}{
|
||||
"nobody": {
|
||||
config: types.AllowNobody,
|
||||
exp: false,
|
||||
},
|
||||
"everybody": {
|
||||
config: types.AllowEverybody,
|
||||
exp: true,
|
||||
},
|
||||
"only address - same": {
|
||||
config: types.AccessTypeOnlyAddress.With(myActorAddress),
|
||||
exp: true,
|
||||
},
|
||||
"only address - different": {
|
||||
config: types.AccessTypeOnlyAddress.With(otherAddress),
|
||||
exp: false,
|
||||
},
|
||||
"any address - included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress),
|
||||
exp: true,
|
||||
},
|
||||
"any address - not included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress),
|
||||
exp: false,
|
||||
},
|
||||
"undefined config - panics": {
|
||||
config: types.AccessConfig{},
|
||||
panics: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := DefaultAuthorizationPolicy{}
|
||||
if !spec.panics {
|
||||
got := policy.CanInstantiateContract(spec.config, myActorAddress)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
return
|
||||
}
|
||||
assert.Panics(t, func() {
|
||||
policy.CanInstantiateContract(spec.config, myActorAddress)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAuthzPolicyCanModifyContract(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
|
||||
specs := map[string]struct {
|
||||
admin sdk.AccAddress
|
||||
exp bool
|
||||
}{
|
||||
"same as actor": {
|
||||
admin: myActorAddress,
|
||||
exp: true,
|
||||
},
|
||||
"different admin": {
|
||||
admin: otherAddress,
|
||||
exp: false,
|
||||
},
|
||||
"no admin": {
|
||||
exp: false,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := DefaultAuthorizationPolicy{}
|
||||
got := policy.CanModifyContract(spec.admin, myActorAddress)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAuthzPolicyCanModifyCodeAccessConfig(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
|
||||
specs := map[string]struct {
|
||||
admin sdk.AccAddress
|
||||
subset bool
|
||||
exp bool
|
||||
}{
|
||||
"same as actor - subset": {
|
||||
admin: myActorAddress,
|
||||
subset: true,
|
||||
exp: true,
|
||||
},
|
||||
"same as actor - not subset": {
|
||||
admin: myActorAddress,
|
||||
subset: false,
|
||||
exp: false,
|
||||
},
|
||||
"different admin": {
|
||||
admin: otherAddress,
|
||||
exp: false,
|
||||
},
|
||||
"no admin": {
|
||||
exp: false,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := DefaultAuthorizationPolicy{}
|
||||
got := policy.CanModifyCodeAccessConfig(spec.admin, myActorAddress, spec.subset)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGovAuthzPolicyCanCreateCode(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
specs := map[string]struct {
|
||||
config types.AccessConfig
|
||||
actor sdk.AccAddress
|
||||
}{
|
||||
"nobody": {
|
||||
config: types.AllowNobody,
|
||||
},
|
||||
"everybody": {
|
||||
config: types.AllowEverybody,
|
||||
},
|
||||
"only address - same": {
|
||||
config: types.AccessTypeOnlyAddress.With(myActorAddress),
|
||||
},
|
||||
"only address - different": {
|
||||
config: types.AccessTypeOnlyAddress.With(otherAddress),
|
||||
},
|
||||
"any address - included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress),
|
||||
},
|
||||
"any address - not included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress),
|
||||
},
|
||||
"undefined config - panics": {
|
||||
config: types.AccessConfig{},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := GovAuthorizationPolicy{}
|
||||
got := policy.CanCreateCode(spec.config, myActorAddress)
|
||||
assert.True(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGovAuthzPolicyCanInstantiateContract(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
specs := map[string]struct {
|
||||
config types.AccessConfig
|
||||
actor sdk.AccAddress
|
||||
}{
|
||||
"nobody": {
|
||||
config: types.AllowNobody,
|
||||
},
|
||||
"everybody": {
|
||||
config: types.AllowEverybody,
|
||||
},
|
||||
"only address - same": {
|
||||
config: types.AccessTypeOnlyAddress.With(myActorAddress),
|
||||
},
|
||||
"only address - different": {
|
||||
config: types.AccessTypeOnlyAddress.With(otherAddress),
|
||||
},
|
||||
"any address - included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress),
|
||||
},
|
||||
"any address - not included": {
|
||||
config: types.AccessTypeAnyOfAddresses.With(otherAddress),
|
||||
},
|
||||
"undefined config - panics": {
|
||||
config: types.AccessConfig{},
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := GovAuthorizationPolicy{}
|
||||
got := policy.CanInstantiateContract(spec.config, myActorAddress)
|
||||
assert.True(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGovAuthzPolicyCanModifyContract(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
|
||||
specs := map[string]struct {
|
||||
admin sdk.AccAddress
|
||||
}{
|
||||
"same as actor": {
|
||||
admin: myActorAddress,
|
||||
},
|
||||
"different admin": {
|
||||
admin: otherAddress,
|
||||
},
|
||||
"no admin": {},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := GovAuthorizationPolicy{}
|
||||
got := policy.CanModifyContract(spec.admin, myActorAddress)
|
||||
assert.True(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGovAuthzPolicyCanModifyCodeAccessConfig(t *testing.T) {
|
||||
myActorAddress := RandomAccountAddress(t)
|
||||
otherAddress := RandomAccountAddress(t)
|
||||
|
||||
specs := map[string]struct {
|
||||
admin sdk.AccAddress
|
||||
subset bool
|
||||
}{
|
||||
"same as actor - subset": {
|
||||
admin: myActorAddress,
|
||||
subset: true,
|
||||
},
|
||||
"same as actor - not subset": {
|
||||
admin: myActorAddress,
|
||||
subset: false,
|
||||
},
|
||||
"different admin": {
|
||||
admin: otherAddress,
|
||||
},
|
||||
"no admin": {},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
policy := GovAuthorizationPolicy{}
|
||||
got := policy.CanModifyCodeAccessConfig(spec.admin, myActorAddress, spec.subset)
|
||||
assert.True(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,7 @@ func validateAccessType(i interface{}) error {
|
||||
return sdkerrors.Wrapf(ErrInvalid, "unknown type: %q", a)
|
||||
}
|
||||
|
||||
// ValidateBasic performs basic validation
|
||||
func (a AccessConfig) ValidateBasic() error {
|
||||
switch a.Permission {
|
||||
case AccessTypeUnspecified:
|
||||
@@ -203,6 +204,8 @@ func assertValidAddresses(addrs []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Allowed returns if permission includes the actor.
|
||||
// Actor address must be valid and not nil
|
||||
func (a AccessConfig) Allowed(actor sdk.AccAddress) bool {
|
||||
switch a.Permission {
|
||||
case AccessTypeNobody:
|
||||
|
||||
@@ -224,3 +224,83 @@ func TestParamsUnmarshalJson(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccessTypeWith(t *testing.T) {
|
||||
myAddress := sdk.AccAddress(randBytes(SDKAddrLen))
|
||||
myOtherAddress := sdk.AccAddress(randBytes(SDKAddrLen))
|
||||
specs := map[string]struct {
|
||||
src AccessType
|
||||
addrs []sdk.AccAddress
|
||||
exp AccessConfig
|
||||
expPanic bool
|
||||
}{
|
||||
"nobody": {
|
||||
src: AccessTypeNobody,
|
||||
exp: AccessConfig{Permission: AccessTypeNobody},
|
||||
},
|
||||
"nobody with address": {
|
||||
src: AccessTypeNobody,
|
||||
addrs: []sdk.AccAddress{myAddress},
|
||||
exp: AccessConfig{Permission: AccessTypeNobody},
|
||||
},
|
||||
"everybody": {
|
||||
src: AccessTypeEverybody,
|
||||
exp: AccessConfig{Permission: AccessTypeEverybody},
|
||||
},
|
||||
"everybody with address": {
|
||||
src: AccessTypeEverybody,
|
||||
addrs: []sdk.AccAddress{myAddress},
|
||||
exp: AccessConfig{Permission: AccessTypeEverybody},
|
||||
},
|
||||
"only address without address": {
|
||||
src: AccessTypeOnlyAddress,
|
||||
expPanic: true,
|
||||
},
|
||||
"only address with address": {
|
||||
src: AccessTypeOnlyAddress,
|
||||
addrs: []sdk.AccAddress{myAddress},
|
||||
exp: AccessConfig{Permission: AccessTypeOnlyAddress, Address: myAddress.String()},
|
||||
},
|
||||
"only address with invalid address": {
|
||||
src: AccessTypeOnlyAddress,
|
||||
addrs: []sdk.AccAddress{nil},
|
||||
expPanic: true,
|
||||
},
|
||||
"any of address without address": {
|
||||
src: AccessTypeAnyOfAddresses,
|
||||
expPanic: true,
|
||||
},
|
||||
"any of address with single address": {
|
||||
src: AccessTypeAnyOfAddresses,
|
||||
addrs: []sdk.AccAddress{myAddress},
|
||||
exp: AccessConfig{Permission: AccessTypeAnyOfAddresses, Addresses: []string{myAddress.String()}},
|
||||
},
|
||||
"any of address with multiple addresses": {
|
||||
src: AccessTypeAnyOfAddresses,
|
||||
addrs: []sdk.AccAddress{myAddress, myOtherAddress},
|
||||
exp: AccessConfig{Permission: AccessTypeAnyOfAddresses, Addresses: []string{myAddress.String(), myOtherAddress.String()}},
|
||||
},
|
||||
"any of address with duplicate addresses": {
|
||||
src: AccessTypeAnyOfAddresses,
|
||||
addrs: []sdk.AccAddress{myAddress, myAddress},
|
||||
expPanic: true,
|
||||
},
|
||||
"any of address with invalid address": {
|
||||
src: AccessTypeAnyOfAddresses,
|
||||
addrs: []sdk.AccAddress{nil},
|
||||
expPanic: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if !spec.expPanic {
|
||||
got := spec.src.With(spec.addrs...)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
return
|
||||
}
|
||||
assert.Panics(t, func() {
|
||||
spec.src.With(spec.addrs...)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user