Skip to content

Commit

Permalink
chore: improve the validations of messages (#484)
Browse files Browse the repository at this point in the history
* chore: improve the validations of messages

* add runtime check

* add runtime check

* add upgrade name

* fix review comments

* refine codes

* refine codes
  • Loading branch information
forcodedancing authored Oct 18, 2023
1 parent 0bd5221 commit 18eaa51
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 58 deletions.
1 change: 1 addition & 0 deletions app/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func (app *App) registerPampasUpgradeHandler() {
app.UpgradeKeeper.SetUpgradeInitializer(upgradetypes.Pampas,
func() error {
app.Logger().Info("Init Pampas upgrade")

// enable chain id for opbnb
app.CrossChainKeeper.SetDestOpChainID(sdk.ChainID(app.appConfig.CrossChain.DestOpChainId))
return nil
Expand Down
10 changes: 7 additions & 3 deletions e2e/tests/permission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,18 @@ func (s *StorageTestSuite) TestCreateObjectByOthers() {
s.Require().Equal(verifyPermResp.Effect, types.EFFECT_DENY)
s.T().Logf("resp: %s, rep %s", verifyPermReq.String(), verifyPermResp.String())

// Put bucket policy
statement := &types.Statement{
// Put object policy
statement1 := &types.Statement{
Actions: []types.ActionType{types.ACTION_CREATE_OBJECT},
Effect: types.EFFECT_ALLOW,
}
statement2 := &types.Statement{
Actions: []types.ActionType{types.ACTION_UPDATE_OBJECT_INFO},
Effect: types.EFFECT_ALLOW,
}
principal := types.NewPrincipalWithAccount(user[1].GetAddr())
msgPutPolicy := storagetypes.NewMsgPutPolicy(user[0].GetAddr(), types2.NewBucketGRN(bucketName).String(),
principal, []*types.Statement{statement}, nil)
principal, []*types.Statement{statement1, statement2}, nil)
s.SendTxBlock(user[0], msgPutPolicy)

// verify permission
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ replace (
github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.0.0
github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1
github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.3.0.20231017121821-7b897e5a86e1
github.com/cosmos/cosmos-sdk => github.com/forcodedancing/greenfield-cosmos-sdk v0.2.1-0.20231016120649-fcdced9e012e
github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/wercker/journalhook => github.com/wercker/journalhook v0.0.0-20230927020745-64542ffa4117
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ github.com/bnb-chain/greenfield-cometbft v1.0.0 h1:0r6hOJWD/+es0gxP/exKuN/krgXAr
github.com/bnb-chain/greenfield-cometbft v1.0.0/go.mod h1:f35mk/r5ab6yvzlqEWZt68LfUje68sYgMpVlt2CUYMk=
github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 h1:XcWulGacHVRiSCx90Q8Y//ajOrLNBQWR/KDB89dy3cU=
github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1/go.mod h1:ey1CiK4bYo1RBNJLRiVbYr5CMdSxci9S/AZRINLtppI=
github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.3.0.20231017121821-7b897e5a86e1 h1:Wef+0FD76aE9l3DjE4tGqeRKvEw98z1YkjJ5rHPL6G4=
github.com/bnb-chain/greenfield-cosmos-sdk v0.2.3-alpha.3.0.20231017121821-7b897e5a86e1/go.mod h1:BGVMW9gRFKGzCwK/8CmDGe3sK9r9QujL1Uz2FMMM+/s=
github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210 h1:GHPbV2bC+gmuO6/sG0Tm8oGal3KKSRlyE+zPscDjlA8=
github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210/go.mod h1:vhsZxXE9tYJeYB5JR4hPhd6Pc/uPf7j1T8IJ7p9FdeM=
github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230816082903-b48770f5e210 h1:FLVOn4+OVbsKi2+YJX5kmD27/4dRu4FW7xCXFhzDO5s=
Expand Down Expand Up @@ -370,6 +368,8 @@ github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/forcodedancing/greenfield-cosmos-sdk v0.2.1-0.20231016120649-fcdced9e012e h1:nHk7ex6a2iwYl/L5ZpffJSlWC81+2IVyw5q9S1dsnKU=
github.com/forcodedancing/greenfield-cosmos-sdk v0.2.1-0.20231016120649-fcdced9e012e/go.mod h1:BGVMW9gRFKGzCwK/8CmDGe3sK9r9QujL1Uz2FMMM+/s=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
Expand Down
87 changes: 54 additions & 33 deletions x/permission/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"time"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

gnfd "github.com/bnb-chain/greenfield/types"
"github.com/bnb-chain/greenfield/types/common"
Expand Down Expand Up @@ -35,6 +37,20 @@ var (

ACTION_TYPE_ALL: true,
}
BucketAllowedActionsAfterPampas = map[ActionType]bool{
ACTION_UPDATE_BUCKET_INFO: true,
ACTION_DELETE_BUCKET: true,

ACTION_CREATE_OBJECT: true,
ACTION_DELETE_OBJECT: true,
ACTION_GET_OBJECT: true,
ACTION_COPY_OBJECT: true,
ACTION_EXECUTE_OBJECT: true,
ACTION_LIST_OBJECT: true,
ACTION_UPDATE_OBJECT_INFO: true,

ACTION_TYPE_ALL: true,
}
ObjectAllowedActions = map[ActionType]bool{
ACTION_UPDATE_OBJECT_INFO: true,
ACTION_CREATE_OBJECT: true,
Expand Down Expand Up @@ -167,26 +183,13 @@ func (s *Statement) ValidateBasic(resType resource.ResourceType) error {
case resource.RESOURCE_TYPE_UNSPECIFIED:
return ErrInvalidStatement.Wrap("Please specify the ResourceType explicitly. Not allowed set RESOURCE_TYPE_UNSPECIFIED")
case resource.RESOURCE_TYPE_BUCKET:
containsCreateObject := false
for _, a := range s.Actions {
if !BucketAllowedActions[a] {
return ErrInvalidStatement.Wrapf("%s not allowed to be used on bucket.", a.String())
}
if a == ACTION_CREATE_OBJECT {
containsCreateObject = true
}
}
for _, r := range s.Resources {
var grn gnfd.GRN
err := grn.ParseFromString(r, true)
if err != nil {
return ErrInvalidStatement.Wrapf("GRN parse from string failed, err: %s", err)
}
}

if !containsCreateObject && s.LimitSize != nil {
return ErrInvalidStatement.Wrap("The LimitSize option can only be used with CreateObject actions at the bucket level. .")
}
case resource.RESOURCE_TYPE_OBJECT:
for _, a := range s.Actions {
if !ObjectAllowedActions[a] {
Expand All @@ -211,30 +214,48 @@ func (s *Statement) ValidateBasic(resType resource.ResourceType) error {
return nil
}

func (s *Statement) ValidateAfterNagqu(resType resource.ResourceType) error {
if s.Effect == EFFECT_UNSPECIFIED {
return ErrInvalidStatement.Wrap("Please specify the Effect explicitly. Not allowed set EFFECT_UNSPECIFIED")
}
switch resType {
case resource.RESOURCE_TYPE_UNSPECIFIED:
return ErrInvalidStatement.Wrap("Please specify the ResourceType explicitly. Not allowed set RESOURCE_TYPE_UNSPECIFIED")
case resource.RESOURCE_TYPE_BUCKET:
for _, r := range s.Resources {
_, err := regexp.Compile(r)
if err != nil {
return ErrInvalidStatement.Wrapf("The Resources regexp compile failed, err: %s", err)
func (s *Statement) ValidateRuntime(ctx sdk.Context, resType resource.ResourceType) error {
if ctx.IsUpgraded(upgradetypes.Nagqu) {
switch resType {
case resource.RESOURCE_TYPE_BUCKET:
for _, r := range s.Resources {
_, err := regexp.Compile(r)
if err != nil {
return ErrInvalidStatement.Wrapf("The Resources regexp compile failed, err: %s", err)
}
}
case resource.RESOURCE_TYPE_OBJECT:
if s.Resources != nil {
return ErrInvalidStatement.Wrap("The Resources option can only be used at the bucket level. ")
}
case resource.RESOURCE_TYPE_GROUP:
if s.Resources != nil {
return ErrInvalidStatement.Wrap("The Resources option can only be used at the bucket level. ")
}
default:
return ErrInvalidStatement.Wrap("unknown resource type.")
}
case resource.RESOURCE_TYPE_OBJECT:
if s.Resources != nil {
return ErrInvalidStatement.Wrap("The Resources option can only be used at the bucket level. ")
}

var bucketAllowedActions map[ActionType]bool
if ctx.IsUpgraded(upgradetypes.Pampas) {
bucketAllowedActions = BucketAllowedActionsAfterPampas
} else {
bucketAllowedActions = BucketAllowedActions
}
if resType == resource.RESOURCE_TYPE_BUCKET {
containsCreateObject := false
for _, a := range s.Actions {
if !bucketAllowedActions[a] {
return ErrInvalidStatement.Wrapf("%s not allowed to be used on bucket.", a.String())
}
if a == ACTION_CREATE_OBJECT {
containsCreateObject = true
}
}
case resource.RESOURCE_TYPE_GROUP:
if s.Resources != nil {
return ErrInvalidStatement.Wrap("The Resources option can only be used at the bucket level. ")
if !containsCreateObject && s.LimitSize != nil {
return ErrInvalidStatement.Wrap("The LimitSize option can only be used with CreateObject actions at the bucket level. .")
}
default:
return ErrInvalidStatement.Wrap("unknown resource type.")
}
return nil
}
12 changes: 6 additions & 6 deletions x/sp/types/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,20 @@ func (msg *MsgCreateStorageProvider) ValidateBasic() error {
if _, err := sdk.AccAddressFromHexUnsafe(msg.GcAddress); err != nil {
return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid gc address (%s)", err)
}
//MaintenanceAddress is validated in msg server
if !msg.Deposit.IsValid() || !msg.Deposit.Amount.IsPositive() {
return errors.Wrap(sdkerrors.ErrInvalidRequest, "invalid deposit amount")
return errors.Wrap(sdkerrors.ErrInvalidCoins, "invalid deposit amount")
}
if msg.Description == (Description{}) {
return errors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
}
if err := validateBlsKeyAndProof(msg.BlsKey, msg.BlsProof); err != nil {
return err
}
err := IsValidEndpointURL(msg.Endpoint)
if err != nil {
if err := ValidateEndpointURL(msg.Endpoint); err != nil {
return errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid endpoint (%s)", err)
}
if msg.ReadPrice.IsNegative() || msg.StorePrice.IsNegative() {
if msg.ReadPrice.IsNil() || msg.ReadPrice.IsNegative() || msg.StorePrice.IsNil() || msg.StorePrice.IsNegative() {
return errors.Wrap(sdkerrors.ErrInvalidRequest, "invalid price")
}
return nil
Expand Down Expand Up @@ -177,7 +177,7 @@ func (msg *MsgEditStorageProvider) ValidateBasic() error {
}

if len(msg.Endpoint) != 0 {
err = IsValidEndpointURL(msg.Endpoint)
err = ValidateEndpointURL(msg.Endpoint)
if err != nil {
return errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid endpoint (%s)", err)
}
Expand Down Expand Up @@ -369,7 +369,7 @@ func (msg *MsgUpdateStorageProviderStatus) ValidateBasic() error {
return errors.Wrapf(sdkerrors.ErrInvalidRequest, "not allowed to update to status %s", msg.Status)
}
if msg.Status == STATUS_IN_MAINTENANCE && msg.Duration <= 0 {
return errors.Wrapf(sdkerrors.ErrInvalidRequest, "maintenanceDuration need to be set for %s", msg.Status)
return errors.Wrapf(sdkerrors.ErrInvalidRequest, "maintenance duration need to be set for %s", msg.Status)
}
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions x/sp/types/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestMsgCreateStorageProvider_ValidateBasic(t *testing.T) {
}{
{"basic", "a", "b", "c", "d", spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, blsPubKey, blsProof, coinPos, nil},
{"basic_empty", "a", "b", "c", "d", sdk.AccAddress{}, spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, blsPubKey, blsProof, coinPos, sdkerrors.ErrInvalidAddress},
{"zero deposit", "a", "b", "c", "d", spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, blsPubKey, blsProof, coinZero, nil},
{"zero deposit", "a", "b", "c", "d", spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, spAddr, blsPubKey, blsProof, coinZero, sdkerrors.ErrInvalidCoins},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -48,7 +48,7 @@ func TestMsgCreateStorageProvider_ValidateBasic(t *testing.T) {
Endpoint: "http://127.0.0.1:9033",
StorePrice: sdk.ZeroDec(),
ReadPrice: sdk.ZeroDec(),
Deposit: coinPos,
Deposit: tt.deposit,
}
err := msg.ValidateBasic()
if tt.err != nil {
Expand Down
2 changes: 1 addition & 1 deletion x/sp/types/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

// Verify if input endpoint URL is valid.
func IsValidEndpointURL(endpointURL string) error {
func ValidateEndpointURL(endpointURL string) error {
if endpointURL == "" {
return errors.Wrap(ErrInvalidEndpointURL, "Endpoint url cannot be empty.")
}
Expand Down
6 changes: 0 additions & 6 deletions x/storage/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,6 @@ func (k msgServer) PutPolicy(goCtx context.Context, msg *types.MsgPutPolicy) (*t
if s.ExpirationTime != nil && s.ExpirationTime.Before(ctx.BlockTime()) {
return nil, permtypes.ErrPermissionExpired.Wrapf("The specified statement expiration time is less than the current block time, block time: %s", ctx.BlockTime().String())
}
if ctx.IsUpgraded(upgradetypes.Nagqu) {
err := s.ValidateAfterNagqu(grn.ResourceType())
if err != nil {
return nil, err
}
}
}

policy := &permtypes.Policy{
Expand Down
42 changes: 39 additions & 3 deletions x/storage/types/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/cosmos/gogoproto/proto"

grn2 "github.com/bnb-chain/greenfield/types"
Expand Down Expand Up @@ -970,6 +971,11 @@ func (msg *MsgLeaveGroup) ValidateBasic() error {
return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err)
}

_, err = sdk.AccAddressFromHexUnsafe(msg.GroupOwner)
if err != nil {
return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid group owner (%s)", err)
}

err = s3util.CheckValidGroupName(msg.GroupName)
if err != nil {
return err
Expand Down Expand Up @@ -1158,6 +1164,10 @@ func (msg *MsgPutPolicy) ValidateBasic() error {
return errors.Wrapf(gnfderrors.ErrInvalidGRN, "invalid greenfield resource name (%s)", err)
}

if msg.Principal == nil {
return gnfderrors.ErrInvalidPrincipal.Wrapf("principal cannot be empty")
}

if msg.Principal.Type == permtypes.PRINCIPAL_TYPE_GNFD_GROUP && grn.ResourceType() == resource.RESOURCE_TYPE_GROUP {
return gnfderrors.ErrInvalidPrincipal.Wrapf("Not allow grant group's permission to another group")
}
Expand All @@ -1177,6 +1187,18 @@ func (msg *MsgPutPolicy) ValidateBasic() error {
return nil
}

func (msg *MsgPutPolicy) ValidateRuntime(ctx sdk.Context) error {
var grn grn2.GRN
_ = grn.ParseFromString(msg.Resource, true) // no error after ValidateBasic
for _, s := range msg.Statements {
err := s.ValidateRuntime(ctx, grn.ResourceType())
if err != nil {
return err
}
}
return nil
}

func NewMsgDeletePolicy(operator sdk.AccAddress, resource string, principal *permtypes.Principal) *MsgDeletePolicy {
return &MsgDeletePolicy{
Operator: operator.String(),
Expand Down Expand Up @@ -1218,9 +1240,23 @@ func (msg *MsgDeletePolicy) ValidateBasic() error {
return errors.Wrapf(gnfderrors.ErrInvalidGRN, "invalid greenfield resource name (%s)", err)
}

if msg.Principal == nil {
return gnfderrors.ErrInvalidPrincipal.Wrapf("principal cannot be empty")
}

if msg.Principal.Type == permtypes.PRINCIPAL_TYPE_GNFD_GROUP && grn.ResourceType() == resource.RESOURCE_TYPE_GROUP {
return gnfderrors.ErrInvalidPrincipal.Wrapf("Not allow grant group's permission to another group")
}

return nil
}

func (msg *MsgDeletePolicy) ValidateRuntime(ctx sdk.Context) error {
if ctx.IsUpgraded(upgradetypes.Pampas) {
if err := msg.Principal.ValidateBasic(); err != nil {
return err
}
}
return nil
}

Expand Down Expand Up @@ -1266,7 +1302,7 @@ func (msg *MsgMirrorBucket) ValidateBasic() error {
return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err)
}

if msg.Id.GT(sdk.NewUint(0)) {
if !msg.Id.IsNil() && msg.Id.GT(sdk.NewUint(0)) {
if msg.BucketName != "" {
return errors.Wrap(gnfderrors.ErrInvalidBucketName, "Bucket name should be empty")
}
Expand Down Expand Up @@ -1324,7 +1360,7 @@ func (msg *MsgMirrorObject) ValidateBasic() error {
return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err)
}

if msg.Id.GT(sdk.NewUint(0)) {
if !msg.Id.IsNil() && msg.Id.GT(sdk.NewUint(0)) {
if msg.BucketName != "" {
return errors.Wrap(gnfderrors.ErrInvalidBucketName, "Bucket name should be empty")
}
Expand Down Expand Up @@ -1389,7 +1425,7 @@ func (msg *MsgMirrorGroup) ValidateBasic() error {
return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err)
}

if msg.Id.GT(sdk.NewUint(0)) {
if !msg.Id.IsNil() && msg.Id.GT(sdk.NewUint(0)) {
if msg.GroupName != "" {
return errors.Wrap(gnfderrors.ErrInvalidGroupName, "Group name should be empty")
}
Expand Down
2 changes: 1 addition & 1 deletion x/virtualgroup/types/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (msg *MsgWithdraw) ValidateBasic() error {
}

if !msg.Withdraw.IsValid() || !msg.Withdraw.Amount.IsPositive() {
return errors.Wrap(sdkerrors.ErrInvalidRequest, "invalid or non-positive deposit amount")
return errors.Wrap(sdkerrors.ErrInvalidRequest, "invalid or non-positive withdraw amount")
}
return nil
}
Expand Down

0 comments on commit 18eaa51

Please sign in to comment.