Skip to content

Commit

Permalink
feat(x/authz): Add the GetAuthorization function. (#13047)
Browse files Browse the repository at this point in the history
* [13027]: Create the GetAuthorization function (in the authz module).

* [13027]: Add unit tests for the new GetAuthorization function.

* [13027]: Add changelog entry.

(cherry picked from commit 5e4651e)

# Conflicts:
#	CHANGELOG.md
#	x/authz/keeper/keeper_test.go
  • Loading branch information
SpicyLemon authored and mergify[bot] committed Aug 25, 2022
1 parent b9d4ed8 commit 3849e5d
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -39,10 +39,17 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

<<<<<<< HEAD
* (export) [#13029](https://github.com/cosmos/cosmos-sdk/pull/13029) Fix exporting the blockParams regression.
* [#13046](https://github.com/cosmos/cosmos-sdk/pull/13046) Fix missing return statement in BaseApp.Query.

## [v0.46.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.1) - 2022-08-24
=======
* (x/authz) [#12648](https://github.com/cosmos/cosmos-sdk/pull/12648) Add an allow list, an optional list of addresses allowed to receive bank assests via authz MsgSend grant.
* (sdk.Coins) [#12627](https://github.com/cosmos/cosmos-sdk/pull/12627) Make a Denoms method on sdk.Coins.
* (testutil) [#12973](https://github.com/cosmos/cosmos-sdk/pull/12973) Add generic `testutil.RandSliceElem` function which selects a random element from the list.
* (x/authz) [#13047](https://github.com/cosmos/cosmos-sdk/pull/13047) Add a GetAuthorization function to the keeper.
>>>>>>> 5e4651eca (feat(x/authz): Add the GetAuthorization function. (#13047))
### Improvements

Expand Down
19 changes: 19 additions & 0 deletions x/authz/keeper/keeper.go
Expand Up @@ -251,6 +251,25 @@ func (k Keeper) GetAuthorizations(ctx sdk.Context, grantee sdk.AccAddress, grant
return authorizations, nil
}

// GetAuthorization returns an Authorization and it's expiration time.
// A nil Authorization is returned under the following circumstances:
// - No grant is found.
// - A grant is found, but it is expired.
// - There was an error getting the authorization from the grant.
func (k Keeper) GetAuthorization(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) {
grant, found := k.getGrant(ctx, grantStoreKey(grantee, granter, msgType))
if !found || (grant.Expiration != nil && grant.Expiration.Before(ctx.BlockHeader().Time)) {
return nil, nil
}

auth, err := grant.GetAuthorization()
if err != nil {
return nil, nil
}

return auth, grant.Expiration
}

// IterateGrants iterates over all authorization grants
// This function should be used with caution because it can involve significant IO operations.
// It should not be used in query or msg services without charging additional gas.
Expand Down
109 changes: 109 additions & 0 deletions x/authz/keeper/keeper_test.go
Expand Up @@ -33,12 +33,42 @@ type TestSuite struct {
}

func (s *TestSuite) SetupTest() {
<<<<<<< HEAD
app := simapp.Setup(s.T(), false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
now := tmtime.Now()
ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
authz.RegisterQueryServer(queryHelper, app.AuthzKeeper)
=======
key := sdk.NewKVStoreKey(authzkeeper.StoreKey)
testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test"))
s.ctx = testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()})
s.encCfg = moduletestutil.MakeTestEncodingConfig(authzmodule.AppModuleBasic{})

s.baseApp = baseapp.NewBaseApp(
"authz",
log.NewNopLogger(),
testCtx.DB,
s.encCfg.TxConfig.TxDecoder(),
)
s.baseApp.SetCMS(testCtx.CMS)
s.baseApp.SetInterfaceRegistry(s.encCfg.InterfaceRegistry)

s.addrs = simtestutil.CreateIncrementalAccounts(7)

// gomock initializations
ctrl := gomock.NewController(s.T())
s.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl)
s.bankKeeper = authztestutil.NewMockBankKeeper(ctrl)
banktypes.RegisterInterfaces(s.encCfg.InterfaceRegistry)
banktypes.RegisterMsgServer(s.baseApp.MsgServiceRouter(), s.bankKeeper)

s.authzKeeper = authzkeeper.NewKeeper(key, s.encCfg.Codec, s.baseApp.MsgServiceRouter(), s.accountKeeper)

queryHelper := baseapp.NewQueryServerTestHelper(s.ctx, s.encCfg.InterfaceRegistry)
authz.RegisterQueryServer(queryHelper, s.authzKeeper)
>>>>>>> 5e4651eca (feat(x/authz): Add the GetAuthorization function. (#13047))
queryClient := authz.NewQueryClient(queryHelper)
s.queryClient = queryClient

Expand Down Expand Up @@ -366,6 +396,85 @@ func (s *TestSuite) TestDequeueAllGrantsQueue() {
require.Len(authzs, 1)
}

func (s *TestSuite) TestGetAuthorization() {
addr1 := s.addrs[3]
addr2 := s.addrs[4]
addr3 := s.addrs[5]
addr4 := s.addrs[6]

genAuthMulti := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgMultiSend{}))
genAuthSend := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{}))
sendAuth := banktypes.NewSendAuthorization(coins10, nil)

start := s.ctx.BlockHeader().Time
expired := start.Add(time.Duration(1) * time.Second)
notExpired := start.Add(time.Duration(5) * time.Hour)

s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr2, genAuthMulti, nil), "creating grant 1->2")
s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr3, genAuthSend, &expired), "creating grant 1->3")
s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr4, sendAuth, &notExpired), "creating grant 1->4")
// Without access to private keeper methods, I don't know how to save a grant with an invalid authorization.
newCtx := s.ctx.WithBlockTime(start.Add(time.Duration(1) * time.Minute))

tests := []struct {
name string
grantee sdk.AccAddress
granter sdk.AccAddress
msgType string
expAuth authz.Authorization
expExp *time.Time
}{
{
name: "grant has nil exp and is returned",
grantee: addr1,
granter: addr2,
msgType: genAuthMulti.MsgTypeURL(),
expAuth: genAuthMulti,
expExp: nil,
},
{
name: "grant is expired not returned",
grantee: addr1,
granter: addr3,
msgType: genAuthSend.MsgTypeURL(),
expAuth: nil,
expExp: nil,
},
{
name: "grant is not expired and is returned",
grantee: addr1,
granter: addr4,
msgType: sendAuth.MsgTypeURL(),
expAuth: sendAuth,
expExp: &notExpired,
},
{
name: "grant is not expired but wrong msg type returns nil",
grantee: addr1,
granter: addr4,
msgType: genAuthMulti.MsgTypeURL(),
expAuth: nil,
expExp: nil,
},
{
name: "no grant exists between the two",
grantee: addr2,
granter: addr3,
msgType: genAuthSend.MsgTypeURL(),
expAuth: nil,
expExp: nil,
},
}

for _, tc := range tests {
s.Run(tc.name, func() {
actAuth, actExp := s.authzKeeper.GetAuthorization(newCtx, tc.grantee, tc.granter, tc.msgType)
s.Assert().Equal(tc.expAuth, actAuth, "authorization")
s.Assert().Equal(tc.expExp, actExp, "expiration")
})
}
}

func TestTestSuite(t *testing.T) {
suite.Run(t, new(TestSuite))
}

0 comments on commit 3849e5d

Please sign in to comment.