Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix] #3853: Compare permission token payload as JSON #3855

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 93 additions & 50 deletions client/tests/integration/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use iroha_genesis::GenesisNetwork;
use serde_json::json;
use test_network::{PeerBuilder, *};

use super::Configuration;

#[test]
fn genesis_transactions_are_validated() {
const POLL_PERIOD: Duration = Duration::from_millis(1000);
Expand Down Expand Up @@ -61,127 +59,124 @@ fn genesis_transactions_are_validated() {
}
}

fn get_assets(iroha_client: &mut Client, id: &<Account as Identifiable>::Id) -> Vec<Asset> {
fn get_assets(iroha_client: &Client, id: &AccountId) -> Vec<Asset> {
iroha_client
.request(client::asset::by_account_id(id.clone()))
.expect("Failed to execute request.")
.collect::<QueryResult<Vec<_>>>()
.expect("Failed to execute request.")
}

#[ignore = "ignore, more in #2851"]
#[test]
#[ignore = "ignore, more in #2851"]
mversic marked this conversation as resolved.
Show resolved Hide resolved
fn permissions_disallow_asset_transfer() {
let (_rt, _peer, mut iroha_client) =
<PeerBuilder>::new().with_port(10_730).start_with_runtime();
let (_rt, _peer, iroha_client) = <PeerBuilder>::new().with_port(10_730).start_with_runtime();
wait_for_genesis_committed(&[iroha_client.clone()], 0);
let pipeline_time = Configuration::pipeline_time();

// Given
let alice_id = <Account as Identifiable>::Id::from_str("alice@wonderland").expect("Valid");
let bob_id = <Account as Identifiable>::Id::from_str("bob@wonderland").expect("Valid");
let alice_id = "alice@wonderland".parse().expect("Valid");
let bob_id: AccountId = "bob@wonderland".parse().expect("Valid");
let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid");
let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse().expect("Valid");
let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone()));
let register_bob = RegisterBox::new(Account::new(bob_id.clone(), []));
let mouse_keypair = iroha_crypto::KeyPair::generate().expect("Failed to generate KeyPair.");

let alice_start_assets = get_assets(&mut iroha_client, &alice_id);
let alice_start_assets = get_assets(&iroha_client, &alice_id);
iroha_client
.submit_all([create_asset, register_bob])
.submit_blocking(create_asset)
.expect("Failed to prepare state.");
thread::sleep(pipeline_time * 2);

let quantity: u32 = 200;
let mint_asset = MintBox::new(
quantity.to_value(),
IdBox::AssetId(AssetId::new(asset_definition_id.clone(), bob_id.clone())),
);
iroha_client
.submit(mint_asset)
.submit_blocking(mint_asset)
.expect("Failed to create asset.");
thread::sleep(pipeline_time * 2);

//When
let transfer_asset = TransferBox::new(
IdBox::AssetId(AssetId::new(asset_definition_id, bob_id)),
quantity.to_value(),
IdBox::AccountId(alice_id.clone()),
);
let transfer_tx = TransactionBuilder::new(mouse_id)
.with_instructions([transfer_asset])
.sign(mouse_keypair)
.expect("Failed to sign mouse transaction");
let err = iroha_client
.submit_blocking(transfer_asset)
.submit_transaction_blocking(&transfer_tx)
.expect_err("Transaction was not rejected.");
let rejection_reason = err
.downcast_ref::<PipelineRejectionReason>()
.unwrap_or_else(|| panic!("Error {err} is not PipelineRejectionReason"));
.expect("Error {err} is not PipelineRejectionReason");
//Then
assert!(matches!(
rejection_reason,
&PipelineRejectionReason::Transaction(TransactionRejectionReason::Validation(
ValidationFail::NotPermitted(_)
))
));
let alice_assets = get_assets(&mut iroha_client, &alice_id);
let alice_assets = get_assets(&iroha_client, &alice_id);
assert_eq!(alice_assets, alice_start_assets);
}

#[ignore = "ignore, more in #2851"]
#[test]
#[ignore = "ignore, more in #2851"]
fn permissions_disallow_asset_burn() {
let (_rt, _not_drop, mut iroha_client) =
<PeerBuilder>::new().with_port(10_735).start_with_runtime();
let pipeline_time = Configuration::pipeline_time();

// Given
thread::sleep(pipeline_time * 5);
let (_rt, _peer, iroha_client) = <PeerBuilder>::new().with_port(10_735).start_with_runtime();

let alice_id = "alice@wonderland".parse().expect("Valid");
let bob_id: <Account as Identifiable>::Id = "bob@wonderland".parse().expect("Valid");
let bob_id: AccountId = "bob@wonderland".parse().expect("Valid");
let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid");
let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid");
let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone()));
let register_bob = RegisterBox::new(Account::new(bob_id.clone(), []));
let mouse_keypair = iroha_crypto::KeyPair::generate().expect("Failed to generate KeyPair.");

let alice_start_assets = get_assets(&mut iroha_client, &alice_id);
let alice_start_assets = get_assets(&iroha_client, &alice_id);

iroha_client
.submit_all([create_asset, register_bob])
.submit_blocking(create_asset)
.expect("Failed to prepare state.");

thread::sleep(pipeline_time * 2);

let quantity: u32 = 200;
let mint_asset = MintBox::new(
quantity.to_value(),
IdBox::AssetId(AssetId::new(asset_definition_id.clone(), bob_id.clone())),
IdBox::AssetId(AssetId::new(asset_definition_id.clone(), bob_id)),
);
iroha_client
.submit_all([mint_asset])
.submit_blocking(mint_asset)
.expect("Failed to create asset.");
thread::sleep(pipeline_time * 2);
//When
let burn_asset = BurnBox::new(
quantity.to_value(),
IdBox::AssetId(AssetId::new(asset_definition_id, bob_id)),
IdBox::AssetId(AssetId::new(asset_definition_id, mouse_id.clone())),
);
let burn_tx = TransactionBuilder::new(mouse_id)
.with_instructions([burn_asset])
.sign(mouse_keypair)
.expect("Failed to sign mouse transaction");

let err = iroha_client
.submit_blocking(burn_asset)
.submit_transaction_blocking(&burn_tx)
.expect_err("Transaction was not rejected.");
let rejection_reason = err
.downcast_ref::<PipelineRejectionReason>()
.unwrap_or_else(|| panic!("Error {err} is not PipelineRejectionReason"));
//Then
.expect("Error {err} is not PipelineRejectionReason");

assert!(matches!(
rejection_reason,
&PipelineRejectionReason::Transaction(TransactionRejectionReason::Validation(
ValidationFail::NotPermitted(_)
))
));

let alice_assets = get_assets(&mut iroha_client, &alice_id);
let alice_assets = get_assets(&iroha_client, &alice_id);
assert_eq!(alice_assets, alice_start_assets);
}

#[ignore = "ignore, more in #2851"]
#[test]
#[ignore = "ignore, more in #2851"]
fn account_can_query_only_its_own_domain() -> Result<()> {
let (_rt, _peer, client) = <PeerBuilder>::new().with_port(10_740).start_with_runtime();
wait_for_genesis_committed(&[client.clone()], 0);
Expand All @@ -203,21 +198,18 @@ fn account_can_query_only_its_own_domain() -> Result<()> {
Ok(())
}

#[ignore = "ignore, more in #2851"]
#[test]
fn permissions_differ_not_only_by_names() {
let (_rt, _not_drop, client) = <PeerBuilder>::new().with_port(10_745).start_with_runtime();

let alice_id: <Account as Identifiable>::Id = "alice@wonderland".parse().expect("Valid");
let mouse_id: <Account as Identifiable>::Id = "mouse@wonderland".parse().expect("Valid");
let alice_id: AccountId = "alice@wonderland".parse().expect("Valid");
let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid");
let mouse_keypair = iroha_crypto::KeyPair::generate().expect("Failed to generate KeyPair.");

// Registering `Store` asset definitions
let hat_definition_id: <AssetDefinition as Identifiable>::Id =
"hat#wonderland".parse().expect("Valid");
let hat_definition_id: AssetDefinitionId = "hat#wonderland".parse().expect("Valid");
let new_hat_definition = AssetDefinition::store(hat_definition_id.clone());
let shoes_definition_id: <AssetDefinition as Identifiable>::Id =
"shoes#wonderland".parse().expect("Valid");
let shoes_definition_id: AssetDefinitionId = "shoes#wonderland".parse().expect("Valid");
let new_shoes_definition = AssetDefinition::store(shoes_definition_id.clone());
client
.submit_all_blocking([
Expand All @@ -233,7 +225,7 @@ fn permissions_differ_not_only_by_names() {
.expect("Failed to register mouse");

// 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 mouse_hat_id = AssetId::new(hat_definition_id, mouse_id.clone());
let allow_alice_to_set_key_value_in_hats = GrantBox::new(
PermissionToken::new(
"CanSetKeyValueInUserAsset".parse().unwrap(),
Expand All @@ -260,7 +252,7 @@ fn permissions_differ_not_only_by_names() {
.expect("Failed to modify Mouse's hats");

// ... but not shoes
let mouse_shoes_id = <Asset as Identifiable>::Id::new(shoes_definition_id, mouse_id.clone());
let mouse_shoes_id = AssetId::new(shoes_definition_id, mouse_id.clone());
let set_shoes_color = SetKeyValueBox::new(
mouse_shoes_id.clone(),
Name::from_str("color").expect("Valid"),
Expand Down Expand Up @@ -293,3 +285,54 @@ fn permissions_differ_not_only_by_names() {
.submit_blocking(set_shoes_color)
.expect("Failed to modify Mouse's shoes");
}

#[test]
fn stored_vs_granted_token_payload() -> Result<()> {
let (_rt, _peer, iroha_client) = <PeerBuilder>::new().with_port(10_730).start_with_runtime();
wait_for_genesis_committed(&[iroha_client.clone()], 0);

// Given
let alice_id = AccountId::from_str("alice@wonderland").expect("Valid");

// Registering mouse and asset definition
let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse().expect("Valid");
let create_asset = RegisterBox::new(AssetDefinition::store(asset_definition_id.clone()));
let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid");
let mouse_keypair = iroha_crypto::KeyPair::generate().expect("Failed to generate KeyPair.");
let new_mouse_account = Account::new(mouse_id.clone(), [mouse_keypair.public_key().clone()]);
let instructions: [InstructionBox; 2] = [
RegisterBox::new(new_mouse_account).into(),
create_asset.into(),
];
iroha_client
.submit_all_blocking(instructions)
.expect("Failed to register mouse");

// Allow alice to mint mouse asset and mint initial value
let mouse_asset = AssetId::new(asset_definition_id, mouse_id.clone());
let allow_alice_to_set_key_value_in_mouse_asset = GrantBox::new(
PermissionToken::from_str_unchecked(
"CanSetKeyValueInUserAsset".parse().unwrap(),
// NOTE: Introduced additional whitespaces in the serialized form
"{ \"asset_id\" : \"xor#wonderland#mouse@wonderland\" }",
),
alice_id,
);

let transaction = TransactionBuilder::new(mouse_id)
.with_instructions([allow_alice_to_set_key_value_in_mouse_asset])
.sign(mouse_keypair)
.expect("Failed to sign mouse transaction");
mversic marked this conversation as resolved.
Show resolved Hide resolved
iroha_client
.submit_transaction_blocking(&transaction)
.expect("Failed to grant permission to alice.");
mversic marked this conversation as resolved.
Show resolved Hide resolved

// Check that alice can indeed mint mouse asset
let set_key_value =
SetKeyValueBox::new(mouse_asset, Name::from_str("color")?, "red".to_owned());
iroha_client
.submit_blocking(set_key_value)
.expect("Failed to mint asset for mouse.");
mversic marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
2 changes: 1 addition & 1 deletion client/tests/integration/smartcontracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ codegen-units = 1 # Further reduces binary size but increases compilation time
[workspace.dependencies]
iroha_wasm = { version = "=2.0.0-pre-rc.19", path = "../../../../wasm", features = ["debug"]}
iroha_trigger = { version = "=2.0.0-pre-rc.19", path = "../../../../wasm/trigger", features = ["debug"]}
iroha_validator = { version = "=2.0.0-pre-rc.19", path = "../../../../wasm/validator", features = ["default-validator"] }
iroha_validator = { version = "=2.0.0-pre-rc.19", path = "../../../../wasm/validator" }
mversic marked this conversation as resolved.
Show resolved Hide resolved
iroha_schema = { version = "=2.0.0-pre-rc.19", path = "../../../../schema" }

parity-scale-codec = { version = "3.2.1", default-features = false }
Expand Down
Loading
Loading