x/authz: audit updates (#9042)

* 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 <aaron@regen.network>

* renames

* refactore authz/exported

* lint fix

* authz/types refactore

* comment update

* conflict updates

* Apply suggestions from code review

Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com>

* authz: move storage keys to keeper

* review updates

* docs update

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

Co-authored-by: Aaron Craelius <aaron@regen.network>

* 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 <aaron@regen.network>
Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com>
This commit is contained in:
Robert Zaremba 2021-05-06 20:23:48 +02:00 committed by GitHub
parent 4f306fca4d
commit 59810f3286
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 3093 additions and 3200 deletions

View File

@ -27,18 +27,20 @@
- [Query](#cosmos.auth.v1beta1.Query)
- [cosmos/authz/v1beta1/authz.proto](#cosmos/authz/v1beta1/authz.proto)
- [AuthorizationGrant](#cosmos.authz.v1beta1.AuthorizationGrant)
- [GenericAuthorization](#cosmos.authz.v1beta1.GenericAuthorization)
- [Grant](#cosmos.authz.v1beta1.Grant)
- [cosmos/authz/v1beta1/event.proto](#cosmos/authz/v1beta1/event.proto)
- [EventGrant](#cosmos.authz.v1beta1.EventGrant)
- [EventRevoke](#cosmos.authz.v1beta1.EventRevoke)
- [cosmos/authz/v1beta1/genesis.proto](#cosmos/authz/v1beta1/genesis.proto)
- [GenesisState](#cosmos.authz.v1beta1.GenesisState)
- [GrantAuthorization](#cosmos.authz.v1beta1.GrantAuthorization)
- [cosmos/authz/v1beta1/query.proto](#cosmos/authz/v1beta1/query.proto)
- [QueryAuthorizationRequest](#cosmos.authz.v1beta1.QueryAuthorizationRequest)
- [QueryAuthorizationResponse](#cosmos.authz.v1beta1.QueryAuthorizationResponse)
- [QueryAuthorizationsRequest](#cosmos.authz.v1beta1.QueryAuthorizationsRequest)
- [QueryAuthorizationsResponse](#cosmos.authz.v1beta1.QueryAuthorizationsResponse)
- [QueryGrantsRequest](#cosmos.authz.v1beta1.QueryGrantsRequest)
- [QueryGrantsResponse](#cosmos.authz.v1beta1.QueryGrantsResponse)
- [Query](#cosmos.authz.v1beta1.Query)
@ -55,12 +57,12 @@
- [TxResponse](#cosmos.base.abci.v1beta1.TxResponse)
- [cosmos/authz/v1beta1/tx.proto](#cosmos/authz/v1beta1/tx.proto)
- [MsgExecAuthorizedRequest](#cosmos.authz.v1beta1.MsgExecAuthorizedRequest)
- [MsgExecAuthorizedResponse](#cosmos.authz.v1beta1.MsgExecAuthorizedResponse)
- [MsgGrantAuthorizationRequest](#cosmos.authz.v1beta1.MsgGrantAuthorizationRequest)
- [MsgGrantAuthorizationResponse](#cosmos.authz.v1beta1.MsgGrantAuthorizationResponse)
- [MsgRevokeAuthorizationRequest](#cosmos.authz.v1beta1.MsgRevokeAuthorizationRequest)
- [MsgRevokeAuthorizationResponse](#cosmos.authz.v1beta1.MsgRevokeAuthorizationResponse)
- [MsgExec](#cosmos.authz.v1beta1.MsgExec)
- [MsgExecResponse](#cosmos.authz.v1beta1.MsgExecResponse)
- [MsgGrant](#cosmos.authz.v1beta1.MsgGrant)
- [MsgGrantResponse](#cosmos.authz.v1beta1.MsgGrantResponse)
- [MsgRevoke](#cosmos.authz.v1beta1.MsgRevoke)
- [MsgRevokeResponse](#cosmos.authz.v1beta1.MsgRevokeResponse)
- [Msg](#cosmos.authz.v1beta1.Msg)
@ -873,10 +875,26 @@ Query defines the gRPC querier service.
<a name="cosmos.authz.v1beta1.AuthorizationGrant"></a>
<a name="cosmos.authz.v1beta1.GenericAuthorization"></a>
### AuthorizationGrant
AuthorizationGrant gives permissions to execute
### GenericAuthorization
GenericAuthorization gives the grantee unrestricted permissions to execute
the provided method on behalf of the granter's account.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `msg` | [string](#string) | | Msg, identified by it's type URL, to grant unrestricted permissions to execute |
<a name="cosmos.authz.v1beta1.Grant"></a>
### Grant
Grant gives permissions to execute
the provide method with expiration time.
@ -889,17 +907,51 @@ the provide method with expiration time.
<!-- end messages -->
<a name="cosmos.authz.v1beta1.GenericAuthorization"></a>
<!-- end enums -->
### GenericAuthorization
GenericAuthorization gives the grantee unrestricted permissions to execute
the provided method on behalf of the granter's account.
<!-- end HasExtensions -->
<!-- end services -->
<a name="cosmos/authz/v1beta1/event.proto"></a>
<p align="right"><a href="#top">Top</a></p>
## cosmos/authz/v1beta1/event.proto
<a name="cosmos.authz.v1beta1.EventGrant"></a>
### EventGrant
EventGrant is emitted on Msg/Grant
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `method_name` | [string](#string) | | 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` |
| `msg_type_url` | [string](#string) | | Msg type URL for which an autorization is granted |
| `granter` | [string](#string) | | Granter account address |
| `grantee` | [string](#string) | | Grantee account address |
<a name="cosmos.authz.v1beta1.EventRevoke"></a>
### EventRevoke
EventRevoke is emitted on Msg/Revoke
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `msg_type_url` | [string](#string) | | Msg type URL for which an autorization is revoked |
| `granter` | [string](#string) | | Granter account address |
| `grantee` | [string](#string) | | Grantee account address |
@ -971,48 +1023,17 @@ GrantAuthorization defines the GenesisState/GrantAuthorization type.
<a name="cosmos.authz.v1beta1.QueryAuthorizationRequest"></a>
<a name="cosmos.authz.v1beta1.QueryGrantsRequest"></a>
### QueryAuthorizationRequest
QueryAuthorizationRequest is the request type for the Query/Authorization RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `granter` | [string](#string) | | |
| `grantee` | [string](#string) | | |
| `method_name` | [string](#string) | | |
<a name="cosmos.authz.v1beta1.QueryAuthorizationResponse"></a>
### QueryAuthorizationResponse
QueryAuthorizationResponse is the response type for the Query/Authorization RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `authorization` | [AuthorizationGrant](#cosmos.authz.v1beta1.AuthorizationGrant) | | authorization is a authorization granted for grantee by granter. |
<a name="cosmos.authz.v1beta1.QueryAuthorizationsRequest"></a>
### QueryAuthorizationsRequest
QueryAuthorizationsRequest is the request type for the Query/Authorizations RPC method.
### QueryGrantsRequest
QueryGrantsRequest is the request type for the Query/Grants RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `granter` | [string](#string) | | |
| `grantee` | [string](#string) | | |
| `msg_type_url` | [string](#string) | | Optional, msg_type_url, when set, will query only grants matching given msg type. |
| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an pagination for the request. |
@ -1020,15 +1041,15 @@ QueryAuthorizationsRequest is the request type for the Query/Authorizations RPC
<a name="cosmos.authz.v1beta1.QueryAuthorizationsResponse"></a>
<a name="cosmos.authz.v1beta1.QueryGrantsResponse"></a>
### QueryAuthorizationsResponse
QueryAuthorizationsResponse is the response type for the Query/Authorizations RPC method.
### QueryGrantsResponse
QueryGrantsResponse is the response type for the Query/Authorizations RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `authorizations` | [AuthorizationGrant](#cosmos.authz.v1beta1.AuthorizationGrant) | repeated | authorizations is a list of grants granted for grantee by granter. |
| `grants` | [Grant](#cosmos.authz.v1beta1.Grant) | repeated | authorizations is a list of grants granted for grantee by granter. |
| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines an pagination for the response. |
@ -1049,8 +1070,7 @@ Query defines the gRPC querier service.
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `Authorization` | [QueryAuthorizationRequest](#cosmos.authz.v1beta1.QueryAuthorizationRequest) | [QueryAuthorizationResponse](#cosmos.authz.v1beta1.QueryAuthorizationResponse) | Returns any `Authorization` (or `nil`), with the expiration time, granted to the grantee by the granter for the provided msg type. | GET|/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grant|
| `Authorizations` | [QueryAuthorizationsRequest](#cosmos.authz.v1beta1.QueryAuthorizationsRequest) | [QueryAuthorizationsResponse](#cosmos.authz.v1beta1.QueryAuthorizationsResponse) | Returns list of `Authorization`, granted to the grantee by the granter. | GET|/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grants|
| `Grants` | [QueryGrantsRequest](#cosmos.authz.v1beta1.QueryGrantsRequest) | [QueryGrantsResponse](#cosmos.authz.v1beta1.QueryGrantsResponse) | Returns list of `Authorization`, granted to the grantee by the granter. | GET|/cosmos/authz/v1beta1/grants|
<!-- end services -->
@ -1260,10 +1280,10 @@ tags are stringified and the log is JSON decoded.
<a name="cosmos.authz.v1beta1.MsgExecAuthorizedRequest"></a>
<a name="cosmos.authz.v1beta1.MsgExec"></a>
### MsgExecAuthorizedRequest
MsgExecAuthorizedRequest attempts to execute the provided messages using
### MsgExec
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.
@ -1271,17 +1291,17 @@ one signer corresponding to the granter of the authorization.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `grantee` | [string](#string) | | |
| `msgs` | [google.protobuf.Any](#google.protobuf.Any) | repeated | |
| `msgs` | [google.protobuf.Any](#google.protobuf.Any) | repeated | 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. |
<a name="cosmos.authz.v1beta1.MsgExecAuthorizedResponse"></a>
<a name="cosmos.authz.v1beta1.MsgExecResponse"></a>
### MsgExecAuthorizedResponse
MsgExecAuthorizedResponse defines the Msg/MsgExecAuthorizedResponse response type.
### MsgExecResponse
MsgExecResponse defines the Msg/MsgExecResponse response type.
| Field | Type | Label | Description |
@ -1293,10 +1313,10 @@ MsgExecAuthorizedResponse defines the Msg/MsgExecAuthorizedResponse response typ
<a name="cosmos.authz.v1beta1.MsgGrantAuthorizationRequest"></a>
<a name="cosmos.authz.v1beta1.MsgGrant"></a>
### MsgGrantAuthorizationRequest
MsgGrantAuthorizationRequest grants the provided authorization to the grantee on the granter's
### MsgGrant
MsgGrant grants the provided authorization to the grantee on the granter's
account with the provided expiration time.
@ -1312,20 +1332,20 @@ account with the provided expiration time.
<a name="cosmos.authz.v1beta1.MsgGrantAuthorizationResponse"></a>
<a name="cosmos.authz.v1beta1.MsgGrantResponse"></a>
### MsgGrantAuthorizationResponse
MsgGrantAuthorizationResponse defines the Msg/MsgGrantAuthorization response type.
### MsgGrantResponse
MsgGrantResponse defines the Msg/MsgGrant response type.
<a name="cosmos.authz.v1beta1.MsgRevokeAuthorizationRequest"></a>
<a name="cosmos.authz.v1beta1.MsgRevoke"></a>
### MsgRevokeAuthorizationRequest
MsgRevokeAuthorizationRequest revokes any authorization with the provided sdk.Msg type on the
### MsgRevoke
MsgRevoke revokes any authorization with the provided sdk.Msg type on the
granter's account with that has been granted to the grantee.
@ -1333,17 +1353,17 @@ granter's account with that has been granted to the grantee.
| ----- | ---- | ----- | ----------- |
| `granter` | [string](#string) | | |
| `grantee` | [string](#string) | | |
| `method_name` | [string](#string) | | |
| `msg_type_url` | [string](#string) | | |
<a name="cosmos.authz.v1beta1.MsgRevokeAuthorizationResponse"></a>
<a name="cosmos.authz.v1beta1.MsgRevokeResponse"></a>
### MsgRevokeAuthorizationResponse
MsgRevokeAuthorizationResponse defines the Msg/MsgRevokeAuthorizationResponse response type.
### MsgRevokeResponse
MsgRevokeResponse defines the Msg/MsgRevokeResponse response type.
@ -1363,9 +1383,9 @@ Msg defines the authz Msg service.
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `GrantAuthorization` | [MsgGrantAuthorizationRequest](#cosmos.authz.v1beta1.MsgGrantAuthorizationRequest) | [MsgGrantAuthorizationResponse](#cosmos.authz.v1beta1.MsgGrantAuthorizationResponse) | GrantAuthorization grants the provided authorization to the grantee on the granter's account with the provided expiration time. | |
| `ExecAuthorized` | [MsgExecAuthorizedRequest](#cosmos.authz.v1beta1.MsgExecAuthorizedRequest) | [MsgExecAuthorizedResponse](#cosmos.authz.v1beta1.MsgExecAuthorizedResponse) | ExecAuthorized 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. | |
| `RevokeAuthorization` | [MsgRevokeAuthorizationRequest](#cosmos.authz.v1beta1.MsgRevokeAuthorizationRequest) | [MsgRevokeAuthorizationResponse](#cosmos.authz.v1beta1.MsgRevokeAuthorizationResponse) | RevokeAuthorization revokes any authorization corresponding to the provided method name on the granter's account that has been granted to the grantee. | |
| `Grant` | [MsgGrant](#cosmos.authz.v1beta1.MsgGrant) | [MsgGrantResponse](#cosmos.authz.v1beta1.MsgGrantResponse) | Grant grants the provided authorization to the grantee on the granter's account with the provided expiration time. | |
| `Exec` | [MsgExec](#cosmos.authz.v1beta1.MsgExec) | [MsgExecResponse](#cosmos.authz.v1beta1.MsgExecResponse) | 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. | |
| `Revoke` | [MsgRevoke](#cosmos.authz.v1beta1.MsgRevoke) | [MsgRevokeResponse](#cosmos.authz.v1beta1.MsgRevokeResponse) | Revoke revokes any authorization corresponding to the provided method name on the granter's account that has been granted to the grantee. | |
<!-- end services -->

View File

@ -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];
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -6,27 +6,29 @@ 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;
@ -34,29 +36,32 @@ message MsgGrantAuthorizationRequest {
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 {}

View File

@ -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"
@ -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"
)
@ -116,7 +115,7 @@ var (
feegrant.AppModuleBasic{},
upgrade.AppModuleBasic{},
evidence.AppModuleBasic{},
authz.AppModuleBasic{},
authz_m.AppModuleBasic{},
vesting.AppModuleBasic{},
)
@ -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)
@ -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()
@ -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
@ -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,
)
@ -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()

View File

@ -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"
@ -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(),
@ -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(),

View File

@ -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.

View File

@ -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"
@ -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 {

View File

@ -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()

View File

@ -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
}

38
x/authz/authorizations.go Normal file
View File

@ -0,0 +1,38 @@
package authz
import (
"github.com/gogo/protobuf/proto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Authorization represents the interface of various Authorization types implemented
// by other modules.
type Authorization interface {
proto.Message
// MsgTypeURL returns the fully-qualified Msg service method URL (as described in ADR 031),
// which will process and accept or reject a request.
MsgTypeURL() string
// Accept determines whether this grant permits the provided sdk.ServiceMsg to be performed, and if
// so provides an upgraded authorization instance.
Accept(ctx sdk.Context, msg sdk.Msg) (AcceptResponse, error)
// ValidateBasic does a simple validation check that
// doesn't require access to any other information.
ValidateBasic() error
}
// AcceptResponse instruments the controller of an authz message if the request is accepted
// and if it should be updated or deleted.
type AcceptResponse struct {
// If Accept=true, the controller can accept and authorization and handle the update.
Accept bool
// If Delete=true, the controller must delete the authorization object and release
// storage resources.
Delete bool
// Controller, who is calling Authorization.Accept must check if `Updated != nil`. If yes,
// it must use the updated version and handle the update on the storage level.
Updated Authorization
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/authz/v1beta1/authz.proto
package types
package authz
import (
fmt "fmt"
@ -32,10 +32,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// GenericAuthorization gives the grantee unrestricted permissions to execute
// the provided method on behalf of the granter's account.
type GenericAuthorization struct {
// 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`
MessageName string `protobuf:"bytes,1,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"`
// Msg, identified by it's type URL, to grant unrestricted permissions to execute
Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
}
func (m *GenericAuthorization) Reset() { *m = GenericAuthorization{} }
@ -71,32 +69,25 @@ func (m *GenericAuthorization) XXX_DiscardUnknown() {
var xxx_messageInfo_GenericAuthorization proto.InternalMessageInfo
func (m *GenericAuthorization) GetMessageName() string {
if m != nil {
return m.MessageName
}
return ""
}
// AuthorizationGrant gives permissions to execute
// Grant gives permissions to execute
// the provide method with expiration time.
type AuthorizationGrant struct {
type Grant struct {
Authorization *types.Any `protobuf:"bytes,1,opt,name=authorization,proto3" json:"authorization,omitempty"`
Expiration time.Time `protobuf:"bytes,2,opt,name=expiration,proto3,stdtime" json:"expiration"`
}
func (m *AuthorizationGrant) Reset() { *m = AuthorizationGrant{} }
func (m *AuthorizationGrant) String() string { return proto.CompactTextString(m) }
func (*AuthorizationGrant) ProtoMessage() {}
func (*AuthorizationGrant) Descriptor() ([]byte, []int) {
func (m *Grant) Reset() { *m = Grant{} }
func (m *Grant) String() string { return proto.CompactTextString(m) }
func (*Grant) ProtoMessage() {}
func (*Grant) Descriptor() ([]byte, []int) {
return fileDescriptor_544dc2e84b61c637, []int{1}
}
func (m *AuthorizationGrant) XXX_Unmarshal(b []byte) error {
func (m *Grant) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *AuthorizationGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
func (m *Grant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_AuthorizationGrant.Marshal(b, m, deterministic)
return xxx_messageInfo_Grant.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
@ -106,62 +97,46 @@ func (m *AuthorizationGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte,
return b[:n], nil
}
}
func (m *AuthorizationGrant) XXX_Merge(src proto.Message) {
xxx_messageInfo_AuthorizationGrant.Merge(m, src)
func (m *Grant) XXX_Merge(src proto.Message) {
xxx_messageInfo_Grant.Merge(m, src)
}
func (m *AuthorizationGrant) XXX_Size() int {
func (m *Grant) XXX_Size() int {
return m.Size()
}
func (m *AuthorizationGrant) XXX_DiscardUnknown() {
xxx_messageInfo_AuthorizationGrant.DiscardUnknown(m)
func (m *Grant) XXX_DiscardUnknown() {
xxx_messageInfo_Grant.DiscardUnknown(m)
}
var xxx_messageInfo_AuthorizationGrant proto.InternalMessageInfo
func (m *AuthorizationGrant) GetAuthorization() *types.Any {
if m != nil {
return m.Authorization
}
return nil
}
func (m *AuthorizationGrant) GetExpiration() time.Time {
if m != nil {
return m.Expiration
}
return time.Time{}
}
var xxx_messageInfo_Grant proto.InternalMessageInfo
func init() {
proto.RegisterType((*GenericAuthorization)(nil), "cosmos.authz.v1beta1.GenericAuthorization")
proto.RegisterType((*AuthorizationGrant)(nil), "cosmos.authz.v1beta1.AuthorizationGrant")
proto.RegisterType((*Grant)(nil), "cosmos.authz.v1beta1.Grant")
}
func init() { proto.RegisterFile("cosmos/authz/v1beta1/authz.proto", fileDescriptor_544dc2e84b61c637) }
var fileDescriptor_544dc2e84b61c637 = []byte{
// 333 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xc1, 0x4e, 0xfa, 0x40,
0x10, 0xc6, 0xbb, 0xff, 0xc3, 0x3f, 0xba, 0x84, 0x18, 0x9a, 0x1e, 0x84, 0x43, 0x4b, 0x38, 0x19,
0x13, 0x5a, 0xd1, 0x9b, 0x37, 0x1a, 0x12, 0x4e, 0x78, 0x20, 0x9e, 0xf4, 0x40, 0xb6, 0x30, 0xb6,
0x8d, 0x6e, 0xa7, 0xe9, 0x6e, 0x0d, 0xf0, 0x14, 0xbc, 0x86, 0x77, 0x1f, 0x82, 0x78, 0x22, 0x9e,
0x3c, 0xa1, 0x29, 0x2f, 0x62, 0xe8, 0x2e, 0x09, 0xe0, 0x69, 0x67, 0xbe, 0xfd, 0xbe, 0xdf, 0x4e,
0x76, 0x68, 0x73, 0x8c, 0x82, 0xa3, 0xf0, 0x58, 0x2e, 0xa3, 0xb9, 0xf7, 0xda, 0x09, 0x40, 0xb2,
0x8e, 0xea, 0xdc, 0x34, 0x43, 0x89, 0xa6, 0xa5, 0x1c, 0xae, 0xd2, 0xb4, 0xa3, 0x51, 0x57, 0xea,
0xa8, 0xf4, 0x78, 0xda, 0x52, 0x36, 0x0d, 0x27, 0x44, 0x0c, 0x5f, 0xc0, 0x2b, 0xbb, 0x20, 0x7f,
0xf2, 0x64, 0xcc, 0x41, 0x48, 0xc6, 0x53, 0x6d, 0xb0, 0x42, 0x0c, 0x51, 0x05, 0xb7, 0x95, 0x56,
0xeb, 0xc7, 0x31, 0x96, 0xcc, 0xd4, 0x55, 0xeb, 0x91, 0x5a, 0x7d, 0x48, 0x20, 0x8b, 0xc7, 0xdd,
0x5c, 0x46, 0x98, 0xc5, 0x73, 0x26, 0x63, 0x4c, 0xcc, 0x2b, 0x5a, 0xe1, 0x20, 0x23, 0x9c, 0x8c,
0x12, 0xc6, 0xe1, 0x9c, 0x34, 0xc9, 0xc5, 0xa9, 0x7f, 0x56, 0xac, 0x9d, 0xca, 0x00, 0x84, 0x60,
0x21, 0xdc, 0x31, 0x0e, 0x43, 0xaa, 0x3c, 0xdb, 0xfa, 0xb6, 0xf6, 0xf9, 0xde, 0xae, 0x1e, 0x40,
0x5a, 0x6f, 0x84, 0x9a, 0x07, 0x4a, 0x3f, 0x63, 0x89, 0x34, 0x07, 0xb4, 0xca, 0xf6, 0xd5, 0x92,
0x5e, 0xb9, 0xb6, 0x5c, 0x35, 0xa6, 0xbb, 0x1b, 0xd3, 0xed, 0x26, 0x33, 0xbf, 0xf6, 0x71, 0x8c,
0x1d, 0x1e, 0xa6, 0xcd, 0x1e, 0xa5, 0x30, 0x4d, 0xe3, 0x4c, 0xb1, 0xfe, 0x95, 0xac, 0xc6, 0x1f,
0xd6, 0xfd, 0xee, 0xa7, 0xfc, 0x93, 0xe5, 0xda, 0x31, 0x16, 0xdf, 0x0e, 0x19, 0xee, 0xe5, 0xfc,
0xde, 0xb2, 0xb0, 0xc9, 0xaa, 0xb0, 0xc9, 0x4f, 0x61, 0x93, 0xc5, 0xc6, 0x36, 0x56, 0x1b, 0xdb,
0xf8, 0xda, 0xd8, 0xc6, 0xc3, 0x65, 0x18, 0xcb, 0x28, 0x0f, 0xdc, 0x31, 0x72, 0xbd, 0x0d, 0x7d,
0xb4, 0xc5, 0xe4, 0xd9, 0x9b, 0xea, 0xfd, 0xca, 0x59, 0x0a, 0x22, 0xf8, 0x5f, 0xbe, 0x77, 0xf3,
0x1b, 0x00, 0x00, 0xff, 0xff, 0x62, 0x49, 0x9d, 0xc0, 0xfc, 0x01, 0x00, 0x00,
// 303 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x2c, 0x2d, 0xc9, 0xa8, 0xd2, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34,
0x84, 0xf0, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x44, 0x20, 0x2a, 0xf4, 0x20, 0x62, 0x50,
0x15, 0x52, 0x92, 0x10, 0xd1, 0x78, 0xb0, 0x1a, 0x7d, 0xa8, 0x12, 0x30, 0x47, 0x4a, 0x3e, 0x3d,
0x3f, 0x3f, 0x3d, 0x27, 0x55, 0x1f, 0xcc, 0x4b, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, 0x2d,
0x2e, 0x49, 0xcc, 0x2d, 0x80, 0x2a, 0x10, 0x49, 0xcf, 0x4f, 0xcf, 0x87, 0x68, 0x04, 0xb1, 0xa0,
0xa2, 0x92, 0xe8, 0xda, 0x12, 0xf3, 0x2a, 0x21, 0x52, 0x4a, 0xd6, 0x5c, 0x22, 0xee, 0xa9, 0x79,
0xa9, 0x45, 0x99, 0xc9, 0x8e, 0xa5, 0x25, 0x19, 0xf9, 0x45, 0x99, 0x55, 0x89, 0x25, 0x99, 0xf9,
0x79, 0x42, 0x02, 0x5c, 0xcc, 0xb9, 0xc5, 0xe9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x20,
0xa6, 0x95, 0xe0, 0xa5, 0x2d, 0xba, 0xbc, 0x28, 0x8a, 0x94, 0xe6, 0x30, 0x72, 0xb1, 0xba, 0x17,
0x25, 0xe6, 0x95, 0x08, 0xf9, 0x72, 0xf1, 0x26, 0x22, 0x4b, 0x81, 0x35, 0x72, 0x1b, 0x89, 0xe8,
0x41, 0x6c, 0xd6, 0x83, 0xd9, 0xac, 0xe7, 0x98, 0x57, 0xe9, 0x24, 0x78, 0x0a, 0xdd, 0xa4, 0x20,
0x54, 0xdd, 0x42, 0x2e, 0x5c, 0x5c, 0xa9, 0x15, 0x05, 0x99, 0x45, 0x10, 0xb3, 0x98, 0xc0, 0x66,
0x49, 0x61, 0x98, 0x15, 0x02, 0xf3, 0xbc, 0x13, 0xc7, 0x89, 0x7b, 0xf2, 0x0c, 0x13, 0xee, 0xcb,
0x33, 0x06, 0x21, 0xe9, 0x73, 0x72, 0x3a, 0xf1, 0x50, 0x8e, 0xe1, 0xc4, 0x23, 0x39, 0xc6, 0x0b,
0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86,
0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x54, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73,
0xa1, 0x81, 0x0c, 0xa5, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x2b, 0x20, 0x11, 0x95, 0xc4, 0x06, 0xb6,
0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x6e, 0xbe, 0xf1, 0x5a, 0xcd, 0x01, 0x00, 0x00,
}
func (m *GenericAuthorization) Marshal() (dAtA []byte, err error) {
@ -184,17 +159,17 @@ func (m *GenericAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.MessageName) > 0 {
i -= len(m.MessageName)
copy(dAtA[i:], m.MessageName)
i = encodeVarintAuthz(dAtA, i, uint64(len(m.MessageName)))
if len(m.Msg) > 0 {
i -= len(m.Msg)
copy(dAtA[i:], m.Msg)
i = encodeVarintAuthz(dAtA, i, uint64(len(m.Msg)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *AuthorizationGrant) Marshal() (dAtA []byte, err error) {
func (m *Grant) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -204,12 +179,12 @@ func (m *AuthorizationGrant) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
func (m *AuthorizationGrant) MarshalTo(dAtA []byte) (int, error) {
func (m *Grant) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *AuthorizationGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *Grant) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@ -254,14 +229,14 @@ func (m *GenericAuthorization) Size() (n int) {
}
var l int
_ = l
l = len(m.MessageName)
l = len(m.Msg)
if l > 0 {
n += 1 + l + sovAuthz(uint64(l))
}
return n
}
func (m *AuthorizationGrant) Size() (n int) {
func (m *Grant) Size() (n int) {
if m == nil {
return 0
}
@ -313,7 +288,7 @@ func (m *GenericAuthorization) Unmarshal(dAtA []byte) error {
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MessageName", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
@ -341,7 +316,7 @@ func (m *GenericAuthorization) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.MessageName = string(dAtA[iNdEx:postIndex])
m.Msg = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
@ -364,7 +339,7 @@ func (m *GenericAuthorization) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *AuthorizationGrant) Unmarshal(dAtA []byte) error {
func (m *Grant) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@ -387,10 +362,10 @@ func (m *AuthorizationGrant) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AuthorizationGrant: wiretype end group for non-group")
return fmt.Errorf("proto: Grant: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AuthorizationGrant: illegal tag %d (wire type %d)", fieldNum, wire)
return fmt.Errorf("proto: Grant: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:

View File

@ -1,7 +1,6 @@
package cli
import (
"context"
"fmt"
"strings"
@ -11,14 +10,14 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
)
// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd() *cobra.Command {
authorizationQueryCmd := &cobra.Command{
Use: types.ModuleName,
Use: authz.ModuleName,
Short: "Querying commands for the authz module",
Long: "",
DisableFlagParsing: true,
@ -27,54 +26,59 @@ func GetQueryCmd() *cobra.Command {
}
authorizationQueryCmd.AddCommand(
GetCmdQueryAuthorization(),
GetCmdQueryAuthorizations(),
GetCmdQueryGrants(),
)
return authorizationQueryCmd
}
// GetCmdQueryAuthorizations implements the query authorizations command.
func GetCmdQueryAuthorizations() *cobra.Command {
// GetCmdQueryGrants implements the query authorization command.
func GetCmdQueryGrants() *cobra.Command {
cmd := &cobra.Command{
Use: "authorizations [granter-addr] [grantee-addr]",
Args: cobra.ExactArgs(2),
Short: "query list of authorizations for a granter-grantee pair",
Use: "grants [granter-addr] [grantee-addr] [msg-type-url]?",
Args: cobra.RangeArgs(2, 3),
Short: "query grants for a granter-grantee pair and optionally a msg-type-url",
Long: strings.TrimSpace(
fmt.Sprintf(`Query list of authorizations for a granter-grantee pair:
Example:
$ %s query %s authorizations cosmos1skj.. cosmos1skjwj..
`, version.AppName, types.ModuleName),
fmt.Sprintf(`Query authorization grants for a granter-grantee pair. If msg-type-url
is set, it will select grants only for that msg type.
Examples:
$ %s query %s grants cosmos1skj.. cosmos1skjwj..
$ %s query %s grants cosmos1skjw.. cosmos1skjwj.. %s
`,
version.AppName, authz.ModuleName,
version.AppName, authz.ModuleName, bank.SendAuthorization{}.MsgTypeURL()),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
queryClient := authz.NewQueryClient(clientCtx)
granterAddr, err := sdk.AccAddressFromBech32(args[0])
granter, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
granteeAddr, err := sdk.AccAddressFromBech32(args[1])
grantee, err := sdk.AccAddressFromBech32(args[1])
if err != nil {
return err
}
var msgAuthorized = ""
if len(args) >= 3 {
msgAuthorized = args[2]
}
pageReq, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}
res, err := queryClient.Authorizations(
context.Background(),
&types.QueryAuthorizationsRequest{
Granter: granterAddr.String(),
Grantee: granteeAddr.String(),
Pagination: pageReq,
},
res, err := queryClient.Grants(
cmd.Context(),
&authz.QueryGrantsRequest{
Granter: granter.String(),
Grantee: grantee.String(),
MsgTypeUrl: msgAuthorized,
Pagination: pageReq},
)
if err != nil {
return err
@ -84,56 +88,6 @@ $ %s query %s authorizations cosmos1skj.. cosmos1skjwj..
},
}
flags.AddQueryFlagsToCmd(cmd)
flags.AddPaginationFlagsToCmd(cmd, "authorizations")
return cmd
}
// GetCmdQueryAuthorization implements the query authorization command.
func GetCmdQueryAuthorization() *cobra.Command {
cmd := &cobra.Command{
Use: "authorization [granter-addr] [grantee-addr] [msg-type]",
Args: cobra.ExactArgs(3),
Short: "query authorization for a granter-grantee pair",
Long: strings.TrimSpace(
fmt.Sprintf(`Query authorization for a granter-grantee pair that matches the given msg-type:
Example:
$ %s query %s authorization cosmos1skjw.. cosmos1skjwj.. %s
`, version.AppName, types.ModuleName, bank.SendAuthorization{}.MethodName()),
),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
granter, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
grantee, err := sdk.AccAddressFromBech32(args[1])
if err != nil {
return err
}
msgAuthorized := args[2]
res, err := queryClient.Authorization(
context.Background(),
&types.QueryAuthorizationRequest{
Granter: granter.String(),
Grantee: grantee.String(),
MethodName: msgAuthorized,
},
)
if err != nil {
return err
}
return clientCtx.PrintProto(res.Authorization)
},
}
flags.AddQueryFlagsToCmd(cmd)
flags.AddPaginationFlagsToCmd(cmd, "grants")
return cmd
}

View File

@ -1,7 +1,6 @@
package cli
import (
"context"
"errors"
"fmt"
"strings"
@ -16,25 +15,27 @@ import (
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/cosmos/cosmos-sdk/version"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
staking "github.com/cosmos/cosmos-sdk/x/staking/types"
)
const FlagSpendLimit = "spend-limit"
const FlagMsgType = "msg-type"
const FlagExpiration = "expiration"
const FlagAllowedValidators = "allowed-validators"
const FlagDenyValidators = "deny-validators"
const delegate = "delegate"
const redelegate = "redelegate"
const unbond = "unbond"
// Flag names and values
const (
FlagSpendLimit = "spend-limit"
FlagMsgType = "msg-type"
FlagExpiration = "expiration"
FlagAllowedValidators = "allowed-validators"
FlagDenyValidators = "deny-validators"
delegate = "delegate"
redelegate = "redelegate"
unbond = "unbond"
)
// GetTxCmd returns the transaction commands for this module
func GetTxCmd() *cobra.Command {
AuthorizationTxCmd := &cobra.Command{
Use: types.ModuleName,
Use: authz.ModuleName,
Short: "Authorization transactions subcommands",
Long: "Authorize and revoke access to execute transactions on behalf of your address",
DisableFlagParsing: true,
@ -56,12 +57,12 @@ func NewCmdGrantAuthorization() *cobra.Command {
Use: "grant <grantee> <authorization_type=\"send\"|\"generic\"|\"delegate\"|\"unbond\"|\"redelegate\"> --from <granter>",
Short: "Grant authorization to an address",
Long: strings.TrimSpace(
fmt.Sprintf(`Grant authorization to an address to execute a transaction on your behalf:
fmt.Sprintf(`grant authorization to an address to execute a transaction on your behalf:
Examples:
$ %s tx %s grant cosmos1skjw.. send %s --spend-limit=1000stake --from=cosmos1skl..
$ %s tx %s grant cosmos1skjw.. generic --msg-type=/cosmos.gov.v1beta1.MsgVote --from=cosmos1sk..
`, version.AppName, types.ModuleName, bank.SendAuthorization{}.MethodName(), version.AppName, types.ModuleName),
`, version.AppName, authz.ModuleName, bank.SendAuthorization{}.MsgTypeURL(), version.AppName, authz.ModuleName),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
@ -80,7 +81,7 @@ Examples:
return err
}
var authorization exported.Authorization
var authorization authz.Authorization
switch args[1] {
case "send":
limit, err := cmd.Flags().GetString(FlagSpendLimit)
@ -104,7 +105,7 @@ Examples:
return err
}
authorization = types.NewGenericAuthorization(msgType)
authorization = authz.NewGenericAuthorization(msgType)
case delegate, unbond, redelegate:
limit, err := cmd.Flags().GetString(FlagSpendLimit)
if err != nil {
@ -160,14 +161,14 @@ Examples:
return fmt.Errorf("invalid authorization type, %s", args[1])
}
msg, err := types.NewMsgGrantAuthorization(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0))
msg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0))
if err != nil {
return err
}
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
msgClient := types.NewMsgClient(svcMsgClientConn)
_, err = msgClient.GrantAuthorization(context.Background(), msg)
msgClient := authz.NewMsgClient(svcMsgClientConn)
_, err = msgClient.Grant(cmd.Context(), msg)
if err != nil {
return err
}
@ -192,7 +193,7 @@ func NewCmdRevokeAuthorization() *cobra.Command {
fmt.Sprintf(`revoke authorization from a granter to a grantee:
Example:
$ %s tx %s revoke cosmos1skj.. %s --from=cosmos1skj..
`, version.AppName, types.ModuleName, bank.SendAuthorization{}.MethodName()),
`, version.AppName, authz.ModuleName, bank.SendAuthorization{}.MsgTypeURL()),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
@ -207,14 +208,12 @@ Example:
}
granter := clientCtx.GetFromAddress()
msgAuthorized := args[1]
msg := types.NewMsgRevokeAuthorization(granter, grantee, msgAuthorized)
msg := authz.NewMsgRevoke(granter, grantee, msgAuthorized)
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
msgClient := types.NewMsgClient(svcMsgClientConn)
_, err = msgClient.RevokeAuthorization(context.Background(), &msg)
msgClient := authz.NewMsgClient(svcMsgClientConn)
_, err = msgClient.Revoke(cmd.Context(), &msg)
if err != nil {
return err
}
@ -235,7 +234,7 @@ func NewCmdExecAuthorization() *cobra.Command {
Example:
$ %s tx %s exec tx.json --from grantee
$ %s tx bank send <granter> <recipient> --from <granter> --chain-id <chain-id> --generate-only > tx.json && %s tx %s exec tx.json --from grantee
`, version.AppName, types.ModuleName, version.AppName, version.AppName, types.ModuleName),
`, version.AppName, authz.ModuleName, version.AppName, version.AppName, authz.ModuleName),
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
@ -254,10 +253,10 @@ Example:
if err != nil {
return err
}
msg := types.NewMsgExecAuthorized(grantee, theTx.GetMsgs())
msg := authz.NewMsgExec(grantee, theTx.GetMsgs())
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
msgClient := types.NewMsgClient(svcMsgClientConn)
_, err = msgClient.ExecAuthorized(context.Background(), &msg)
msgClient := authz.NewMsgClient(svcMsgClientConn)
_, err = msgClient.Exec(cmd.Context(), &msg)
if err != nil {
return err
}

View File

@ -15,9 +15,9 @@ import (
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
authztestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil"
types "github.com/cosmos/cosmos-sdk/x/authz/types"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
@ -30,7 +30,7 @@ type IntegrationTestSuite struct {
grantee sdk.AccAddress
}
var typeMsgSend = banktypes.SendAuthorization{}.MethodName()
var typeMsgSend = banktypes.SendAuthorization{}.MsgTypeURL()
var typeMsgVote = sdk.MsgTypeURL(&govtypes.MsgVote{})
func (s *IntegrationTestSuite) SetupSuite() {
@ -61,7 +61,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.Require().Contains(out.String(), `"code":0`)
// grant authorization
out, err = authztestutil.ExecGrantAuthorization(val, []string{
out, err = authztestutil.ExecGrant(val, []string{
newAddr.String(),
"send",
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
@ -84,9 +84,9 @@ func (s *IntegrationTestSuite) TearDownSuite() {
s.network.Cleanup()
}
func (s *IntegrationTestSuite) TestQueryAuthorizationGRPC() {
func (s *IntegrationTestSuite) TestQueryGrantGRPC() {
val := s.network.Validators[0]
baseURL := val.APIAddress
grantsURL := val.APIAddress + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s&msg_type_url=%s"
testCases := []struct {
name string
url string
@ -95,37 +95,37 @@ func (s *IntegrationTestSuite) TestQueryAuthorizationGRPC() {
}{
{
"fail invalid granter address",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?method_name=%s", baseURL, "invalid_granter", s.grantee.String(), typeMsgSend),
fmt.Sprintf(grantsURL, "invalid_granter", s.grantee.String(), typeMsgSend),
true,
"decoding bech32 failed: invalid index of 1: invalid request",
},
{
"fail invalid grantee address",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?method_name=%s", baseURL, val.Address.String(), "invalid_grantee", typeMsgSend),
fmt.Sprintf(grantsURL, val.Address.String(), "invalid_grantee", typeMsgSend),
true,
"decoding bech32 failed: invalid index of 1: invalid request",
},
{
"fail with empty granter",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?method_name=%s", baseURL, "", s.grantee.String(), typeMsgSend),
fmt.Sprintf(grantsURL, "", s.grantee.String(), typeMsgSend),
true,
"Not Implemented",
"empty address string is not allowed: invalid request",
},
{
"fail with empty grantee",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?method_name=%s", baseURL, val.Address.String(), "", typeMsgSend),
fmt.Sprintf(grantsURL, val.Address.String(), "", typeMsgSend),
true,
"Not Implemented",
"empty address string is not allowed: invalid request",
},
{
"fail invalid msg-type",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?method_name=%s", baseURL, val.Address.String(), s.grantee.String(), "invalidMsg"),
fmt.Sprintf(grantsURL, val.Address.String(), s.grantee.String(), "invalidMsg"),
true,
"rpc error: code = NotFound desc = no authorization found for invalidMsg type: key not found",
},
{
"valid query",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?method_name=%s", baseURL, val.Address.String(), s.grantee.String(), typeMsgSend),
fmt.Sprintf(grantsURL, val.Address.String(), s.grantee.String(), typeMsgSend),
false,
"",
},
@ -134,72 +134,50 @@ func (s *IntegrationTestSuite) TestQueryAuthorizationGRPC() {
tc := tc
s.Run(tc.name, func() {
resp, _ := rest.GetRequest(tc.url)
require := s.Require()
if tc.expectErr {
s.Require().Contains(string(resp), tc.errorMsg)
require.Contains(string(resp), tc.errorMsg)
} else {
var authorization types.QueryAuthorizationResponse
err := val.ClientCtx.JSONCodec.UnmarshalJSON(resp, &authorization)
s.Require().NoError(err)
authorization.Authorization.UnpackInterfaces(val.ClientCtx.InterfaceRegistry)
auth := authorization.Authorization.GetAuthorizationGrant()
s.Require().Equal(auth.MethodName(), banktypes.SendAuthorization{}.MethodName())
var g authz.QueryGrantsResponse
err := val.ClientCtx.JSONCodec.UnmarshalJSON(resp, &g)
require.NoError(err)
require.Len(g.Grants, 1)
g.Grants[0].UnpackInterfaces(val.ClientCtx.InterfaceRegistry)
auth := g.Grants[0].GetAuthorization()
require.Equal(auth.MsgTypeURL(), banktypes.SendAuthorization{}.MsgTypeURL())
}
})
}
}
func (s *IntegrationTestSuite) TestQueryAuthorizationsGRPC() {
func (s *IntegrationTestSuite) TestQueryGrantsGRPC() {
val := s.network.Validators[0]
baseURL := val.APIAddress
grantsURL := val.APIAddress + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s"
testCases := []struct {
name string
url string
expectErr bool
errMsg string
preRun func()
postRun func(*types.QueryAuthorizationsResponse)
postRun func(*authz.QueryGrantsResponse)
}{
{
"fail invalid granter address",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, "invalid_granter", s.grantee.String()),
true,
"decoding bech32 failed: invalid index of 1: invalid request",
func() {},
func(_ *types.QueryAuthorizationsResponse) {},
},
{
"fail invalid grantee address",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), "invalid_grantee"),
true,
"decoding bech32 failed: invalid index of 1: invalid request",
func() {},
func(_ *types.QueryAuthorizationsResponse) {},
},
{
"fail empty grantee address",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, "", "invalid_grantee"),
true,
"Not Implemented",
func() {},
func(_ *types.QueryAuthorizationsResponse) {},
},
{
"valid query: expect single grant",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), s.grantee.String()),
fmt.Sprintf(grantsURL, val.Address.String(), s.grantee.String()),
false,
"",
func() {},
func(authorizations *types.QueryAuthorizationsResponse) {
s.Require().Len(authorizations.Authorizations), 1)
func(g *authz.QueryGrantsResponse) {
s.Require().Len(g.Grants, 1)
},
},
{
"valid query: expect two grants",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), s.grantee.String()),
fmt.Sprintf(grantsURL, val.Address.String(), s.grantee.String()),
false,
"",
func() {
_, err := authztestutil.ExecGrantAuthorization(val, []string{
_, err := authztestutil.ExecGrant(val, []string{
s.grantee.String(),
"generic",
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
@ -211,28 +189,28 @@ func (s *IntegrationTestSuite) TestQueryAuthorizationsGRPC() {
})
s.Require().NoError(err)
},
func(authorizations *types.QueryAuthorizationsResponse) {
s.Require().Equal(len(authorizations.Authorizations), 2)
func(g *authz.QueryGrantsResponse) {
s.Require().Len(g.Grants, 2)
},
},
{
"valid query: expect single grant with pagination",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants?pagination.limit=1", baseURL, val.Address.String(), s.grantee.String()),
fmt.Sprintf(grantsURL+"&pagination.limit=1", val.Address.String(), s.grantee.String()),
false,
"",
func() {},
func(authorizations *types.QueryAuthorizationsResponse) {
s.Require().Equal(len(authorizations.Authorizations), 1)
func(g *authz.QueryGrantsResponse) {
s.Require().Len(g.Grants, 1)
},
},
{
"valid query: expect two grants with pagination",
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants?pagination.limit=2", baseURL, val.Address.String(), s.grantee.String()),
fmt.Sprintf(grantsURL+"&pagination.limit=2", val.Address.String(), s.grantee.String()),
false,
"",
func() {},
func(authorizations *types.QueryAuthorizationsResponse) {
s.Require().Equal(len(authorizations.Authorizations), 2)
func(g *authz.QueryGrantsResponse) {
s.Require().Len(g.Grants, 2)
},
},
}
@ -244,7 +222,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorizationsGRPC() {
if tc.expectErr {
s.Require().Contains(string(resp), tc.errMsg)
} else {
var authorizations types.QueryAuthorizationsResponse
var authorizations authz.QueryGrantsResponse
err := val.ClientCtx.JSONCodec.UnmarshalJSON(resp, &authorizations)
s.Require().NoError(err)
tc.postRun(&authorizations)

View File

@ -5,9 +5,9 @@ package testutil
import (
"testing"
"github.com/cosmos/cosmos-sdk/testutil/network"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/testutil/network"
)
func TestIntegrationTestSuite(t *testing.T) {

View File

@ -10,9 +10,8 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
"github.com/cosmos/cosmos-sdk/x/authz/types"
)
func (s *IntegrationTestSuite) TestQueryAuthorizations() {
@ -21,7 +20,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorizations() {
grantee := s.grantee
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -77,7 +76,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorizations() {
tc := tc
s.Run(tc.name, func() {
cmd := cli.GetCmdQueryAuthorizations()
cmd := cli.GetCmdQueryGrants()
clientCtx := val.ClientCtx
resp, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
@ -85,7 +84,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorizations() {
s.Require().Contains(string(resp.Bytes()), tc.expErrMsg)
} else {
s.Require().NoError(err)
var grants types.QueryAuthorizationsResponse
var grants authz.QueryGrantsResponse
err = val.ClientCtx.JSONCodec.UnmarshalJSON(resp.Bytes(), &grants)
s.Require().NoError(err)
}
@ -99,7 +98,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorization() {
grantee := s.grantee
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -169,7 +168,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorization() {
tc := tc
s.Run(tc.name, func() {
cmd := cli.GetCmdQueryAuthorization()
cmd := cli.GetCmdQueryGrants()
clientCtx := val.ClientCtx
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {

View File

@ -7,7 +7,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
)
func ExecGrantAuthorization(val *network.Validator, args []string) (testutil.BufferWriter, error) {
func ExecGrant(val *network.Validator, args []string) (testutil.BufferWriter, error) {
cmd := cli.NewCmdGrantAuthorization()
clientCtx := val.ClientCtx
return clitestutil.ExecTestCLICmd(clientCtx, cmd, args)

View File

@ -77,7 +77,7 @@ func (s *IntegrationTestSuite) TearDownSuite() {
s.network.Cleanup()
}
var typeMsgSend = bank.SendAuthorization{}.MethodName()
var typeMsgSend = bank.SendAuthorization{}.MsgTypeURL()
var typeMsgVote = sdk.MsgTypeURL(&govtypes.MsgVote{})
func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() {
@ -264,7 +264,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() {
tc := tc
s.Run(tc.name, func() {
clientCtx := val.ClientCtx
out, err := ExecGrantAuthorization(
out, err := ExecGrant(
val,
tc.args,
)
@ -293,7 +293,7 @@ func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
// send-authorization
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -309,7 +309,7 @@ func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
s.Require().NoError(err)
// generic-authorization
_, err = ExecGrantAuthorization(
_, err = ExecGrant(
val,
[]string{
grantee.String(),
@ -407,7 +407,7 @@ func (s *IntegrationTestSuite) TestExecAuthorizationWithExpiration() {
grantee := s.grantee
tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix()
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -447,7 +447,7 @@ func (s *IntegrationTestSuite) TestNewExecGenericAuthorized() {
grantee := s.grantee
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -536,7 +536,7 @@ func (s *IntegrationTestSuite) TestNewExecGrantAuthorized() {
grantee := s.grantee
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -621,7 +621,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
grantee := s.grantee
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -713,7 +713,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
}
// test delegate no spend-limit
_, err = ExecGrantAuthorization(
_, err = ExecGrant(
val,
[]string{
grantee.String(),
@ -790,7 +790,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
}
// test delegating to denied validator
_, err = ExecGrantAuthorization(
_, err = ExecGrant(
val,
[]string{
grantee.String(),
@ -825,7 +825,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() {
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
// granting undelegate msg authorization
_, err := ExecGrantAuthorization(
_, err := ExecGrant(
val,
[]string{
grantee.String(),
@ -931,7 +931,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() {
}
// grant undelegate authorization without limit
_, err = ExecGrantAuthorization(
_, err = ExecGrant(
val,
[]string{
grantee.String(),

24
x/authz/codec.go Normal file
View File

@ -0,0 +1,24 @@
package authz
import (
types "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
)
// RegisterInterfaces registers the interfaces types with the interface registry
func RegisterInterfaces(registry types.InterfaceRegistry) {
registry.RegisterImplementations((*sdk.Msg)(nil),
&MsgGrant{},
&MsgRevoke{},
&MsgExec{},
)
registry.RegisterInterface(
"cosmos.v1beta1.Authorization",
(*Authorization)(nil),
&GenericAuthorization{},
)
msgservice.RegisterMsgServiceDesc(registry, MsgServiceDesc())
}

View File

@ -1,4 +1,4 @@
package types
package authz
import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

700
x/authz/event.pb.go Normal file
View File

@ -0,0 +1,700 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/authz/v1beta1/event.proto
package authz
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// EventGrant is emitted on Msg/Grant
type EventGrant struct {
// Msg type URL for which an autorization is granted
MsgTypeUrl string `protobuf:"bytes,2,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"`
// Granter account address
Granter string `protobuf:"bytes,3,opt,name=granter,proto3" json:"granter,omitempty"`
// Grantee account address
Grantee string `protobuf:"bytes,4,opt,name=grantee,proto3" json:"grantee,omitempty"`
}
func (m *EventGrant) Reset() { *m = EventGrant{} }
func (m *EventGrant) String() string { return proto.CompactTextString(m) }
func (*EventGrant) ProtoMessage() {}
func (*EventGrant) Descriptor() ([]byte, []int) {
return fileDescriptor_1f88cbc71a8baf1f, []int{0}
}
func (m *EventGrant) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EventGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EventGrant.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *EventGrant) XXX_Merge(src proto.Message) {
xxx_messageInfo_EventGrant.Merge(m, src)
}
func (m *EventGrant) XXX_Size() int {
return m.Size()
}
func (m *EventGrant) XXX_DiscardUnknown() {
xxx_messageInfo_EventGrant.DiscardUnknown(m)
}
var xxx_messageInfo_EventGrant proto.InternalMessageInfo
func (m *EventGrant) GetMsgTypeUrl() string {
if m != nil {
return m.MsgTypeUrl
}
return ""
}
func (m *EventGrant) GetGranter() string {
if m != nil {
return m.Granter
}
return ""
}
func (m *EventGrant) GetGrantee() string {
if m != nil {
return m.Grantee
}
return ""
}
// EventRevoke is emitted on Msg/Revoke
type EventRevoke struct {
// Msg type URL for which an autorization is revoked
MsgTypeUrl string `protobuf:"bytes,2,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"`
// Granter account address
Granter string `protobuf:"bytes,3,opt,name=granter,proto3" json:"granter,omitempty"`
// Grantee account address
Grantee string `protobuf:"bytes,4,opt,name=grantee,proto3" json:"grantee,omitempty"`
}
func (m *EventRevoke) Reset() { *m = EventRevoke{} }
func (m *EventRevoke) String() string { return proto.CompactTextString(m) }
func (*EventRevoke) ProtoMessage() {}
func (*EventRevoke) Descriptor() ([]byte, []int) {
return fileDescriptor_1f88cbc71a8baf1f, []int{1}
}
func (m *EventRevoke) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EventRevoke) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EventRevoke.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *EventRevoke) XXX_Merge(src proto.Message) {
xxx_messageInfo_EventRevoke.Merge(m, src)
}
func (m *EventRevoke) XXX_Size() int {
return m.Size()
}
func (m *EventRevoke) XXX_DiscardUnknown() {
xxx_messageInfo_EventRevoke.DiscardUnknown(m)
}
var xxx_messageInfo_EventRevoke proto.InternalMessageInfo
func (m *EventRevoke) GetMsgTypeUrl() string {
if m != nil {
return m.MsgTypeUrl
}
return ""
}
func (m *EventRevoke) GetGranter() string {
if m != nil {
return m.Granter
}
return ""
}
func (m *EventRevoke) GetGrantee() string {
if m != nil {
return m.Grantee
}
return ""
}
func init() {
proto.RegisterType((*EventGrant)(nil), "cosmos.authz.v1beta1.EventGrant")
proto.RegisterType((*EventRevoke)(nil), "cosmos.authz.v1beta1.EventRevoke")
}
func init() { proto.RegisterFile("cosmos/authz/v1beta1/event.proto", fileDescriptor_1f88cbc71a8baf1f) }
var fileDescriptor_1f88cbc71a8baf1f = []byte{
// 210 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x2c, 0x2d, 0xc9, 0xa8, 0xd2, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34,
0xd4, 0x4f, 0x2d, 0x4b, 0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x81, 0xa8,
0xd0, 0x03, 0xab, 0xd0, 0x83, 0xaa, 0x50, 0x4a, 0xe2, 0xe2, 0x72, 0x05, 0x29, 0x72, 0x2f, 0x4a,
0xcc, 0x2b, 0x11, 0x52, 0xe0, 0xe2, 0xc9, 0x2d, 0x4e, 0x8f, 0x2f, 0xa9, 0x2c, 0x48, 0x8d, 0x2f,
0x2d, 0xca, 0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0c, 0xe2, 0xca, 0x2d, 0x4e, 0x0f, 0xa9, 0x2c,
0x48, 0x0d, 0x2d, 0xca, 0x11, 0x92, 0xe0, 0x62, 0x4f, 0x07, 0x29, 0x4d, 0x2d, 0x92, 0x60, 0x06,
0x4b, 0xc2, 0xb8, 0x08, 0x99, 0x54, 0x09, 0x16, 0x64, 0x99, 0x54, 0xa5, 0x64, 0x2e, 0x6e, 0xb0,
0x1d, 0x41, 0xa9, 0x65, 0xf9, 0xd9, 0xa9, 0xb4, 0xb1, 0xc4, 0xc9, 0xee, 0xc4, 0x23, 0x39, 0xc6,
0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39,
0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x54, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3,
0x73, 0xf5, 0xa1, 0xa1, 0x04, 0xa1, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x2b, 0x20, 0x41, 0x96, 0xc4,
0x06, 0x0e, 0x25, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x98, 0xf0, 0x6c, 0x35, 0x49, 0x01,
0x00, 0x00,
}
func (m *EventGrant) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *EventGrant) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EventGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Grantee) > 0 {
i -= len(m.Grantee)
copy(dAtA[i:], m.Grantee)
i = encodeVarintEvent(dAtA, i, uint64(len(m.Grantee)))
i--
dAtA[i] = 0x22
}
if len(m.Granter) > 0 {
i -= len(m.Granter)
copy(dAtA[i:], m.Granter)
i = encodeVarintEvent(dAtA, i, uint64(len(m.Granter)))
i--
dAtA[i] = 0x1a
}
if len(m.MsgTypeUrl) > 0 {
i -= len(m.MsgTypeUrl)
copy(dAtA[i:], m.MsgTypeUrl)
i = encodeVarintEvent(dAtA, i, uint64(len(m.MsgTypeUrl)))
i--
dAtA[i] = 0x12
}
return len(dAtA) - i, nil
}
func (m *EventRevoke) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *EventRevoke) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EventRevoke) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Grantee) > 0 {
i -= len(m.Grantee)
copy(dAtA[i:], m.Grantee)
i = encodeVarintEvent(dAtA, i, uint64(len(m.Grantee)))
i--
dAtA[i] = 0x22
}
if len(m.Granter) > 0 {
i -= len(m.Granter)
copy(dAtA[i:], m.Granter)
i = encodeVarintEvent(dAtA, i, uint64(len(m.Granter)))
i--
dAtA[i] = 0x1a
}
if len(m.MsgTypeUrl) > 0 {
i -= len(m.MsgTypeUrl)
copy(dAtA[i:], m.MsgTypeUrl)
i = encodeVarintEvent(dAtA, i, uint64(len(m.MsgTypeUrl)))
i--
dAtA[i] = 0x12
}
return len(dAtA) - i, nil
}
func encodeVarintEvent(dAtA []byte, offset int, v uint64) int {
offset -= sovEvent(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *EventGrant) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.MsgTypeUrl)
if l > 0 {
n += 1 + l + sovEvent(uint64(l))
}
l = len(m.Granter)
if l > 0 {
n += 1 + l + sovEvent(uint64(l))
}
l = len(m.Grantee)
if l > 0 {
n += 1 + l + sovEvent(uint64(l))
}
return n
}
func (m *EventRevoke) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.MsgTypeUrl)
if l > 0 {
n += 1 + l + sovEvent(uint64(l))
}
l = len(m.Granter)
if l > 0 {
n += 1 + l + sovEvent(uint64(l))
}
l = len(m.Grantee)
if l > 0 {
n += 1 + l + sovEvent(uint64(l))
}
return n
}
func sovEvent(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozEvent(x uint64) (n int) {
return sovEvent(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *EventGrant) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: EventGrant: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EventGrant: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MsgTypeUrl", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthEvent
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthEvent
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.MsgTypeUrl = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Granter", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthEvent
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthEvent
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Granter = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Grantee", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthEvent
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthEvent
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Grantee = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipEvent(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthEvent
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *EventRevoke) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: EventRevoke: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EventRevoke: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MsgTypeUrl", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthEvent
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthEvent
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.MsgTypeUrl = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Granter", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthEvent
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthEvent
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Granter = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Grantee", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthEvent
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthEvent
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Grantee = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipEvent(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthEvent
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipEvent(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEvent
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEvent
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEvent
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthEvent
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupEvent
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthEvent
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthEvent = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowEvent = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupEvent = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,13 +1,13 @@
package types
package authz
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
// AccountKeeper defines the expected account keeper (noalias)
type AccountKeeper interface {
GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
}
// BankKeeper defines the expected interface needed to retrieve account balances.

View File

@ -1,23 +0,0 @@
package exported
import (
"github.com/gogo/protobuf/proto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Authorization represents the interface of various Authorization types.
type Authorization interface {
proto.Message
// MethodName returns the fully-qualified Msg service method name as described in ADR 031.
MethodName() string
// Accept determines whether this grant permits the provided sdk.ServiceMsg to be performed, and if
// so provides an upgraded authorization instance.
Accept(ctx sdk.Context, msg sdk.Msg) (updated Authorization, delete bool, err error)
// ValidateBasic does a simple validation check that
// doesn't require access to any other information.
ValidateBasic() error
}

View File

@ -0,0 +1,31 @@
package authz
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
_ Authorization = &GenericAuthorization{}
)
// NewGenericAuthorization creates a new GenericAuthorization object.
func NewGenericAuthorization(msgTypeURL string) *GenericAuthorization {
return &GenericAuthorization{
Msg: msgTypeURL,
}
}
// MsgTypeURL implements Authorization.MsgTypeURL.
func (a GenericAuthorization) MsgTypeURL() string {
return a.Msg
}
// Accept implements Authorization.Accept.
func (a GenericAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (AcceptResponse, error) {
return AcceptResponse{Accept: true}, nil
}
// ValidateBasic implements Authorization.ValidateBasic.
func (a GenericAuthorization) ValidateBasic() error {
return nil
}

View File

@ -0,0 +1,17 @@
package authz_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
func TestGenericAuthorization(t *testing.T) {
t.Log("verify ValidateBasic returns nil for service msg")
a := authz.NewGenericAuthorization(banktypes.SendAuthorization{}.MsgTypeURL())
require.NoError(t, a.ValidateBasic())
require.Equal(t, banktypes.SendAuthorization{}.MsgTypeURL(), a.Msg)
}

View File

@ -1,48 +1,41 @@
package authz
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
"github.com/cosmos/cosmos-sdk/x/authz/types"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
)
// InitGenesis new authz genesis
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState) {
for _, entry := range data.Authorization {
grantee, err := sdk.AccAddressFromBech32(entry.Grantee)
if err != nil {
panic(err)
}
granter, err := sdk.AccAddressFromBech32(entry.Granter)
if err != nil {
panic(err)
}
authorization, ok := entry.Authorization.GetCachedValue().(exported.Authorization)
if !ok {
panic("expected authorization")
}
err = keeper.Grant(ctx, grantee, granter, authorization, entry.Expiration)
if err != nil {
panic(err)
}
// NewGenesisState creates new GenesisState object
func NewGenesisState(entries []GrantAuthorization) *GenesisState {
return &GenesisState{
Authorization: entries,
}
}
// ExportGenesis returns a GenesisState for a given context and keeper.
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState {
var entries []types.GrantAuthorization
keeper.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
exp := grant.Expiration
entries = append(entries, types.GrantAuthorization{
Granter: granter.String(),
Grantee: grantee.String(),
Expiration: exp,
Authorization: grant.Authorization,
})
return false
})
return types.NewGenesisState(entries)
// ValidateGenesis check the given genesis state has no integrity issues
func ValidateGenesis(data GenesisState) error {
return nil
}
// DefaultGenesisState - Return a default genesis state
func DefaultGenesisState() *GenesisState {
return &GenesisState{}
}
var _ cdctypes.UnpackInterfacesMessage = GenesisState{}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (data GenesisState) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
for _, a := range data.Authorization {
err := a.UnpackInterfaces(unpacker)
if err != nil {
return err
}
}
return nil
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg GrantAuthorization) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
var a Authorization
return unpacker.UnpackAny(msg.Authorization, &a)
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/authz/v1beta1/genesis.proto
package types
package authz
import (
fmt "fmt"
@ -153,29 +153,29 @@ func init() {
}
var fileDescriptor_4c2fbb971da7c892 = []byte{
// 340 bytes of a gzipped FileDescriptorProto
// 337 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xbb, 0x6e, 0xc2, 0x30,
0x14, 0x8d, 0x0b, 0xea, 0xc3, 0x94, 0xa1, 0x11, 0x43, 0xca, 0x10, 0x10, 0x53, 0x54, 0x09, 0x5b,
0xd0, 0x2f, 0x20, 0x42, 0x62, 0xea, 0x42, 0x99, 0xba, 0x54, 0x0e, 0xb8, 0x26, 0x6a, 0x13, 0x47,
0xb1, 0xa9, 0x80, 0xaf, 0xe0, 0x63, 0xfa, 0x11, 0xa8, 0x13, 0x63, 0x97, 0x3e, 0x04, 0x3f, 0x52,
0xc5, 0x76, 0x54, 0x08, 0x9d, 0x72, 0x6f, 0xce, 0xb9, 0xe7, 0x1c, 0x5f, 0x1b, 0xb6, 0xc6, 0x5c,
0x44, 0x5c, 0x60, 0x32, 0x93, 0xd3, 0x25, 0x7e, 0xed, 0x04, 0x54, 0x92, 0x0e, 0x66, 0x34, 0xa6,
0x22, 0x14, 0x28, 0x49, 0xb9, 0xe4, 0x76, 0x4d, 0x73, 0x90, 0xe2, 0x20, 0xc3, 0xa9, 0x37, 0x18,
0xe7, 0xec, 0x85, 0x62, 0xc5, 0x09, 0x66, 0x4f, 0x58, 0x86, 0x11, 0x15, 0x92, 0x44, 0x89, 0x1e,
0xab, 0x5f, 0x17, 0x09, 0x24, 0x5e, 0x18, 0xa8, 0xc6, 0x38, 0xe3, 0xaa, 0xc4, 0x59, 0x95, 0x0f,
0x68, 0x9f, 0x47, 0x0d, 0x18, 0x53, 0xd5, 0xb4, 0x26, 0xf0, 0x72, 0xa0, 0x33, 0xdd, 0x4b, 0x22,
0xa9, 0x3d, 0x82, 0xd5, 0x2c, 0x0d, 0x4f, 0xc3, 0x25, 0x91, 0x21, 0x8f, 0x1d, 0xd0, 0x2c, 0x79,
0x95, 0xae, 0x87, 0xfe, 0x8b, 0x8a, 0x06, 0x29, 0x89, 0x65, 0x6f, 0x9f, 0xef, 0x97, 0xd7, 0x5f,
0x0d, 0x6b, 0x78, 0x28, 0xd2, 0xfa, 0x04, 0xd0, 0x3e, 0xe6, 0xda, 0x0e, 0x3c, 0x63, 0xd9, 0x5f,
0x9a, 0x3a, 0xa0, 0x09, 0xbc, 0x8b, 0x61, 0xde, 0xfe, 0x21, 0xd4, 0x39, 0xd9, 0x47, 0xa8, 0x7d,
0x57, 0x0c, 0x58, 0x6a, 0x02, 0xaf, 0xd2, 0xad, 0x21, 0xbd, 0x14, 0x94, 0x2f, 0x05, 0xf5, 0xe2,
0x85, 0x7f, 0xf5, 0xfe, 0xd6, 0xae, 0x1e, 0x78, 0x16, 0x92, 0xd9, 0x7d, 0x08, 0xe9, 0x3c, 0x09,
0x53, 0xad, 0x55, 0x56, 0x5a, 0xf5, 0x23, 0xad, 0x51, 0x7e, 0x03, 0xfe, 0x79, 0x76, 0xbc, 0xd5,
0x77, 0x03, 0x0c, 0xf7, 0xe6, 0xfc, 0xfe, 0x7a, 0xeb, 0x82, 0xcd, 0xd6, 0x05, 0x3f, 0x5b, 0x17,
0xac, 0x76, 0xae, 0xb5, 0xd9, 0xb9, 0xd6, 0xc7, 0xce, 0xb5, 0x1e, 0x6e, 0x58, 0x28, 0xa7, 0xb3,
0x00, 0x8d, 0x79, 0x64, 0x16, 0x6f, 0x3e, 0x6d, 0x31, 0x79, 0xc6, 0x73, 0xf3, 0x3c, 0xe4, 0x22,
0xa1, 0x22, 0x38, 0x55, 0x7e, 0xb7, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x94, 0xbe, 0x5b, 0xfa,
0x3b, 0x02, 0x00, 0x00,
0x14, 0x8d, 0x0b, 0xea, 0xc3, 0x94, 0xa1, 0x11, 0x43, 0xca, 0x60, 0x10, 0xea, 0x90, 0x05, 0x5b,
0xd0, 0xbd, 0x12, 0x51, 0x25, 0xa6, 0x2e, 0x94, 0xa9, 0x4b, 0xe5, 0x80, 0x6b, 0xac, 0x36, 0x31,
0x8a, 0x4d, 0x05, 0x7c, 0x05, 0x1f, 0xd3, 0x8f, 0x40, 0x9d, 0x18, 0xbb, 0xf4, 0x21, 0xf8, 0x91,
0x2a, 0x76, 0xa2, 0xf2, 0xe8, 0x94, 0x7b, 0x73, 0xce, 0x3d, 0xe7, 0xf8, 0xda, 0xb0, 0x31, 0x90,
0x2a, 0x92, 0x8a, 0xd0, 0x89, 0x1e, 0xcd, 0xc9, 0x6b, 0x2b, 0x64, 0x9a, 0xb6, 0x08, 0x67, 0x31,
0x53, 0x42, 0xe1, 0x71, 0x22, 0xb5, 0x74, 0x2b, 0x96, 0x83, 0x0d, 0x07, 0x67, 0x9c, 0x6a, 0x8d,
0x4b, 0xc9, 0x5f, 0x18, 0x31, 0x9c, 0x70, 0xf2, 0x44, 0xb4, 0x88, 0x98, 0xd2, 0x34, 0x1a, 0xdb,
0xb1, 0xea, 0xe5, 0x3e, 0x81, 0xc6, 0xb3, 0x0c, 0xaa, 0x70, 0xc9, 0xa5, 0x29, 0x49, 0x5a, 0xe5,
0x03, 0xd6, 0xe7, 0xd1, 0x02, 0x99, 0xa9, 0x69, 0x1a, 0x43, 0x78, 0xde, 0xb5, 0x99, 0xee, 0x35,
0xd5, 0xcc, 0xed, 0xc3, 0x72, 0x9a, 0x46, 0x26, 0x62, 0x4e, 0xb5, 0x90, 0xb1, 0x07, 0xea, 0x05,
0xbf, 0xd4, 0xf6, 0xf1, 0x7f, 0x51, 0x71, 0x37, 0xa1, 0xb1, 0xee, 0x6c, 0xf3, 0x83, 0xe2, 0xf2,
0xab, 0xe6, 0xf4, 0x76, 0x45, 0x1a, 0x9f, 0x00, 0xba, 0x87, 0x5c, 0xd7, 0x83, 0x27, 0x3c, 0xfd,
0xcb, 0x12, 0x0f, 0xd4, 0x81, 0x7f, 0xd6, 0xcb, 0xdb, 0x3f, 0x84, 0x79, 0x47, 0xdb, 0x08, 0x73,
0xef, 0xf6, 0x03, 0x16, 0xea, 0xc0, 0x2f, 0xb5, 0x2b, 0xd8, 0x2e, 0x05, 0xe7, 0x4b, 0xc1, 0x9d,
0x78, 0x16, 0x5c, 0xbc, 0xbf, 0x35, 0xcb, 0x3b, 0x9e, 0x7b, 0xc9, 0xdc, 0x5b, 0x08, 0xd9, 0x74,
0x2c, 0x12, 0xab, 0x55, 0x34, 0x5a, 0xd5, 0x03, 0xad, 0x7e, 0x7e, 0x03, 0xc1, 0x69, 0x7a, 0xbc,
0xc5, 0x77, 0x0d, 0xf4, 0xb6, 0xe6, 0x82, 0x9b, 0xe5, 0x1a, 0x81, 0xd5, 0x1a, 0x81, 0x9f, 0x35,
0x02, 0x8b, 0x0d, 0x72, 0x56, 0x1b, 0xe4, 0x7c, 0x6c, 0x90, 0xf3, 0x70, 0xc5, 0x85, 0x1e, 0x4d,
0x42, 0x3c, 0x90, 0x51, 0xb6, 0xf8, 0xec, 0xd3, 0x54, 0xc3, 0x67, 0x32, 0xb5, 0xcf, 0x23, 0x3c,
0x36, 0x4e, 0xd7, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7c, 0xdb, 0x6c, 0xcb, 0x35, 0x02, 0x00,
0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {

View File

@ -1,4 +1,4 @@
package authz_test
package keeper_test
import (
"testing"
@ -10,7 +10,6 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
authz "github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
)
@ -42,15 +41,15 @@ func (suite *GenesisTestSuite) TestImportExportGenesis() {
now := suite.ctx.BlockHeader().Time
grant := &bank.SendAuthorization{SpendLimit: coins}
err := suite.keeper.Grant(suite.ctx, granteeAddr, granterAddr, grant, now.Add(time.Hour))
err := suite.keeper.SaveGrant(suite.ctx, granteeAddr, granterAddr, grant, now.Add(time.Hour))
suite.Require().NoError(err)
genesis := authz.ExportGenesis(suite.ctx, suite.keeper)
genesis := suite.keeper.ExportGenesis(suite.ctx)
// Clear keeper
suite.keeper.Revoke(suite.ctx, granteeAddr, granterAddr, grant.MethodName())
suite.keeper.DeleteGrant(suite.ctx, granteeAddr, granterAddr, grant.MsgTypeURL())
authz.InitGenesis(suite.ctx, suite.keeper, genesis)
newGenesis := authz.ExportGenesis(suite.ctx, suite.keeper)
suite.keeper.InitGenesis(suite.ctx, genesis)
newGenesis := suite.keeper.ExportGenesis(suite.ctx)
suite.Require().Equal(genesis, newGenesis)
}

View File

@ -13,39 +13,56 @@ import (
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
)
var _ types.QueryServer = Keeper{}
var _ authz.QueryServer = Keeper{}
// Authorizations implements the Query/Authorizations gRPC method.
func (k Keeper) Authorizations(c context.Context, req *types.QueryAuthorizationsRequest) (*types.QueryAuthorizationsResponse, error) {
// Authorizations implements the Query/Grants gRPC method.
func (k Keeper) Grants(c context.Context, req *authz.QueryGrantsRequest) (*authz.QueryGrantsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
granter, err := sdk.AccAddressFromBech32(req.Granter)
if err != nil {
return nil, err
}
grantee, err := sdk.AccAddressFromBech32(req.Grantee)
grantee, err := sdk.AccAddressFromBech32(req.Grantee)
if err != nil {
return nil, err
}
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
key := types.GetAuthorizationStoreKey(grantee, granter, "")
key := grantStoreKey(grantee, granter, "")
authStore := prefix.NewStore(store, key)
var authorizations []*types.AuthorizationGrant
if req.MsgTypeUrl != "" {
authorization, expiration := k.GetCleanAuthorization(ctx, grantee, granter, req.MsgTypeUrl)
if authorization == nil {
return nil, status.Errorf(codes.NotFound, "no authorization found for %s type", req.MsgTypeUrl)
}
authorizationAny, err := codectypes.NewAnyWithValue(authorization)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
return &authz.QueryGrantsResponse{
Grants: []*authz.Grant{{
Authorization: authorizationAny,
Expiration: expiration,
}},
}, nil
}
var authorizations []*authz.Grant
pageRes, err := query.FilteredPaginate(authStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) {
auth, err := unmarshalAuthorization(k.cdc, value)
if err != nil {
return false, err
}
auth1 := auth.GetAuthorizationGrant()
auth1 := auth.GetAuthorization()
if accumulate {
msg, ok := auth1.(proto.Message)
if !ok {
@ -56,7 +73,7 @@ func (k Keeper) Authorizations(c context.Context, req *types.QueryAuthorizations
if err != nil {
return false, status.Errorf(codes.Internal, err.Error())
}
authorizations = append(authorizations, &types.AuthorizationGrant{
authorizations = append(authorizations, &authz.Grant{
Authorization: authorizationAny,
Expiration: auth.Expiration,
})
@ -67,54 +84,14 @@ func (k Keeper) Authorizations(c context.Context, req *types.QueryAuthorizations
return nil, err
}
return &types.QueryAuthorizationsResponse{
Authorizations: authorizations,
Pagination: pageRes,
return &authz.QueryGrantsResponse{
Grants: authorizations,
Pagination: pageRes,
}, nil
}
// unmarshal an authorization from a store value
func unmarshalAuthorization(cdc codec.BinaryCodec, value []byte) (v types.AuthorizationGrant, err error) {
func unmarshalAuthorization(cdc codec.BinaryCodec, value []byte) (v authz.Grant, err error) {
err = cdc.Unmarshal(value, &v)
return v, err
}
// Authorization implements the Query/Authorization gRPC method.
func (k Keeper) Authorization(c context.Context, req *types.QueryAuthorizationRequest) (*types.QueryAuthorizationResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
if req.MethodName == "" {
return nil, status.Errorf(codes.InvalidArgument, "empty method-name")
}
granter, err := sdk.AccAddressFromBech32(req.Granter)
if err != nil {
return nil, err
}
grantee, err := sdk.AccAddressFromBech32(req.Grantee)
if err != nil {
return nil, err
}
ctx := sdk.UnwrapSDKContext(c)
authorization, expiration := k.GetOrRevokeAuthorization(ctx, grantee, granter, req.MethodName)
if authorization == nil {
return nil, status.Errorf(codes.NotFound, "no authorization found for %s type", req.MethodName)
}
authorizationAny, err := codectypes.NewAnyWithValue(authorization)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
return &types.QueryAuthorizationResponse{
Authorization: &types.AuthorizationGrant{
Authorization: authorizationAny,
Expiration: expiration,
},
}, nil
}

View File

@ -6,86 +6,90 @@ import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
)
func (suite *TestSuite) TestGRPCQueryAuthorization() {
app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
var (
req *types.QueryAuthorizationRequest
expAuthorization exported.Authorization
req *authz.QueryGrantsRequest
expAuthorization authz.Authorization
)
testCases := []struct {
msg string
malleate func()
expPass bool
postTest func(res *types.QueryAuthorizationResponse)
malleate func(require *require.Assertions)
expError string
postTest func(require *require.Assertions, res *authz.QueryGrantsResponse)
}{
{
"fail invalid granter addr",
func() {
req = &types.QueryAuthorizationRequest{}
func(require *require.Assertions) {
req = &authz.QueryGrantsRequest{}
},
false,
func(res *types.QueryAuthorizationResponse) {},
"empty address string is not allowed",
func(require *require.Assertions, res *authz.QueryGrantsResponse) {},
},
{
"fail invalid grantee addr",
func() {
req = &types.QueryAuthorizationRequest{
func(require *require.Assertions) {
req = &authz.QueryGrantsRequest{
Granter: addrs[0].String(),
}
},
false,
func(res *types.QueryAuthorizationResponse) {},
"empty address string is not allowed",
func(require *require.Assertions, res *authz.QueryGrantsResponse) {},
},
{
"fail invalid msg-type",
func() {
req = &types.QueryAuthorizationRequest{
Granter: addrs[0].String(),
Grantee: addrs[1].String(),
func(require *require.Assertions) {
req = &authz.QueryGrantsRequest{
Granter: addrs[0].String(),
Grantee: addrs[1].String(),
MsgTypeUrl: "unknown",
}
},
false,
func(res *types.QueryAuthorizationResponse) {},
"no authorization found for unknown type",
func(require *require.Assertions, res *authz.QueryGrantsResponse) {},
},
{
"Success",
func() {
func(require *require.Assertions) {
now := ctx.BlockHeader().Time
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
expAuthorization = &banktypes.SendAuthorization{SpendLimit: newCoins}
err := app.AuthzKeeper.Grant(ctx, addrs[0], addrs[1], expAuthorization, now.Add(time.Hour))
suite.Require().NoError(err)
req = &types.QueryAuthorizationRequest{
err := app.AuthzKeeper.SaveGrant(ctx, addrs[0], addrs[1], expAuthorization, now.Add(time.Hour))
require.NoError(err)
req = &authz.QueryGrantsRequest{
Granter: addrs[1].String(),
Grantee: addrs[0].String(),
MethodName: expAuthorization.MethodName(),
MsgTypeUrl: expAuthorization.MsgTypeURL(),
}
},
true,
func(res *types.QueryAuthorizationResponse) {
var auth exported.Authorization
err := suite.app.InterfaceRegistry().UnpackAny(res.Authorization.Authorization, &auth)
suite.Require().NoError(err)
suite.Require().NotNil(auth)
suite.Require().Equal(auth.String(), expAuthorization.String())
"",
func(require *require.Assertions, res *authz.QueryGrantsResponse) {
var auth authz.Authorization
require.Equal(1, len(res.Grants))
err := suite.app.InterfaceRegistry().UnpackAny(res.Grants[0].Authorization, &auth)
require.NoError(err)
require.NotNil(auth)
require.Equal(auth.String(), expAuthorization.String())
},
},
}
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
result, err := queryClient.Authorization(gocontext.Background(), req)
if testCase.expPass {
suite.Require().NoError(err)
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
require := suite.Require()
tc.malleate(require)
result, err := queryClient.Grants(gocontext.Background(), req)
if tc.expError == "" {
require.NoError(err)
} else {
suite.Require().Error(err)
require.Error(err)
require.Contains(err.Error(), tc.expError)
}
testCase.postTest(result)
tc.postTest(require, result)
})
}
}
@ -93,32 +97,32 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() {
func (suite *TestSuite) TestGRPCQueryAuthorizations() {
app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
var (
req *types.QueryAuthorizationsRequest
expAuthorization exported.Authorization
req *authz.QueryGrantsRequest
expAuthorization authz.Authorization
)
testCases := []struct {
msg string
malleate func()
expPass bool
postTest func(res *types.QueryAuthorizationsResponse)
postTest func(res *authz.QueryGrantsResponse)
}{
{
"fail invalid granter addr",
func() {
req = &types.QueryAuthorizationsRequest{}
req = &authz.QueryGrantsRequest{}
},
false,
func(res *types.QueryAuthorizationsResponse) {},
func(res *authz.QueryGrantsResponse) {},
},
{
"fail invalid grantee addr",
func() {
req = &types.QueryAuthorizationsRequest{
req = &authz.QueryGrantsRequest{
Granter: addrs[0].String(),
}
},
false,
func(res *types.QueryAuthorizationsResponse) {},
func(res *authz.QueryGrantsResponse) {},
},
{
"Success",
@ -126,18 +130,18 @@ func (suite *TestSuite) TestGRPCQueryAuthorizations() {
now := ctx.BlockHeader().Time
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
expAuthorization = &banktypes.SendAuthorization{SpendLimit: newCoins}
err := app.AuthzKeeper.Grant(ctx, addrs[0], addrs[1], expAuthorization, now.Add(time.Hour))
err := app.AuthzKeeper.SaveGrant(ctx, addrs[0], addrs[1], expAuthorization, now.Add(time.Hour))
suite.Require().NoError(err)
req = &types.QueryAuthorizationsRequest{
req = &authz.QueryGrantsRequest{
Granter: addrs[1].String(),
Grantee: addrs[0].String(),
}
},
true,
func(res *types.QueryAuthorizationsResponse) {
var auth exported.Authorization
suite.Require().Equal(1, len(res.Authorizations))
err := suite.app.InterfaceRegistry().UnpackAny(res.Authorizations[0].Authorization, &auth)
func(res *authz.QueryGrantsResponse) {
var auth authz.Authorization
suite.Require().Equal(1, len(res.Grants))
err := suite.app.InterfaceRegistry().UnpackAny(res.Grants[0].Authorization, &auth)
suite.Require().NoError(err)
suite.Require().NotNil(auth)
suite.Require().Equal(auth.String(), expAuthorization.String())
@ -147,7 +151,7 @@ func (suite *TestSuite) TestGRPCQueryAuthorizations() {
for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()
result, err := queryClient.Authorizations(gocontext.Background(), req)
result, err := queryClient.Grants(gocontext.Background(), req)
if testCase.expPass {
suite.Require().NoError(err)
} else {

View File

@ -13,8 +13,7 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
)
type Keeper struct {
@ -34,13 +33,13 @@ func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryCodec, router *baseapp.Msg
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
return ctx.Logger().With("module", fmt.Sprintf("x/%s", authz.ModuleName))
}
// getAuthorizationGrant returns grant between granter and grantee for the given msg type
func (k Keeper) getAuthorizationGrant(ctx sdk.Context, grantStoreKey []byte) (grant types.AuthorizationGrant, found bool) {
// getGrant returns grant stored at skey.
func (k Keeper) getGrant(ctx sdk.Context, skey []byte) (grant authz.Grant, found bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(grantStoreKey)
bz := store.Get(skey)
if bz == nil {
return grant, false
}
@ -48,16 +47,16 @@ func (k Keeper) getAuthorizationGrant(ctx sdk.Context, grantStoreKey []byte) (gr
return grant, true
}
func (k Keeper) update(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, updated exported.Authorization) error {
grantStoreKey := types.GetAuthorizationStoreKey(grantee, granter, updated.MethodName())
grant, found := k.getAuthorizationGrant(ctx, grantStoreKey)
func (k Keeper) update(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, updated authz.Authorization) error {
skey := grantStoreKey(grantee, granter, updated.MsgTypeURL())
grant, found := k.getGrant(ctx, skey)
if !found {
return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "authorization not found")
return sdkerrors.ErrNotFound.Wrap("authorization not found")
}
msg, ok := updated.(proto.Message)
if !ok {
sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", updated)
sdkerrors.ErrPackAny.Wrapf("cannot proto marshal %T", updated)
}
any, err := codectypes.NewAnyWithValue(msg)
@ -67,7 +66,7 @@ func (k Keeper) update(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccA
grant.Authorization = any
store := ctx.KVStore(k.storeKey)
store.Set(grantStoreKey, k.cdc.MustMarshal(&grant))
store.Set(skey, k.cdc.MustMarshal(&grant))
return nil
}
@ -79,34 +78,35 @@ func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []
for _, msg := range msgs {
signers := msg.GetSigners()
if len(signers) != 1 {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "authorization can be given to msg with only one signer")
return nil, sdkerrors.ErrInvalidRequest.Wrap("authorization can be given to msg with only one signer")
}
granter := signers[0]
// if granter != grantee then check authorization.Accept, otherwise we implicitly accept.
if !granter.Equals(grantee) {
authorization, _ := k.GetOrRevokeAuthorization(ctx, grantee, granter, sdk.MsgTypeURL(msg))
authorization, _ := k.GetCleanAuthorization(ctx, grantee, granter, sdk.MsgTypeURL(msg))
if authorization == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "authorization not found")
return nil, sdkerrors.ErrUnauthorized.Wrap("authorization not found")
}
updated, del, err := authorization.Accept(ctx, msg)
resp, err := authorization.Accept(ctx, msg)
if err != nil {
return nil, err
}
if del {
err = k.Revoke(ctx, grantee, granter, sdk.MsgTypeURL(msg))
if err != nil {
return nil, err
}
} else if updated != nil {
err = k.update(ctx, grantee, granter, updated)
if err != nil {
return nil, err
}
if resp.Delete {
err = k.DeleteGrant(ctx, grantee, granter, sdk.MsgTypeURL(msg))
} else if resp.Updated != nil {
err = k.update(ctx, grantee, granter, resp.Updated)
}
if err != nil {
return nil, err
}
if !resp.Accept {
return nil, sdkerrors.ErrUnauthorized
}
}
handler := k.router.Handler(msg)
if handler == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s", sdk.MsgTypeURL(msg))
return nil, sdkerrors.ErrUnknownRequest.Wrapf("unrecognized message route: %s", sdk.MsgTypeURL(msg))
}
msgResult, err = handler(ctx, msg)
@ -118,97 +118,128 @@ func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []
return msgResult, nil
}
// Grant method grants the provided authorization to the grantee on the granter's account with the provided expiration
// time. If there is an existing authorization grant for the same `sdk.Msg` type, this grant
// overwrites that.
func (k Keeper) Grant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization exported.Authorization, expiration time.Time) error {
// SaveGrant method grants the provided authorization to the grantee on the granter's account
// with the provided expiration time. If there is an existing authorization grant for the
// same `sdk.Msg` type, this grant overwrites that.
func (k Keeper) SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error {
store := ctx.KVStore(k.storeKey)
grant, err := types.NewAuthorizationGrant(authorization, expiration)
grant, err := authz.NewGrant(authorization, expiration)
if err != nil {
return err
}
bz := k.cdc.MustMarshal(&grant)
grantStoreKey := types.GetAuthorizationStoreKey(grantee, granter, authorization.MethodName())
store.Set(grantStoreKey, bz)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventGrantAuthorization,
sdk.NewAttribute(types.AttributeKeyGrantType, authorization.MethodName()),
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(types.AttributeKeyGranterAddress, granter.String()),
sdk.NewAttribute(types.AttributeKeyGranteeAddress, grantee.String()),
),
)
return nil
skey := grantStoreKey(grantee, granter, authorization.MsgTypeURL())
store.Set(skey, bz)
return ctx.EventManager().EmitTypedEvent(&authz.EventGrant{
MsgTypeUrl: authorization.MsgTypeURL(),
Granter: granter.String(),
Grantee: grantee.String(),
})
}
// Revoke method revokes any authorization for the provided message type granted to the grantee by the granter.
func (k Keeper) Revoke(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error {
// DeleteGrant revokes any authorization for the provided message type granted to the grantee
// by the granter.
func (k Keeper) DeleteGrant(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error {
store := ctx.KVStore(k.storeKey)
grantStoreKey := types.GetAuthorizationStoreKey(grantee, granter, msgType)
_, found := k.getAuthorizationGrant(ctx, grantStoreKey)
skey := grantStoreKey(grantee, granter, msgType)
_, found := k.getGrant(ctx, skey)
if !found {
return sdkerrors.Wrap(sdkerrors.ErrNotFound, "authorization not found")
return sdkerrors.ErrNotFound.Wrap("authorization not found")
}
store.Delete(grantStoreKey)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventRevokeAuthorization,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(types.AttributeKeyGrantType, msgType),
sdk.NewAttribute(types.AttributeKeyGranterAddress, granter.String()),
sdk.NewAttribute(types.AttributeKeyGranteeAddress, grantee.String()),
),
)
return nil
store.Delete(skey)
return ctx.EventManager().EmitTypedEvent(&authz.EventRevoke{
MsgTypeUrl: msgType,
Granter: granter.String(),
Grantee: grantee.String(),
})
}
// GetAuthorizations Returns list of `Authorizations` granted to the grantee by the granter.
func (k Keeper) GetAuthorizations(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress) (authorizations []exported.Authorization) {
func (k Keeper) GetAuthorizations(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress) (authorizations []authz.Authorization) {
store := ctx.KVStore(k.storeKey)
key := types.GetAuthorizationStoreKey(grantee, granter, "")
key := grantStoreKey(grantee, granter, "")
iter := sdk.KVStorePrefixIterator(store, key)
defer iter.Close()
var authorization types.AuthorizationGrant
var authorization authz.Grant
for ; iter.Valid(); iter.Next() {
k.cdc.MustUnmarshal(iter.Value(), &authorization)
authorizations = append(authorizations, authorization.GetAuthorizationGrant())
authorizations = append(authorizations, authorization.GetAuthorization())
}
return authorizations
}
// GetOrRevokeAuthorization Returns any `Authorization` (or `nil`), with the expiration time,
// granted to the grantee by the granter for the provided msg type.
// If the Authorization is expired already, it will revoke the authorization and return nil
func (k Keeper) GetOrRevokeAuthorization(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (cap exported.Authorization, expiration time.Time) {
grant, found := k.getAuthorizationGrant(ctx, types.GetAuthorizationStoreKey(grantee, granter, msgType))
// GetCleanAuthorization returns an `Authorization` and it's expiration time for
// (grantee, granter, message name) grant. If there is no grant `nil` is returned.
// If the grant is expired, the grant is revoked, removed from the storage, and `nil` is returned.
func (k Keeper) GetCleanAuthorization(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (cap authz.Authorization, expiration time.Time) {
grant, found := k.getGrant(ctx, grantStoreKey(grantee, granter, msgType))
if !found {
return nil, time.Time{}
}
if grant.Expiration.Before(ctx.BlockHeader().Time) {
k.Revoke(ctx, grantee, granter, msgType)
k.DeleteGrant(ctx, grantee, granter, msgType)
return nil, time.Time{}
}
return grant.GetAuthorizationGrant(), grant.Expiration
return grant.GetAuthorization(), 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.
func (k Keeper) IterateGrants(ctx sdk.Context,
handler func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant types.AuthorizationGrant) bool) {
handler func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant authz.Grant) bool) {
store := ctx.KVStore(k.storeKey)
iter := sdk.KVStorePrefixIterator(store, types.GrantKey)
iter := sdk.KVStorePrefixIterator(store, GrantKey)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var grant types.AuthorizationGrant
granterAddr, granteeAddr := types.ExtractAddressesFromGrantKey(iter.Key())
var grant authz.Grant
granterAddr, granteeAddr := addressesFromGrantStoreKey(iter.Key())
k.cdc.MustUnmarshal(iter.Value(), &grant)
if handler(granterAddr, granteeAddr, grant) {
break
}
}
}
// ExportGenesis returns a GenesisState for a given context.
func (k Keeper) ExportGenesis(ctx sdk.Context) *authz.GenesisState {
var entries []authz.GrantAuthorization
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) bool {
exp := grant.Expiration
entries = append(entries, authz.GrantAuthorization{
Granter: granter.String(),
Grantee: grantee.String(),
Expiration: exp,
Authorization: grant.Authorization,
})
return false
})
return authz.NewGenesisState(entries)
}
// InitGenesis new authz genesis
func (k Keeper) InitGenesis(ctx sdk.Context, data *authz.GenesisState) {
for _, entry := range data.Authorization {
grantee, err := sdk.AccAddressFromBech32(entry.Grantee)
if err != nil {
panic(err)
}
granter, err := sdk.AccAddressFromBech32(entry.Granter)
if err != nil {
panic(err)
}
a, ok := entry.Authorization.GetCachedValue().(authz.Authorization)
if !ok {
panic("expected authorization")
}
err = k.SaveGrant(ctx, grantee, granter, a, entry.Expiration)
if err != nil {
panic(err)
}
}
}

View File

@ -11,17 +11,19 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
var bankSendAuthMsgType = banktypes.SendAuthorization{}.MsgTypeURL()
type TestSuite struct {
suite.Suite
app *simapp.SimApp
ctx sdk.Context
addrs []sdk.AccAddress
queryClient types.QueryClient
queryClient authz.QueryClient
}
func (s *TestSuite) SetupTest() {
@ -30,8 +32,8 @@ func (s *TestSuite) SetupTest() {
now := tmtime.Now()
ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, app.AuthzKeeper)
queryClient := types.NewQueryClient(queryHelper)
authz.RegisterQueryServer(queryHelper, app.AuthzKeeper)
queryClient := authz.NewQueryClient(queryHelper)
s.queryClient = queryClient
s.app = app
@ -48,7 +50,7 @@ func (s *TestSuite) TestKeeper() {
recipientAddr := addrs[2]
s.T().Log("verify that no authorization returns nil")
authorization, expiration := app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, expiration := app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)
s.Require().Equal(expiration, time.Time{})
now := s.ctx.BlockHeader().Time
@ -57,37 +59,37 @@ func (s *TestSuite) TestKeeper() {
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
s.T().Log("verify if expired authorization is rejected")
x := &banktypes.SendAuthorization{SpendLimit: newCoins}
err := app.AuthzKeeper.Grant(ctx, granterAddr, granteeAddr, x, now.Add(-1*time.Hour))
err := app.AuthzKeeper.SaveGrant(ctx, granterAddr, granteeAddr, x, now.Add(-1*time.Hour))
s.Require().NoError(err)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)
s.T().Log("verify if authorization is accepted")
x = &banktypes.SendAuthorization{SpendLimit: newCoins}
err = app.AuthzKeeper.Grant(ctx, granteeAddr, granterAddr, x, now.Add(time.Hour))
err = app.AuthzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, x, now.Add(time.Hour))
s.Require().NoError(err)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().NotNil(authorization)
s.Require().Equal(authorization.MethodName(), banktypes.SendAuthorization{}.MethodName())
s.Require().Equal(authorization.MsgTypeURL(), bankSendAuthMsgType)
s.T().Log("verify fetching authorization with wrong msg type fails")
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, sdk.MsgTypeURL(&banktypes.MsgMultiSend{}))
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, sdk.MsgTypeURL(&banktypes.MsgMultiSend{}))
s.Require().Nil(authorization)
s.T().Log("verify fetching authorization with wrong grantee fails")
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, recipientAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, recipientAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)
s.T().Log("verify revoke fails with wrong information")
err = app.AuthzKeeper.Revoke(ctx, recipientAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
err = app.AuthzKeeper.DeleteGrant(ctx, recipientAddr, granterAddr, bankSendAuthMsgType)
s.Require().Error(err)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, recipientAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, recipientAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)
s.T().Log("verify revoke executes with correct information")
err = app.AuthzKeeper.Revoke(ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
err = app.AuthzKeeper.DeleteGrant(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().NoError(err)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)
}
@ -99,7 +101,7 @@ func (s *TestSuite) TestKeeperIter() {
granteeAddr := addrs[1]
s.T().Log("verify that no authorization returns nil")
authorization, expiration := app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, "Abcd")
authorization, expiration := app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, "Abcd")
s.Require().Nil(authorization)
s.Require().Equal(time.Time{}, expiration)
now := s.ctx.BlockHeader().Time
@ -108,12 +110,12 @@ func (s *TestSuite) TestKeeperIter() {
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
s.T().Log("verify if expired authorization is rejected")
x := &banktypes.SendAuthorization{SpendLimit: newCoins}
err := app.AuthzKeeper.Grant(ctx, granteeAddr, granterAddr, x, now.Add(-1*time.Hour))
err := app.AuthzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, x, now.Add(-1*time.Hour))
s.Require().NoError(err)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, "abcd")
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, "abcd")
s.Require().Nil(authorization)
app.AuthzKeeper.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
app.AuthzKeeper.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) bool {
s.Require().Equal(granter, granterAddr)
s.Require().Equal(grantee, granteeAddr)
return true
@ -134,7 +136,7 @@ func (s *TestSuite) TestKeeperFees() {
smallCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 20))
someCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 123))
msgs := types.NewMsgExecAuthorized(granteeAddr, []sdk.Msg{
msgs := authz.NewMsgExec(granteeAddr, []sdk.Msg{
&banktypes.MsgSend{
Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)),
FromAddress: granterAddr.String(),
@ -154,12 +156,12 @@ func (s *TestSuite) TestKeeperFees() {
s.T().Log("verify dispatch executes with correct information")
// grant authorization
err = app.AuthzKeeper.Grant(s.ctx, granteeAddr, granterAddr, &banktypes.SendAuthorization{SpendLimit: smallCoin}, now)
err = app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr, granterAddr, &banktypes.SendAuthorization{SpendLimit: smallCoin}, now)
s.Require().NoError(err)
authorization, _ := app.AuthzKeeper.GetOrRevokeAuthorization(s.ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ := app.AuthzKeeper.GetCleanAuthorization(s.ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().NotNil(authorization)
s.Require().Equal(authorization.MethodName(), banktypes.SendAuthorization{}.MethodName())
s.Require().Equal(authorization.MsgTypeURL(), bankSendAuthMsgType)
executeMsgs, err = msgs.GetMessages()
s.Require().NoError(err)
@ -168,13 +170,13 @@ func (s *TestSuite) TestKeeperFees() {
s.Require().NoError(err)
s.Require().NotNil(result)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(s.ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(s.ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().NotNil(authorization)
s.T().Log("verify dispatch fails with overlimit")
// grant authorization
msgs = types.NewMsgExecAuthorized(granteeAddr, []sdk.Msg{
msgs = authz.NewMsgExec(granteeAddr, []sdk.Msg{
&banktypes.MsgSend{
Amount: someCoin,
FromAddress: granterAddr.String(),
@ -190,7 +192,7 @@ func (s *TestSuite) TestKeeperFees() {
s.Require().Nil(result)
s.Require().NotNil(err)
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(s.ctx, granteeAddr, granterAddr, banktypes.SendAuthorization{}.MethodName())
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(s.ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().NotNil(authorization)
}

47
x/authz/keeper/keys.go Normal file
View File

@ -0,0 +1,47 @@
package keeper
import (
"github.com/cosmos/cosmos-sdk/internal/conv"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"github.com/cosmos/cosmos-sdk/x/authz"
)
// Keys for store prefixes
var (
GrantKey = []byte{0x01} // prefix for each key
)
// StoreKey is the store key string for authz
const StoreKey = authz.ModuleName
// grantStoreKey - return authorization store key
// Items are stored with the following key: values
//
// - 0x01<granterAddressLen (1 Byte)><granterAddress_Bytes><granteeAddressLen (1 Byte)><granteeAddress_Bytes><msgType_Bytes>: Grant
func grantStoreKey(grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) []byte {
m := conv.UnsafeStrToBytes(msgType)
granter = address.MustLengthPrefix(granter)
grantee = address.MustLengthPrefix(grantee)
l := 1 + len(grantee) + len(granter) + len(m)
var key = make([]byte, l)
copy(key, GrantKey)
copy(key[1:], granter)
copy(key[1+len(granter):], grantee)
copy(key[l-len(m):], m)
// fmt.Println(">>>> len", l, key)
return key
}
// addressesFromGrantStoreKey - split granter & grantee address from the authorization key
func addressesFromGrantStoreKey(key []byte) (granterAddr, granteeAddr sdk.AccAddress) {
// key is of format:
// 0x01<granterAddressLen (1 Byte)><granterAddress_Bytes><granteeAddressLen (1 Byte)><granteeAddress_Bytes><msgType_Bytes>
granterAddrLen := key[1] // remove prefix key
granterAddr = sdk.AccAddress(key[2 : 2+granterAddrLen])
granteeAddrLen := int(key[2+granterAddrLen])
granteeAddr = sdk.AccAddress(key[3+granterAddrLen : 3+granterAddrLen+byte(granteeAddrLen)])
return granterAddr, granteeAddr
}

View File

@ -0,0 +1,26 @@
package keeper
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
)
var granter = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
var grantee = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
var msgType = bank.SendAuthorization{}.MsgTypeURL()
func TestGrantkey(t *testing.T) {
require := require.New(t)
key := grantStoreKey(grantee, granter, msgType)
require.Len(key, len(GrantKey)+len(address.MustLengthPrefix(grantee))+len(address.MustLengthPrefix(granter))+len([]byte(msgType)))
granter1, grantee1 := addressesFromGrantStoreKey(grantStoreKey(grantee, granter, msgType))
require.Equal(granter, granter1)
require.Equal(grantee, grantee1)
}

View File

@ -5,13 +5,13 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
)
var _ types.MsgServer = Keeper{}
var _ authz.MsgServer = Keeper{}
// GrantAuthorization implements the MsgServer.GrantAuthorization method.
func (k Keeper) GrantAuthorization(goCtx context.Context, msg *types.MsgGrantAuthorizationRequest) (*types.MsgGrantAuthorizationResponse, error) {
// GrantAuthorization implements the MsgServer.Grant method.
func (k Keeper) Grant(goCtx context.Context, msg *authz.MsgGrant) (*authz.MsgGrantResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
if err != nil {
@ -22,22 +22,25 @@ func (k Keeper) GrantAuthorization(goCtx context.Context, msg *types.MsgGrantAut
return nil, err
}
authorization := msg.GetGrantAuthorization()
// If the granted service Msg doesn't exist, we throw an error.
if k.router.HandlerbyTypeURL(authorization.MethodName()) == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%s doesn't exist.", authorization.MethodName())
authorization := msg.GetAuthorization()
if authorization == nil {
return nil, sdkerrors.ErrUnpackAny.Wrap("Authorization is not present in the msg")
}
t := authorization.MsgTypeURL()
if k.router.HandlerbyTypeURL(t) == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%s doesn't exist.", t)
}
err = k.Grant(ctx, grantee, granter, authorization, msg.Expiration)
err = k.SaveGrant(ctx, grantee, granter, authorization, msg.Expiration)
if err != nil {
return nil, err
}
return &types.MsgGrantAuthorizationResponse{}, nil
return &authz.MsgGrantResponse{}, nil
}
// RevokeAuthorization implements the MsgServer.RevokeAuthorization method.
func (k Keeper) RevokeAuthorization(goCtx context.Context, msg *types.MsgRevokeAuthorizationRequest) (*types.MsgRevokeAuthorizationResponse, error) {
// RevokeAuthorization implements the MsgServer.Revoke method.
func (k Keeper) Revoke(goCtx context.Context, msg *authz.MsgRevoke) (*authz.MsgRevokeResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
if err != nil {
@ -48,16 +51,16 @@ func (k Keeper) RevokeAuthorization(goCtx context.Context, msg *types.MsgRevokeA
return nil, err
}
err = k.Revoke(ctx, grantee, granter, msg.MethodName)
err = k.DeleteGrant(ctx, grantee, granter, msg.MsgTypeUrl)
if err != nil {
return nil, err
}
return &types.MsgRevokeAuthorizationResponse{}, nil
return &authz.MsgRevokeResponse{}, nil
}
// ExecAuthorized implements the MsgServer.ExecAuthorized method.
func (k Keeper) ExecAuthorized(goCtx context.Context, msg *types.MsgExecAuthorizedRequest) (*types.MsgExecAuthorizedResponse, error) {
// Exec implements the MsgServer.Exec method.
func (k Keeper) Exec(goCtx context.Context, msg *authz.MsgExec) (*authz.MsgExecResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
if err != nil {
@ -71,5 +74,5 @@ func (k Keeper) ExecAuthorized(goCtx context.Context, msg *types.MsgExecAuthoriz
if err != nil {
return nil, err
}
return &types.MsgExecAuthorizedResponse{Result: result}, nil
return &authz.MsgExecResponse{Result: result}, nil
}

12
x/authz/keys.go Normal file
View File

@ -0,0 +1,12 @@
package authz
const (
// ModuleName is the module name constant used in many places
ModuleName = "authz"
// RouterKey is the message route for authz
RouterKey = ModuleName
// QuerierRoute is the querier route for authz
QuerierRoute = ModuleName
)

View File

@ -16,12 +16,10 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
"github.com/cosmos/cosmos-sdk/x/authz/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
)
@ -38,14 +36,14 @@ type AppModuleBasic struct {
// Name returns the authz module's name.
func (AppModuleBasic) Name() string {
return types.ModuleName
return authz.ModuleName
}
// RegisterServices registers a gRPC query service to respond to the
// module-specific gRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
authz.RegisterQueryServer(cfg.QueryServer(), am.keeper)
authz.RegisterMsgServer(cfg.MsgServer(), am.keeper)
}
// RegisterLegacyAminoCodec registers the authz module's types for the given codec.
@ -53,23 +51,23 @@ func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {}
// RegisterInterfaces registers the authz module's interface types
func (AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
types.RegisterInterfaces(registry)
authz.RegisterInterfaces(registry)
}
// DefaultGenesis returns default genesis state as raw bytes for the authz
// module.
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(types.DefaultGenesisState())
return cdc.MustMarshalJSON(authz.DefaultGenesisState())
}
// ValidateGenesis performs genesis state validation for the authz module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
var data authz.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return sdkerrors.Wrapf(err, "failed to unmarshal %s genesis state", types.ModuleName)
return sdkerrors.Wrapf(err, "failed to unmarshal %s genesis state", authz.ModuleName)
}
return types.ValidateGenesis(data)
return authz.ValidateGenesis(data)
}
// RegisterRESTRoutes registers the REST routes for the authz module.
@ -78,7 +76,7 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, r *mux.Rou
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the authz module.
func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) {
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
authz.RegisterQueryHandlerClient(context.Background(), mux, authz.NewQueryClient(clientCtx))
}
// GetQueryCmd returns the cli query commands for the authz module
@ -95,13 +93,13 @@ func (AppModuleBasic) GetTxCmd() *cobra.Command {
type AppModule struct {
AppModuleBasic
keeper keeper.Keeper
accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
accountKeeper authz.AccountKeeper
bankKeeper authz.BankKeeper
registry cdctypes.InterfaceRegistry
}
// NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper, bk types.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule {
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak authz.AccountKeeper, bk authz.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc},
keeper: keeper,
@ -113,7 +111,7 @@ func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper,
// Name returns the authz module's name.
func (AppModule) Name() string {
return types.ModuleName
return authz.ModuleName
}
// RegisterInvariants does nothing, there are no invariants to enforce
@ -121,7 +119,7 @@ func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the staking module.
func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, nil)
return sdk.NewRoute(authz.RouterKey, nil)
}
func (am AppModule) NewHandler() sdk.Handler {
@ -139,16 +137,16 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// InitGenesis performs genesis initialization for the authz module. It returns
// no validator updates.
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
var genesisState types.GenesisState
var genesisState authz.GenesisState
cdc.MustUnmarshalJSON(data, &genesisState)
InitGenesis(ctx, am.keeper, &genesisState)
am.keeper.InitGenesis(ctx, &genesisState)
return []abci.ValidatorUpdate{}
}
// ExportGenesis returns the exported genesis state as raw bytes for the authz
// module.
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
gs := ExportGenesis(ctx, am.keeper)
gs := am.keeper.ExportGenesis(ctx)
return cdc.MustMarshalJSON(gs)
}
@ -184,7 +182,7 @@ func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
// RegisterStoreDecoder registers a decoder for authz module's types
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
sdr[keeper.StoreKey] = simulation.NewDecodeStore(am.cdc)
}
// WeightedOperations returns the all the gov module operations with their respective weights.

View File

@ -1,34 +1,33 @@
package types
package authz
import (
"time"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/codec/types"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
)
var (
_ sdk.Msg = &MsgGrantAuthorizationRequest{}
_ sdk.Msg = &MsgRevokeAuthorizationRequest{}
_ sdk.Msg = &MsgExecAuthorizedRequest{}
_ sdk.Msg = &MsgGrant{}
_ sdk.Msg = &MsgRevoke{}
_ sdk.Msg = &MsgExec{}
_ types.UnpackInterfacesMessage = &MsgGrantAuthorizationRequest{}
_ types.UnpackInterfacesMessage = &MsgExecAuthorizedRequest{}
_ cdctypes.UnpackInterfacesMessage = &MsgGrant{}
_ cdctypes.UnpackInterfacesMessage = &MsgExec{}
)
// NewMsgGrantAuthorization creates a new MsgGrantAuthorization
// NewMsgGrant creates a new MsgGrant
//nolint:interfacer
func NewMsgGrantAuthorization(granter sdk.AccAddress, grantee sdk.AccAddress, authorization exported.Authorization, expiration time.Time) (*MsgGrantAuthorizationRequest, error) {
m := &MsgGrantAuthorizationRequest{
func NewMsgGrant(granter sdk.AccAddress, grantee sdk.AccAddress, a Authorization, expiration time.Time) (*MsgGrant, error) {
m := &MsgGrant{
Granter: granter.String(),
Grantee: grantee.String(),
Expiration: expiration,
}
err := m.SetAuthorization(authorization)
err := m.SetAuthorization(a)
if err != nil {
return nil, err
}
@ -36,7 +35,7 @@ func NewMsgGrantAuthorization(granter sdk.AccAddress, grantee sdk.AccAddress, au
}
// GetSigners implements Msg
func (msg MsgGrantAuthorizationRequest) GetSigners() []sdk.AccAddress {
func (msg MsgGrant) GetSigners() []sdk.AccAddress {
granter, err := sdk.AccAddressFromBech32(msg.Granter)
if err != nil {
panic(err)
@ -45,7 +44,7 @@ func (msg MsgGrantAuthorizationRequest) GetSigners() []sdk.AccAddress {
}
// ValidateBasic implements Msg
func (msg MsgGrantAuthorizationRequest) ValidateBasic() error {
func (msg MsgGrant) ValidateBasic() error {
granter, err := sdk.AccAddressFromBech32(msg.Granter)
if err != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid granter address")
@ -63,29 +62,30 @@ func (msg MsgGrantAuthorizationRequest) ValidateBasic() error {
return sdkerrors.Wrap(ErrInvalidExpirationTime, "Time can't be in the past")
}
authorization, ok := msg.Authorization.GetCachedValue().(exported.Authorization)
av := msg.Authorization.GetCachedValue()
a, ok := av.(Authorization)
if !ok {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (exported.Authorization)(nil), msg.Authorization.GetCachedValue())
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (Authorization)(nil), av)
}
return authorization.ValidateBasic()
return a.ValidateBasic()
}
// GetGrantAuthorization returns the cache value from the MsgGrantAuthorization.Authorization if present.
func (msg *MsgGrantAuthorizationRequest) GetGrantAuthorization() exported.Authorization {
authorization, ok := msg.Authorization.GetCachedValue().(exported.Authorization)
// GetAuthorization returns the cache value from the MsgGrant.Authorization if present.
func (msg *MsgGrant) GetAuthorization() Authorization {
a, ok := msg.Authorization.GetCachedValue().(Authorization)
if !ok {
return nil
}
return authorization
return a
}
// SetAuthorization converts Authorization to any and adds it to MsgGrantAuthorization.Authorization.
func (msg *MsgGrantAuthorizationRequest) SetAuthorization(authorization exported.Authorization) error {
m, ok := authorization.(proto.Message)
// SetAuthorization converts Authorization to any and adds it to MsgGrant.Authorization.
func (msg *MsgGrant) SetAuthorization(a Authorization) error {
m, ok := a.(proto.Message)
if !ok {
return sdkerrors.Wrapf(sdkerrors.ErrPackAny, "can't proto marshal %T", m)
}
any, err := types.NewAnyWithValue(m)
any, err := cdctypes.NewAnyWithValue(m)
if err != nil {
return err
}
@ -94,7 +94,7 @@ func (msg *MsgGrantAuthorizationRequest) SetAuthorization(authorization exported
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg MsgExecAuthorizedRequest) UnpackInterfaces(unpacker types.AnyUnpacker) error {
func (msg MsgExec) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
for _, x := range msg.Msgs {
var msgExecAuthorized sdk.Msg
err := unpacker.UnpackAny(x, &msgExecAuthorized)
@ -107,23 +107,23 @@ func (msg MsgExecAuthorizedRequest) UnpackInterfaces(unpacker types.AnyUnpacker)
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg MsgGrantAuthorizationRequest) UnpackInterfaces(unpacker types.AnyUnpacker) error {
var authorization exported.Authorization
return unpacker.UnpackAny(msg.Authorization, &authorization)
func (msg MsgGrant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
var a Authorization
return unpacker.UnpackAny(msg.Authorization, &a)
}
// NewMsgRevokeAuthorization creates a new MsgRevokeAuthorization
// NewMsgRevoke creates a new MsgRevoke
//nolint:interfacer
func NewMsgRevokeAuthorization(granter sdk.AccAddress, grantee sdk.AccAddress, methodName string) MsgRevokeAuthorizationRequest {
return MsgRevokeAuthorizationRequest{
func NewMsgRevoke(granter sdk.AccAddress, grantee sdk.AccAddress, msgTypeURL string) MsgRevoke {
return MsgRevoke{
Granter: granter.String(),
Grantee: grantee.String(),
MethodName: methodName,
MsgTypeUrl: msgTypeURL,
}
}
// GetSigners implements Msg
func (msg MsgRevokeAuthorizationRequest) GetSigners() []sdk.AccAddress {
func (msg MsgRevoke) GetSigners() []sdk.AccAddress {
granter, err := sdk.AccAddressFromBech32(msg.Granter)
if err != nil {
panic(err)
@ -132,7 +132,7 @@ func (msg MsgRevokeAuthorizationRequest) GetSigners() []sdk.AccAddress {
}
// ValidateBasic implements MsgRequest.ValidateBasic
func (msg MsgRevokeAuthorizationRequest) ValidateBasic() error {
func (msg MsgRevoke) ValidateBasic() error {
granter, err := sdk.AccAddressFromBech32(msg.Granter)
if err != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid granter address")
@ -146,19 +146,19 @@ func (msg MsgRevokeAuthorizationRequest) ValidateBasic() error {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "granter and grantee cannot be same")
}
if msg.MethodName == "" {
if msg.MsgTypeUrl == "" {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "missing method name")
}
return nil
}
// NewMsgExecAuthorized creates a new MsgExecAuthorized
// NewMsgExec creates a new MsgExecAuthorized
//nolint:interfacer
func NewMsgExecAuthorized(grantee sdk.AccAddress, msgs []sdk.Msg) MsgExecAuthorizedRequest {
msgsAny := make([]*types.Any, len(msgs))
func NewMsgExec(grantee sdk.AccAddress, msgs []sdk.Msg) MsgExec {
msgsAny := make([]*cdctypes.Any, len(msgs))
for i, msg := range msgs {
any, err := types.NewAnyWithValue(msg)
any, err := cdctypes.NewAnyWithValue(msg)
if err != nil {
panic(err)
}
@ -166,14 +166,14 @@ func NewMsgExecAuthorized(grantee sdk.AccAddress, msgs []sdk.Msg) MsgExecAuthori
msgsAny[i] = any
}
return MsgExecAuthorizedRequest{
return MsgExec{
Grantee: grantee.String(),
Msgs: msgsAny,
}
}
// GetMessages returns the cache values from the MsgExecAuthorized.Msgs if present.
func (msg MsgExecAuthorizedRequest) GetMessages() ([]sdk.Msg, error) {
func (msg MsgExec) GetMessages() ([]sdk.Msg, error) {
msgs := make([]sdk.Msg, len(msg.Msgs))
for i, msgAny := range msg.Msgs {
msg, ok := msgAny.GetCachedValue().(sdk.Msg)
@ -187,7 +187,7 @@ func (msg MsgExecAuthorizedRequest) GetMessages() ([]sdk.Msg, error) {
}
// GetSigners implements Msg
func (msg MsgExecAuthorizedRequest) GetSigners() []sdk.AccAddress {
func (msg MsgExec) GetSigners() []sdk.AccAddress {
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
if err != nil {
panic(err)
@ -196,7 +196,7 @@ func (msg MsgExecAuthorizedRequest) GetSigners() []sdk.AccAddress {
}
// ValidateBasic implements Msg
func (msg MsgExecAuthorizedRequest) ValidateBasic() error {
func (msg MsgExec) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Grantee)
if err != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid grantee address")

View File

@ -1,4 +1,4 @@
package types_test
package authz_test
import (
"testing"
@ -6,11 +6,9 @@ import (
"github.com/stretchr/testify/require"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
var (
@ -37,7 +35,7 @@ func TestMsgExecAuthorized(t *testing.T) {
}, true},
}
for i, tc := range tests {
msg := types.NewMsgExecAuthorized(tc.grantee, tc.msgs)
msg := authz.NewMsgExec(tc.grantee, tc.msgs)
if tc.expectPass {
require.NoError(t, msg.ValidateBasic(), "test: %v", i)
} else {
@ -58,7 +56,7 @@ func TestMsgRevokeAuthorization(t *testing.T) {
{"valid test case", granter, grantee, "hello", true},
}
for i, tc := range tests {
msg := types.NewMsgRevokeAuthorization(tc.granter, tc.grantee, tc.msgType)
msg := authz.NewMsgRevoke(tc.granter, tc.grantee, tc.msgType)
if tc.expectPass {
require.NoError(t, msg.ValidateBasic(), "test: %v", i)
} else {
@ -71,7 +69,7 @@ func TestMsgGrantAuthorization(t *testing.T) {
tests := []struct {
title string
granter, grantee sdk.AccAddress
authorization exported.Authorization
authorization authz.Authorization
expiration time.Time
expectErr bool
expectPass bool
@ -84,7 +82,7 @@ func TestMsgGrantAuthorization(t *testing.T) {
{"past time", granter, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 0, -1), false, false},
}
for i, tc := range tests {
msg, err := types.NewMsgGrantAuthorization(
msg, err := authz.NewMsgGrant(
tc.granter, tc.grantee, tc.authorization, tc.expiration,
)
if !tc.expectErr {

8
x/authz/proto_desc.go Normal file
View File

@ -0,0 +1,8 @@
package authz
import grpc "google.golang.org/grpc"
// MsgServiceDesc return ServiceDesc for Msg server
func MsgServiceDesc() *grpc.ServiceDesc {
return &_Msg_serviceDesc
}

826
x/authz/query.pb.go Normal file
View File

@ -0,0 +1,826 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/authz/v1beta1/query.proto
package authz
import (
context "context"
fmt "fmt"
query "github.com/cosmos/cosmos-sdk/types/query"
grpc1 "github.com/gogo/protobuf/grpc"
proto "github.com/gogo/protobuf/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// QueryGrantsRequest is the request type for the Query/Grants RPC method.
type QueryGrantsRequest struct {
Granter string `protobuf:"bytes,1,opt,name=granter,proto3" json:"granter,omitempty"`
Grantee string `protobuf:"bytes,2,opt,name=grantee,proto3" json:"grantee,omitempty"`
// Optional, msg_type_url, when set, will query only grants matching given msg type.
MsgTypeUrl string `protobuf:"bytes,3,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"`
// pagination defines an pagination for the request.
Pagination *query.PageRequest `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination,omitempty"`
}
func (m *QueryGrantsRequest) Reset() { *m = QueryGrantsRequest{} }
func (m *QueryGrantsRequest) String() string { return proto.CompactTextString(m) }
func (*QueryGrantsRequest) ProtoMessage() {}
func (*QueryGrantsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_376d714ffdeb1545, []int{0}
}
func (m *QueryGrantsRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryGrantsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryGrantsRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *QueryGrantsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryGrantsRequest.Merge(m, src)
}
func (m *QueryGrantsRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryGrantsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryGrantsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryGrantsRequest proto.InternalMessageInfo
func (m *QueryGrantsRequest) GetGranter() string {
if m != nil {
return m.Granter
}
return ""
}
func (m *QueryGrantsRequest) GetGrantee() string {
if m != nil {
return m.Grantee
}
return ""
}
func (m *QueryGrantsRequest) GetMsgTypeUrl() string {
if m != nil {
return m.MsgTypeUrl
}
return ""
}
func (m *QueryGrantsRequest) GetPagination() *query.PageRequest {
if m != nil {
return m.Pagination
}
return nil
}
// QueryGrantsResponse is the response type for the Query/Authorizations RPC method.
type QueryGrantsResponse struct {
// authorizations is a list of grants granted for grantee by granter.
Grants []*Grant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants,omitempty"`
// pagination defines an pagination for the response.
Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
}
func (m *QueryGrantsResponse) Reset() { *m = QueryGrantsResponse{} }
func (m *QueryGrantsResponse) String() string { return proto.CompactTextString(m) }
func (*QueryGrantsResponse) ProtoMessage() {}
func (*QueryGrantsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_376d714ffdeb1545, []int{1}
}
func (m *QueryGrantsResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryGrantsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryGrantsResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *QueryGrantsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryGrantsResponse.Merge(m, src)
}
func (m *QueryGrantsResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryGrantsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryGrantsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryGrantsResponse proto.InternalMessageInfo
func (m *QueryGrantsResponse) GetGrants() []*Grant {
if m != nil {
return m.Grants
}
return nil
}
func (m *QueryGrantsResponse) GetPagination() *query.PageResponse {
if m != nil {
return m.Pagination
}
return nil
}
func init() {
proto.RegisterType((*QueryGrantsRequest)(nil), "cosmos.authz.v1beta1.QueryGrantsRequest")
proto.RegisterType((*QueryGrantsResponse)(nil), "cosmos.authz.v1beta1.QueryGrantsResponse")
}
func init() { proto.RegisterFile("cosmos/authz/v1beta1/query.proto", fileDescriptor_376d714ffdeb1545) }
var fileDescriptor_376d714ffdeb1545 = []byte{
// 381 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x4f, 0xf2, 0x30,
0x18, 0xc7, 0x29, 0xbc, 0x2f, 0xc6, 0xe2, 0xa9, 0x7a, 0x58, 0x90, 0x2c, 0x0b, 0x21, 0x3a, 0x4d,
0xec, 0x02, 0xdc, 0x3d, 0x78, 0x90, 0xab, 0x2e, 0x7a, 0xf1, 0x42, 0x3a, 0x6c, 0xca, 0x22, 0x5b,
0xc7, 0xda, 0x19, 0xf1, 0xa8, 0x67, 0x13, 0x13, 0xbe, 0x89, 0x9f, 0xc2, 0x23, 0x89, 0x17, 0x8f,
0x06, 0xfc, 0x20, 0x86, 0xb6, 0x08, 0xc4, 0x25, 0x7a, 0x5a, 0xb6, 0xe7, 0xf7, 0xfc, 0x9f, 0x5f,
0x9f, 0x15, 0x3a, 0x3d, 0x2e, 0x22, 0x2e, 0x3c, 0x92, 0xc9, 0xfe, 0xbd, 0x77, 0xdb, 0x0c, 0xa8,
0x24, 0x4d, 0x6f, 0x98, 0xd1, 0x74, 0x84, 0x93, 0x94, 0x4b, 0x8e, 0x76, 0x34, 0x81, 0x15, 0x81,
0x0d, 0x51, 0xad, 0x31, 0xce, 0xd9, 0x80, 0x7a, 0x24, 0x09, 0x3d, 0x12, 0xc7, 0x5c, 0x12, 0x19,
0xf2, 0x58, 0xe8, 0x9e, 0xea, 0xa1, 0x49, 0x0d, 0x88, 0xa0, 0x3a, 0xec, 0x3b, 0x3a, 0x21, 0x2c,
0x8c, 0x15, 0x6c, 0xd8, 0x7c, 0x03, 0x3d, 0x4d, 0x11, 0xf5, 0x17, 0x00, 0xd1, 0xf9, 0x3c, 0xa4,
0x93, 0x92, 0x58, 0x0a, 0x9f, 0x0e, 0x33, 0x2a, 0x24, 0xb2, 0xe0, 0x06, 0x9b, 0x7f, 0xa0, 0xa9,
0x05, 0x1c, 0xe0, 0x6e, 0xfa, 0x8b, 0xd7, 0x65, 0x85, 0x5a, 0xc5, 0xd5, 0x0a, 0x45, 0x0e, 0xdc,
0x8a, 0x04, 0xeb, 0xca, 0x51, 0x42, 0xbb, 0x59, 0x3a, 0xb0, 0x4a, 0xaa, 0x0c, 0x23, 0xc1, 0x2e,
0x46, 0x09, 0xbd, 0x4c, 0x07, 0xe8, 0x14, 0xc2, 0xa5, 0xa2, 0xf5, 0xcf, 0x01, 0x6e, 0xa5, 0xb5,
0x87, 0xcd, 0x0e, 0xe6, 0xe7, 0xc1, 0x7a, 0x39, 0x46, 0x14, 0x9f, 0x11, 0x46, 0x8d, 0x91, 0xbf,
0xd2, 0x59, 0x1f, 0x03, 0xb8, 0xbd, 0x26, 0x2d, 0x12, 0x1e, 0x0b, 0x8a, 0xda, 0xb0, 0xac, 0x64,
0x84, 0x05, 0x9c, 0x92, 0x5b, 0x69, 0xed, 0xe2, 0xbc, 0xfd, 0x62, 0xd5, 0xe5, 0x1b, 0x14, 0x75,
0xd6, 0xa4, 0x8a, 0x4a, 0x6a, 0xff, 0x57, 0x29, 0x3d, 0x71, 0xd5, 0xaa, 0xf5, 0x04, 0xe0, 0x7f,
0x65, 0x85, 0x1e, 0x01, 0x2c, 0x6b, 0x35, 0xe4, 0xe6, 0x2b, 0xfc, 0x5c, 0x79, 0xf5, 0xe0, 0x0f,
0xa4, 0x9e, 0x5a, 0x6f, 0x3c, 0xbc, 0x7d, 0x8e, 0x8b, 0x36, 0xaa, 0x79, 0xb9, 0xff, 0x57, 0x1f,
0xec, 0xe4, 0xf8, 0x75, 0x6a, 0x83, 0xc9, 0xd4, 0x06, 0x1f, 0x53, 0x1b, 0x3c, 0xcf, 0xec, 0xc2,
0x64, 0x66, 0x17, 0xde, 0x67, 0x76, 0xe1, 0xaa, 0xc1, 0x42, 0xd9, 0xcf, 0x02, 0xdc, 0xe3, 0xd1,
0x22, 0x41, 0x3f, 0x8e, 0xc4, 0xf5, 0x8d, 0x77, 0xa7, 0xe3, 0x82, 0xb2, 0xba, 0x21, 0xed, 0xaf,
0x00, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x52, 0x9e, 0x65, 0xc7, 0x02, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
// Returns list of `Authorization`, granted to the grantee by the granter.
Grants(ctx context.Context, in *QueryGrantsRequest, opts ...grpc.CallOption) (*QueryGrantsResponse, error)
}
type queryClient struct {
cc grpc1.ClientConn
}
func NewQueryClient(cc grpc1.ClientConn) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) Grants(ctx context.Context, in *QueryGrantsRequest, opts ...grpc.CallOption) (*QueryGrantsResponse, error) {
out := new(QueryGrantsResponse)
err := c.cc.Invoke(ctx, "/cosmos.authz.v1beta1.Query/Grants", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// Returns list of `Authorization`, granted to the grantee by the granter.
Grants(context.Context, *QueryGrantsRequest) (*QueryGrantsResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (*UnimplementedQueryServer) Grants(ctx context.Context, req *QueryGrantsRequest) (*QueryGrantsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Grants not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
}
func _Query_Grants_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryGrantsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).Grants(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.authz.v1beta1.Query/Grants",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).Grants(ctx, req.(*QueryGrantsRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.authz.v1beta1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Grants",
Handler: _Query_Grants_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/authz/v1beta1/query.proto",
}
func (m *QueryGrantsRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *QueryGrantsRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryGrantsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Pagination != nil {
{
size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x22
}
if len(m.MsgTypeUrl) > 0 {
i -= len(m.MsgTypeUrl)
copy(dAtA[i:], m.MsgTypeUrl)
i = encodeVarintQuery(dAtA, i, uint64(len(m.MsgTypeUrl)))
i--
dAtA[i] = 0x1a
}
if len(m.Grantee) > 0 {
i -= len(m.Grantee)
copy(dAtA[i:], m.Grantee)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Grantee)))
i--
dAtA[i] = 0x12
}
if len(m.Granter) > 0 {
i -= len(m.Granter)
copy(dAtA[i:], m.Granter)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Granter)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *QueryGrantsResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *QueryGrantsResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryGrantsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Pagination != nil {
{
size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.Grants) > 0 {
for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *QueryGrantsRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Granter)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
l = len(m.Grantee)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
l = len(m.MsgTypeUrl)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
if m.Pagination != nil {
l = m.Pagination.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func (m *QueryGrantsResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Grants) > 0 {
for _, e := range m.Grants {
l = e.Size()
n += 1 + l + sovQuery(uint64(l))
}
}
if m.Pagination != nil {
l = m.Pagination.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozQuery(x uint64) (n int) {
return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *QueryGrantsRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: QueryGrantsRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryGrantsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Granter", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Granter = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Grantee", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Grantee = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MsgTypeUrl", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.MsgTypeUrl = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Pagination == nil {
m.Pagination = &query.PageRequest{}
}
if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryGrantsResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: QueryGrantsResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryGrantsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Grants = append(m.Grants, &Grant{})
if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Pagination == nil {
m.Pagination = &query.PageResponse{}
}
if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthQuery
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupQuery
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthQuery
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
)

166
x/authz/query.pb.gw.go Normal file
View File

@ -0,0 +1,166 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: cosmos/authz/v1beta1/query.proto
/*
Package authz is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package authz
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var (
filter_Query_Grants_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Query_Grants_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryGrantsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Grants_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Grants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_Grants_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryGrantsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Grants_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Grants(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
mux.Handle("GET", pattern_Query_Grants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_Grants_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Grants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterQueryHandler(ctx, mux, conn)
}
// RegisterQueryHandler registers the http handlers for service Query to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
}
// RegisterQueryHandlerClient registers the http handlers for service Query
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "QueryClient" to call the correct interceptors.
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
mux.Handle("GET", pattern_Query_Grants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_Grants_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Grants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Query_Grants_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "authz", "v1beta1", "grants"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_Grants_0 = runtime.ForwardResponseMessage
)

View File

@ -6,7 +6,8 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/kv"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
)
// NewDecodeStore returns a decoder function closure that umarshals the KVPair's
@ -14,8 +15,8 @@ import (
func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string {
return func(kvA, kvB kv.Pair) string {
switch {
case bytes.Equal(kvA.Key[:1], types.GrantKey):
var grantA, grantB types.AuthorizationGrant
case bytes.Equal(kvA.Key[:1], keeper.GrantKey):
var grantA, grantB authz.Grant
cdc.MustUnmarshal(kvA.Value, &grantA)
cdc.MustUnmarshal(kvB.Value, &grantB)
return fmt.Sprintf("%v\n%v", grantA, grantB)

View File

@ -10,8 +10,9 @@ import (
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/kv"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
"github.com/cosmos/cosmos-sdk/x/authz/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
@ -19,12 +20,12 @@ func TestDecodeStore(t *testing.T) {
cdc := simapp.MakeTestEncodingConfig().Marshaler
dec := simulation.NewDecodeStore(cdc)
grant, _ := types.NewAuthorizationGrant(banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewInt64Coin("foo", 123))), time.Now().UTC())
grant, _ := authz.NewGrant(banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewInt64Coin("foo", 123))), time.Now().UTC())
grantBz, err := cdc.Marshal(&grant)
require.NoError(t, err)
kvPairs := kv.Pairs{
Pairs: []kv.Pair{
{Key: []byte(types.GrantKey), Value: grantBz},
{Key: []byte(keeper.GrantKey), Value: grantBz},
{Key: []byte{0x99}, Value: []byte{0x99}},
},
}

View File

@ -7,32 +7,29 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/authz/types"
"github.com/cosmos/cosmos-sdk/x/authz"
)
// Simulation parameter constant.
const authz = "authz"
// GenAuthorizationGrant returns an empty slice of authorization grants.
func GenAuthorizationGrant(_ *rand.Rand, _ []simtypes.Account) []types.GrantAuthorization {
return []types.GrantAuthorization{}
func GenAuthorizationGrant(_ *rand.Rand, _ []simtypes.Account) []authz.GrantAuthorization {
return []authz.GrantAuthorization{}
}
// RandomizedGenState generates a random GenesisState for authz.
func RandomizedGenState(simState *module.SimulationState) {
var grants []types.GrantAuthorization
var grants []authz.GrantAuthorization
simState.AppParams.GetOrGenerate(
simState.Cdc, authz, &grants, simState.Rand,
simState.Cdc, "authz", &grants, simState.Rand,
func(r *rand.Rand) { grants = GenAuthorizationGrant(r, simState.Accounts) },
)
authzGrantsGenesis := types.NewGenesisState(grants)
authzGrantsGenesis := authz.NewGenesisState(grants)
bz, err := json.MarshalIndent(&authzGrantsGenesis, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("Selected randomly generated %s parameters:\n%s\n", types.ModuleName, bz)
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(authzGrantsGenesis)
fmt.Printf("Selected randomly generated %s parameters:\n%s\n", authz.ModuleName, bz)
simState.GenState[authz.ModuleName] = simState.Cdc.MustMarshalJSON(authzGrantsGenesis)
}

View File

@ -11,8 +11,8 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
"github.com/cosmos/cosmos-sdk/x/authz/types"
)
func TestRandomizedGenState(t *testing.T) {
@ -33,8 +33,8 @@ func TestRandomizedGenState(t *testing.T) {
}
simulation.RandomizedGenState(&simState)
var authzGenesis types.GenesisState
simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &authzGenesis)
var authzGenesis authz.GenesisState
simState.Cdc.MustUnmarshalJSON(simState.GenState[authz.ModuleName], &authzGenesis)
require.Len(t, authzGenesis.Authorization, 0)
}

View File

@ -13,31 +13,29 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
"github.com/cosmos/cosmos-sdk/x/authz/types"
banktype "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
// authz message types
var (
// TODO Remove `Request` suffix
// https://github.com/cosmos/cosmos-sdk/issues/9114
TypeMsgGrantAuthorization = sdk.MsgTypeURL(&types.MsgGrantAuthorizationRequest{})
TypeMsgRevokeAuthorization = sdk.MsgTypeURL(&types.MsgRevokeAuthorizationRequest{})
TypeMsgExecDelegated = sdk.MsgTypeURL(&types.MsgExecAuthorizedRequest{})
TypeMsgGrantAuthorization = sdk.MsgTypeURL(&authz.MsgGrant{})
TypeMsgRevokeAuthorization = sdk.MsgTypeURL(&authz.MsgRevoke{})
TypeMsgExecDelegated = sdk.MsgTypeURL(&authz.MsgExec{})
)
// Simulation operation weights constants
const (
OpWeightMsgGrantAuthorization = "op_weight_msg_grant_authorization"
OpWeightRevokeAuthorization = "op_weight_msg_revoke_authorization"
OpWeightExecAuthorized = "op_weight_msg_execute_authorized"
OpWeightMsgGrantAuthorization = "op_weight_msg_grant"
OpWeightRevokeAuthorization = "op_weight_msg_revoke"
OpWeightExecAuthorized = "op_weight_msg_execute"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(
appParams simtypes.AppParams, cdc codec.JSONCodec, ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, appCdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simulation.WeightedOperations {
appParams simtypes.AppParams, cdc codec.JSONCodec, ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, appCdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simulation.WeightedOperations {
var (
weightMsgGrantAuthorization int
@ -81,7 +79,7 @@ func WeightedOperations(
// SimulateMsgGrantAuthorization generates a MsgGrantAuthorization with random values.
// nolint: funlen
func SimulateMsgGrantAuthorization(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper,
func SimulateMsgGrantAuthorization(ak authz.AccountKeeper, bk authz.BankKeeper, _ keeper.Keeper,
protoCdc *codec.ProtoCodec) simtypes.Operation {
return func(
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
@ -94,26 +92,26 @@ func SimulateMsgGrantAuthorization(ak types.AccountKeeper, bk types.BankKeeper,
spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
fees, err := simtypes.RandomFees(r, ctx, spendableCoins)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
}
blockTime := ctx.BlockTime()
spendLimit := spendableCoins.Sub(fees)
if spendLimit == nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, "spend limit is nil"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, "spend limit is nil"), nil, nil
}
msg, err := types.NewMsgGrantAuthorization(granter.Address, grantee.Address,
msg, err := authz.NewMsgGrant(granter.Address, grantee.Address,
banktype.NewSendAuthorization(spendLimit), blockTime.AddDate(1, 0, 0))
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
}
txGen := simappparams.MakeTestEncodingConfig().TxConfig
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
_, err = authzMsgClient.GrantAuthorization(context.Background(), msg)
authzMsgClient := authz.NewMsgClient(svcMsgClientConn)
_, err = authzMsgClient.Grant(context.Background(), msg)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
}
tx, err := helpers.GenTx(
txGen,
@ -127,12 +125,12 @@ func SimulateMsgGrantAuthorization(ak types.AccountKeeper, bk types.BankKeeper,
)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, "unable to generate mock tx"), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, "unable to generate mock tx"), nil, err
}
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(svcMsgClientConn.GetMsgs()[0]), "unable to deliver tx"), nil, err
return simtypes.NoOpMsg(authz.ModuleName, sdk.MsgTypeURL(svcMsgClientConn.GetMsgs()[0]), "unable to deliver tx"), nil, err
}
return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "", protoCdc), nil, err
}
@ -140,15 +138,15 @@ func SimulateMsgGrantAuthorization(ak types.AccountKeeper, bk types.BankKeeper,
// SimulateMsgRevokeAuthorization generates a MsgRevokeAuthorization with random values.
// nolint: funlen
func SimulateMsgRevokeAuthorization(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, protoCdc *codec.ProtoCodec) simtypes.Operation {
func SimulateMsgRevokeAuthorization(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, protoCdc *codec.ProtoCodec) simtypes.Operation {
return func(
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
hasGrant := false
var targetGrant types.AuthorizationGrant
var targetGrant authz.Grant
var granterAddr sdk.AccAddress
var granteeAddr sdk.AccAddress
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) bool {
targetGrant = grant
granterAddr = granter
granteeAddr = grantee
@ -157,29 +155,29 @@ func SimulateMsgRevokeAuthorization(ak types.AccountKeeper, bk types.BankKeeper,
})
if !hasGrant {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, "no grants"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, "no grants"), nil, nil
}
granter, ok := simtypes.FindAccount(accs, granterAddr)
if !ok {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, "Account not found"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, "Account not found"), nil, nil
}
account := ak.GetAccount(ctx, granter.Address)
spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
fees, err := simtypes.RandomFees(r, ctx, spendableCoins)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, "fee error"), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, "fee error"), nil, err
}
auth := targetGrant.GetAuthorizationGrant()
msg := types.NewMsgRevokeAuthorization(granterAddr, granteeAddr, auth.MethodName())
auth := targetGrant.GetAuthorization()
msg := authz.NewMsgRevoke(granterAddr, granteeAddr, auth.MsgTypeURL())
txGen := simappparams.MakeTestEncodingConfig().TxConfig
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
_, err = authzMsgClient.RevokeAuthorization(context.Background(), &msg)
authzMsgClient := authz.NewMsgClient(svcMsgClientConn)
_, err = authzMsgClient.Revoke(context.Background(), &msg)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
}
tx, err := helpers.GenTx(
txGen,
@ -193,7 +191,7 @@ func SimulateMsgRevokeAuthorization(ak types.AccountKeeper, bk types.BankKeeper,
)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
}
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
@ -203,16 +201,16 @@ func SimulateMsgRevokeAuthorization(ak types.AccountKeeper, bk types.BankKeeper,
// SimulateMsgExecuteAuthorized generates a MsgExecuteAuthorized with random values.
// nolint: funlen
func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, cdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simtypes.Operation {
func SimulateMsgExecuteAuthorized(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, cdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simtypes.Operation {
return func(
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
hasGrant := false
var targetGrant types.AuthorizationGrant
var targetGrant authz.Grant
var granterAddr sdk.AccAddress
var granteeAddr sdk.AccAddress
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) bool {
targetGrant = grant
granterAddr = granter
granteeAddr = grantee
@ -221,7 +219,7 @@ func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k
})
if !hasGrant {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "Not found"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "Not found"), nil, nil
}
grantee, _ := simtypes.FindAccount(accs, granteeAddr)
@ -230,17 +228,17 @@ func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k
granterspendableCoins := bk.SpendableCoins(ctx, granterAccount.GetAddress())
if granterspendableCoins.Empty() {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "no coins"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "no coins"), nil, nil
}
if targetGrant.Expiration.Before(ctx.BlockHeader().Time) {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "grant expired"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "grant expired"), nil, nil
}
granteespendableCoins := bk.SpendableCoins(ctx, granteeAccount.GetAddress())
fees, err := simtypes.RandomFees(r, ctx, granteespendableCoins)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "fee error"), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "fee error"), nil, err
}
sendCoins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10)))
@ -250,19 +248,19 @@ func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k
sendCoins,
)
msg := types.NewMsgExecAuthorized(grantee.Address, []sdk.Msg{execMsg})
msg := authz.NewMsgExec(grantee.Address, []sdk.Msg{execMsg})
sendGrant := targetGrant.Authorization.GetCachedValue().(*banktype.SendAuthorization)
_, _, err = sendGrant.Accept(ctx, execMsg)
_, err = sendGrant.Accept(ctx, execMsg)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, nil
}
txGen := simappparams.MakeTestEncodingConfig().TxConfig
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
_, err = authzMsgClient.ExecAuthorized(context.Background(), &msg)
authzMsgClient := authz.NewMsgClient(svcMsgClientConn)
_, err = authzMsgClient.Exec(context.Background(), &msg)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
}
tx, err := helpers.GenTx(
txGen,
@ -276,18 +274,18 @@ func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k
)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
}
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
if err != nil {
if strings.Contains(err.Error(), "insufficient fee") {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "insufficient fee"), nil, nil
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "insufficient fee"), nil, nil
}
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
}
msg.UnpackInterfaces(cdc)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "unmarshal error"), nil, err
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "unmarshal error"), nil, err
}
return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "success", protoCdc), nil, nil
}

View File

@ -15,8 +15,8 @@ import (
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
"github.com/cosmos/cosmos-sdk/x/authz/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
@ -54,9 +54,9 @@ func (suite *SimTestSuite) TestWeightedOperations() {
opMsgRoute string
opMsgName string
}{
{simappparams.DefaultWeightMsgDelegate, types.ModuleName, simulation.TypeMsgGrantAuthorization},
{simappparams.DefaultWeightMsgUndelegate, types.ModuleName, simulation.TypeMsgRevokeAuthorization},
{simappparams.DefaultWeightMsgSend, types.ModuleName, simulation.TypeMsgExecDelegated},
{simappparams.DefaultWeightMsgDelegate, authz.ModuleName, simulation.TypeMsgGrantAuthorization},
{simappparams.DefaultWeightMsgUndelegate, authz.ModuleName, simulation.TypeMsgRevokeAuthorization},
{simappparams.DefaultWeightMsgSend, authz.ModuleName, simulation.TypeMsgExecDelegated},
}
for i, w := range weightesOps {
@ -110,7 +110,7 @@ func (suite *SimTestSuite) TestSimulateGrantAuthorization() {
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, ctx, accounts, "")
suite.Require().NoError(err)
var msg types.MsgGrantAuthorizationRequest
var msg authz.MsgGrant
suite.app.AppCodec().UnmarshalJSON(operationMsg.Msg, &msg)
suite.Require().True(operationMsg.OK)
suite.Require().Equal(granter.Address.String(), msg.Granter)
@ -139,7 +139,7 @@ func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
grantee := accounts[1]
authorization := banktypes.NewSendAuthorization(initCoins)
err := suite.app.AuthzKeeper.Grant(suite.ctx, grantee.Address, granter.Address, authorization, time.Now().Add(30*time.Hour))
err := suite.app.AuthzKeeper.SaveGrant(suite.ctx, grantee.Address, granter.Address, authorization, time.Now().Add(30*time.Hour))
suite.Require().NoError(err)
// execute operation
@ -147,13 +147,13 @@ func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
suite.Require().NoError(err)
var msg types.MsgRevokeAuthorizationRequest
var msg authz.MsgRevoke
suite.app.AppCodec().UnmarshalJSON(operationMsg.Msg, &msg)
suite.Require().True(operationMsg.OK)
suite.Require().Equal(granter.Address.String(), msg.Granter)
suite.Require().Equal(grantee.Address.String(), msg.Grantee)
suite.Require().Equal(banktypes.SendAuthorization{}.MethodName(), msg.MethodName)
suite.Require().Equal(banktypes.SendAuthorization{}.MsgTypeURL(), msg.MsgTypeUrl)
suite.Require().Len(futureOperations, 0)
}
@ -174,7 +174,7 @@ func (suite *SimTestSuite) TestSimulateExecAuthorization() {
grantee := accounts[1]
authorization := banktypes.NewSendAuthorization(initCoins)
err := suite.app.AuthzKeeper.Grant(suite.ctx, grantee.Address, granter.Address, authorization, time.Now().Add(30*time.Hour))
err := suite.app.AuthzKeeper.SaveGrant(suite.ctx, grantee.Address, granter.Address, authorization, time.Now().Add(30*time.Hour))
suite.Require().NoError(err)
// execute operation
@ -182,7 +182,7 @@ func (suite *SimTestSuite) TestSimulateExecAuthorization() {
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
suite.Require().NoError(err)
var msg types.MsgExecAuthorizedRequest
var msg authz.MsgExec
suite.app.AppCodec().UnmarshalJSON(operationMsg.Msg, &msg)

View File

@ -4,8 +4,12 @@ order: 1
# Concepts
## Authorization
Any concrete type of authorization defined in the `x/authz` module must fulfill the `Authorization` interface outlined below. Authorizations determine exactly what privileges are granted. They are extensible and can be defined for any Msg service method even outside of the module where the Msg method is defined. Authorizations use the new `ServiceMsg` type from [ADR 031](../../../architecture/adr-031-msg-service.md).
## Authorization and Grant
`x/authz` module defines interfaces and messages grant authorizations to perform actions
on behalf of one account to other accounts. The design is defined in the [ADR 030](../../../architecture/adr-030-authz-module.md).
Grant is an allowance to execute an Msg by grantee address on behalf of the granter.
Authorization is an interface which must be implemented by a concrete authorization logic to validate and execute grants. They are extensible and can be defined for any Msg service method even outside of the module where the Msg method is defined. See the `SendAuthorization` example below for more details.
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/x/authz/types/authorizations.go#L15-L24
@ -17,7 +21,7 @@ Cosmos-SDK `x/authz` module comes with following authorization types
### SendAuthorization
`SendAuthorization` implements `Authorization` interface for the `cosmos.bank.v1beta1.Msg/Send` ServiceMsg, that takes a `SpendLimit` and updates it down to zero.
`SendAuthorization` implements `Authorization` interface for the `cosmos.bank.v1beta1.MsgSend` Msg, that takes a `SpendLimit` and updates it down to zero.
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/proto/cosmos/authz/v1beta1/authz.proto#L12-L19
@ -28,13 +32,14 @@ Cosmos-SDK `x/authz` module comes with following authorization types
### GenericAuthorization
`GenericAuthorization` implements the `Authorization` interface, that gives unrestricted permission to execute the provided ServiceMsg on behalf of granter's account.
`GenericAuthorization` implements the `Authorization` interface, that gives unrestricted permission to execute the provided Msg on behalf of granter's account.
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/proto/cosmos/authz/v1beta1/authz.proto#L21-L30
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/x/authz/types/generic_authorization.go#L20-L28
- `method_name` holds ServiceMsg type.
- `msg` stores Msg type URL.
## Gas
In order to prevent DoS attacks, granting `StakeAuthorizaiton`s with `x/authz` incur gas. `StakeAuthorizaiton` allows you to authorize another account to delegate, undelegate, or redelegate to validators. The authorizer can define a list of validators they will allow and/or deny delegations to. The SDK will iterate over these lists and charge 10 gas for each validator in both of the lists.
In order to prevent DoS attacks, granting `StakeAuthorizaiton`s with `x/authz` incur gas. `StakeAuthorizaiton` allows you to authorize another account to delegate, undelegate, or redelegate to validators. The authorizer can define a list of validators they will allow and/or deny delegations to. The SDK will iterate over these lists and charge 10 gas for each validator in both of the lists.

View File

@ -6,7 +6,7 @@ order: 2
## AuthorizationGrant
Authorizations are identified by combining granter address (the address bytes of the granter), grantee address (the address bytes of the grantee) and ServiceMsg type (its method name).
Grants are identified by combining granter address (the address bytes of the granter), grantee address (the address bytes of the grantee) and Msg type (its TypeURL). Hence we only allow one grant for the (granter, grantee, msg type) triple.
- AuthorizationGrant: `0x01 | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes | msgType_bytes-> ProtocolBuffer(AuthorizationGrant)`

View File

@ -6,32 +6,33 @@ order: 3
In this section we describe the processing of messages for the authz module.
## Msg/GrantAuthorization
## Msg/Grant
An authorization-grant is created using the `MsgGrantAuthorization` message.
An authorization-grant is created using the `MsgGrant` message.
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/proto/cosmos/authz/v1beta1/tx.proto#L27-L35
This message is expected to fail if:
- both granter & grantee have same address.
- provided `Expiration` time less than current unix timestamp.
- provided `Authorization` is not implemented.
- Authorization Method doesn't exist (there is no defined handler in the app router to handle that Msg types)
## Msg/RevokeAuthorization
## Msg/Revoke
An allowed authorization can be removed with `MsgRevokeAuthorization` message.
An allowed authorization can be removed with `MsgRevoke` message.
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/proto/cosmos/authz/v1beta1/tx.proto#L53-L59
This message is expected to fail if:
- both granter & grantee have same address.
- provided `MethodName` is empty.
- provided `MsgTypeUrl` is empty.
## Msg/ExecAuthorizedRequest
## Msg/Exec
When a grantee wants to execute transaction on behalf of a granter, it must send MsgExecAuthorizedRequest.
When a grantee wants to execute transaction on behalf of a granter, it must send MsgExecRequest.
+++ https://github.com/cosmos/cosmos-sdk/blob/c95de9c4177442dee4c69d96917efc955b5d19d9/proto/cosmos/authz/v1beta1/tx.proto#L42-L48
@ -39,4 +40,4 @@ This message is expected to fail if:
- authorization not implemented for the provided msg.
- grantee don't have permission to run transaction.
- if granted authorization is expired.
- if granted authorization is expired.

View File

@ -4,25 +4,4 @@ order: 4
# Events
The authz module emits the following events:
## Keeper
### GrantAuthorization
| Type | Attribute Key | Attribute Value |
|----------------------|-------------------|--------------------|
| grant-authorization | module | authz |
| grant-authorization | grant-type | {msgType} |
| grant-authorization | granter | {granterAddress} |
| grant-authorization | grantee | {granteeAddress} |
### RevokeAuthorization
| Type | Attribute Key | Attribute Value |
|----------------------|-------------------|--------------------|
| revoke-authorization | module | authz |
| revoke-authorization | grant-type | {msgType} |
| revoke-authorization | granter | {granterAddress} |
| revoke-authorization | grantee | {granteeAddress} |
The authz module emits proto events defined in [the Protobuf reference](../../../docs/core/proto-docs.md#cosmos/authz/v1beta1/event.proto).

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
package types
import (
"time"
proto "github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/codec/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
)
// NewAuthorizationGrant returns new AuthrizationGrant
func NewAuthorizationGrant(authorization exported.Authorization, expiration time.Time) (AuthorizationGrant, error) {
auth := AuthorizationGrant{
Expiration: expiration,
}
msg, ok := authorization.(proto.Message)
if !ok {
return AuthorizationGrant{}, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", authorization)
}
any, err := types.NewAnyWithValue(msg)
if err != nil {
return AuthorizationGrant{}, err
}
auth.Authorization = any
return auth, nil
}
var (
_ types.UnpackInterfacesMessage = &AuthorizationGrant{}
)
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (auth AuthorizationGrant) UnpackInterfaces(unpacker types.AnyUnpacker) error {
var authorization exported.Authorization
return unpacker.UnpackAny(auth.Authorization, &authorization)
}
// GetAuthorizationGrant returns the cached value from the AuthorizationGrant.Authorization if present.
func (auth AuthorizationGrant) GetAuthorizationGrant() exported.Authorization {
authorization, ok := auth.Authorization.GetCachedValue().(exported.Authorization)
if !ok {
return nil
}
return authorization
}

View File

@ -1,29 +0,0 @@
package types
import (
types "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
staking "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// RegisterInterfaces registers the interfaces types with the interface registry
func RegisterInterfaces(registry types.InterfaceRegistry) {
registry.RegisterImplementations((*sdk.Msg)(nil),
&MsgGrantAuthorizationRequest{},
&MsgRevokeAuthorizationRequest{},
&MsgExecAuthorizedRequest{},
)
registry.RegisterInterface(
"cosmos.authz.v1beta1.Authorization",
(*exported.Authorization)(nil),
&bank.SendAuthorization{},
&GenericAuthorization{},
&staking.StakeAuthorization{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}

View File

@ -1,14 +0,0 @@
package types
// authz module events
const (
EventGrantAuthorization = "grant-authorization"
EventRevokeAuthorization = "revoke-authorization"
EventExecuteAuthorization = "execute-authorization"
AttributeKeyGrantType = "grant-type"
AttributeKeyGranteeAddress = "grantee"
AttributeKeyGranterAddress = "granter"
AttributeValueCategory = ModuleName
)

View File

@ -1,32 +0,0 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
)
var (
_ exported.Authorization = &GenericAuthorization{}
)
// NewGenericAuthorization creates a new GenericAuthorization object.
func NewGenericAuthorization(methodName string) *GenericAuthorization {
return &GenericAuthorization{
MessageName: methodName,
}
}
// MethodName implements Authorization.MethodName.
func (authorization GenericAuthorization) MethodName() string {
return authorization.MessageName
}
// Accept implements Authorization.Accept.
func (authorization GenericAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (updated exported.Authorization, delete bool, err error) {
return &authorization, false, nil
}
// ValidateBasic implements Authorization.ValidateBasic.
func (authorization GenericAuthorization) ValidateBasic() error {
return nil
}

View File

@ -1,17 +0,0 @@
package types_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/x/authz/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
func TestGenericAuthorization(t *testing.T) {
t.Log("verify ValidateBasic returns nil for service msg")
authorization := types.NewGenericAuthorization(banktypes.SendAuthorization{}.MethodName())
require.NoError(t, authorization.ValidateBasic())
require.Equal(t, banktypes.SendAuthorization{}.MethodName(), authorization.MessageName)
}

View File

@ -1,42 +0,0 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/x/authz/exported"
)
// NewGenesisState creates new GenesisState object
func NewGenesisState(entries []GrantAuthorization) *GenesisState {
return &GenesisState{
Authorization: entries,
}
}
// ValidateGenesis check the given genesis state has no integrity issues
func ValidateGenesis(data GenesisState) error {
return nil
}
// DefaultGenesisState - Return a default genesis state
func DefaultGenesisState() *GenesisState {
return &GenesisState{}
}
var _ types.UnpackInterfacesMessage = GenesisState{}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (data GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error {
for _, authorization := range data.Authorization {
err := authorization.UnpackInterfaces(unpacker)
if err != nil {
return err
}
}
return nil
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg GrantAuthorization) UnpackInterfaces(unpacker types.AnyUnpacker) error {
var authorization exported.Authorization
return unpacker.UnpackAny(msg.Authorization, &authorization)
}

View File

@ -1,52 +0,0 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
)
const (
// ModuleName is the module name constant used in many places
ModuleName = "authz"
// StoreKey is the store key string for authz
StoreKey = ModuleName
// RouterKey is the message route for authz
RouterKey = ModuleName
// QuerierRoute is the querier route for authz
QuerierRoute = ModuleName
)
// Keys for authz store
// Items are stored with the following key: values
//
// - 0x01<granterAddressLen (1 Byte)><granterAddress_Bytes><granteeAddressLen (1 Byte)><granteeAddress_Bytes><msgType_Bytes>: Grant
var (
// Keys for store prefixes
GrantKey = []byte{0x01} // prefix for each key
)
// GetAuthorizationStoreKey - return authorization store key
func GetAuthorizationStoreKey(grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) []byte {
return append(append(append(
GrantKey,
address.MustLengthPrefix(granter)...),
address.MustLengthPrefix(grantee)...),
[]byte(msgType)...,
)
}
// ExtractAddressesFromGrantKey - split granter & grantee address from the authorization key
func ExtractAddressesFromGrantKey(key []byte) (granterAddr, granteeAddr sdk.AccAddress) {
// key if of format:
// 0x01<granterAddressLen (1 Byte)><granterAddress_Bytes><granteeAddressLen (1 Byte)><granteeAddress_Bytes><msgType_Bytes>
granterAddrLen := key[1] // remove prefix key
granterAddr = sdk.AccAddress(key[2 : 2+granterAddrLen])
granteeAddrLen := int(key[2+granterAddrLen])
granteeAddr = sdk.AccAddress(key[3+granterAddrLen : 3+granterAddrLen+byte(granteeAddrLen)])
return granterAddr, granteeAddr
}

View File

@ -1,21 +0,0 @@
package types
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
sdk "github.com/cosmos/cosmos-sdk/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
)
var granter = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
var grantee = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
var msgType = bank.SendAuthorization{}.MethodName()
func TestGrantkey(t *testing.T) {
granter1, grantee1 := ExtractAddressesFromGrantKey(GetAuthorizationStoreKey(grantee, granter, msgType))
require.Equal(t, granter, granter1)
require.Equal(t, grantee, grantee1)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,362 +0,0 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: cosmos/authz/v1beta1/query.proto
/*
Package types is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package types
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var (
filter_Query_Authorization_0 = &utilities.DoubleArray{Encoding: map[string]int{"granter": 0, "grantee": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
)
func request_Query_Authorization_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryAuthorizationRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["granter"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
}
protoReq.Granter, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
}
val, ok = pathParams["grantee"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
}
protoReq.Grantee, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorization_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Authorization(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_Authorization_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryAuthorizationRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["granter"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
}
protoReq.Granter, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
}
val, ok = pathParams["grantee"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
}
protoReq.Grantee, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorization_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Authorization(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_Query_Authorizations_0 = &utilities.DoubleArray{Encoding: map[string]int{"granter": 0, "grantee": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
)
func request_Query_Authorizations_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryAuthorizationsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["granter"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
}
protoReq.Granter, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
}
val, ok = pathParams["grantee"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
}
protoReq.Grantee, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorizations_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Authorizations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_Authorizations_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryAuthorizationsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["granter"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
}
protoReq.Granter, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
}
val, ok = pathParams["grantee"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
}
protoReq.Grantee, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorizations_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Authorizations(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
mux.Handle("GET", pattern_Query_Authorization_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_Authorization_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Authorization_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_Authorizations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_Authorizations_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Authorizations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterQueryHandler(ctx, mux, conn)
}
// RegisterQueryHandler registers the http handlers for service Query to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
}
// RegisterQueryHandlerClient registers the http handlers for service Query
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "QueryClient" to call the correct interceptors.
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
mux.Handle("GET", pattern_Query_Authorization_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_Authorization_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Authorization_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_Authorizations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_Authorizations_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Authorizations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Query_Authorization_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7}, []string{"cosmos", "authz", "v1beta1", "granters", "granter", "grantees", "grantee", "grant"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_Authorizations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7}, []string{"cosmos", "authz", "v1beta1", "granters", "granter", "grantees", "grantee", "grants"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_Authorization_0 = runtime.ForwardResponseMessage
forward_Query_Authorizations_0 = runtime.ForwardResponseMessage
)

View File

@ -6,6 +6,7 @@ import (
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/cosmos/cosmos-sdk/x/authz"
)
// RegisterLegacyAminoCodec registers the necessary x/bank interfaces and concrete types
@ -20,6 +21,10 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgSend{},
&MsgMultiSend{},
)
registry.RegisterImplementations(
(*authz.Authorization)(nil),
&SendAuthorization{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}

View File

@ -3,7 +3,7 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authz "github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz"
)
var (
@ -17,36 +17,35 @@ func NewSendAuthorization(spendLimit sdk.Coins) *SendAuthorization {
}
}
// MethodName implements Authorization.MethodName.
func (authorization SendAuthorization) MethodName() string {
// MethodName implements Authorization.MsgTypeURL.
func (a SendAuthorization) MsgTypeURL() string {
return sdk.MsgTypeURL(&MsgSend{})
}
// Accept implements Authorization.Accept.
func (authorization SendAuthorization) Accept(_ sdk.Context, msg sdk.Msg) (updated authz.Authorization, delete bool, err error) {
msgSend, ok := msg.(*MsgSend)
func (a SendAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authz.AcceptResponse, error) {
mSend, ok := msg.(*MsgSend)
if !ok {
return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "type mismatch")
return authz.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch")
}
limitLeft, isNegative := authorization.SpendLimit.SafeSub(msgSend.Amount)
limitLeft, isNegative := a.SpendLimit.SafeSub(mSend.Amount)
if isNegative {
return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "requested amount is more than spend limit")
return authz.AcceptResponse{}, sdkerrors.ErrInsufficientFunds.Wrapf("requested amount is more than spend limit")
}
if limitLeft.IsZero() {
return nil, true, nil
return authz.AcceptResponse{Accept: true, Delete: true}, nil
}
return &SendAuthorization{SpendLimit: limitLeft}, false, nil
return authz.AcceptResponse{Accept: true, Delete: false, Updated: &SendAuthorization{SpendLimit: limitLeft}}, nil
}
// ValidateBasic implements Authorization.ValidateBasic.
func (authorization SendAuthorization) ValidateBasic() error {
if authorization.SpendLimit == nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "spend limit cannot be nil")
func (a SendAuthorization) ValidateBasic() error {
if a.SpendLimit == nil {
return sdkerrors.ErrInvalidCoins.Wrap("spend limit cannot be nil")
}
if !authorization.SpendLimit.IsAllPositive() {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "spend limit cannot be negitive")
if !a.SpendLimit.IsAllPositive() {
return sdkerrors.ErrInvalidCoins.Wrapf("spend limit cannot be negitive")
}
return nil
}

View File

@ -24,35 +24,35 @@ func TestSendAuthorization(t *testing.T) {
authorization := types.NewSendAuthorization(coins1000)
t.Log("verify authorization returns valid method name")
require.Equal(t, authorization.MethodName(), "/cosmos.bank.v1beta1.MsgSend")
require.Equal(t, authorization.MsgTypeURL(), "/cosmos.bank.v1beta1.MsgSend")
require.NoError(t, authorization.ValidateBasic())
send := types.NewMsgSend(fromAddr, toAddr, coins1000)
require.NoError(t, authorization.ValidateBasic())
t.Log("verify updated authorization returns nil")
updated, del, err := authorization.Accept(ctx, send)
resp, err := authorization.Accept(ctx, send)
require.NoError(t, err)
require.True(t, del)
require.Nil(t, updated)
require.True(t, resp.Delete)
require.Nil(t, resp.Updated)
authorization = types.NewSendAuthorization(coins1000)
require.Equal(t, authorization.MethodName(), "/cosmos.bank.v1beta1.MsgSend")
require.Equal(t, authorization.MsgTypeURL(), "/cosmos.bank.v1beta1.MsgSend")
require.NoError(t, authorization.ValidateBasic())
send = types.NewMsgSend(fromAddr, toAddr, coins500)
require.NoError(t, authorization.ValidateBasic())
updated, del, err = authorization.Accept(ctx, send)
resp, err = authorization.Accept(ctx, send)
t.Log("verify updated authorization returns remaining spent limit")
require.NoError(t, err)
require.False(t, del)
require.NotNil(t, updated)
require.False(t, resp.Delete)
require.NotNil(t, resp.Updated)
sendAuth := types.NewSendAuthorization(coins500)
require.Equal(t, sendAuth.String(), updated.String())
require.Equal(t, sendAuth.String(), resp.Updated.String())
t.Log("expect updated authorization nil after spending remaining amount")
updated, del, err = updated.Accept(ctx, send)
resp, err = resp.Updated.Accept(ctx, send)
require.NoError(t, err)
require.True(t, del)
require.Nil(t, updated)
require.True(t, resp.Delete)
require.Nil(t, resp.Updated)
}

View File

@ -3,13 +3,14 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authz "github.com/cosmos/cosmos-sdk/x/authz/exported"
"github.com/cosmos/cosmos-sdk/x/authz"
)
// TODO: Revisit this once we have propoer gas fee framework.
// Tracking issues https://github.com/cosmos/cosmos-sdk/issues/9054, https://github.com/cosmos/cosmos-sdk/discussions/9072
const gasCostPerIteration = uint64(10)
// Normalized Msg type URLs
var (
_ authz.Authorization = &StakeAuthorization{}
)
@ -21,35 +22,35 @@ func NewStakeAuthorization(allowed []sdk.ValAddress, denied []sdk.ValAddress, au
return nil, err
}
authorization := StakeAuthorization{}
a := StakeAuthorization{}
if allowedValidators != nil {
authorization.Validators = &StakeAuthorization_AllowList{AllowList: &StakeAuthorization_Validators{Address: allowedValidators}}
a.Validators = &StakeAuthorization_AllowList{AllowList: &StakeAuthorization_Validators{Address: allowedValidators}}
} else {
authorization.Validators = &StakeAuthorization_DenyList{DenyList: &StakeAuthorization_Validators{Address: deniedValidators}}
a.Validators = &StakeAuthorization_DenyList{DenyList: &StakeAuthorization_Validators{Address: deniedValidators}}
}
if amount != nil {
authorization.MaxTokens = amount
a.MaxTokens = amount
}
authorization.AuthorizationType = authzType
a.AuthorizationType = authzType
return &authorization, nil
return &a, nil
}
// MethodName implements Authorization.MethodName.
func (authorization StakeAuthorization) MethodName() string {
authzType, err := normalizeAuthzType(authorization.AuthorizationType)
// MsgTypeURL implements Authorization.MsgTypeURL.
func (a StakeAuthorization) MsgTypeURL() string {
authzType, err := normalizeAuthzType(a.AuthorizationType)
if err != nil {
panic(err)
}
return authzType
}
func (authorization StakeAuthorization) ValidateBasic() error {
if authorization.MaxTokens != nil && authorization.MaxTokens.IsNegative() {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "negative coin amount: %v", authorization.MaxTokens)
func (a StakeAuthorization) ValidateBasic() error {
if a.MaxTokens != nil && a.MaxTokens.IsNegative() {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "negative coin amount: %v", a.MaxTokens)
}
if authorization.AuthorizationType == AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED {
if a.AuthorizationType == AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown authorization type")
}
@ -57,7 +58,7 @@ func (authorization StakeAuthorization) ValidateBasic() error {
}
// Accept implements Authorization.Accept.
func (authorization StakeAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (updated authz.Authorization, delete bool, err error) {
func (a StakeAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authz.AcceptResponse, error) {
var validatorAddress string
var amount sdk.Coin
@ -72,11 +73,11 @@ func (authorization StakeAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (up
validatorAddress = msg.ValidatorDstAddress
amount = msg.Amount
default:
return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "unknown msg type")
return authz.AcceptResponse{}, sdkerrors.ErrInvalidRequest.Wrap("unknown msg type")
}
isValidatorExists := false
allowedList := authorization.GetAllowList().GetAddress()
allowedList := a.GetAllowList().GetAddress()
for _, validator := range allowedList {
ctx.GasMeter().ConsumeGas(gasCostPerIteration, "stake authorization")
if validator == validatorAddress {
@ -85,38 +86,38 @@ func (authorization StakeAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (up
}
}
denyList := authorization.GetDenyList().GetAddress()
denyList := a.GetDenyList().GetAddress()
for _, validator := range denyList {
ctx.GasMeter().ConsumeGas(gasCostPerIteration, "stake authorization")
if validator == validatorAddress {
return nil, false, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, " cannot delegate/undelegate to %s validator", validator)
return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf(" cannot delegate/undelegate to %s validator", validator)
}
}
if !isValidatorExists {
return nil, false, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot delegate/undelegate to %s validator", validatorAddress)
return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("cannot delegate/undelegate to %s validator", validatorAddress)
}
if authorization.MaxTokens == nil {
return &StakeAuthorization{Validators: authorization.GetValidators(), AuthorizationType: authorization.GetAuthorizationType()}, false, nil
if a.MaxTokens == nil {
return authz.AcceptResponse{Accept: true, Delete: false,
Updated: &StakeAuthorization{Validators: a.GetValidators(), AuthorizationType: a.GetAuthorizationType()}}, nil
}
limitLeft := authorization.MaxTokens.Sub(amount)
limitLeft := a.MaxTokens.Sub(amount)
if limitLeft.IsZero() {
return nil, true, nil
return authz.AcceptResponse{Accept: true, Delete: true}, nil
}
return &StakeAuthorization{Validators: authorization.GetValidators(), MaxTokens: &limitLeft, AuthorizationType: authorization.GetAuthorizationType()}, false, nil
return authz.AcceptResponse{Accept: true, Delete: false,
Updated: &StakeAuthorization{Validators: a.GetValidators(), AuthorizationType: a.GetAuthorizationType(), MaxTokens: &limitLeft}}, nil
}
func validateAndBech32fy(allowed []sdk.ValAddress, denied []sdk.ValAddress) ([]string, []string, error) {
if len(allowed) == 0 && len(denied) == 0 {
return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "both allowed & deny list cannot be empty")
return nil, nil, sdkerrors.ErrInvalidRequest.Wrap("both allowed & deny list cannot be empty")
}
if len(allowed) > 0 && len(denied) > 0 {
return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "cannot set both allowed & deny list")
return nil, nil, sdkerrors.ErrInvalidRequest.Wrap("cannot set both allowed & deny list")
}
allowedValidators := make([]string, len(allowed))
@ -144,6 +145,6 @@ func normalizeAuthzType(authzType AuthorizationType) (string, error) {
case AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE:
return sdk.MsgTypeURL(&MsgBeginRedelegate{}), nil
default:
return "", sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown authorization type %T", authzType)
return "", sdkerrors.ErrInvalidType.Wrapf("unknown authorization type %T", authzType)
}
}

View File

@ -32,7 +32,7 @@ func TestAuthzAuthorizations(t *testing.T) {
// verify MethodName
delAuth, err = stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100)
require.NoError(t, err)
require.Equal(t, delAuth.MethodName(), sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}))
require.Equal(t, delAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}))
// error both allow & deny list
_, err = stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{val1}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100)
@ -40,11 +40,11 @@ func TestAuthzAuthorizations(t *testing.T) {
// verify MethodName
undelAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100)
require.Equal(t, undelAuth.MethodName(), sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}))
require.Equal(t, undelAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}))
// verify MethodName
beginRedelAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100)
require.Equal(t, beginRedelAuth.MethodName(), sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}))
require.Equal(t, beginRedelAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}))
validators1_2 := []string{val1.String(), val2.String()}
@ -251,15 +251,14 @@ func TestAuthzAuthorizations(t *testing.T) {
t.Run(tc.msg, func(t *testing.T) {
delAuth, err := stakingtypes.NewStakeAuthorization(tc.allowed, tc.denied, tc.msgType, tc.limit)
require.NoError(t, err)
updated, del, err := delAuth.Accept(ctx, tc.srvMsg)
resp, err := delAuth.Accept(ctx, tc.srvMsg)
require.Equal(t, tc.isDelete, resp.Delete)
if tc.expectErr {
require.Error(t, err)
require.Equal(t, tc.isDelete, del)
} else {
require.NoError(t, err)
require.Equal(t, tc.isDelete, del)
if tc.updatedAuthorization != nil {
require.Equal(t, tc.updatedAuthorization.String(), updated.String())
require.Equal(t, tc.updatedAuthorization.String(), resp.Updated.String())
}
}
})

View File

@ -6,6 +6,7 @@ import (
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/cosmos/cosmos-sdk/x/authz"
)
// RegisterLegacyAminoCodec registers the necessary x/staking interfaces and concrete types
@ -27,6 +28,10 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgUndelegate{},
&MsgBeginRedelegate{},
)
registry.RegisterImplementations(
(*authz.Authorization)(nil),
&StakeAuthorization{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}