Skip to content

Commit

Permalink
feat(x/authz): Add the GetAuthorization function. (cosmos#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.
  • Loading branch information
SpicyLemon authored Aug 25, 2022
1 parent c73171f commit 5e4651e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (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.

### Improvements

Expand Down
19 changes: 19 additions & 0 deletions x/authz/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,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
81 changes: 80 additions & 1 deletion x/authz/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (s *TestSuite) SetupTest() {
s.baseApp.SetCMS(testCtx.CMS)
s.baseApp.SetInterfaceRegistry(s.encCfg.InterfaceRegistry)

s.addrs = simtestutil.CreateIncrementalAccounts(3)
s.addrs = simtestutil.CreateIncrementalAccounts(7)

// gomock initializations
ctrl := gomock.NewController(s.T())
Expand Down Expand Up @@ -392,6 +392,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 5e4651e

Please sign in to comment.