Skip to content

Commit

Permalink
x/authz: audit updates (cosmos#9042)
Browse files Browse the repository at this point in the history
* x/authz: audit updates

* audit with Aaron

* authz: Update Authorization.Accept method

* authz: add event proto definitions

* update query service

* authz: use typed events

* refactore and rename query authorizations

* remve Authorization infix from proto services

* renames wip

* refactoring

* update tests

* fix compilation

* fixing gRPC query tests

* fix simulation tests

* few renames

* more refactore

* add missing file

* moving export genesis to keeper

* Update docs

* update tests

* rename event Msg attribute to MsgTypeURL

* Upate Authorization interface

* rollback Makefile changes

* fix tests

* Apply suggestions from code review

Co-authored-by: Aaron Craelius <[email protected]>

* renames

* refactore authz/exported

* lint fix

* authz/types refactore

* comment update

* conflict updates

* Apply suggestions from code review

Co-authored-by: Amaury <[email protected]>

* authz: move storage keys to keeper

* review updates

* docs update

* Update x/authz/client/cli/query.go

Co-authored-by: Aaron Craelius <[email protected]>

* move codec to the root package

* authz CMD info update

* comment update

* update imports and build flags

* fix functional tests

* update proto comment

* fix tests

* fix test

Co-authored-by: Aaron Craelius <[email protected]>
Co-authored-by: Amaury <[email protected]>
  • Loading branch information
3 people authored May 6, 2021
1 parent 4f306fc commit 59810f3
Show file tree
Hide file tree
Showing 72 changed files with 3,087 additions and 3,194 deletions.
178 changes: 99 additions & 79 deletions docs/core/proto-docs.md

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions proto/cosmos/authz/v1beta1/authz.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,21 @@ import "google/protobuf/timestamp.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz";
option (gogoproto.goproto_getters_all) = false;

// GenericAuthorization gives the grantee unrestricted permissions to execute
// the provided method on behalf of the granter's account.
message GenericAuthorization {
option (cosmos_proto.implements_interface) = "Authorization";

// method name to grant unrestricted permissions to execute
// Note: MethodName() is already a method on `GenericAuthorization` type,
// we need some custom naming here so using `MessageName`
string method_name = 1 [(gogoproto.customname) = "MessageName"];
// Msg, identified by it's type URL, to grant unrestricted permissions to execute
string msg = 1;
}

// AuthorizationGrant gives permissions to execute
// Grant gives permissions to execute
// the provide method with expiration time.
message AuthorizationGrant {
message Grant {
google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"];
google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}
24 changes: 24 additions & 0 deletions proto/cosmos/authz/v1beta1/event.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
syntax = "proto3";
package cosmos.authz.v1beta1;

option go_package = "github.com/cosmos/cosmos-sdk/x/authz";

// EventGrant is emitted on Msg/Grant
message EventGrant {
// Msg type URL for which an autorization is granted
string msg_type_url = 2;
// Granter account address
string granter = 3;
// Grantee account address
string grantee = 4;
}

// EventRevoke is emitted on Msg/Revoke
message EventRevoke {
// Msg type URL for which an autorization is revoked
string msg_type_url = 2;
// Granter account address
string granter = 3;
// Grantee account address
string grantee = 4;
}
2 changes: 1 addition & 1 deletion proto/cosmos/authz/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz";

// GenesisState defines the authz module's genesis state.
message GenesisState {
Expand Down
39 changes: 11 additions & 28 deletions proto/cosmos/authz/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,30 @@ import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/authz/v1beta1/authz.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz";

// Query defines the gRPC querier service.
service Query {
// Returns any `Authorization` (or `nil`), with the expiration time, granted to the grantee by the granter for the
// provided msg type.
rpc Authorization(QueryAuthorizationRequest) returns (QueryAuthorizationResponse) {
option (google.api.http).get = "/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grant";
}

// Returns list of `Authorization`, granted to the grantee by the granter.
rpc Authorizations(QueryAuthorizationsRequest) returns (QueryAuthorizationsResponse) {
option (google.api.http).get = "/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grants";
rpc Grants(QueryGrantsRequest) returns (QueryGrantsResponse) {
option (google.api.http).get = "/cosmos/authz/v1beta1/grants";
}
}

// QueryAuthorizationRequest is the request type for the Query/Authorization RPC method.
message QueryAuthorizationRequest {
string granter = 1;
string grantee = 2;
string method_name = 3;
}

// QueryAuthorizationResponse is the response type for the Query/Authorization RPC method.
message QueryAuthorizationResponse {
// authorization is a authorization granted for grantee by granter.
cosmos.authz.v1beta1.AuthorizationGrant authorization = 1;
}

// QueryAuthorizationsRequest is the request type for the Query/Authorizations RPC method.
message QueryAuthorizationsRequest {
// QueryGrantsRequest is the request type for the Query/Grants RPC method.
message QueryGrantsRequest {
string granter = 1;
string grantee = 2;
// Optional, msg_type_url, when set, will query only grants matching given msg type.
string msg_type_url = 3;
// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 3;
cosmos.base.query.v1beta1.PageRequest pagination = 4;
}

// QueryAuthorizationsResponse is the response type for the Query/Authorizations RPC method.
message QueryAuthorizationsResponse {
// QueryGrantsResponse is the response type for the Query/Authorizations RPC method.
message QueryGrantsResponse {
// authorizations is a list of grants granted for grantee by granter.
repeated cosmos.authz.v1beta1.AuthorizationGrant authorizations = 1;
repeated cosmos.authz.v1beta1.Grant grants = 1;
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
47 changes: 26 additions & 21 deletions proto/cosmos/authz/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,57 +6,62 @@ import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
import "cosmos/base/abci/v1beta1/abci.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";

option go_package = "github.com/cosmos/cosmos-sdk/x/authz";
option (gogoproto.goproto_getters_all) = false;

// Msg defines the authz Msg service.
service Msg {
// GrantAuthorization grants the provided authorization to the grantee on the granter's
// Grant grants the provided authorization to the grantee on the granter's
// account with the provided expiration time.
rpc GrantAuthorization(MsgGrantAuthorizationRequest) returns (MsgGrantAuthorizationResponse);
rpc Grant(MsgGrant) returns (MsgGrantResponse);

// ExecAuthorized attempts to execute the provided messages using
// Exec attempts to execute the provided messages using
// authorizations granted to the grantee. Each message should have only
// one signer corresponding to the granter of the authorization.
rpc ExecAuthorized(MsgExecAuthorizedRequest) returns (MsgExecAuthorizedResponse);
rpc Exec(MsgExec) returns (MsgExecResponse);

// RevokeAuthorization revokes any authorization corresponding to the provided method name on the
// Revoke revokes any authorization corresponding to the provided method name on the
// granter's account that has been granted to the grantee.
rpc RevokeAuthorization(MsgRevokeAuthorizationRequest) returns (MsgRevokeAuthorizationResponse);
rpc Revoke(MsgRevoke) returns (MsgRevokeResponse);
}

// MsgGrantAuthorizationRequest grants the provided authorization to the grantee on the granter's
// MsgGrant grants the provided authorization to the grantee on the granter's
// account with the provided expiration time.
message MsgGrantAuthorizationRequest {
message MsgGrant {
string granter = 1;
string grantee = 2;

google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"];
google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

// MsgExecAuthorizedResponse defines the Msg/MsgExecAuthorizedResponse response type.
message MsgExecAuthorizedResponse {
// MsgExecResponse defines the Msg/MsgExecResponse response type.
message MsgExecResponse {
cosmos.base.abci.v1beta1.Result result = 1;
}

// MsgExecAuthorizedRequest attempts to execute the provided messages using
// MsgExec attempts to execute the provided messages using
// authorizations granted to the grantee. Each message should have only
// one signer corresponding to the granter of the authorization.
message MsgExecAuthorizedRequest {
message MsgExec {
string grantee = 1;
repeated google.protobuf.Any msgs = 2;
// Authorization Msg requests to execute. Each msg must implement Authorization interface
// The x/authz will try to find a grant matching (msg.signers[0], grantee, MsgTypeURL(msg))
// triple and validate it.
repeated google.protobuf.Any msgs = 2 [(cosmos_proto.accepts_interface) = "sdk.Msg, authz.Authorization"];;
}

// MsgGrantAuthorizationResponse defines the Msg/MsgGrantAuthorization response type.
message MsgGrantAuthorizationResponse {}
// MsgGrantResponse defines the Msg/MsgGrant response type.
message MsgGrantResponse {}

// MsgRevokeAuthorizationRequest revokes any authorization with the provided sdk.Msg type on the
// MsgRevoke revokes any authorization with the provided sdk.Msg type on the
// granter's account with that has been granted to the grantee.
message MsgRevokeAuthorizationRequest {
message MsgRevoke {
string granter = 1;
string grantee = 2;
string method_name = 3;
string msg_type_url = 3;
}

// MsgRevokeAuthorizationResponse defines the Msg/MsgRevokeAuthorizationResponse response type.
message MsgRevokeAuthorizationResponse {}
// MsgRevokeResponse defines the Msg/MsgRevokeResponse response type.
message MsgRevokeResponse {}
19 changes: 9 additions & 10 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ import (
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

"github.com/cosmos/cosmos-sdk/x/authz"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
authz_m "github.com/cosmos/cosmos-sdk/x/authz/module"
"github.com/cosmos/cosmos-sdk/x/crisis"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
Expand Down Expand Up @@ -82,10 +85,6 @@ import (
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

authz "github.com/cosmos/cosmos-sdk/x/authz"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
authztypes "github.com/cosmos/cosmos-sdk/x/authz/types"

// unnamed import of statik for swagger UI support
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"
)
Expand Down Expand Up @@ -116,7 +115,7 @@ var (
feegrant.AppModuleBasic{},
upgrade.AppModuleBasic{},
evidence.AppModuleBasic{},
authz.AppModuleBasic{},
authz_m.AppModuleBasic{},
vesting.AppModuleBasic{},
)

Expand Down Expand Up @@ -208,7 +207,7 @@ func NewSimApp(
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey, feegranttypes.StoreKey,
evidencetypes.StoreKey, capabilitytypes.StoreKey,
authztypes.StoreKey,
authzkeeper.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
Expand Down Expand Up @@ -265,7 +264,7 @@ func NewSimApp(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
)

app.AuthzKeeper = authzkeeper.NewKeeper(keys[authztypes.StoreKey], appCodec, app.BaseApp.MsgServiceRouter())
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.BaseApp.MsgServiceRouter())

// register the proposal types
govRouter := govtypes.NewRouter()
Expand Down Expand Up @@ -318,7 +317,7 @@ func NewSimApp(
upgrade.NewAppModule(app.UpgradeKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
params.NewAppModule(app.ParamsKeeper),
authz.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
authz_m.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
)

// During begin block slashing happens after distr.BeginBlocker so that
Expand All @@ -339,7 +338,7 @@ func NewSimApp(
app.mm.SetOrderInitGenesis(
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName,
genutiltypes.ModuleName, evidencetypes.ModuleName, authztypes.ModuleName,
genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
feegranttypes.ModuleName,
)

Expand Down Expand Up @@ -367,7 +366,7 @@ func NewSimApp(
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
params.NewAppModule(app.ParamsKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
authz.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
authz_m.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
)

app.sm.RegisterStoreDecoders()
Expand Down
6 changes: 3 additions & 3 deletions simapp/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/authz"
authz_m "github.com/cosmos/cosmos-sdk/x/authz/module"
"github.com/cosmos/cosmos-sdk/x/bank"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/capability"
Expand Down Expand Up @@ -168,7 +168,7 @@ func TestRunMigrations(t *testing.T) {
module.VersionMap{
"bank": 1,
"auth": auth.AppModule{}.ConsensusVersion(),
"authz": authz.AppModule{}.ConsensusVersion(),
"authz": authz_m.AppModule{}.ConsensusVersion(),
"staking": staking.AppModule{}.ConsensusVersion(),
"mint": mint.AppModule{}.ConsensusVersion(),
"distribution": distribution.AppModule{}.ConsensusVersion(),
Expand Down Expand Up @@ -219,7 +219,7 @@ func TestInitGenesisOnMigration(t *testing.T) {
module.VersionMap{
"bank": bank.AppModule{}.ConsensusVersion(),
"auth": auth.AppModule{}.ConsensusVersion(),
"authz": authz.AppModule{}.ConsensusVersion(),
"authz": authz_m.AppModule{}.ConsensusVersion(),
"staking": staking.AppModule{}.ConsensusVersion(),
"mint": mint.AppModule{}.ConsensusVersion(),
"distribution": distribution.AppModule{}.ConsensusVersion(),
Expand Down
2 changes: 1 addition & 1 deletion simapp/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
)

// The genesis state of the blockchain is represented here as a map of raw json
// GenesisState of the blockchain is represented here as a map of raw json
// messages key'd by a identifier string.
// The identifier is used to determine which module genesis information belongs
// to so it may be appropriately routed during init chain.
Expand Down
4 changes: 2 additions & 2 deletions simapp/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authztypes "github.com/cosmos/cosmos-sdk/x/authz/types"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
Expand Down Expand Up @@ -174,7 +174,7 @@ func TestAppImportExport(t *testing.T) {
{app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}},
{app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
{app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
{app.keys[authztypes.StoreKey], newApp.keys[authztypes.StoreKey], [][]byte{}},
{app.keys[authzkeeper.StoreKey], newApp.keys[authzkeeper.StoreKey], [][]byte{}},
}

for _, skp := range storeKeysPrefixes {
Expand Down
2 changes: 1 addition & 1 deletion store/gaskv/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (gi *gasIterator) Error() error {
return gi.parent.Error()
}

// consumeSeekGas consumes a flat gas cost for seeking and a variable gas cost
// consumeSeekGas consumes on each iteration step a flat gas cost and a variable gas cost
// based on the current value's length.
func (gi *gasIterator) consumeSeekGas() {
value := gi.Value()
Expand Down
49 changes: 49 additions & 0 deletions x/authz/authorization_grant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package authz

import (
"time"

proto "github.com/gogo/protobuf/proto"

cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// NewGrant returns new AuthrizationGrant
func NewGrant(authorization Authorization, expiration time.Time) (Grant, error) {
auth := Grant{
Expiration: expiration,
}
msg, ok := authorization.(proto.Message)
if !ok {
return Grant{}, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", authorization)
}

any, err := cdctypes.NewAnyWithValue(msg)
if err != nil {
return Grant{}, err
}

auth.Authorization = any

return auth, nil
}

var (
_ cdctypes.UnpackInterfacesMessage = &Grant{}
)

// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (auth Grant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
var authorization Authorization
return unpacker.UnpackAny(auth.Authorization, &authorization)
}

// GetAuthorization returns the cached value from the Grant.Authorization if present.
func (auth Grant) GetAuthorization() Authorization {
authorization, ok := auth.Authorization.GetCachedValue().(Authorization)
if !ok {
return nil
}
return authorization
}
Loading

0 comments on commit 59810f3

Please sign in to comment.