Skip to content

Commit

Permalink
[feature] hyperledger-iroha#3624: introduce general purpose permissio…
Browse files Browse the repository at this point in the history
…n tokens

Signed-off-by: Marin Veršić <marin.versic101@gmail.com>
  • Loading branch information
mversic committed Jul 10, 2023
1 parent d3f7271 commit 1fbc566
Show file tree
Hide file tree
Showing 54 changed files with 904 additions and 1,469 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions client/benches/tps/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,10 @@ impl MeasurerUnit {
));
self.client.submit_blocking(register_me)?;

let can_burn_my_asset = PermissionToken::new("can_burn_user_asset".parse()?)
.with_params([("asset_id".parse()?, asset_id.clone().into())]);
let can_burn_my_asset = PermissionToken::new("CanBurnUserAsset".to_owned(), &asset_id);
let allow_alice_to_burn_my_asset = GrantBox::new(can_burn_my_asset, alice_id.clone());
let can_transfer_my_asset = PermissionToken::new("can_transfer_user_asset".parse()?)
.with_params([("asset_id".parse()?, asset_id.clone().into())]);
let can_transfer_my_asset =
PermissionToken::new("CanTransferUserAsset".to_owned(), &asset_id);
let allow_alice_to_transfer_my_asset = GrantBox::new(can_transfer_my_asset, alice_id);
let grant_tx = TransactionBuilder::new(account_id)
.with_instructions([
Expand Down
3 changes: 1 addition & 2 deletions client/tests/integration/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ fn find_rate_and_make_exchange_isi_should_succeed() {

let grant_alice_asset_transfer_permission = |asset_id: AssetId, owner_keypair: KeyPair| {
let allow_alice_to_transfer_asset = GrantBox::new(
PermissionToken::new("can_transfer_user_asset".parse().expect("Valid"))
.with_params([("asset_id".parse().expect("Valid"), asset_id.clone().into())]),
PermissionToken::new("CanTransferUserAsset".to_owned(), &asset_id),
alice_id.clone(),
);

Expand Down
23 changes: 7 additions & 16 deletions client/tests/integration/events/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{fmt::Write as _, str::FromStr, sync::mpsc, thread};

use eyre::Result;
use iroha_data_model::{prelude::*, transaction::WasmSmartContract};
use parity_scale_codec::Encode;
use parity_scale_codec::Encode as _;
use test_network::*;

use crate::wasm::utils::wasm_template;
Expand Down Expand Up @@ -163,17 +163,8 @@ fn produce_multiple_events() -> Result<()> {
// Registering role
let alice_id = <Account as Identifiable>::Id::from_str("alice@wonderland")?;
let role_id = <Role as Identifiable>::Id::from_str("TEST_ROLE")?;
let token_1 = PermissionToken::new(
"can_remove_key_value_in_user_account"
.parse()
.expect("valid"),
)
.with_params([(
"account_id".parse().expect("valid"),
alice_id.clone().into(),
)]);
let token_2 = PermissionToken::new("can_set_key_value_in_user_account".parse().expect("valid"))
.with_params([("account_id".parse().expect("valid"), alice_id.into())]);
let token_1 = PermissionToken::new("CanRemoveKeyValueInUserAccount".to_owned(), &alice_id);
let token_2 = PermissionToken::new("CanSetKeyValueInUserAccount".to_owned(), &alice_id);
let role = iroha_data_model::role::Role::new(role_id.clone())
.add_permission(token_1.clone())
.add_permission(token_2.clone());
Expand Down Expand Up @@ -207,13 +198,13 @@ fn produce_multiple_events() -> Result<()> {
WorldEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdded(
AccountPermissionChanged {
account_id: bob_id.clone(),
permission_id: token_1.definition_id().clone(),
permission_id: token_1.definition_id.clone(),
},
))),
WorldEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdded(
AccountPermissionChanged {
account_id: bob_id.clone(),
permission_id: token_2.definition_id().clone(),
permission_id: token_2.definition_id.clone(),
},
))),
WorldEvent::Domain(DomainEvent::Account(AccountEvent::RoleGranted(
Expand All @@ -225,13 +216,13 @@ fn produce_multiple_events() -> Result<()> {
WorldEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemoved(
AccountPermissionChanged {
account_id: bob_id.clone(),
permission_id: token_1.definition_id().clone(),
permission_id: token_1.definition_id,
},
))),
WorldEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemoved(
AccountPermissionChanged {
account_id: bob_id.clone(),
permission_id: token_2.definition_id().clone(),
permission_id: token_2.definition_id,
},
))),
WorldEvent::Domain(DomainEvent::Account(AccountEvent::RoleRevoked(
Expand Down
59 changes: 15 additions & 44 deletions client/tests/integration/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,7 @@ fn permissions_differ_not_only_by_names() {
// Granting permission to Alice to modify metadata in Mouse's hats
let mouse_hat_id = <Asset as Identifiable>::Id::new(hat_definition_id, mouse_id.clone());
let allow_alice_to_set_key_value_in_hats = GrantBox::new(
PermissionToken::new("can_set_key_value_in_user_asset".parse().expect("Valid"))
.with_params([(
"asset_id".parse().expect("Valid"),
mouse_hat_id.clone().into(),
)]),
PermissionToken::new("CanSetKeyValueInUserAsset".to_owned(), &mouse_hat_id),
alice_id.clone(),
);

Expand Down Expand Up @@ -219,8 +215,7 @@ fn permissions_differ_not_only_by_names() {

// Granting permission to Alice to modify metadata in Mouse's shoes
let allow_alice_to_set_key_value_in_shoes = GrantBox::new(
PermissionToken::new("can_set_key_value_in_user_asset".parse().expect("Valid"))
.with_params([("asset_id".parse().expect("Valid"), mouse_shoes_id.into())]),
PermissionToken::new("CanSetKeyValueInUserAsset".to_owned(), &mouse_shoes_id),
alice_id,
);

Expand All @@ -242,23 +237,13 @@ fn permissions_differ_not_only_by_names() {
mod token_parameters {
use super::*;

static TEST_TOKEN_DEFINITION_ID: once_cell::sync::Lazy<
<PermissionTokenDefinition as Identifiable>::Id,
> = once_cell::sync::Lazy::new(|| {
<PermissionTokenDefinition as Identifiable>::Id::new(
"test_permission_token_definition".parse().expect("Valid"),
)
});

static NUMBER_PARAMETER_NAME: once_cell::sync::Lazy<Name> =
once_cell::sync::Lazy::new(|| "number".parse().expect("Valid"));
static STRING_PARAMETER_NAME: once_cell::sync::Lazy<Name> =
once_cell::sync::Lazy::new(|| "string".parse().expect("Valid"));
static TEST_TOKEN_DEFINITION_ID: once_cell::sync::Lazy<PermissionTokenId> =
once_cell::sync::Lazy::new(|| "TestPermissionTokenDefinition".parse().expect("Valid"));

#[ignore = "ignore, more in #2851"]
#[test]
fn token_with_missing_parameters_is_not_accepted() {
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone());
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone(), &());
let expect = "Expected to fail to grant permission token without parameters";

run_grant_token_error_test(token.clone(), expect);
Expand All @@ -268,8 +253,7 @@ mod token_parameters {
#[ignore = "ignore, more in #2851"]
#[test]
fn token_with_one_missing_parameter_is_not_accepted() {
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone())
.with_params([(NUMBER_PARAMETER_NAME.clone(), 1_u32.into())]);
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone(), &1_u32);
let expect = "Expected to fail to grant permission token with one missing parameter";

run_grant_token_error_test(token.clone(), expect);
Expand All @@ -279,13 +263,7 @@ mod token_parameters {
#[ignore = "ignore, more in #2851"]
#[test]
fn token_with_changed_parameter_name_is_not_accepted() {
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone()).with_params([
(NUMBER_PARAMETER_NAME.clone(), 1_u32.into()),
(
"it's_a_trap".parse().expect("Valid"),
"test".to_owned().into(),
),
]);
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone(), &(1_u32, "test"));
let expect = "Expected to fail to grant permission token with one changed parameter";

run_grant_token_error_test(token.clone(), expect);
Expand All @@ -295,14 +273,10 @@ mod token_parameters {
#[ignore = "ignore, more in #2851"]
#[test]
fn token_with_extra_parameter_is_not_accepted() {
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone()).with_params([
(NUMBER_PARAMETER_NAME.clone(), 1_u32.into()),
(STRING_PARAMETER_NAME.clone(), "test".to_owned().into()),
(
"extra_param".parse().expect("Valid"),
"extra_test".to_owned().into(),
),
]);
let token = PermissionToken::new(
TEST_TOKEN_DEFINITION_ID.clone(),
&(1_u32, "test", "extra_test"),
);
let expect = "Expected to fail to grant permission token with extra parameter";

run_grant_token_error_test(token.clone(), expect);
Expand All @@ -312,13 +286,10 @@ mod token_parameters {
#[ignore = "ignore, more in #2851"]
#[test]
fn token_with_wrong_parameter_type_is_not_accepted() {
let token = PermissionToken::new(TEST_TOKEN_DEFINITION_ID.clone()).with_params([
(NUMBER_PARAMETER_NAME.clone(), 1_u32.into()),
(
STRING_PARAMETER_NAME.clone(),
Value::Name("test".parse().expect("Valid")),
),
]);
let token = PermissionToken::new(
TEST_TOKEN_DEFINITION_ID.clone(),
&(91_u32, Value::Name("test".parse().expect("Valid"))),
);
let expect = "Expected to fail to grant permission token with wrong parameter type";

run_grant_token_error_test(token.clone(), expect);
Expand Down
15 changes: 4 additions & 11 deletions client/tests/integration/queries/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,10 @@ fn find_roles_by_account_id() -> Result<()> {
.iter()
.cloned()
.map(|role_id| {
RegisterBox::new(
Role::new(role_id).add_permission(
PermissionToken::new(
"can_set_key_value_in_user_account".parse().expect("Valid"),
)
.with_params([(
"account_id".parse().expect("Valid"),
alice_id.clone().into(),
)]),
),
)
RegisterBox::new(Role::new(role_id).add_permission(PermissionToken::new(
"CanSetKeyValueInUserAccount".to_owned(),
&alice_id,
)))
})
.collect::<Vec<_>>();
test_client.submit_all_blocking(register_roles)?;
Expand Down
27 changes: 12 additions & 15 deletions client/tests/integration/roles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn register_role_with_empty_token_params() -> Result<()> {
wait_for_genesis_committed(&vec![test_client.clone()], 0);

let role_id = "root".parse().expect("Valid");
let token = PermissionToken::new("token".parse().expect("Valid"));
let token = PermissionToken::new("token".to_owned(), &());
let role = Role::new(role_id).add_permission(token);

test_client.submit(RegisterBox::new(role))?;
Expand Down Expand Up @@ -61,14 +61,14 @@ fn register_and_grant_role_for_metadata_access() -> Result<()> {
// Registering role
let role_id = <Role as Identifiable>::Id::from_str("ACCESS_TO_MOUSE_METADATA")?;
let role = Role::new(role_id.clone())
.add_permission(
PermissionToken::new("can_set_key_value_in_user_account".parse()?)
.with_params([("account_id".parse()?, mouse_id.clone().into())]),
)
.add_permission(
PermissionToken::new("can_remove_key_value_in_user_account".parse()?)
.with_params([("account_id".parse()?, mouse_id.clone().into())]),
);
.add_permission(PermissionToken::new(
"CanSetKeyValueInUserAccount".to_owned(),
&mouse_id,
))
.add_permission(PermissionToken::new(
"CanRemoveKeyValueInUserAccount".to_owned(),
&mouse_id,
));
let register_role = RegisterBox::new(role);
test_client.submit_blocking(register_role)?;

Expand Down Expand Up @@ -108,12 +108,9 @@ fn unregistered_role_removed_from_account() -> Result<()> {
test_client.submit_blocking(register_mouse)?;

// Register root role
let register_role = RegisterBox::new(
Role::new(role_id.clone()).add_permission(
PermissionToken::new("can_set_key_value_in_user_account".parse()?)
.with_params([("account_id".parse()?, alice_id.into())]),
),
);
let register_role = RegisterBox::new(Role::new(role_id.clone()).add_permission(
PermissionToken::new("CanSetKeyValueInUserAccount".to_owned(), &alice_id),
));
test_client.submit_blocking(register_role)?;

// Grant root role to Mouse
Expand Down
3 changes: 3 additions & 0 deletions client/tests/integration/smartcontracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ codegen-units = 1 # Further reduces binary size but increases compilation time
[workspace.dependencies]
iroha_validator = { version = "=2.0.0-pre-rc.16", path = "../../../../wasm/validator", features = ["default-validator"] }
iroha_wasm = { version = "=2.0.0-pre-rc.16", path = "../../../../wasm", features = ["debug"]}
iroha_schema = { version = "=2.0.0-pre-rc.16", path = "../../../../schema" }

parity-scale-codec = { version = "3.2.1", default-features = false }
panic-halt = "0.2.0"
6 changes: 3 additions & 3 deletions client/tests/integration/smartcontracts/mint_rose/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use iroha_wasm::data_model::prelude::*;

/// Mint 1 rose for authority
#[iroha_wasm::main(params = "[authority]")]
fn main(authority: <Account as Identifiable>::Id) {
let rose_definition_id = <AssetDefinition as Identifiable>::Id::from_str("rose#wonderland")
fn main(authority: AccountId) {
let rose_definition_id = AssetDefinitionId::from_str("rose#wonderland")
.dbg_expect("Failed to parse `rose#wonderland` asset definition id");
let rose_id = <Asset as Identifiable>::Id::new(rose_definition_id, authority);
let rose_id = AssetId::new(rose_definition_id, authority);

MintBox::new(1_u32, rose_id)
.execute()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ crate-type = ['cdylib']

[dependencies]
iroha_validator.workspace = true
iroha_schema.workspace = true

panic-halt.workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
//! If authority is not `admin@admin` then [`DefaultValidator`] is used as a backup.
#![no_std]

extern crate alloc;

use iroha_validator::{
data_model::evaluate::{EvaluationError, ExpressionEvaluator},
parse,
Expand Down Expand Up @@ -92,8 +90,8 @@ impl Visit for CustomValidator {
}

impl Validate for CustomValidator {
fn permission_tokens() -> Vec<PermissionTokenDefinition> {
DefaultValidator::permission_tokens()
fn permission_token_schema() -> PermissionTokenSchema {
DefaultValidator::permission_token_schema()
}

fn verdict(&self) -> &Result {
Expand All @@ -116,8 +114,8 @@ impl ExpressionEvaluator for CustomValidator {

/// Entrypoint to return permission token definitions defined in this validator.
#[entrypoint]
pub fn permission_tokens() -> Vec<PermissionTokenDefinition> {
CustomValidator::permission_tokens()
pub fn permission_token_schema() -> PermissionTokenSchema {
CustomValidator::permission_token_schema()
}

/// Allow operation if authority is `admin@admin` and if not,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ crate-type = ['cdylib']

[dependencies]
iroha_validator.workspace = true
iroha_schema.workspace = true

parity-scale-codec.workspace = true
panic-halt.workspace = true
Loading

0 comments on commit 1fbc566

Please sign in to comment.