mirror of https://github.com/certusone/wasmd.git
453 lines
13 KiB
Go
453 lines
13 KiB
Go
package keeper
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
|
)
|
|
|
|
func TestDefaultAuthzPolicyCanCreateCode(t *testing.T) {
|
|
myActorAddress := RandomAccountAddress(t)
|
|
otherAddress := RandomAccountAddress(t)
|
|
specs := map[string]struct {
|
|
chainConfigs types.ChainAccessConfigs
|
|
contractInstConf types.AccessConfig
|
|
actor sdk.AccAddress
|
|
exp bool
|
|
panics bool
|
|
}{
|
|
"upload nobody": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
exp: false,
|
|
},
|
|
"upload everybody": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
exp: true,
|
|
},
|
|
"upload any address - included": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
exp: true,
|
|
},
|
|
"upload any address - not included": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
exp: false,
|
|
},
|
|
"contract config - subtype": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody),
|
|
contractInstConf: types.AccessTypeAnyOfAddresses.With(myActorAddress),
|
|
exp: true,
|
|
},
|
|
"contract config - not subtype": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody),
|
|
contractInstConf: types.AllowEverybody,
|
|
exp: false,
|
|
},
|
|
"upload undefined config - panics": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
panics: true,
|
|
},
|
|
}
|
|
for name, spec := range specs {
|
|
t.Run(name, func(t *testing.T) {
|
|
policy := DefaultAuthorizationPolicy{}
|
|
if !spec.panics {
|
|
got := policy.CanCreateCode(spec.chainConfigs, myActorAddress, spec.contractInstConf)
|
|
assert.Equal(t, spec.exp, got)
|
|
return
|
|
}
|
|
assert.Panics(t, func() {
|
|
policy.CanCreateCode(spec.chainConfigs, myActorAddress, spec.contractInstConf)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
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,
|
|
},
|
|
"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 TestDefaultAuthzPolicySubMessageAuthorizationPolicy(t *testing.T) {
|
|
policy := DefaultAuthorizationPolicy{}
|
|
for _, v := range []types.AuthorizationPolicyAction{types.AuthZActionInstantiate, types.AuthZActionMigrateContract} {
|
|
got := policy.SubMessageAuthorizationPolicy(v)
|
|
assert.Equal(t, policy, got)
|
|
}
|
|
}
|
|
|
|
func TestGovAuthzPolicyCanCreateCode(t *testing.T) {
|
|
myActorAddress := RandomAccountAddress(t)
|
|
otherAddress := RandomAccountAddress(t)
|
|
specs := map[string]struct {
|
|
chainConfigs types.ChainAccessConfigs
|
|
contractInstConf types.AccessConfig
|
|
actor sdk.AccAddress
|
|
}{
|
|
"upload nobody": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
},
|
|
"upload everybody": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
},
|
|
"upload any address - included": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
},
|
|
"upload any address - not included": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
},
|
|
"contract config - subtype": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody),
|
|
contractInstConf: types.AccessTypeAnyOfAddresses.With(myActorAddress),
|
|
},
|
|
"contract config - not subtype": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody),
|
|
contractInstConf: types.AllowEverybody,
|
|
},
|
|
"upload undefined config - not panics": {
|
|
chainConfigs: types.NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody),
|
|
contractInstConf: types.AllowEverybody,
|
|
},
|
|
}
|
|
for name, spec := range specs {
|
|
t.Run(name, func(t *testing.T) {
|
|
policy := GovAuthorizationPolicy{}
|
|
got := policy.CanCreateCode(spec.chainConfigs, myActorAddress, spec.contractInstConf)
|
|
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,
|
|
},
|
|
"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 := newGovAuthorizationPolicy(nil)
|
|
got := policy.CanModifyCodeAccessConfig(spec.admin, myActorAddress, spec.subset)
|
|
assert.True(t, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGovAuthorizationPolicySubMessageAuthorizationPolicy(t *testing.T) {
|
|
specs := map[string]struct {
|
|
propagate map[types.AuthorizationPolicyAction]struct{}
|
|
entrypoint types.AuthorizationPolicyAction
|
|
exp types.AuthorizationPolicy
|
|
}{
|
|
"non propagating": {
|
|
exp: DefaultAuthorizationPolicy{},
|
|
},
|
|
"propagating with matching action": {
|
|
propagate: map[types.AuthorizationPolicyAction]struct{}{
|
|
types.AuthZActionMigrateContract: {},
|
|
},
|
|
entrypoint: types.AuthZActionMigrateContract,
|
|
exp: NewPartialGovAuthorizationPolicy(DefaultAuthorizationPolicy{}, types.AuthZActionMigrateContract),
|
|
},
|
|
"propagating for non matching action": {
|
|
propagate: map[types.AuthorizationPolicyAction]struct{}{
|
|
types.AuthZActionMigrateContract: {},
|
|
},
|
|
entrypoint: types.AuthZActionInstantiate,
|
|
exp: DefaultAuthorizationPolicy{},
|
|
},
|
|
}
|
|
for name, spec := range specs {
|
|
t.Run(name, func(t *testing.T) {
|
|
got := newGovAuthorizationPolicy(spec.propagate).SubMessageAuthorizationPolicy(spec.entrypoint)
|
|
assert.Equal(t, spec.exp, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPartialGovAuthorizationPolicyCanInstantiateContract(t *testing.T) {
|
|
specs := map[string]struct {
|
|
allowedAction types.AuthorizationPolicyAction
|
|
exp bool
|
|
}{
|
|
"instantiation granted": {
|
|
allowedAction: types.AuthZActionInstantiate,
|
|
exp: true,
|
|
},
|
|
"decorated policy when instantiation not granted ": {
|
|
allowedAction: types.AuthZActionMigrateContract,
|
|
exp: false,
|
|
},
|
|
"decorated policy when nothing set": {
|
|
exp: false,
|
|
},
|
|
}
|
|
for name, spec := range specs {
|
|
t.Run(name, func(t *testing.T) {
|
|
policy := NewPartialGovAuthorizationPolicy(AlwaysRejectTestAuthZPolicy{}, spec.allowedAction)
|
|
got := policy.CanInstantiateContract(types.AccessConfig{}, nil)
|
|
assert.Equal(t, spec.exp, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPartialGovAuthorizationPolicyCanModifyContract(t *testing.T) {
|
|
specs := map[string]struct {
|
|
allowedAction types.AuthorizationPolicyAction
|
|
exp bool
|
|
}{
|
|
"migration granted": {
|
|
allowedAction: types.AuthZActionMigrateContract,
|
|
exp: true,
|
|
},
|
|
"decorated policy when migration not granted ": {
|
|
allowedAction: types.AuthZActionInstantiate,
|
|
exp: false,
|
|
},
|
|
"decorated policy when nothing set": {
|
|
exp: false,
|
|
},
|
|
}
|
|
for name, spec := range specs {
|
|
t.Run(name, func(t *testing.T) {
|
|
policy := NewPartialGovAuthorizationPolicy(AlwaysRejectTestAuthZPolicy{}, spec.allowedAction)
|
|
got := policy.CanModifyContract(nil, nil)
|
|
assert.Equal(t, spec.exp, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPartialGovAuthorizationPolicyDelegatedOnly(t *testing.T) {
|
|
for _, v := range []types.AuthorizationPolicy{AlwaysRejectTestAuthZPolicy{}, NewGovAuthorizationPolicy()} {
|
|
policy := NewPartialGovAuthorizationPolicy(v, types.AuthZActionInstantiate)
|
|
|
|
got := policy.CanCreateCode(types.ChainAccessConfigs{}, nil, types.AccessConfig{})
|
|
exp := v.CanCreateCode(types.ChainAccessConfigs{}, nil, types.AccessConfig{})
|
|
assert.Equal(t, exp, got)
|
|
|
|
got = policy.CanModifyCodeAccessConfig(nil, nil, false)
|
|
exp = v.CanModifyCodeAccessConfig(nil, nil, false)
|
|
assert.Equal(t, exp, got)
|
|
}
|
|
}
|
|
|
|
func TestPartialGovAuthorizationPolicySubMessageAuthorizationPolicy(t *testing.T) {
|
|
policy := NewPartialGovAuthorizationPolicy(DefaultAuthorizationPolicy{}, types.AuthZActionInstantiate)
|
|
for _, v := range []types.AuthorizationPolicyAction{types.AuthZActionInstantiate, types.AuthZActionMigrateContract} {
|
|
got := policy.SubMessageAuthorizationPolicy(v)
|
|
assert.Equal(t, policy, got)
|
|
}
|
|
}
|
|
|
|
var _ types.AuthorizationPolicy = AlwaysRejectTestAuthZPolicy{}
|
|
|
|
type AlwaysRejectTestAuthZPolicy struct{}
|
|
|
|
func (a AlwaysRejectTestAuthZPolicy) CanCreateCode(chainConfigs types.ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool {
|
|
return false
|
|
}
|
|
|
|
func (a AlwaysRejectTestAuthZPolicy) CanInstantiateContract(c types.AccessConfig, actor sdk.AccAddress) bool {
|
|
return false
|
|
}
|
|
|
|
func (a AlwaysRejectTestAuthZPolicy) CanModifyContract(admin, actor sdk.AccAddress) bool {
|
|
return false
|
|
}
|
|
|
|
func (a AlwaysRejectTestAuthZPolicy) CanModifyCodeAccessConfig(creator, actor sdk.AccAddress, isSubset bool) bool {
|
|
return false
|
|
}
|
|
|
|
func (a AlwaysRejectTestAuthZPolicy) SubMessageAuthorizationPolicy(entrypoint types.AuthorizationPolicyAction) types.AuthorizationPolicy {
|
|
return a
|
|
}
|