diff --git a/e2e/tests/permission_test.go b/e2e/tests/permission_test.go index df5ccf718..dbc2a4aee 100644 --- a/e2e/tests/permission_test.go +++ b/e2e/tests/permission_test.go @@ -1503,3 +1503,122 @@ func (s *StorageTestSuite) TestPutPolicy_ObjectWithSlash() { s.SendTxBlock(user[0], msgPutPolicy) } + +func (s *StorageTestSuite) TestVerifyStaleGroupPermission() { + ctx := context.Background() + user := s.GenAndChargeAccounts(3, 10000) + _, owner, bucketName, bucketId, objectName, objectId := s.createObjectWithVisibility(storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + + // Create Group with 3 group member + testGroupName := "testGroup" + msgCreateGroup := storagetypes.NewMsgCreateGroup(owner.GetAddr(), testGroupName, []sdk.AccAddress{user[0].GetAddr(), user[1].GetAddr(), user[2].GetAddr()}, "") + s.SendTxBlock(owner, msgCreateGroup) + + // Head Group + headGroupRequest := storagetypes.QueryHeadGroupRequest{GroupOwner: owner.GetAddr().String(), GroupName: testGroupName} + headGroupResponse, err := s.Client.HeadGroup(ctx, &headGroupRequest) + s.Require().NoError(err) + s.Require().Equal(headGroupResponse.GroupInfo.GroupName, testGroupName) + s.Require().True(owner.GetAddr().Equals(sdk.MustAccAddressFromHex(headGroupResponse.GroupInfo.Owner))) + s.T().Logf("GroupInfo: %s", headGroupResponse.GetGroupInfo().String()) + + principal := types.NewPrincipalWithGroupId(headGroupResponse.GroupInfo.Id) + // Put bucket policy for group + bucketStatement := &types.Statement{ + Actions: []types.ActionType{types.ACTION_DELETE_BUCKET}, + Effect: types.EFFECT_ALLOW, + } + msgPutBucketPolicy := storagetypes.NewMsgPutPolicy(owner.GetAddr(), types2.NewBucketGRN(bucketName).String(), + principal, []*types.Statement{bucketStatement}, nil) + s.SendTxBlock(owner, msgPutBucketPolicy) + + // Put Object policy for group + objectStatement := &types.Statement{ + Actions: []types.ActionType{types.ACTION_DELETE_OBJECT}, + Effect: types.EFFECT_ALLOW, + } + msgPutObjectPolicy := storagetypes.NewMsgPutPolicy(owner.GetAddr(), types2.NewObjectGRN(bucketName, objectName).String(), + principal, []*types.Statement{objectStatement}, nil) + s.SendTxBlock(owner, msgPutObjectPolicy) + + // Query bucket policy for group + grn := types2.NewBucketGRN(bucketName) + queryPolicyForGroupReq := storagetypes.QueryPolicyForGroupRequest{Resource: grn.String(), + PrincipalGroupId: headGroupResponse.GroupInfo.Id.String()} + + queryPolicyForGroupResp, err := s.Client.QueryPolicyForGroup(ctx, &queryPolicyForGroupReq) + s.Require().NoError(err) + s.Require().Equal(bucketId, queryPolicyForGroupResp.Policy.ResourceId) + s.Require().Equal(queryPolicyForGroupResp.Policy.ResourceType, resource.RESOURCE_TYPE_BUCKET) + s.Require().Equal(types.EFFECT_ALLOW, queryPolicyForGroupResp.Policy.Statements[0].Effect) + bucketPolicyID := queryPolicyForGroupResp.Policy.Id + + // Query object policy for group + grn2 := types2.NewObjectGRN(bucketName, objectName) + queryPolicyForGroupResp, err = s.Client.QueryPolicyForGroup(ctx, &storagetypes.QueryPolicyForGroupRequest{Resource: grn2.String(), + PrincipalGroupId: headGroupResponse.GroupInfo.Id.String()}) + s.Require().NoError(err) + s.Require().Equal(objectId, queryPolicyForGroupResp.Policy.ResourceId) + s.Require().Equal(queryPolicyForGroupResp.Policy.ResourceType, resource.RESOURCE_TYPE_OBJECT) + s.Require().Equal(types.EFFECT_ALLOW, queryPolicyForGroupResp.Policy.Statements[0].Effect) + objectPolicyID := queryPolicyForGroupResp.Policy.Id + + // verify group policy + verifyPermResp, err := s.Client.VerifyPermission(ctx, &storagetypes.QueryVerifyPermissionRequest{ + Operator: user[1].GetAddr().String(), + BucketName: bucketName, + ActionType: types.ACTION_DELETE_BUCKET, + }) + s.T().Logf("Verify Bucket Permission, %s", verifyPermResp.String()) + s.Require().NoError(err) + s.Require().Equal(types.EFFECT_ALLOW, verifyPermResp.Effect) + // verify group policy + verifyPermResp, err = s.Client.VerifyPermission(ctx, &storagetypes.QueryVerifyPermissionRequest{ + Operator: user[1].GetAddr().String(), + BucketName: bucketName, + ObjectName: objectName, + ActionType: types.ACTION_DELETE_OBJECT, + }) + s.T().Logf("Verify Object Permission, %s", verifyPermResp.String()) + s.Require().NoError(err) + s.Require().Equal(types.EFFECT_ALLOW, verifyPermResp.Effect) + + // user1 deletes the group + msgDeleteGroup := storagetypes.NewMsgDeleteGroup(owner.GetAddr(), testGroupName) + s.SendTxBlock(owner, msgDeleteGroup) + + // stale permission is still exist + _, err = s.Client.QueryPolicyById(ctx, &storagetypes.QueryPolicyByIdRequest{PolicyId: bucketPolicyID.String()}) + s.Require().NoError(err) + + _, err = s.Client.QueryPolicyById(ctx, &storagetypes.QueryPolicyByIdRequest{PolicyId: objectPolicyID.String()}) + s.Require().NoError(err) + + // group don't exist after deletion + _, err = s.Client.HeadGroup(ctx, &storagetypes.QueryHeadGroupRequest{ + GroupOwner: user[1].GetAddr().String(), + GroupName: testGroupName, + }) + s.Require().Error(err) + s.Require().ErrorContains(err, "No such group") + + // verify group policy + verifyPermResp, err = s.Client.VerifyPermission(ctx, &storagetypes.QueryVerifyPermissionRequest{ + Operator: user[1].GetAddr().String(), + BucketName: bucketName, + ActionType: types.ACTION_DELETE_BUCKET, + }) + s.T().Logf("Verify Bucket Permission, %s", verifyPermResp.String()) + s.Require().NoError(err) + s.Require().Equal(types.EFFECT_DENY, verifyPermResp.Effect) + // verify group policy + verifyPermResp, err = s.Client.VerifyPermission(ctx, &storagetypes.QueryVerifyPermissionRequest{ + Operator: user[1].GetAddr().String(), + BucketName: bucketName, + ObjectName: objectName, + ActionType: types.ACTION_DELETE_OBJECT, + }) + s.T().Logf("Verify Object Permission, %s", verifyPermResp.String()) + s.Require().NoError(err) + s.Require().Equal(types.EFFECT_DENY, verifyPermResp.Effect) +}