Skip to content

Commit

Permalink
feat(x/authz): Add the GetAuthorization function. (backport cosmos#13047
Browse files Browse the repository at this point in the history
) (cosmos#13052)

* feat(x/authz): Add the GetAuthorization function. (cosmos#13047)

* [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

* fix changelog

* Fix failed merge.

* Fix build issue introduced by merge.

Co-authored-by: Daniel Wedul <[email protected]>
Co-authored-by: Julien Robert <[email protected]>
  • Loading branch information
3 people authored Aug 26, 2022
1 parent b9d4ed8 commit e2fe96a
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

### Features

* (x/authz) [#13047](https://github.com/cosmos/cosmos-sdk/pull/13047) Add a GetAuthorization function to the keeper.

### Bug Fixes

* (export) [#13029](https://github.com/cosmos/cosmos-sdk/pull/13029) Fix exporting the blockParams regression.
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 @@ -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
81 changes: 80 additions & 1 deletion x/authz/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (s *TestSuite) SetupTest() {
s.app = app
s.ctx = ctx
s.queryClient = queryClient
s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(30000000))
s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 7, sdk.NewInt(30000000))
}

func (s *TestSuite) TestKeeper() {
Expand Down Expand Up @@ -366,6 +366,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)

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.app.AuthzKeeper.SaveGrant(s.ctx, addr1, addr2, genAuthMulti, nil), "creating grant 1->2")
s.Require().NoError(s.app.AuthzKeeper.SaveGrant(s.ctx, addr1, addr3, genAuthSend, &expired), "creating grant 1->3")
s.Require().NoError(s.app.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.app.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 e2fe96a

Please sign in to comment.