From c5cec08e8d74a83475ed17ace877bbff5dbd5347 Mon Sep 17 00:00:00 2001 From: constwz Date: Mon, 8 Jul 2024 09:41:24 +0800 Subject: [PATCH] feat: Support msg to create policy by cross chain --- x/storage/keeper/cross_app_permission.go | 129 +++++++++++++++++++++-- x/storage/types/expected_keepers.go | 2 + 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/x/storage/keeper/cross_app_permission.go b/x/storage/keeper/cross_app_permission.go index 681d5f24d..d2764cd12 100644 --- a/x/storage/keeper/cross_app_permission.go +++ b/x/storage/keeper/cross_app_permission.go @@ -4,6 +4,7 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + types2 "github.com/bnb-chain/greenfield/types" gnfderrors "github.com/bnb-chain/greenfield/types/errors" gnfdresource "github.com/bnb-chain/greenfield/types/resource" permtypes "github.com/bnb-chain/greenfield/x/permission/types" @@ -146,16 +147,88 @@ func (app *PermissionApp) handleCreatePolicySynPackage(ctx sdk.Context, createPo } var policy permtypes.Policy + var grn types2.GRN err = policy.Unmarshal(createPolicyPackage.Data) if err != nil { - return sdk.ExecuteResult{ - Payload: types.CreatePolicyAckPackage{ - Status: types.StatusFail, - Creator: createPolicyPackage.Operator, - ExtraData: createPolicyPackage.ExtraData, - }.MustSerialize(), - Err: err, + var msgPutPolicy types.MsgPutPolicy + err = msgPutPolicy.Unmarshal(createPolicyPackage.Data) + if err != nil { + return sdk.ExecuteResult{ + Payload: types.CreatePolicyAckPackage{ + Status: types.StatusFail, + Creator: createPolicyPackage.Operator, + ExtraData: createPolicyPackage.ExtraData, + }.MustSerialize(), + Err: err, + } + } + if msgPutPolicy.GetOperator() != createPolicyPackage.Operator.String() { + return sdk.ExecuteResult{ + Payload: types.CreatePolicyAckPackage{ + Status: types.StatusFail, + Creator: createPolicyPackage.Operator, + ExtraData: createPolicyPackage.ExtraData, + }.MustSerialize(), + Err: types.ErrAccessDenied.Wrapf( + "Only resource owner can put policy, operator (%s)", + msgPutPolicy.GetOperator()), + } + } + + err = grn.ParseFromString(msgPutPolicy.Resource, true) + if err != nil { + return sdk.ExecuteResult{ + Payload: types.CreatePolicyAckPackage{ + Status: types.StatusFail, + Creator: createPolicyPackage.Operator, + ExtraData: createPolicyPackage.ExtraData, + }.MustSerialize(), + Err: err, + } } + + if msgPutPolicy.ExpirationTime != nil && msgPutPolicy.ExpirationTime.Before(ctx.BlockTime()) { + return sdk.ExecuteResult{ + Payload: types.CreatePolicyAckPackage{ + Status: types.StatusFail, + Creator: createPolicyPackage.Operator, + ExtraData: createPolicyPackage.ExtraData, + }.MustSerialize(), + Err: permtypes.ErrPermissionExpired.Wrapf("The specified policy expiration time is less than the current block time, block time: %s", ctx.BlockTime().String()), + } + } + + for _, s := range msgPutPolicy.Statements { + if s.ExpirationTime != nil && s.ExpirationTime.Before(ctx.BlockTime()) { + return sdk.ExecuteResult{ + Payload: types.CreatePolicyAckPackage{ + Status: types.StatusFail, + Creator: createPolicyPackage.Operator, + ExtraData: createPolicyPackage.ExtraData, + }.MustSerialize(), + Err: permtypes.ErrPermissionExpired.Wrapf("The specified statement expiration time is less than the current block time, block time: %s", ctx.BlockTime().String()), + } + } + } + + policy = permtypes.Policy{ + ResourceType: grn.ResourceType(), + Principal: msgPutPolicy.Principal, + Statements: msgPutPolicy.Statements, + ExpirationTime: msgPutPolicy.ExpirationTime, + } + _, resID, err := app.getResourceOwnerAndIdFromGRN(ctx, grn) + if err != nil { + return sdk.ExecuteResult{ + Payload: types.CreatePolicyAckPackage{ + Status: types.StatusFail, + Creator: createPolicyPackage.Operator, + ExtraData: createPolicyPackage.ExtraData, + }.MustSerialize(), + Err: err, + } + } + policy.ResourceId = resID } resOwner, err := app.getResourceOwner(ctx, &policy) @@ -243,3 +316,45 @@ func (app *PermissionApp) getResourceOwner(ctx sdk.Context, policy *permtypes.Po } return resOwner, nil } + +func (app *PermissionApp) getResourceOwnerAndIdFromGRN(ctx sdk.Context, grn types2.GRN) (resOwner sdk.AccAddress, resID math.Uint, err error) { + switch grn.ResourceType() { + case gnfdresource.RESOURCE_TYPE_BUCKET: + bucketName, grnErr := grn.GetBucketName() + if grnErr != nil { + return resOwner, resID, grnErr + } + bucketInfo, found := app.storageKeeper.GetBucketInfo(ctx, bucketName) + if !found { + return resOwner, resID, types.ErrNoSuchBucket.Wrapf("bucketName: %s", bucketName) + } + resOwner = sdk.MustAccAddressFromHex(bucketInfo.Owner) + resID = bucketInfo.Id + case gnfdresource.RESOURCE_TYPE_OBJECT: + bucketName, objectName, grnErr := grn.GetBucketAndObjectName() + if grnErr != nil { + return resOwner, resID, grnErr + } + objectInfo, found := app.storageKeeper.GetObjectInfo(ctx, bucketName, objectName) + if !found { + return resOwner, resID, types.ErrNoSuchObject.Wrapf("BucketName: %s, objectName: %s", bucketName, objectName) + } + resOwner = sdk.MustAccAddressFromHex(objectInfo.Owner) + resID = objectInfo.Id + case gnfdresource.RESOURCE_TYPE_GROUP: + groupOwner, groupName, grnErr := grn.GetGroupOwnerAndAccount() + if grnErr != nil { + return resOwner, resID, grnErr + } + groupInfo, found := app.storageKeeper.GetGroupInfo(ctx, groupOwner, groupName) + if !found { + return resOwner, resID, types.ErrNoSuchBucket.Wrapf("groupOwner: %s, groupName: %s", groupOwner.String(), groupName) + } + resOwner = sdk.MustAccAddressFromHex(groupInfo.Owner) + resID = groupInfo.Id + default: + return resOwner, resID, gnfderrors.ErrInvalidGRN.Wrap("Unknown resource type in greenfield resource name") + } + + return resOwner, resID, nil +} diff --git a/x/storage/types/expected_keepers.go b/x/storage/types/expected_keepers.go index 5cddd04ae..352cd5cd1 100644 --- a/x/storage/types/expected_keepers.go +++ b/x/storage/types/expected_keepers.go @@ -105,6 +105,8 @@ type VirtualGroupKeeper interface { type StorageKeeper interface { Logger(ctx sdk.Context) log.Logger GetBucketInfoById(ctx sdk.Context, bucketId sdkmath.Uint) (*BucketInfo, bool) + GetBucketInfo(ctx sdk.Context, bucketName string) (*BucketInfo, bool) + GetObjectInfo(ctx sdk.Context, bucketName, objectName string) (*ObjectInfo, bool) SetBucketInfo(ctx sdk.Context, bucketInfo *BucketInfo) CreateBucket( ctx sdk.Context, ownerAcc sdk.AccAddress, bucketName string,