From 45edafa4b258f78927f5faba9a9cc4f04cf152c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Ver=C5=A1i=C4=87?= Date: Fri, 13 Sep 2024 15:46:06 +0900 Subject: [PATCH] refactor(permissions): define default permission set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marin Veršić --- crates/iroha/tests/integration/asset.rs | 4 +- crates/iroha/tests/integration/events/data.rs | 61 +- crates/iroha/tests/integration/multisig.rs | 46 +- crates/iroha/tests/integration/permissions.rs | 31 +- .../iroha/tests/integration/queries/role.rs | 24 +- crates/iroha/tests/integration/roles.rs | 48 +- .../tests/integration/transfer_domain.rs | 20 +- .../integration/triggers/by_call_trigger.rs | 9 +- crates/iroha/tests/integration/upgrade.rs | 3 +- crates/iroha_core/src/kura.rs | 2 +- .../src/smartcontracts/isi/account.rs | 62 +- .../src/smartcontracts/isi/world.rs | 2 +- crates/iroha_core/src/state.rs | 14 +- crates/iroha_data_model/src/isi.rs | 2 +- crates/iroha_data_model/src/role.rs | 16 +- crates/iroha_executor/src/default.rs | 539 ++++++++---------- crates/iroha_executor/src/lib.rs | 11 +- crates/iroha_executor/src/permission.rs | 322 +++++------ .../src/permission.rs | 126 ++-- crates/iroha_kagami/src/genesis/generate.rs | 25 +- crates/iroha_schema_gen/src/lib.rs | 108 ++-- crates/iroha_test_network/src/lib.rs | 32 +- defaults/genesis.json | 24 +- docs/source/references/schema.json | 160 ++---- .../src/lib.rs | 2 +- wasm_samples/multisig_register/src/lib.rs | 21 +- 26 files changed, 666 insertions(+), 1048 deletions(-) diff --git a/crates/iroha/tests/integration/asset.rs b/crates/iroha/tests/integration/asset.rs index 41c3216b51f..23e73d71748 100644 --- a/crates/iroha/tests/integration/asset.rs +++ b/crates/iroha/tests/integration/asset.rs @@ -12,7 +12,7 @@ use iroha::{ }, }; use iroha_config::parameters::actual::Root as Config; -use iroha_executor_data_model::permission::asset::CanTransferUserAsset; +use iroha_executor_data_model::permission::asset::CanModifyAsset; use iroha_test_network::*; use iroha_test_samples::{gen_account_in, ALICE_ID, BOB_ID}; @@ -328,7 +328,7 @@ fn find_rate_and_make_exchange_isi_should_succeed() { let alice_id = ALICE_ID.clone(); let alice_can_transfer_asset = |asset_id: AssetId, owner_key_pair: KeyPair| { - let permission = CanTransferUserAsset { + let permission = CanModifyAsset { asset: asset_id.clone(), }; let instruction = Grant::account_permission(permission, alice_id.clone()); diff --git a/crates/iroha/tests/integration/events/data.rs b/crates/iroha/tests/integration/events/data.rs index e42e119518a..217623a8df0 100644 --- a/crates/iroha/tests/integration/events/data.rs +++ b/crates/iroha/tests/integration/events/data.rs @@ -2,8 +2,8 @@ use std::{fmt::Write as _, sync::mpsc, thread}; use eyre::Result; use iroha::data_model::{prelude::*, transaction::WasmSmartContract}; -use iroha_executor_data_model::permission::account::{ - CanRemoveKeyValueInAccount, CanSetKeyValueInAccount, +use iroha_executor_data_model::permission::{ + account::CanModifyAccountMetadata, domain::CanModifyDomainMetadata, }; use iroha_test_network::*; use iroha_test_samples::{ALICE_ID, BOB_ID}; @@ -176,7 +176,6 @@ fn transaction_execution_should_produce_events( } #[test] -#[allow(clippy::too_many_lines)] fn produce_multiple_events() -> Result<()> { let (_rt, _peer, client) = ::new().with_port(10_645).start_with_runtime(); wait_for_genesis_committed(&[client.clone()], 0); @@ -201,11 +200,13 @@ fn produce_multiple_events() -> Result<()> { // Registering role let alice_id = ALICE_ID.clone(); let role_id = "TEST_ROLE".parse::()?; - let permission_1 = CanRemoveKeyValueInAccount { + let permission_1 = CanModifyAccountMetadata { account: alice_id.clone(), }; - let permission_2 = CanSetKeyValueInAccount { account: alice_id }; - let role = iroha::data_model::role::Role::new(role_id.clone()) + let permission_2 = CanModifyDomainMetadata { + domain: alice_id.domain().clone(), + }; + let role = iroha::data_model::role::Role::new(role_id.clone(), alice_id.clone()) .add_permission(permission_1.clone()) .add_permission(permission_2.clone()); let instructions = [Register::role(role.clone())]; @@ -213,7 +214,7 @@ fn produce_multiple_events() -> Result<()> { // Grants role to Bob let bob_id = BOB_ID.clone(); - let grant_role = Grant::role(role_id.clone(), bob_id.clone()); + let grant_role = Grant::account_role(role_id.clone(), bob_id.clone()); client.submit_blocking(grant_role)?; // Unregister role @@ -236,63 +237,37 @@ fn produce_multiple_events() -> Result<()> { } } - if let DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdded(event))) = - event_receiver.recv()??.try_into()? - { - assert_eq!(*event.account(), bob_id); - assert_eq!( - CanRemoveKeyValueInAccount::try_from(event.permission()).unwrap(), - permission_1 - ); - } else { - panic!("Expected event is not an AccountEvent::PermissionAdded") - } - if let DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdded(event))) = - event_receiver.recv()??.try_into()? - { - assert_eq!(*event.account(), bob_id); - assert_eq!( - CanSetKeyValueInAccount::try_from(event.permission()).unwrap(), - permission_2 - ); - } else { - panic!("Expected event is not an AccountEvent::PermissionAdded") - } if let DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleGranted(event))) = event_receiver.recv()??.try_into()? { - assert_eq!(*event.account(), bob_id); + assert_eq!(*event.account(), alice_id); assert_eq!(*event.role(), role_id); } else { panic!("Expected event is not an AccountEvent::RoleGranted") } - if let DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemoved(event))) = + if let DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleGranted(event))) = event_receiver.recv()??.try_into()? { assert_eq!(*event.account(), bob_id); - assert_eq!( - CanRemoveKeyValueInAccount::try_from(event.permission()).unwrap(), - permission_1 - ); + assert_eq!(*event.role(), role_id); } else { - panic!("Expected event is not an AccountEvent::PermissionRemoved") + panic!("Expected event is not an AccountEvent::RoleGranted") } - if let DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemoved(event))) = + + if let DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleRevoked(event))) = event_receiver.recv()??.try_into()? { assert_eq!(*event.account(), bob_id); - assert_eq!( - CanSetKeyValueInAccount::try_from(event.permission()).unwrap(), - permission_2 - ); + assert_eq!(*event.role(), role_id); } else { - panic!("Expected event is not an AccountEvent::PermissionRemoved") + panic!("Expected event is not an AccountEvent::RoleRevoked") } + if let DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleRevoked(event))) = event_receiver.recv()??.try_into()? { - assert_eq!(*event.account(), bob_id); + assert_eq!(*event.account(), alice_id); assert_eq!(*event.role(), role_id); } else { panic!("Expected event is not an AccountEvent::RoleRevoked") diff --git a/crates/iroha/tests/integration/multisig.rs b/crates/iroha/tests/integration/multisig.rs index f1eba4fc63e..55e61bbec36 100644 --- a/crates/iroha/tests/integration/multisig.rs +++ b/crates/iroha/tests/integration/multisig.rs @@ -12,11 +12,14 @@ use iroha::{ transaction::{TransactionBuilder, WasmSmartContract}, }, }; +use iroha_data_model::asset::{AssetDefinition, AssetDefinitionId}; +use iroha_executor_data_model::permission::asset_definition::CanRegisterAssetDefinition; use iroha_test_network::*; use iroha_test_samples::{gen_account_in, ALICE_ID}; use nonzero_ext::nonzero; #[test] +#[expect(clippy::too_many_lines)] fn mutlisig() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(11_400).start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); @@ -85,14 +88,15 @@ fn mutlisig() -> Result<()> { test_client.submit_blocking(call_trigger)?; // Check that multisig account exist - let account = test_client - .query(client::account::all()) - .filter_with(|account| account.id.eq(multisig_account_id.clone())) - .execute_single() + test_client + .submit_blocking(Grant::account_permission( + CanRegisterAssetDefinition { + domain: "wonderland".parse().unwrap(), + }, + multisig_account_id.clone(), + )) .expect("multisig account should be created after the call to register multisig trigger"); - assert_eq!(account.id(), &multisig_account_id); - // Check that multisig trigger exist let trigger = test_client .query(FindTriggers::new()) @@ -102,8 +106,14 @@ fn mutlisig() -> Result<()> { assert_eq!(trigger.id(), &multisig_trigger_id); - let domain_id: DomainId = "domain_controlled_by_multisig".parse().unwrap(); - let isi = vec![Register::domain(Domain::new(domain_id.clone())).into()]; + let asset_definition_id = "asset_definition_controlled_by_multisig#wonderland" + .parse::() + .unwrap(); + let isi = + vec![ + Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())) + .into(), + ]; let isi_hash = HashOf::new(&isi); let mut signatories_iter = signatories.into_iter(); @@ -118,12 +128,12 @@ fn mutlisig() -> Result<()> { )?; } - // Check that domain isn't created yet + // Check that asset definition isn't created yet let err = test_client - .query(client::domain::all()) - .filter_with(|domain| domain.id.eq(domain_id.clone())) + .query(client::asset::all_definitions()) + .filter_with(|asset_definition| asset_definition.id.eq(asset_definition_id.clone())) .execute_single() - .expect_err("domain shouldn't be created before enough votes are collected"); + .expect_err("asset definition shouldn't be created before enough votes are collected"); assert!(matches!(err, SingleQueryError::ExpectedOneGotNone)); for (signatory, key_pair) in signatories_iter { @@ -136,14 +146,14 @@ fn mutlisig() -> Result<()> { )?; } - // Check that new domain was created and multisig account is owner - let domain = test_client - .query(client::domain::all()) - .filter_with(|domain| domain.id.eq(domain_id.clone())) + // Check that new asset definition was created and multisig account is owner + let asset_definition = test_client + .query(client::asset::all_definitions()) + .filter_with(|asset_definition| asset_definition.id.eq(asset_definition_id.clone())) .execute_single() - .expect("domain should be created after enough votes are collected"); + .expect("asset definition should be created after enough votes are collected"); - assert_eq!(domain.owned_by(), &multisig_account_id); + assert_eq!(asset_definition.owned_by(), &multisig_account_id); Ok(()) } diff --git a/crates/iroha/tests/integration/permissions.rs b/crates/iroha/tests/integration/permissions.rs index 66c79041a0b..aad8930d5e8 100644 --- a/crates/iroha/tests/integration/permissions.rs +++ b/crates/iroha/tests/integration/permissions.rs @@ -10,8 +10,8 @@ use iroha::{ }, }; use iroha_executor_data_model::permission::{ - asset::{CanSetKeyValueInUserAsset, CanTransferUserAsset}, - domain::CanSetKeyValueInDomain, + asset::{CanModifyAsset, CanModifyAssetMetadata}, + domain::CanModifyDomainMetadata, }; use iroha_genesis::GenesisBlock; use iroha_test_network::{PeerBuilder, *}; @@ -243,7 +243,7 @@ fn permissions_differ_not_only_by_names() { // Granting permission to Alice to modify metadata in Mouse's hats let mouse_hat_id = AssetId::new(hat_definition_id, mouse_id.clone()); - let mouse_hat_permission = CanSetKeyValueInUserAsset { + let mouse_hat_permission = CanModifyAssetMetadata { asset: mouse_hat_id.clone(), }; let allow_alice_to_set_key_value_in_hats = @@ -276,7 +276,7 @@ fn permissions_differ_not_only_by_names() { .submit_blocking(set_shoes_color.clone()) .expect_err("Expected Alice to fail to modify Mouse's shoes"); - let mouse_shoes_permission = CanSetKeyValueInUserAsset { + let mouse_shoes_permission = CanModifyAssetMetadata { asset: mouse_shoes_id, }; let allow_alice_to_set_key_value_in_shoes = @@ -326,7 +326,7 @@ fn stored_vs_granted_permission_payload() -> Result<()> { let mouse_asset = AssetId::new(asset_definition_id, mouse_id.clone()); let allow_alice_to_set_key_value_in_mouse_asset = Grant::account_permission( - Permission::new("CanSetKeyValueInUserAsset".parse().unwrap(), value_json), + Permission::new("CanModifyAssetMetadata".parse().unwrap(), value_json), alice_id, ); @@ -359,12 +359,12 @@ fn permissions_are_unified() { // Given let alice_id = ALICE_ID.clone(); - let permission1 = CanTransferUserAsset { + let permission1 = CanModifyAsset { asset: format!("rose#wonderland#{alice_id}").parse().unwrap(), }; let allow_alice_to_transfer_rose_1 = Grant::account_permission(permission1, alice_id.clone()); - let permission2 = CanTransferUserAsset { + let permission2 = CanModifyAsset { asset: format!("rose##{alice_id}").parse().unwrap(), }; let allow_alice_to_transfer_rose_2 = Grant::account_permission(permission2, alice_id); @@ -389,7 +389,7 @@ fn associated_permissions_removed_on_unregister() { // register kingdom and give bob permissions in this domain let register_domain = Register::domain(kingdom); - let bob_to_set_kv_in_domain = CanSetKeyValueInDomain { + let bob_to_set_kv_in_domain = CanModifyDomainMetadata { domain: kingdom_id.clone(), }; let allow_bob_to_set_kv_in_domain = @@ -409,7 +409,7 @@ fn associated_permissions_removed_on_unregister() { .expect("failed to get permissions for bob") .into_iter() .any(|permission| { - CanSetKeyValueInDomain::try_from(&permission) + CanModifyDomainMetadata::try_from(&permission) .is_ok_and(|permission| permission == bob_to_set_kv_in_domain) })); @@ -425,7 +425,7 @@ fn associated_permissions_removed_on_unregister() { .expect("failed to get permissions for bob") .into_iter() .any(|permission| { - CanSetKeyValueInDomain::try_from(&permission) + CanModifyDomainMetadata::try_from(&permission) .is_ok_and(|permission| permission == bob_to_set_kv_in_domain) })); } @@ -441,11 +441,12 @@ fn associated_permissions_removed_from_role_on_unregister() { // register kingdom and give bob permissions in this domain let register_domain = Register::domain(kingdom); - let set_kv_in_domain = CanSetKeyValueInDomain { + let set_kv_in_domain = CanModifyDomainMetadata { domain: kingdom_id.clone(), }; - let role = Role::new(role_id.clone()).add_permission(set_kv_in_domain.clone()); - let register_role = Register::role(role); + let register_role = Register::role( + Role::new(role_id.clone(), ALICE_ID.clone()).add_permission(set_kv_in_domain.clone()), + ); iroha .submit_all_blocking::([register_domain.into(), register_role.into()]) @@ -459,7 +460,7 @@ fn associated_permissions_removed_from_role_on_unregister() { .expect("failed to get role") .permissions() .any(|permission| { - CanSetKeyValueInDomain::try_from(permission) + CanModifyDomainMetadata::try_from(permission) .is_ok_and(|permission| permission == set_kv_in_domain) })); @@ -476,7 +477,7 @@ fn associated_permissions_removed_from_role_on_unregister() { .expect("failed to get role") .permissions() .any(|permission| { - CanSetKeyValueInDomain::try_from(permission) + CanModifyDomainMetadata::try_from(permission) .is_ok_and(|permission| permission == set_kv_in_domain) })); } diff --git a/crates/iroha/tests/integration/queries/role.rs b/crates/iroha/tests/integration/queries/role.rs index bd88e982302..6eecb164f77 100644 --- a/crates/iroha/tests/integration/queries/role.rs +++ b/crates/iroha/tests/integration/queries/role.rs @@ -5,7 +5,7 @@ use iroha::{ client, data_model::{prelude::*, query::builder::SingleQueryError}, }; -use iroha_executor_data_model::permission::account::CanSetKeyValueInAccount; +use iroha_executor_data_model::permission::account::CanModifyAccountMetadata; use iroha_test_network::*; use iroha_test_samples::ALICE_ID; @@ -30,7 +30,7 @@ fn find_roles() -> Result<()> { let register_roles = role_ids .iter() .cloned() - .map(|role_id| Register::role(Role::new(role_id))) + .map(|role_id| Register::role(Role::new(role_id, ALICE_ID.clone()))) .collect::>(); test_client.submit_all_blocking(register_roles)?; @@ -62,7 +62,7 @@ fn find_role_ids() -> Result<()> { let register_roles = role_ids .iter() .cloned() - .map(|role_id| Register::role(Role::new(role_id))) + .map(|role_id| Register::role(Role::new(role_id, ALICE_ID.clone()))) .collect::>(); test_client.submit_all_blocking(register_roles)?; @@ -83,7 +83,7 @@ fn find_role_by_id() -> Result<()> { wait_for_genesis_committed(&[test_client.clone()], 0); let role_id: RoleId = "root".parse().expect("Valid"); - let new_role = Role::new(role_id.clone()); + let new_role = Role::new(role_id.clone(), ALICE_ID.clone()); // Registering role let register_role = Register::role(new_role.clone()); @@ -133,21 +133,15 @@ fn find_roles_by_account_id() -> Result<()> { .iter() .cloned() .map(|role_id| { - Register::role(Role::new(role_id).add_permission(CanSetKeyValueInAccount { - account: alice_id.clone(), - })) + Register::role(Role::new(role_id, alice_id.clone()).add_permission( + CanModifyAccountMetadata { + account: alice_id.clone(), + }, + )) }) .collect::>(); test_client.submit_all_blocking(register_roles)?; - // Granting roles to account - let grant_roles = role_ids - .iter() - .cloned() - .map(|role_id| Grant::role(role_id, alice_id.clone())) - .collect::>(); - test_client.submit_all_blocking(grant_roles)?; - let role_ids = HashSet::from(role_ids); // Checking results diff --git a/crates/iroha/tests/integration/roles.rs b/crates/iroha/tests/integration/roles.rs index 1430c8a6a4e..549b9e02f85 100644 --- a/crates/iroha/tests/integration/roles.rs +++ b/crates/iroha/tests/integration/roles.rs @@ -4,9 +4,7 @@ use iroha::{ client, data_model::{prelude::*, transaction::error::TransactionRejectionReason}, }; -use iroha_executor_data_model::permission::account::{ - CanRemoveKeyValueInAccount, CanSetKeyValueInAccount, -}; +use iroha_executor_data_model::permission::account::CanModifyAccountMetadata; use iroha_test_network::*; use iroha_test_samples::{gen_account_in, ALICE_ID}; use serde_json::json; @@ -17,7 +15,7 @@ fn register_empty_role() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let role_id = "root".parse().expect("Valid"); - let register_role = Register::role(Role::new(role_id)); + let register_role = Register::role(Role::new(role_id, ALICE_ID.clone())); test_client.submit(register_role)?; Ok(()) @@ -49,18 +47,15 @@ fn register_and_grant_role_for_metadata_access() -> Result<()> { // Registering role let role_id = "ACCESS_TO_MOUSE_METADATA".parse::()?; - let role = Role::new(role_id.clone()) - .add_permission(CanSetKeyValueInAccount { - account: mouse_id.clone(), - }) - .add_permission(CanRemoveKeyValueInAccount { + let role = + Role::new(role_id.clone(), mouse_id.clone()).add_permission(CanModifyAccountMetadata { account: mouse_id.clone(), }); let register_role = Register::role(role); test_client.submit_blocking(register_role)?; // Mouse grants role to Alice - let grant_role = Grant::role(role_id.clone(), alice_id.clone()); + let grant_role = Grant::account_role(role_id.clone(), alice_id.clone()); let grant_role_tx = TransactionBuilder::new(chain_id, mouse_id.clone()) .with_instructions([grant_role]) .sign(mouse_keypair.private_key()); @@ -98,12 +93,13 @@ fn unregistered_role_removed_from_account() -> Result<()> { // Register root role let register_role = Register::role( - Role::new(role_id.clone()).add_permission(CanSetKeyValueInAccount { account: alice_id }), + Role::new(role_id.clone(), alice_id.clone()) + .add_permission(CanModifyAccountMetadata { account: alice_id }), ); test_client.submit_blocking(register_role)?; // Grant root role to Mouse - let grant_role = Grant::role(role_id.clone(), mouse_id.clone()); + let grant_role = Grant::account_role(role_id.clone(), mouse_id.clone()); test_client.submit_blocking(grant_role)?; // Check that Mouse has root role @@ -131,7 +127,7 @@ fn role_with_invalid_permissions_is_not_accepted() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let role_id = "ACCESS_TO_ACCOUNT_METADATA".parse()?; - let role = Role::new(role_id).add_permission(CanControlDomainLives); + let role = Role::new(role_id, ALICE_ID.clone()).add_permission(CanControlDomainLives); let err = test_client .submit_blocking(Register::role(role)) @@ -150,7 +146,6 @@ fn role_with_invalid_permissions_is_not_accepted() -> Result<()> { } #[test] -#[allow(deprecated)] // NOTE: Permissions in this test are created explicitly as json strings // so that they don't get deduplicated eagerly but rather in the executor // This way, if the executor compares permissions just as JSON strings, the test will fail @@ -159,18 +154,18 @@ fn role_permissions_are_deduplicated() { wait_for_genesis_committed(&vec![test_client.clone()], 0); let allow_alice_to_transfer_rose_1 = Permission::new( - "CanTransferUserAsset".parse().unwrap(), + "CanModifyAsset".parse().unwrap(), json!({ "asset": "rose#wonderland#ed0120CE7FA46C9DCE7EA4B125E2E36BDB63EA33073E7590AC92816AE1E861B7048B03@wonderland" }), ); // Different content, but same meaning let allow_alice_to_transfer_rose_2 = Permission::new( - "CanTransferUserAsset".parse().unwrap(), + "CanModifyAsset".parse().unwrap(), json!({ "asset": "rose##ed0120CE7FA46C9DCE7EA4B125E2E36BDB63EA33073E7590AC92816AE1E861B7048B03@wonderland" }), ); let role_id: RoleId = "role_id".parse().expect("Valid"); - let role = Role::new(role_id.clone()) + let role = Role::new(role_id.clone(), ALICE_ID.clone()) .add_permission(allow_alice_to_transfer_rose_1) .add_permission(allow_alice_to_transfer_rose_2); @@ -208,7 +203,7 @@ fn grant_revoke_role_permissions() -> Result<()> { // Registering role let role_id = "ACCESS_TO_MOUSE_METADATA".parse::()?; - let role = Role::new(role_id.clone()); + let role = Role::new(role_id.clone(), mouse_id.clone()); let register_role = Register::role(role); test_client.submit_blocking(register_role)?; @@ -218,7 +213,7 @@ fn grant_revoke_role_permissions() -> Result<()> { test_client.submit_blocking(transfer_domain)?; // Mouse grants role to Alice - let grant_role = Grant::role(role_id.clone(), alice_id.clone()); + let grant_role = Grant::account_role(role_id.clone(), alice_id.clone()); let grant_role_tx = TransactionBuilder::new(chain_id.clone(), mouse_id.clone()) .with_instructions([grant_role]) .sign(mouse_keypair.private_key()); @@ -229,7 +224,7 @@ fn grant_revoke_role_permissions() -> Result<()> { "key".parse()?, "value".parse::()?, ); - let can_set_key_value_in_mouse = CanSetKeyValueInAccount { + let can_set_key_value_in_mouse = CanModifyAccountMetadata { account: mouse_id.clone(), }; let grant_role_permission = @@ -243,7 +238,7 @@ fn grant_revoke_role_permissions() -> Result<()> { .execute_all()? .iter() .any(|permission| { - CanSetKeyValueInAccount::try_from(permission) + CanModifyAccountMetadata::try_from(permission) .is_ok_and(|permission| permission == can_set_key_value_in_mouse) })); let _ = test_client @@ -256,13 +251,10 @@ fn grant_revoke_role_permissions() -> Result<()> { .sign(mouse_keypair.private_key()); test_client.submit_transaction_blocking(&grant_role_permission_tx)?; assert!(test_client - .query(client::permission::by_account_id(alice_id.clone())) + .query(client::role::by_account_id(alice_id.clone())) .execute_all()? .iter() - .any(|permission| { - CanSetKeyValueInAccount::try_from(permission) - .is_ok_and(|permission| permission == can_set_key_value_in_mouse) - })); + .any(|account_role_id| *account_role_id == role_id)); test_client.submit_blocking(set_key_value.clone())?; // Alice can't modify Mouse's metadata after permission is removed from role @@ -275,11 +267,11 @@ fn grant_revoke_role_permissions() -> Result<()> { .execute_all()? .iter() .any(|permission| { - CanSetKeyValueInAccount::try_from(permission) + CanModifyAccountMetadata::try_from(permission) .is_ok_and(|permission| permission == can_set_key_value_in_mouse) })); let _ = test_client - .submit_blocking(set_key_value.clone()) + .submit_blocking(set_key_value) .expect_err("shouldn't be able to modify metadata"); Ok(()) diff --git a/crates/iroha/tests/integration/transfer_domain.rs b/crates/iroha/tests/integration/transfer_domain.rs index 4f006b20818..8854b6a627b 100644 --- a/crates/iroha/tests/integration/transfer_domain.rs +++ b/crates/iroha/tests/integration/transfer_domain.rs @@ -7,10 +7,10 @@ use iroha::{ }; use iroha_executor_data_model::permission::{ account::CanUnregisterAccount, - asset::CanUnregisterUserAsset, - asset_definition::CanUnregisterAssetDefinition, - domain::{CanRegisterAssetDefinitionInDomain, CanUnregisterDomain}, - trigger::CanUnregisterUserTrigger, + asset::CanUnregisterAsset, + asset_definition::{CanRegisterAssetDefinition, CanUnregisterAssetDefinition}, + domain::CanUnregisterDomain, + trigger::CanUnregisterTrigger, }; use iroha_genesis::GenesisBlock; use iroha_primitives::json::JsonString; @@ -59,7 +59,7 @@ fn domain_owner_domain_permissions() -> Result<()> { test_client.submit_blocking(Unregister::asset_definition(coin_id))?; // Granting a respective permission also allows "bob@kingdom" to do so - let permission = CanRegisterAssetDefinitionInDomain { + let permission = CanRegisterAssetDefinition { domain: kingdom_id.clone(), }; test_client.submit_blocking(Grant::account_permission( @@ -158,7 +158,7 @@ fn domain_owner_asset_definition_permissions() -> Result<()> { test_client.submit_blocking(Register::account(rabbit))?; // Grant permission to register asset definitions to "bob@kingdom" - let permission = CanRegisterAssetDefinitionInDomain { domain: kingdom_id }; + let permission = CanRegisterAssetDefinition { domain: kingdom_id }; test_client.submit_blocking(Grant::account_permission(permission, bob_id.clone()))?; // register asset definitions by "bob@kingdom" so he is owner of it @@ -222,7 +222,7 @@ fn domain_owner_asset_permissions() -> Result<()> { test_client.submit_blocking(Register::account(bob))?; // Grant permission to register asset definitions to "bob@kingdom" - let permission = CanRegisterAssetDefinitionInDomain { domain: kingdom_id }; + let permission = CanRegisterAssetDefinition { domain: kingdom_id }; test_client.submit_blocking(Grant::account_permission(permission, bob_id.clone()))?; // register asset definitions by "bob@kingdom" so he is owner of it @@ -255,7 +255,7 @@ fn domain_owner_asset_permissions() -> Result<()> { test_client.submit_blocking(RemoveKeyValue::asset(bob_store_id.clone(), key))?; // check that "alice@wonderland" as owner of domain can grant and revoke asset related permissions in her domain - let permission = CanUnregisterUserAsset { + let permission = CanUnregisterAsset { asset: bob_store_id, }; test_client.submit_blocking(Grant::account_permission( @@ -308,8 +308,8 @@ fn domain_owner_trigger_permissions() -> Result<()> { let _result = test_client.submit_blocking(execute_trigger)?; // check that "alice@wonderland" as owner of domain can grant and revoke trigger related permissions in her domain - let permission = CanUnregisterUserTrigger { - account: bob_id.clone(), + let permission = CanUnregisterTrigger { + trigger: trigger_id.clone(), }; test_client.submit_blocking(Grant::account_permission( permission.clone(), diff --git a/crates/iroha/tests/integration/triggers/by_call_trigger.rs b/crates/iroha/tests/integration/triggers/by_call_trigger.rs index eb11b0c9b3f..063a96e05eb 100644 --- a/crates/iroha/tests/integration/triggers/by_call_trigger.rs +++ b/crates/iroha/tests/integration/triggers/by_call_trigger.rs @@ -12,7 +12,7 @@ use iroha::{ }, }; use iroha_data_model::query::{builder::SingleQueryError, trigger::FindTriggers}; -use iroha_executor_data_model::permission::trigger::CanRegisterUserTrigger; +use iroha_executor_data_model::permission::trigger::CanRegisterTrigger; use iroha_genesis::GenesisBlock; use iroha_logger::info; use iroha_test_network::{Peer as TestPeer, *}; @@ -217,8 +217,7 @@ fn trigger_should_not_be_executed_with_zero_repeats_count() -> Result<()> { downcasted_error, Some(FindError::Trigger(id)) if *id == trigger_id ), - "Unexpected error received: {:?}", - error + "Unexpected error received: {error:?}", ); // Checking results @@ -295,8 +294,8 @@ fn only_account_with_permission_can_register_trigger() -> Result<()> { rabbit_client.key_pair = rabbit_keys; // Permission for the trigger registration on behalf of alice - let permission_on_registration = CanRegisterUserTrigger { - account: ALICE_ID.clone(), + let permission_on_registration = CanRegisterTrigger { + authority: ALICE_ID.clone(), }; // Trigger with 'alice' as authority diff --git a/crates/iroha/tests/integration/upgrade.rs b/crates/iroha/tests/integration/upgrade.rs index a2309416cc0..902f47eaeca 100644 --- a/crates/iroha/tests/integration/upgrade.rs +++ b/crates/iroha/tests/integration/upgrade.rs @@ -137,7 +137,8 @@ fn executor_upgrade_should_revoke_removed_permissions() -> Result<()> { // Register `TEST_ROLE` with permission let test_role_id: RoleId = "TEST_ROLE".parse()?; - let test_role = Role::new(test_role_id.clone()).add_permission(can_unregister_domain.clone()); + let test_role = Role::new(test_role_id.clone(), ALICE_ID.clone()) + .add_permission(can_unregister_domain.clone()); client.submit_blocking(Register::role(test_role))?; // Check that permission exists diff --git a/crates/iroha_core/src/kura.rs b/crates/iroha_core/src/kura.rs index d4c8761e6c2..a5656b2fd62 100644 --- a/crates/iroha_core/src/kura.rs +++ b/crates/iroha_core/src/kura.rs @@ -1030,6 +1030,7 @@ mod tests { #[allow(clippy::too_many_lines)] fn create_blocks(rt: &tokio::runtime::Runtime, temp_dir: &TempDir) -> Vec { + const BLOCK_FLUSH_TIMEOUT: Duration = Duration::from_secs(1); let mut blocks = Vec::new(); let (leader_public_key, leader_private_key) = KeyPair::random().into_parts(); @@ -1136,7 +1137,6 @@ mod tests { blocks.push(block.clone()); kura.store_block(block); } - const BLOCK_FLUSH_TIMEOUT: Duration = Duration::from_secs(1); thread::sleep(BLOCK_FLUSH_TIMEOUT); { diff --git a/crates/iroha_core/src/smartcontracts/isi/account.rs b/crates/iroha_core/src/smartcontracts/isi/account.rs index c63f33b1758..ab5c769a145 100644 --- a/crates/iroha_core/src/smartcontracts/isi/account.rs +++ b/crates/iroha_core/src/smartcontracts/isi/account.rs @@ -308,14 +308,6 @@ pub mod isi { let account_id = self.destination; let role_id = self.object; - let permissions = state_transaction - .world - .roles - .get(&role_id) - .ok_or_else(|| FindError::Role(role_id.clone()))? - .permissions - .clone(); - state_transaction.world.account(&account_id)?; if state_transaction @@ -334,23 +326,12 @@ pub mod isi { .into()); } - state_transaction.world.emit_events({ - let account_id_clone = account_id.clone(); - permissions - .into_iter() - .zip(core::iter::repeat_with(move || account_id.clone())) - .map(|(permission, account_id)| AccountPermissionChanged { - account: account_id, - permission, - }) - .map(AccountEvent::PermissionAdded) - .chain(std::iter::once(AccountEvent::RoleGranted( - AccountRoleChanged { - account: account_id_clone, - role: role_id, - }, - ))) - }); + state_transaction + .world + .emit_events(Some(AccountEvent::RoleGranted(AccountRoleChanged { + account: account_id.clone(), + role: role_id, + }))); Ok(()) } @@ -366,14 +347,6 @@ pub mod isi { let account_id = self.destination; let role_id = self.object; - let permissions = state_transaction - .world - .roles - .get(&role_id) - .ok_or_else(|| FindError::Role(role_id.clone()))? - .permissions - .clone(); - if state_transaction .world .account_roles @@ -386,23 +359,12 @@ pub mod isi { return Err(FindError::Role(role_id).into()); } - state_transaction.world.emit_events({ - let account_id_clone = account_id.clone(); - permissions - .into_iter() - .zip(core::iter::repeat_with(move || account_id.clone())) - .map(|(permission, account_id)| AccountPermissionChanged { - account: account_id, - permission, - }) - .map(AccountEvent::PermissionRemoved) - .chain(std::iter::once(AccountEvent::RoleRevoked( - AccountRoleChanged { - account: account_id_clone, - role: role_id, - }, - ))) - }); + state_transaction + .world + .emit_events(Some(AccountEvent::RoleRevoked(AccountRoleChanged { + account: account_id.clone(), + role: role_id, + }))); Ok(()) } diff --git a/crates/iroha_core/src/smartcontracts/isi/world.rs b/crates/iroha_core/src/smartcontracts/isi/world.rs index ecac74b11de..a36443dc243 100644 --- a/crates/iroha_core/src/smartcontracts/isi/world.rs +++ b/crates/iroha_core/src/smartcontracts/isi/world.rs @@ -417,7 +417,7 @@ pub mod isi { state_transaction .world - .emit_events(std::iter::once(ExecutorEvent::Upgraded(ExecutorUpgrade { + .emit_events(Some(ExecutorEvent::Upgraded(ExecutorUpgrade { new_data_model: state_transaction.world.executor_data_model.clone(), }))); diff --git a/crates/iroha_core/src/state.rs b/crates/iroha_core/src/state.rs index c3ab092e804..98411cee24b 100644 --- a/crates/iroha_core/src/state.rs +++ b/crates/iroha_core/src/state.rs @@ -576,20 +576,10 @@ pub trait WorldReadOnly { fn account_permissions_iter<'slf>( &'slf self, account_id: &AccountId, - ) -> Result, FindError> { + ) -> Result, FindError> { self.account(account_id)?; - let mut tokens = self - .account_inherent_permissions(account_id) - .collect::>(); - - for role_id in self.account_roles_iter(account_id) { - if let Some(role) = self.roles().get(role_id) { - tokens.extend(role.permissions.iter()); - } - } - - Ok(tokens.into_iter()) + Ok(self.account_inherent_permissions(account_id)) } /// Return a set of permission tokens granted to this account not as part of any role. diff --git a/crates/iroha_data_model/src/isi.rs b/crates/iroha_data_model/src/isi.rs index 74a2ac1fbec..1d6a7e16f0a 100644 --- a/crates/iroha_data_model/src/isi.rs +++ b/crates/iroha_data_model/src/isi.rs @@ -823,7 +823,7 @@ mod transparent { impl Grant { /// Constructs a new [`Grant`] for a [`Role`]. - pub fn role(role_id: RoleId, to: AccountId) -> Self { + pub fn account_role(role_id: RoleId, to: AccountId) -> Self { Self { object: role_id, destination: to, diff --git a/crates/iroha_data_model/src/role.rs b/crates/iroha_data_model/src/role.rs index 01e5876fbd7..d47cc3328a3 100644 --- a/crates/iroha_data_model/src/role.rs +++ b/crates/iroha_data_model/src/role.rs @@ -7,6 +7,7 @@ use iroha_data_model_derive::model; pub use self::model::*; use crate::{ + account::AccountId, permission::{Permission, Permissions}, Identifiable, Name, Registered, }; @@ -76,23 +77,23 @@ mod model { Serialize, IntoSchema, )] - #[serde(transparent, rename = "Role")] - #[ffi_type(unsafe {robust})] + #[ffi_type] #[getset(get = "pub")] - #[schema(transparent)] - #[repr(transparent)] + #[display(fmt = "{grant_to}: {inner}")] pub struct NewRole { #[allow(missing_docs)] #[id(transparent)] pub inner: Role, + /// First owner + pub grant_to: AccountId, } } impl Role { /// Constructor. #[inline] - pub fn new(id: RoleId) -> ::With { - NewRole::new(id) + pub fn new(id: RoleId, grant_to: AccountId) -> ::With { + NewRole::new(id, grant_to) } /// Get an iterator over [`permissions`](Permission) of the `Role` @@ -106,8 +107,9 @@ impl NewRole { /// Constructor #[must_use] #[inline] - fn new(id: RoleId) -> Self { + fn new(id: RoleId, grant_to: AccountId) -> Self { Self { + grant_to, inner: Role { id, permissions: Permissions::new(), diff --git a/crates/iroha_executor/src/default.rs b/crates/iroha_executor/src/default.rs index 56a8d5f3a41..716a1d4ef60 100644 --- a/crates/iroha_executor/src/default.rs +++ b/crates/iroha_executor/src/default.rs @@ -40,7 +40,7 @@ pub use trigger::{ use crate::{ deny, execute, - permission::{AnyPermission, ExecutorPermision as _}, + permission::{AnyPermission, ExecutorPermission as _}, Validate, }; @@ -129,19 +129,25 @@ pub fn visit_instruction( } pub mod peer { - use iroha_executor_data_model::permission::peer::CanUnregisterAnyPeer; + use iroha_executor_data_model::permission::peer::CanManagePeers; use super::*; pub fn visit_register_peer( executor: &mut V, - _authority: &AccountId, + authority: &AccountId, isi: &Register, ) { - execute!(executor, isi) + if is_genesis(executor) { + execute!(executor, isi); + } + if CanManagePeers.is_owned_by(authority) { + execute!(executor, isi); + } + + deny!(executor, "Can't register peer"); } - #[allow(clippy::needless_pass_by_value)] pub fn visit_unregister_peer( executor: &mut V, authority: &AccountId, @@ -150,7 +156,7 @@ pub mod peer { if is_genesis(executor) { execute!(executor, isi); } - if CanUnregisterAnyPeer.is_owned_by(authority) { + if CanManagePeers.is_owned_by(authority) { execute!(executor, isi); } @@ -160,7 +166,7 @@ pub mod peer { pub mod domain { use iroha_executor_data_model::permission::domain::{ - CanRemoveKeyValueInDomain, CanSetKeyValueInDomain, CanUnregisterDomain, + CanModifyDomainMetadata, CanRegisterDomain, CanUnregisterDomain, }; use iroha_smart_contract::data_model::domain::DomainId; @@ -171,10 +177,17 @@ pub mod domain { pub fn visit_register_domain( executor: &mut V, - _authority: &AccountId, + authority: &AccountId, isi: &Register, ) { - execute!(executor, isi) + if is_genesis(executor) { + execute!(executor, isi); + } + if CanRegisterDomain.is_owned_by(authority) { + execute!(executor, isi); + } + + deny!(executor, "Can't register domain"); } pub fn visit_unregister_domain( @@ -199,18 +212,18 @@ pub mod domain { use iroha_smart_contract::ExecuteOnHost as _; for (owner_id, permission) in accounts_permissions() { - if is_token_domain_associated(&permission, domain_id) { + if is_permission_domain_associated(&permission, domain_id) { let isi = Revoke::account_permission(permission, owner_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } for (role_id, permission) in roles_permissions() { - if is_token_domain_associated(&permission, domain_id) { + if is_permission_domain_associated(&permission, domain_id) { let isi = Revoke::role_permission(permission, role_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } @@ -259,7 +272,7 @@ pub mod domain { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_set_key_value_in_domain_token = CanSetKeyValueInDomain { + let can_set_key_value_in_domain_token = CanModifyDomainMetadata { domain: domain_id.clone(), }; if can_set_key_value_in_domain_token.is_owned_by(authority) { @@ -284,7 +297,7 @@ pub mod domain { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_remove_key_value_in_domain_token = CanRemoveKeyValueInDomain { + let can_remove_key_value_in_domain_token = CanModifyDomainMetadata { domain: domain_id.clone(), }; if can_remove_key_value_in_domain_token.is_owned_by(authority) { @@ -295,27 +308,21 @@ pub mod domain { } #[allow(clippy::too_many_lines)] - fn is_token_domain_associated(permission: &Permission, domain_id: &DomainId) -> bool { + fn is_permission_domain_associated(permission: &Permission, domain_id: &DomainId) -> bool { let Ok(permission) = AnyPermission::try_from(permission) else { return false; }; match permission { AnyPermission::CanUnregisterDomain(permission) => &permission.domain == domain_id, - AnyPermission::CanSetKeyValueInDomain(permission) => &permission.domain == domain_id, - AnyPermission::CanRemoveKeyValueInDomain(permission) => &permission.domain == domain_id, - AnyPermission::CanRegisterAccountInDomain(permission) => { - &permission.domain == domain_id - } - AnyPermission::CanRegisterAssetDefinitionInDomain(permission) => { + AnyPermission::CanModifyDomainMetadata(permission) => &permission.domain == domain_id, + AnyPermission::CanRegisterAccount(permission) => &permission.domain == domain_id, + AnyPermission::CanRegisterAssetDefinition(permission) => { &permission.domain == domain_id } AnyPermission::CanUnregisterAssetDefinition(permission) => { permission.asset_definition.domain() == domain_id } - AnyPermission::CanSetKeyValueInAssetDefinition(permission) => { - permission.asset_definition.domain() == domain_id - } - AnyPermission::CanRemoveKeyValueInAssetDefinition(permission) => { + AnyPermission::CanModifyAssetDefinitionMetadata(permission) => { permission.asset_definition.domain() == domain_id } AnyPermission::CanRegisterAssetWithDefinition(permission) => { @@ -324,71 +331,47 @@ pub mod domain { AnyPermission::CanUnregisterAssetWithDefinition(permission) => { permission.asset_definition.domain() == domain_id } - AnyPermission::CanBurnAssetWithDefinition(permission) => { + AnyPermission::CanModifyAssetsWithDefinition(permission) => { permission.asset_definition.domain() == domain_id } - AnyPermission::CanMintAssetWithDefinition(permission) => { - permission.asset_definition.domain() == domain_id - } - AnyPermission::CanTransferAssetWithDefinition(permission) => { - permission.asset_definition.domain() == domain_id - } - AnyPermission::CanBurnUserAsset(permission) => { - permission.asset.definition().domain() == domain_id - || permission.asset.account().domain() == domain_id - } - AnyPermission::CanTransferUserAsset(permission) => { - permission.asset.definition().domain() == domain_id - || permission.asset.account().domain() == domain_id - } - AnyPermission::CanUnregisterUserAsset(permission) => { - permission.asset.definition().domain() == domain_id - || permission.asset.account().domain() == domain_id - } - AnyPermission::CanSetKeyValueInUserAsset(permission) => { + AnyPermission::CanRegisterAsset(permission) => permission.owner.domain() == domain_id, + AnyPermission::CanUnregisterAsset(permission) => { permission.asset.definition().domain() == domain_id || permission.asset.account().domain() == domain_id } - AnyPermission::CanRemoveKeyValueInUserAsset(permission) => { + AnyPermission::CanModifyAssetMetadata(permission) => { permission.asset.definition().domain() == domain_id || permission.asset.account().domain() == domain_id } - AnyPermission::CanMintUserAsset(permission) => { + AnyPermission::CanModifyAsset(permission) => { permission.asset.definition().domain() == domain_id || permission.asset.account().domain() == domain_id } AnyPermission::CanUnregisterAccount(permission) => { permission.account.domain() == domain_id } - AnyPermission::CanSetKeyValueInAccount(permission) => { - permission.account.domain() == domain_id - } - AnyPermission::CanRemoveKeyValueInAccount(permission) => { + AnyPermission::CanModifyAccountMetadata(permission) => { permission.account.domain() == domain_id } - AnyPermission::CanRegisterUserTrigger(permission) => { - permission.account.domain() == domain_id - } - AnyPermission::CanUnregisterUserTrigger(permission) => { - permission.account.domain() == domain_id + AnyPermission::CanRegisterTrigger(permission) => { + permission.authority.domain() == domain_id } - AnyPermission::CanExecuteUserTrigger(_) - | AnyPermission::CanBurnUserTrigger(_) - | AnyPermission::CanMintUserTrigger(_) - | AnyPermission::CanSetKeyValueInTrigger(_) - | AnyPermission::CanRemoveKeyValueInTrigger(_) - | AnyPermission::CanUnregisterAnyPeer(_) + AnyPermission::CanUnregisterTrigger(_) + | AnyPermission::CanExecuteTrigger(_) + | AnyPermission::CanModifyTrigger(_) + | AnyPermission::CanModifyTriggerMetadata(_) + | AnyPermission::CanManagePeers(_) + | AnyPermission::CanRegisterDomain(_) | AnyPermission::CanSetParameters(_) - | AnyPermission::CanUnregisterAnyRole(_) + | AnyPermission::CanManageRoles(_) | AnyPermission::CanUpgradeExecutor(_) => false, } } } pub mod account { - use iroha_executor_data_model::permission::{ - account::{CanRemoveKeyValueInAccount, CanSetKeyValueInAccount, CanUnregisterAccount}, - domain::CanRegisterAccountInDomain, + use iroha_executor_data_model::permission::account::{ + CanModifyAccountMetadata, CanRegisterAccount, CanUnregisterAccount, }; use super::*; @@ -407,7 +390,7 @@ pub mod account { Ok(false) => {} } - let can_register_account_in_domain = CanRegisterAccountInDomain { + let can_register_account_in_domain = CanRegisterAccount { domain: domain_id.clone(), }; if can_register_account_in_domain.is_owned_by(authority) { @@ -442,18 +425,18 @@ pub mod account { use iroha_smart_contract::ExecuteOnHost as _; for (owner_id, permission) in accounts_permissions() { - if is_token_account_associated(&permission, account_id) { + if is_permission_account_associated(&permission, account_id) { let isi = Revoke::account_permission(permission, owner_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } for (role_id, permission) in roles_permissions() { - if is_token_account_associated(&permission, account_id) { + if is_permission_account_associated(&permission, account_id) { let isi = Revoke::role_permission(permission, role_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } @@ -477,7 +460,7 @@ pub mod account { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_set_key_value_in_user_account_token = CanSetKeyValueInAccount { + let can_set_key_value_in_user_account_token = CanModifyAccountMetadata { account: account_id.clone(), }; if can_set_key_value_in_user_account_token.is_owned_by(authority) { @@ -505,7 +488,7 @@ pub mod account { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_remove_key_value_in_user_account_token = CanRemoveKeyValueInAccount { + let can_remove_key_value_in_user_account_token = CanModifyAccountMetadata { account: account_id.clone(), }; if can_remove_key_value_in_user_account_token.is_owned_by(authority) { @@ -518,67 +501,49 @@ pub mod account { ); } - fn is_token_account_associated(permission: &Permission, account_id: &AccountId) -> bool { + fn is_permission_account_associated(permission: &Permission, account_id: &AccountId) -> bool { let Ok(permission) = AnyPermission::try_from(permission) else { return false; }; match permission { - AnyPermission::CanUnregisterAccount(permission) => &permission.account == account_id, - AnyPermission::CanSetKeyValueInAccount(permission) => &permission.account == account_id, - AnyPermission::CanRemoveKeyValueInAccount(permission) => { - &permission.account == account_id - } - AnyPermission::CanBurnUserAsset(permission) => permission.asset.account() == account_id, - AnyPermission::CanTransferUserAsset(permission) => { - permission.asset.account() == account_id - } - AnyPermission::CanUnregisterUserAsset(permission) => { - permission.asset.account() == account_id + AnyPermission::CanUnregisterAccount(permission) => permission.account == *account_id, + AnyPermission::CanModifyAccountMetadata(permission) => { + permission.account == *account_id } - AnyPermission::CanSetKeyValueInUserAsset(permission) => { + AnyPermission::CanRegisterAsset(permission) => permission.owner == *account_id, + AnyPermission::CanUnregisterAsset(permission) => { permission.asset.account() == account_id } - AnyPermission::CanRemoveKeyValueInUserAsset(permission) => { + AnyPermission::CanModifyAssetMetadata(permission) => { permission.asset.account() == account_id } - AnyPermission::CanMintUserAsset(permission) => permission.asset.account() == account_id, - AnyPermission::CanRegisterUserTrigger(permission) => &permission.account == account_id, - AnyPermission::CanUnregisterUserTrigger(permission) => { - &permission.account == account_id - } - AnyPermission::CanExecuteUserTrigger(_) - | AnyPermission::CanBurnUserTrigger(_) - | AnyPermission::CanMintUserTrigger(_) - | AnyPermission::CanSetKeyValueInTrigger(_) - | AnyPermission::CanRemoveKeyValueInTrigger(_) - | AnyPermission::CanUnregisterAnyPeer(_) + AnyPermission::CanModifyAsset(permission) => permission.asset.account() == account_id, + AnyPermission::CanRegisterTrigger(permission) => permission.authority == *account_id, + AnyPermission::CanUnregisterTrigger(_) + | AnyPermission::CanExecuteTrigger(_) + | AnyPermission::CanModifyTrigger(_) + | AnyPermission::CanModifyTriggerMetadata(_) + | AnyPermission::CanManagePeers(_) + | AnyPermission::CanRegisterDomain(_) | AnyPermission::CanUnregisterDomain(_) - | AnyPermission::CanSetKeyValueInDomain(_) - | AnyPermission::CanRemoveKeyValueInDomain(_) - | AnyPermission::CanRegisterAccountInDomain(_) - | AnyPermission::CanRegisterAssetDefinitionInDomain(_) + | AnyPermission::CanModifyDomainMetadata(_) + | AnyPermission::CanRegisterAccount(_) + | AnyPermission::CanRegisterAssetDefinition(_) | AnyPermission::CanUnregisterAssetDefinition(_) - | AnyPermission::CanSetKeyValueInAssetDefinition(_) - | AnyPermission::CanRemoveKeyValueInAssetDefinition(_) + | AnyPermission::CanModifyAssetDefinitionMetadata(_) | AnyPermission::CanRegisterAssetWithDefinition(_) | AnyPermission::CanUnregisterAssetWithDefinition(_) - | AnyPermission::CanBurnAssetWithDefinition(_) - | AnyPermission::CanMintAssetWithDefinition(_) - | AnyPermission::CanTransferAssetWithDefinition(_) + | AnyPermission::CanModifyAssetsWithDefinition(_) | AnyPermission::CanSetParameters(_) - | AnyPermission::CanUnregisterAnyRole(_) + | AnyPermission::CanManageRoles(_) | AnyPermission::CanUpgradeExecutor(_) => false, } } } pub mod asset_definition { - use iroha_executor_data_model::permission::{ - asset_definition::{ - CanRemoveKeyValueInAssetDefinition, CanSetKeyValueInAssetDefinition, - CanUnregisterAssetDefinition, - }, - domain::CanRegisterAssetDefinitionInDomain, + use iroha_executor_data_model::permission::asset_definition::{ + CanModifyAssetDefinitionMetadata, CanRegisterAssetDefinition, CanUnregisterAssetDefinition, }; use iroha_smart_contract::data_model::asset::AssetDefinitionId; @@ -601,7 +566,7 @@ pub mod asset_definition { Ok(false) => {} } - let can_register_asset_definition_in_domain_token = CanRegisterAssetDefinitionInDomain { + let can_register_asset_definition_in_domain_token = CanRegisterAssetDefinition { domain: domain_id.clone(), }; if can_register_asset_definition_in_domain_token.is_owned_by(authority) { @@ -636,18 +601,18 @@ pub mod asset_definition { use iroha_smart_contract::ExecuteOnHost as _; for (owner_id, permission) in accounts_permissions() { - if is_token_asset_definition_associated(&permission, asset_definition_id) { + if is_permission_asset_definition_associated(&permission, asset_definition_id) { let isi = Revoke::account_permission(permission, owner_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } for (role_id, permission) in roles_permissions() { - if is_token_asset_definition_associated(&permission, asset_definition_id) { + if is_permission_asset_definition_associated(&permission, asset_definition_id) { let isi = Revoke::role_permission(permission, role_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } @@ -702,7 +667,7 @@ pub mod asset_definition { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_set_key_value_in_asset_definition_token = CanSetKeyValueInAssetDefinition { + let can_set_key_value_in_asset_definition_token = CanModifyAssetDefinitionMetadata { asset_definition: asset_definition_id.clone(), }; if can_set_key_value_in_asset_definition_token.is_owned_by(authority) { @@ -730,7 +695,7 @@ pub mod asset_definition { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_remove_key_value_in_asset_definition_token = CanRemoveKeyValueInAssetDefinition { + let can_remove_key_value_in_asset_definition_token = CanModifyAssetDefinitionMetadata { asset_definition: asset_definition_id.clone(), }; if can_remove_key_value_in_asset_definition_token.is_owned_by(authority) { @@ -743,7 +708,7 @@ pub mod asset_definition { ); } - fn is_token_asset_definition_associated( + fn is_permission_asset_definition_associated( permission: &Permission, asset_definition_id: &AssetDefinitionId, ) -> bool { @@ -754,10 +719,7 @@ pub mod asset_definition { AnyPermission::CanUnregisterAssetDefinition(permission) => { &permission.asset_definition == asset_definition_id } - AnyPermission::CanSetKeyValueInAssetDefinition(permission) => { - &permission.asset_definition == asset_definition_id - } - AnyPermission::CanRemoveKeyValueInAssetDefinition(permission) => { + AnyPermission::CanModifyAssetDefinitionMetadata(permission) => { &permission.asset_definition == asset_definition_id } AnyPermission::CanRegisterAssetWithDefinition(permission) => { @@ -766,51 +728,34 @@ pub mod asset_definition { AnyPermission::CanUnregisterAssetWithDefinition(permission) => { &permission.asset_definition == asset_definition_id } - AnyPermission::CanBurnAssetWithDefinition(permission) => { - &permission.asset_definition == asset_definition_id - } - AnyPermission::CanMintAssetWithDefinition(permission) => { + AnyPermission::CanModifyAssetsWithDefinition(permission) => { &permission.asset_definition == asset_definition_id } - AnyPermission::CanTransferAssetWithDefinition(permission) => { - &permission.asset_definition == asset_definition_id - } - AnyPermission::CanBurnUserAsset(permission) => { - permission.asset.definition() == asset_definition_id - } - AnyPermission::CanTransferUserAsset(permission) => { - permission.asset.definition() == asset_definition_id - } - AnyPermission::CanUnregisterUserAsset(permission) => { + AnyPermission::CanUnregisterAsset(permission) => { permission.asset.definition() == asset_definition_id } - AnyPermission::CanSetKeyValueInUserAsset(permission) => { + AnyPermission::CanModifyAssetMetadata(permission) => { permission.asset.definition() == asset_definition_id } - AnyPermission::CanRemoveKeyValueInUserAsset(permission) => { - permission.asset.definition() == asset_definition_id - } - AnyPermission::CanMintUserAsset(permission) => { + AnyPermission::CanModifyAsset(permission) => { permission.asset.definition() == asset_definition_id } AnyPermission::CanUnregisterAccount(_) - | AnyPermission::CanSetKeyValueInAccount(_) - | AnyPermission::CanRemoveKeyValueInAccount(_) - | AnyPermission::CanRegisterUserTrigger(_) - | AnyPermission::CanUnregisterUserTrigger(_) - | AnyPermission::CanExecuteUserTrigger(_) - | AnyPermission::CanBurnUserTrigger(_) - | AnyPermission::CanMintUserTrigger(_) - | AnyPermission::CanSetKeyValueInTrigger(_) - | AnyPermission::CanRemoveKeyValueInTrigger(_) - | AnyPermission::CanUnregisterAnyPeer(_) + | AnyPermission::CanRegisterAsset(_) + | AnyPermission::CanModifyAccountMetadata(_) + | AnyPermission::CanRegisterTrigger(_) + | AnyPermission::CanUnregisterTrigger(_) + | AnyPermission::CanExecuteTrigger(_) + | AnyPermission::CanModifyTrigger(_) + | AnyPermission::CanModifyTriggerMetadata(_) + | AnyPermission::CanManagePeers(_) + | AnyPermission::CanRegisterDomain(_) | AnyPermission::CanUnregisterDomain(_) - | AnyPermission::CanSetKeyValueInDomain(_) - | AnyPermission::CanRemoveKeyValueInDomain(_) - | AnyPermission::CanRegisterAccountInDomain(_) - | AnyPermission::CanRegisterAssetDefinitionInDomain(_) + | AnyPermission::CanModifyDomainMetadata(_) + | AnyPermission::CanRegisterAccount(_) + | AnyPermission::CanRegisterAssetDefinition(_) | AnyPermission::CanSetParameters(_) - | AnyPermission::CanUnregisterAnyRole(_) + | AnyPermission::CanManageRoles(_) | AnyPermission::CanUpgradeExecutor(_) => false, } } @@ -818,10 +763,8 @@ pub mod asset_definition { pub mod asset { use iroha_executor_data_model::permission::asset::{ - CanBurnAssetWithDefinition, CanBurnUserAsset, CanMintAssetWithDefinition, CanMintUserAsset, - CanRegisterAssetWithDefinition, CanRemoveKeyValueInUserAsset, CanSetKeyValueInUserAsset, - CanTransferAssetWithDefinition, CanTransferUserAsset, CanUnregisterAssetWithDefinition, - CanUnregisterUserAsset, + CanModifyAsset, CanModifyAssetMetadata, CanModifyAssetsWithDefinition, CanRegisterAsset, + CanRegisterAssetWithDefinition, CanUnregisterAsset, CanUnregisterAssetWithDefinition, }; use iroha_smart_contract::data_model::{ asset::AssetValue, isi::BuiltInInstruction, metadata::Metadata, @@ -852,6 +795,12 @@ pub mod asset { if can_register_assets_with_definition_token.is_owned_by(authority) { execute!(executor, isi); } + let can_register_user_asset_token = CanRegisterAsset { + owner: asset.id().account().clone(), + }; + if can_register_user_asset_token.is_owned_by(authority) { + execute!(executor, isi); + } deny!( executor, @@ -885,7 +834,7 @@ pub mod asset { if can_unregister_assets_with_definition_token.is_owned_by(authority) { execute!(executor, isi); } - let can_unregister_user_asset_token = CanUnregisterUserAsset { + let can_unregister_user_asset_token = CanUnregisterAsset { asset: asset_id.clone(), }; if can_unregister_user_asset_token.is_owned_by(authority) { @@ -910,13 +859,13 @@ pub mod asset { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_mint_assets_with_definition_token = CanMintAssetWithDefinition { + let can_mint_assets_with_definition_token = CanModifyAssetsWithDefinition { asset_definition: asset_id.definition().clone(), }; if can_mint_assets_with_definition_token.is_owned_by(authority) { execute!(executor, isi); } - let can_mint_user_asset_token = CanMintUserAsset { + let can_mint_user_asset_token = CanModifyAsset { asset: asset_id.clone(), }; if can_mint_user_asset_token.is_owned_by(authority) { @@ -947,23 +896,18 @@ pub mod asset { if is_genesis(executor) { execute!(executor, isi); } - match is_asset_owner(asset_id, authority) { - Err(err) => deny!(executor, err), - Ok(true) => execute!(executor, isi), - Ok(false) => {} - } match is_asset_definition_owner(asset_id.definition(), authority) { Err(err) => deny!(executor, err), Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_burn_assets_with_definition_token = CanBurnAssetWithDefinition { + let can_burn_assets_with_definition_token = CanModifyAssetsWithDefinition { asset_definition: asset_id.definition().clone(), }; if can_burn_assets_with_definition_token.is_owned_by(authority) { execute!(executor, isi); } - let can_burn_user_asset_token = CanBurnUserAsset { + let can_burn_user_asset_token = CanModifyAsset { asset: asset_id.clone(), }; if can_burn_user_asset_token.is_owned_by(authority) { @@ -1004,13 +948,13 @@ pub mod asset { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_transfer_assets_with_definition_token = CanTransferAssetWithDefinition { + let can_transfer_assets_with_definition_token = CanModifyAssetsWithDefinition { asset_definition: asset_id.definition().clone(), }; if can_transfer_assets_with_definition_token.is_owned_by(authority) { execute!(executor, isi); } - let can_transfer_user_asset_token = CanTransferUserAsset { + let can_transfer_user_asset_token = CanModifyAsset { asset: asset_id.clone(), }; if can_transfer_user_asset_token.is_owned_by(authority) { @@ -1052,7 +996,7 @@ pub mod asset { Ok(false) => {} } - let can_set_key_value_in_user_asset_token = CanSetKeyValueInUserAsset { + let can_set_key_value_in_user_asset_token = CanModifyAssetMetadata { asset: asset_id.clone(), }; if can_set_key_value_in_user_asset_token.is_owned_by(authority) { @@ -1080,7 +1024,7 @@ pub mod asset { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_remove_key_value_in_user_asset_token = CanRemoveKeyValueInUserAsset { + let can_remove_key_value_in_user_asset_token = CanModifyAssetMetadata { asset: asset_id.clone(), }; if can_remove_key_value_in_user_asset_token.is_owned_by(authority) { @@ -1099,7 +1043,6 @@ pub mod parameter { use super::*; - #[allow(clippy::needless_pass_by_value)] pub fn visit_set_parameter( executor: &mut V, authority: &AccountId, @@ -1120,65 +1063,23 @@ pub mod parameter { } pub mod role { - use iroha_executor_data_model::permission::role::CanUnregisterAnyRole; + use iroha_executor_data_model::permission::role::CanManageRoles; use iroha_smart_contract::data_model::role::Role; use super::*; macro_rules! impl_validate_grant_revoke_account_role { - ($executor:ident, $isi:ident, $authority:ident, $method:ident) => { + ($executor:ident, $isi:ident, $authority:ident) => { let role_id = $isi.object(); - let find_role_query_res = - match crate::data_model::query::builder::QueryBuilderExt::execute_single( - iroha_smart_contract::query(FindRoles) - .filter_with(|role| role.id.eq(role_id.clone())), - ) { - Ok(res) => res, - Err(crate::data_model::query::builder::SingleQueryError::QueryError(error)) => { - deny!($executor, error); - } - Err( - crate::data_model::query::builder::SingleQueryError::ExpectedOneGotNone, - ) => { - // assuming that only a "not found" case is possible here - $executor.deny($crate::data_model::ValidationFail::QueryFailed( - $crate::data_model::query::error::QueryExecutionFail::Find( - $crate::data_model::query::error::FindError::Role(role_id.clone()), - ), - )); - return; - } - Err(_) => { - unreachable!(); - } - }; - let role = Role::try_from(find_role_query_res).unwrap(); - - let mut unknown_tokens = alloc::vec::Vec::new(); - for permission in role.permissions() { - if let Ok(permission) = AnyPermission::try_from(permission) { - if !is_genesis($executor) { - if let Err(error) = crate::permission::ValidateGrantRevoke::$method( - &permission, - $authority, - $executor.block_height(), - ) { - deny!($executor, error); - } - } - - continue; - } - - unknown_tokens.push(permission); + if is_genesis($executor) + || find_account_roles($authority.clone()) + .any(|authority_role_id| authority_role_id == *role_id) + { + execute!($executor, $isi) } - assert!( - unknown_tokens.is_empty(), - "Role contains unknown permission tokens: {unknown_tokens:?}" - ); - execute!($executor, $isi) + deny!($executor, "Can't grant or revoke role to another account"); }; } @@ -1189,6 +1090,12 @@ pub mod role { if let Ok(any_permission) = AnyPermission::try_from(permission) { if !is_genesis($executor) { + if !find_account_roles($authority.clone()) + .any(|authority_role_id| authority_role_id == role_id) + { + deny!($executor, "Can't modify role"); + } + if let Err(error) = crate::permission::ValidateGrantRevoke::$method( &any_permission, $authority, @@ -1204,49 +1111,67 @@ pub mod role { deny!( $executor, - ValidationFail::NotPermitted(format!( - "{permission:?}: Unknown permission permission" - )) + ValidationFail::NotPermitted(format!("{permission:?}: Unknown permission")) ); }; } - #[allow(clippy::needless_pass_by_value)] + fn find_account_roles(account_id: AccountId) -> impl Iterator { + use iroha_smart_contract_utils::debug::DebugExpectExt as _; + + iroha_smart_contract::query(FindRolesByAccountId::new(account_id)) + .execute() + .dbg_expect("INTERNAL BUG: `FindRolesByAccountId` must never fail") + .map(|role| role.dbg_expect("Failed to get role from cursor")) + } + pub fn visit_register_role( executor: &mut V, - _authority: &AccountId, + authority: &AccountId, isi: &Register, ) { - let role = isi.object().inner(); + use crate::smart_contract::ExecuteOnHost as _; + + let role = isi.object(); + let mut new_role = Role::new(role.id().clone(), role.grant_to().clone()); - // Unify permission tokens inside role and deduplicate them - let mut new_role = Role::new(role.id().clone()); - let mut unknown_tokens = alloc::vec::Vec::new(); - for permission in role.permissions() { + for permission in role.inner().permissions() { iroha_smart_contract::debug!(&format!("Checking `{permission:?}`")); if let Ok(any_permission) = AnyPermission::try_from(permission) { + if !is_genesis(executor) { + if let Err(error) = crate::permission::ValidateGrantRevoke::validate_grant( + &any_permission, + role.grant_to(), + executor.block_height(), + ) { + deny!(executor, error); + } + } + new_role = new_role.add_permission(any_permission); - continue; + } else { + deny!( + executor, + ValidationFail::NotPermitted(format!("{permission:?}: Unknown permission")) + ); } - - unknown_tokens.push(permission); } - if !unknown_tokens.is_empty() { - deny!( - executor, - ValidationFail::NotPermitted(format!( - "{unknown_tokens:?}: Unrecognised permission tokens" - )) - ); + let isi = Register::role(new_role); + if is_genesis(executor) || CanManageRoles.is_owned_by(authority) { + let grant_role = Grant::account_role(role.id().clone(), role.grant_to().clone()); + + if let Err(err) = isi.execute() { + executor.deny(err); + } + + execute!(executor, grant_role); } - let isi = Register::role(new_role); - execute!(executor, isi); + deny!(executor, "Can't register role"); } - #[allow(clippy::needless_pass_by_value)] pub fn visit_unregister_role( executor: &mut V, authority: &AccountId, @@ -1255,7 +1180,7 @@ pub mod role { if is_genesis(executor) { execute!(executor, isi); } - if CanUnregisterAnyRole.is_owned_by(authority) { + if CanManageRoles.is_owned_by(authority) { execute!(executor, isi); } @@ -1267,7 +1192,7 @@ pub mod role { authority: &AccountId, isi: &Grant, ) { - impl_validate_grant_revoke_account_role!(executor, isi, authority, validate_grant); + impl_validate_grant_revoke_account_role!(executor, isi, authority); } pub fn visit_revoke_account_role( @@ -1275,7 +1200,7 @@ pub mod role { authority: &AccountId, isi: &Revoke, ) { - impl_validate_grant_revoke_account_role!(executor, isi, authority, validate_revoke); + impl_validate_grant_revoke_account_role!(executor, isi, authority); } pub fn visit_grant_role_permission( @@ -1297,17 +1222,14 @@ pub mod role { pub mod trigger { use iroha_executor_data_model::permission::trigger::{ - CanBurnUserTrigger, CanExecuteUserTrigger, CanMintUserTrigger, CanRegisterUserTrigger, - CanRemoveKeyValueInTrigger, CanSetKeyValueInTrigger, CanUnregisterUserTrigger, + CanExecuteTrigger, CanModifyTrigger, CanModifyTriggerMetadata, CanRegisterTrigger, + CanUnregisterTrigger, }; use iroha_smart_contract::data_model::trigger::Trigger; use super::*; use crate::permission::{ - accounts_permissions, - domain::is_domain_owner, - roles_permissions, - trigger::{find_trigger, is_trigger_owner}, + accounts_permissions, domain::is_domain_owner, roles_permissions, trigger::is_trigger_owner, }; pub fn visit_register_trigger( @@ -1325,8 +1247,8 @@ pub mod trigger { } } || { - let can_register_user_trigger_token = CanRegisterUserTrigger { - account: isi.object().action().authority().clone(), + let can_register_user_trigger_token = CanRegisterTrigger { + authority: isi.object().action().authority().clone(), }; can_register_user_trigger_token.is_owned_by(authority) } @@ -1349,12 +1271,8 @@ pub mod trigger { Ok(is_trigger_owner) => is_trigger_owner, } || { - let can_unregister_user_trigger_token = CanUnregisterUserTrigger { - account: find_trigger(trigger_id) - .unwrap() - .action() - .authority() - .clone(), + let can_unregister_user_trigger_token = CanUnregisterTrigger { + trigger: trigger_id.clone(), }; can_unregister_user_trigger_token.is_owned_by(authority) } @@ -1362,18 +1280,18 @@ pub mod trigger { use iroha_smart_contract::ExecuteOnHost as _; for (owner_id, permission) in accounts_permissions() { - if is_token_trigger_associated(&permission, trigger_id) { + if is_permission_trigger_associated(&permission, trigger_id) { let isi = Revoke::account_permission(permission, owner_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } for (role_id, permission) in roles_permissions() { - if is_token_trigger_associated(&permission, trigger_id) { + if is_permission_trigger_associated(&permission, trigger_id) { let isi = Revoke::role_permission(permission, role_id.clone()); - if let Err(_err) = isi.execute() { - deny!(executor, "Can't revoke associated permission"); + if let Err(err) = isi.execute() { + deny!(executor, err); } } } @@ -1400,7 +1318,7 @@ pub mod trigger { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_mint_user_trigger_token = CanMintUserTrigger { + let can_mint_user_trigger_token = CanModifyTrigger { trigger: trigger_id.clone(), }; if can_mint_user_trigger_token.is_owned_by(authority) { @@ -1428,7 +1346,7 @@ pub mod trigger { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_mint_user_trigger_token = CanBurnUserTrigger { + let can_mint_user_trigger_token = CanModifyTrigger { trigger: trigger_id.clone(), }; if can_mint_user_trigger_token.is_owned_by(authority) { @@ -1456,7 +1374,7 @@ pub mod trigger { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_execute_trigger_token = CanExecuteUserTrigger { + let can_execute_trigger_token = CanExecuteTrigger { trigger: trigger_id.clone(), }; if can_execute_trigger_token.is_owned_by(authority) { @@ -1481,7 +1399,7 @@ pub mod trigger { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_set_key_value_in_user_trigger_token = CanSetKeyValueInTrigger { + let can_set_key_value_in_user_trigger_token = CanModifyTriggerMetadata { trigger: trigger_id.clone(), }; if can_set_key_value_in_user_trigger_token.is_owned_by(authority) { @@ -1509,7 +1427,7 @@ pub mod trigger { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_remove_key_value_in_trigger_token = CanRemoveKeyValueInTrigger { + let can_remove_key_value_in_trigger_token = CanModifyTriggerMetadata { trigger: trigger_id.clone(), }; if can_remove_key_value_in_trigger_token.is_owned_by(authority) { @@ -1522,45 +1440,37 @@ pub mod trigger { ); } - fn is_token_trigger_associated(permission: &Permission, trigger_id: &TriggerId) -> bool { + fn is_permission_trigger_associated(permission: &Permission, trigger_id: &TriggerId) -> bool { let Ok(permission) = AnyPermission::try_from(permission) else { return false; }; match permission { - AnyPermission::CanExecuteUserTrigger(permission) => &permission.trigger == trigger_id, - AnyPermission::CanBurnUserTrigger(permission) => &permission.trigger == trigger_id, - AnyPermission::CanMintUserTrigger(permission) => &permission.trigger == trigger_id, - AnyPermission::CanSetKeyValueInTrigger(permission) => &permission.trigger == trigger_id, - AnyPermission::CanRemoveKeyValueInTrigger(permission) => { + AnyPermission::CanUnregisterTrigger(permission) => &permission.trigger == trigger_id, + AnyPermission::CanExecuteTrigger(permission) => &permission.trigger == trigger_id, + AnyPermission::CanModifyTrigger(permission) => &permission.trigger == trigger_id, + AnyPermission::CanModifyTriggerMetadata(permission) => { &permission.trigger == trigger_id } - AnyPermission::CanRegisterUserTrigger(_) - | AnyPermission::CanUnregisterUserTrigger(_) - | AnyPermission::CanUnregisterAnyPeer(_) + AnyPermission::CanRegisterTrigger(_) + | AnyPermission::CanManagePeers(_) + | AnyPermission::CanRegisterDomain(_) | AnyPermission::CanUnregisterDomain(_) - | AnyPermission::CanSetKeyValueInDomain(_) - | AnyPermission::CanRemoveKeyValueInDomain(_) - | AnyPermission::CanRegisterAccountInDomain(_) - | AnyPermission::CanRegisterAssetDefinitionInDomain(_) + | AnyPermission::CanModifyDomainMetadata(_) + | AnyPermission::CanRegisterAccount(_) + | AnyPermission::CanRegisterAssetDefinition(_) | AnyPermission::CanUnregisterAccount(_) - | AnyPermission::CanSetKeyValueInAccount(_) - | AnyPermission::CanRemoveKeyValueInAccount(_) + | AnyPermission::CanModifyAccountMetadata(_) | AnyPermission::CanUnregisterAssetDefinition(_) - | AnyPermission::CanSetKeyValueInAssetDefinition(_) - | AnyPermission::CanRemoveKeyValueInAssetDefinition(_) + | AnyPermission::CanModifyAssetDefinitionMetadata(_) | AnyPermission::CanRegisterAssetWithDefinition(_) | AnyPermission::CanUnregisterAssetWithDefinition(_) - | AnyPermission::CanUnregisterUserAsset(_) - | AnyPermission::CanBurnAssetWithDefinition(_) - | AnyPermission::CanBurnUserAsset(_) - | AnyPermission::CanMintAssetWithDefinition(_) - | AnyPermission::CanTransferAssetWithDefinition(_) - | AnyPermission::CanTransferUserAsset(_) - | AnyPermission::CanSetKeyValueInUserAsset(_) - | AnyPermission::CanRemoveKeyValueInUserAsset(_) - | AnyPermission::CanMintUserAsset(_) + | AnyPermission::CanRegisterAsset(_) + | AnyPermission::CanUnregisterAsset(_) + | AnyPermission::CanModifyAssetsWithDefinition(_) + | AnyPermission::CanModifyAssetMetadata(_) + | AnyPermission::CanModifyAsset(_) | AnyPermission::CanSetParameters(_) - | AnyPermission::CanUnregisterAnyRole(_) + | AnyPermission::CanManageRoles(_) | AnyPermission::CanUpgradeExecutor(_) => false, } } @@ -1630,7 +1540,6 @@ pub mod executor { use super::*; - #[allow(clippy::needless_pass_by_value)] pub fn visit_upgrade( executor: &mut V, authority: &AccountId, diff --git a/crates/iroha_executor/src/lib.rs b/crates/iroha_executor/src/lib.rs index 66c7d8814de..11f7ccda712 100644 --- a/crates/iroha_executor/src/lib.rs +++ b/crates/iroha_executor/src/lib.rs @@ -137,7 +137,12 @@ mod host { #[macro_export] macro_rules! execute { ($executor:ident, $isi:ident) => {{ - if $executor.verdict().is_ok() { + #[cfg(debug_assertions)] + if !$executor.verdict().is_ok() { + unreachable!("Executor already denied"); + } + + { use $crate::smart_contract::ExecuteOnHost as _; if let Err(err) = $isi.execute() { @@ -156,7 +161,7 @@ macro_rules! execute { macro_rules! deny { ($executor:ident, $l:literal $(,)?) => {{ #[cfg(debug_assertions)] - if let Err(_error) = $executor.verdict() { + if $executor.verdict().is_err() { unreachable!("Executor already denied"); } $executor.deny($crate::data_model::ValidationFail::NotPermitted( @@ -166,7 +171,7 @@ macro_rules! deny { }}; ($executor:ident, $e:expr $(,)?) => {{ #[cfg(debug_assertions)] - if let Err(_error) = $executor.verdict() { + if $executor.verdict().is_err() { unreachable!("Executor already denied"); } $executor.deny($e); diff --git a/crates/iroha_executor/src/permission.rs b/crates/iroha_executor/src/permission.rs index 64f663bcb57..fca51ed0755 100644 --- a/crates/iroha_executor/src/permission.rs +++ b/crates/iroha_executor/src/permission.rs @@ -9,7 +9,7 @@ use iroha_smart_contract::{ }; use iroha_smart_contract_utils::debug::DebugExpectExt as _; -/// Declare token types of current module. Use it with a full path to the token. +/// Declare permission types of current module. Use it with a full path to the permission. /// Used to iterate over tokens to validate `Grant` and `Revoke` instructions. /// /// @@ -20,17 +20,17 @@ use iroha_smart_contract_utils::debug::DebugExpectExt as _; /// use std::borrow::ToOwned; /// /// use iroha_schema::IntoSchema; -/// use iroha_executor_derive::Token; +/// use iroha_executor_derive::Permission; /// use serde::{Deserialize, Serialize}; /// -/// #[derive(Clone, PartialEq, Deserialize, Serialize, IntoSchema, Token)] +/// #[derive(Clone, PartialEq, Deserialize, Serialize, IntoSchema, Permission)] /// #[validate(iroha_executor::permission::OnlyGenesis)] /// pub struct MyToken; /// } /// ``` macro_rules! declare_permissions { ($($($token_path:ident ::)+ { $token_ty:ident }),+ $(,)?) => { - /// Enum with every default token + /// Enum with every default permission #[allow(clippy::enum_variant_names)] #[derive(Clone)] pub(crate) enum AnyPermission { $( @@ -40,21 +40,21 @@ macro_rules! declare_permissions { impl TryFrom<&PermissionObject> for AnyPermission { type Error = iroha_executor_data_model::TryFromDataModelObjectError; - fn try_from(token: &PermissionObject) -> Result { - match token.name().as_ref() { $( + fn try_from(permission: &PermissionObject) -> Result { + match permission.name().as_ref() { $( stringify!($token_ty) => { - let token = <$($token_path::)+$token_ty>::try_from(token)?; - Ok(Self::$token_ty(token)) + let permission = <$($token_path::)+$token_ty>::try_from(permission)?; + Ok(Self::$token_ty(permission)) } )+ - _ => Err(Self::Error::UnknownIdent(token.name().to_owned())) + _ => Err(Self::Error::UnknownIdent(permission.name().to_owned())) } } } impl From for PermissionObject { - fn from(token: AnyPermission) -> Self { - match token { $( - AnyPermission::$token_ty(token) => token.into(), )* + fn from(permission: AnyPermission) -> Self { + match permission { $( + AnyPermission::$token_ty(permission) => permission.into(), )* } } } @@ -62,13 +62,13 @@ macro_rules! declare_permissions { impl ValidateGrantRevoke for AnyPermission { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { match self { $( - AnyPermission::$token_ty(token) => token.validate_grant(authority, block_height), )* + AnyPermission::$token_ty(permission) => permission.validate_grant(authority, block_height), )* } } fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { match self { $( - AnyPermission::$token_ty(token) => token.validate_revoke(authority, block_height), )* + AnyPermission::$token_ty(permission) => permission.validate_revoke(authority, block_height), )* } } } @@ -84,69 +84,97 @@ macro_rules! declare_permissions { } declare_permissions! { - iroha_executor_data_model::permission::peer::{CanUnregisterAnyPeer}, + iroha_executor_data_model::permission::peer::{CanManagePeers}, + iroha_executor_data_model::permission::domain::{CanRegisterDomain}, iroha_executor_data_model::permission::domain::{CanUnregisterDomain}, - iroha_executor_data_model::permission::domain::{CanSetKeyValueInDomain}, - iroha_executor_data_model::permission::domain::{CanRemoveKeyValueInDomain}, - iroha_executor_data_model::permission::domain::{CanRegisterAccountInDomain}, - iroha_executor_data_model::permission::domain::{CanRegisterAssetDefinitionInDomain}, + iroha_executor_data_model::permission::domain::{CanModifyDomainMetadata}, + iroha_executor_data_model::permission::account::{CanRegisterAccount}, iroha_executor_data_model::permission::account::{CanUnregisterAccount}, - iroha_executor_data_model::permission::account::{CanSetKeyValueInAccount}, - iroha_executor_data_model::permission::account::{CanRemoveKeyValueInAccount}, + iroha_executor_data_model::permission::account::{CanModifyAccountMetadata}, + iroha_executor_data_model::permission::asset_definition::{CanRegisterAssetDefinition}, iroha_executor_data_model::permission::asset_definition::{CanUnregisterAssetDefinition}, - iroha_executor_data_model::permission::asset_definition::{CanSetKeyValueInAssetDefinition}, - iroha_executor_data_model::permission::asset_definition::{CanRemoveKeyValueInAssetDefinition}, + iroha_executor_data_model::permission::asset_definition::{CanModifyAssetDefinitionMetadata}, iroha_executor_data_model::permission::asset::{CanRegisterAssetWithDefinition}, iroha_executor_data_model::permission::asset::{CanUnregisterAssetWithDefinition}, - iroha_executor_data_model::permission::asset::{CanUnregisterUserAsset}, - iroha_executor_data_model::permission::asset::{CanBurnAssetWithDefinition}, - iroha_executor_data_model::permission::asset::{CanMintAssetWithDefinition}, - iroha_executor_data_model::permission::asset::{CanMintUserAsset}, - iroha_executor_data_model::permission::asset::{CanBurnUserAsset}, - iroha_executor_data_model::permission::asset::{CanTransferAssetWithDefinition}, - iroha_executor_data_model::permission::asset::{CanTransferUserAsset}, - iroha_executor_data_model::permission::asset::{CanSetKeyValueInUserAsset}, - iroha_executor_data_model::permission::asset::{CanRemoveKeyValueInUserAsset}, + iroha_executor_data_model::permission::asset::{CanModifyAssetsWithDefinition}, + iroha_executor_data_model::permission::asset::{CanRegisterAsset}, + iroha_executor_data_model::permission::asset::{CanUnregisterAsset}, + iroha_executor_data_model::permission::asset::{CanModifyAsset}, + iroha_executor_data_model::permission::asset::{CanModifyAssetMetadata}, iroha_executor_data_model::permission::parameter::{CanSetParameters}, - iroha_executor_data_model::permission::role::{CanUnregisterAnyRole}, + iroha_executor_data_model::permission::role::{CanManageRoles}, - iroha_executor_data_model::permission::trigger::{CanRegisterUserTrigger}, - iroha_executor_data_model::permission::trigger::{CanExecuteUserTrigger}, - iroha_executor_data_model::permission::trigger::{CanUnregisterUserTrigger}, - iroha_executor_data_model::permission::trigger::{CanMintUserTrigger}, - iroha_executor_data_model::permission::trigger::{CanBurnUserTrigger}, - iroha_executor_data_model::permission::trigger::{CanSetKeyValueInTrigger}, - iroha_executor_data_model::permission::trigger::{CanRemoveKeyValueInTrigger}, + iroha_executor_data_model::permission::trigger::{CanRegisterTrigger}, + iroha_executor_data_model::permission::trigger::{CanUnregisterTrigger}, + iroha_executor_data_model::permission::trigger::{CanModifyTrigger}, + iroha_executor_data_model::permission::trigger::{CanExecuteTrigger}, + iroha_executor_data_model::permission::trigger::{CanModifyTriggerMetadata}, iroha_executor_data_model::permission::executor::{CanUpgradeExecutor}, } /// Trait that enables using permissions on the blockchain -pub trait ExecutorPermision: Permission + PartialEq { - /// Check if the account owns this token +pub trait ExecutorPermission: Permission + PartialEq { + /// Check if the account owns this permission fn is_owned_by(&self, account_id: &AccountId) -> bool where for<'a> Self: TryFrom<&'a crate::data_model::permission::Permission>, { - query(FindPermissionsByAccountId::new(account_id.clone())) + if query(FindPermissionsByAccountId::new(account_id.clone())) .execute() .expect("INTERNAL BUG: `FindPermissionsByAccountId` must never fail") .map(|res| res.dbg_expect("Failed to get permission from cursor")) .filter_map(|permission| Self::try_from(&permission).ok()) .any(|permission| *self == permission) + { + return true; + } + + query(FindRolesByAccountId::new(account_id.clone())) + .execute() + .expect("INTERNAL BUG: `FindRolesByAccountId` must never fail") + .map(|role_id| { + let role_id = role_id.dbg_expect("Failed to get role from cursor"); + + let role = match crate::data_model::query::builder::QueryBuilderExt::execute_single( + iroha_smart_contract::query(FindRoles) + .filter_with(|role| role.id.eq(role_id.clone())), + ) { + Ok(res) => res, + Err(crate::data_model::query::builder::SingleQueryError::QueryError(_)) => { + unreachable!("INTERNAL BUG: `FindRoles` must never fail") + } + Err( + crate::data_model::query::builder::SingleQueryError::ExpectedOneGotNone, + ) => { + unreachable!("INTERNAL BUG: integrity violated, role missing") + } + Err(_) => { + unreachable!(); + } + }; + + let found = role + .permissions() + .filter_map(|permission| Self::try_from(permission).ok()) + .any(|permission| *self == permission); + + found + }) + .any(|res| res) } } -impl ExecutorPermision for T {} +impl ExecutorPermission for T {} /// Trait that should be implemented for all permission tokens. /// Provides a function to check validity of [`Grant`] and [`Revoke`] -/// instructions containing implementing token. +/// instructions containing implementing permission. pub(super) trait ValidateGrantRevoke { #[allow(missing_docs, clippy::missing_errors_doc)] fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result; @@ -177,11 +205,11 @@ mod executor { } mod peer { - use iroha_executor_data_model::permission::peer::CanUnregisterAnyPeer; + use iroha_executor_data_model::permission::peer::CanManagePeers; use super::*; - impl ValidateGrantRevoke for CanUnregisterAnyPeer { + impl ValidateGrantRevoke for CanManagePeers { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { OnlyGenesis::from(self).validate(authority, block_height) } @@ -192,11 +220,11 @@ mod peer { } mod role { - use iroha_executor_data_model::permission::role::CanUnregisterAnyRole; + use iroha_executor_data_model::permission::role::CanManageRoles; use super::*; - impl ValidateGrantRevoke for CanUnregisterAnyRole { + impl ValidateGrantRevoke for CanManageRoles { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { OnlyGenesis::from(self).validate(authority, block_height) } @@ -241,10 +269,8 @@ pub mod asset { //! Module with pass conditions for asset related tokens use iroha_executor_data_model::permission::asset::{ - CanBurnAssetWithDefinition, CanBurnUserAsset, CanMintAssetWithDefinition, CanMintUserAsset, - CanRegisterAssetWithDefinition, CanRemoveKeyValueInUserAsset, CanSetKeyValueInUserAsset, - CanTransferAssetWithDefinition, CanTransferUserAsset, CanUnregisterAssetWithDefinition, - CanUnregisterUserAsset, + CanModifyAsset, CanModifyAssetMetadata, CanModifyAssetsWithDefinition, CanRegisterAsset, + CanRegisterAssetWithDefinition, CanUnregisterAsset, CanUnregisterAssetWithDefinition, }; use super::*; @@ -299,16 +325,7 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanBurnAssetWithDefinition { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - super::asset_definition::Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - super::asset_definition::Owner::from(self).validate(authority, block_height) - } - } - - impl ValidateGrantRevoke for CanMintAssetWithDefinition { + impl ValidateGrantRevoke for CanModifyAssetsWithDefinition { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { super::asset_definition::Owner::from(self).validate(authority, block_height) } @@ -317,25 +334,16 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanTransferAssetWithDefinition { + impl ValidateGrantRevoke for CanRegisterAsset { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - super::asset_definition::Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - super::asset_definition::Owner::from(self).validate(authority, block_height) - } - } - - impl ValidateGrantRevoke for CanUnregisterUserAsset { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + super::account::Owner::from(self).validate(authority, block_height) } fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + super::account::Owner::from(self).validate(authority, block_height) } } - impl ValidateGrantRevoke for CanMintUserAsset { + impl ValidateGrantRevoke for CanUnregisterAsset { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -344,7 +352,7 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanBurnUserAsset { + impl ValidateGrantRevoke for CanModifyAsset { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -353,7 +361,7 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanTransferUserAsset { + impl ValidateGrantRevoke for CanModifyAssetMetadata { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -362,20 +370,11 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanSetKeyValueInUserAsset { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - } - impl ValidateGrantRevoke for CanRemoveKeyValueInUserAsset { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + impl<'t> From<&'t CanRegisterAsset> for super::account::Owner<'t> { + fn from(value: &'t CanRegisterAsset) -> Self { + Self { + account: &value.owner, + } } } @@ -389,22 +388,14 @@ pub mod asset { }; } - impl_froms!( - CanUnregisterUserAsset, - CanMintUserAsset, - CanBurnUserAsset, - CanTransferUserAsset, - CanSetKeyValueInUserAsset, - CanRemoveKeyValueInUserAsset, - ); + impl_froms!(CanUnregisterAsset, CanModifyAsset, CanModifyAssetMetadata,); } pub mod asset_definition { //! Module with pass conditions for asset definition related tokens use iroha_executor_data_model::permission::asset_definition::{ - CanRemoveKeyValueInAssetDefinition, CanSetKeyValueInAssetDefinition, - CanUnregisterAssetDefinition, + CanModifyAssetDefinitionMetadata, CanRegisterAssetDefinition, CanUnregisterAssetDefinition, }; use iroha_smart_contract::data_model::{ isi::error::InstructionExecutionError, @@ -468,16 +459,16 @@ pub mod asset_definition { } } - impl ValidateGrantRevoke for CanUnregisterAssetDefinition { + impl ValidateGrantRevoke for CanRegisterAssetDefinition { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + super::domain::Owner::from(self).validate(authority, block_height) } fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + super::domain::Owner::from(self).validate(authority, block_height) } } - impl ValidateGrantRevoke for CanSetKeyValueInAssetDefinition { + impl ValidateGrantRevoke for CanUnregisterAssetDefinition { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -486,7 +477,7 @@ pub mod asset_definition { } } - impl ValidateGrantRevoke for CanRemoveKeyValueInAssetDefinition { + impl ValidateGrantRevoke for CanModifyAssetDefinitionMetadata { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -507,13 +498,10 @@ pub mod asset_definition { impl_froms!( CanUnregisterAssetDefinition, - CanSetKeyValueInAssetDefinition, - CanRemoveKeyValueInAssetDefinition, + CanModifyAssetDefinitionMetadata, iroha_executor_data_model::permission::asset::CanRegisterAssetWithDefinition, iroha_executor_data_model::permission::asset::CanUnregisterAssetWithDefinition, - iroha_executor_data_model::permission::asset::CanBurnAssetWithDefinition, - iroha_executor_data_model::permission::asset::CanMintAssetWithDefinition, - iroha_executor_data_model::permission::asset::CanTransferAssetWithDefinition, + iroha_executor_data_model::permission::asset::CanModifyAssetsWithDefinition, ); } @@ -521,7 +509,7 @@ pub mod account { //! Module with pass conditions for asset related tokens use iroha_executor_data_model::permission::account::{ - CanRemoveKeyValueInAccount, CanSetKeyValueInAccount, CanUnregisterAccount, + CanModifyAccountMetadata, CanRegisterAccount, CanUnregisterAccount, }; use super::*; @@ -562,16 +550,16 @@ pub mod account { } } - impl ValidateGrantRevoke for CanUnregisterAccount { + impl ValidateGrantRevoke for CanRegisterAccount { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + super::domain::Owner::from(self).validate(authority, block_height) } fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + super::domain::Owner::from(self).validate(authority, block_height) } } - impl ValidateGrantRevoke for CanSetKeyValueInAccount { + impl ValidateGrantRevoke for CanUnregisterAccount { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -580,7 +568,7 @@ pub mod account { } } - impl ValidateGrantRevoke for CanRemoveKeyValueInAccount { + impl ValidateGrantRevoke for CanModifyAccountMetadata { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -599,20 +587,14 @@ pub mod account { }; } - impl_froms!( - CanUnregisterAccount, - CanSetKeyValueInAccount, - CanRemoveKeyValueInAccount, - iroha_executor_data_model::permission::trigger::CanRegisterUserTrigger, - iroha_executor_data_model::permission::trigger::CanUnregisterUserTrigger, - ); + impl_froms!(CanUnregisterAccount, CanModifyAccountMetadata,); } pub mod trigger { //! Module with pass conditions for trigger related tokens use iroha_executor_data_model::permission::trigger::{ - CanBurnUserTrigger, CanExecuteUserTrigger, CanMintUserTrigger, CanRegisterUserTrigger, - CanRemoveKeyValueInTrigger, CanSetKeyValueInTrigger, CanUnregisterUserTrigger, + CanExecuteTrigger, CanModifyTrigger, CanModifyTriggerMetadata, CanRegisterTrigger, + CanUnregisterTrigger, }; use super::*; @@ -640,7 +622,7 @@ pub mod trigger { || is_domain_owner(trigger.action().authority().domain(), authority)?) } /// Returns the trigger. - pub(crate) fn find_trigger(trigger_id: &TriggerId) -> Result { + fn find_trigger(trigger_id: &TriggerId) -> Result { query(FindTriggers::new()) .filter_with(|trigger| trigger.id.eq(trigger_id.clone())) .execute_single() @@ -672,7 +654,7 @@ pub mod trigger { } } - impl ValidateGrantRevoke for CanRegisterUserTrigger { + impl ValidateGrantRevoke for CanRegisterTrigger { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { super::account::Owner::from(self).validate(authority, block_height) } @@ -681,7 +663,7 @@ pub mod trigger { } } - impl ValidateGrantRevoke for CanExecuteUserTrigger { + impl ValidateGrantRevoke for CanExecuteTrigger { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -690,16 +672,7 @@ pub mod trigger { } } - impl ValidateGrantRevoke for CanUnregisterUserTrigger { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - super::account::Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - super::account::Owner::from(self).validate(authority, block_height) - } - } - - impl ValidateGrantRevoke for CanMintUserTrigger { + impl ValidateGrantRevoke for CanUnregisterTrigger { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -708,7 +681,7 @@ pub mod trigger { } } - impl ValidateGrantRevoke for CanBurnUserTrigger { + impl ValidateGrantRevoke for CanModifyTrigger { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -716,7 +689,8 @@ pub mod trigger { Owner::from(self).validate(authority, block_height) } } - impl ValidateGrantRevoke for CanSetKeyValueInTrigger { + + impl ValidateGrantRevoke for CanModifyTriggerMetadata { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -725,12 +699,11 @@ pub mod trigger { } } - impl ValidateGrantRevoke for CanRemoveKeyValueInTrigger { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + impl<'t> From<&'t CanRegisterTrigger> for super::account::Owner<'t> { + fn from(value: &'t CanRegisterTrigger) -> Self { + Self { + account: &value.authority, + } } } @@ -745,19 +718,17 @@ pub mod trigger { } impl_froms!( - CanMintUserTrigger, - CanBurnUserTrigger, - CanExecuteUserTrigger, - CanSetKeyValueInTrigger, - CanRemoveKeyValueInTrigger, + CanUnregisterTrigger, + CanModifyTrigger, + CanExecuteTrigger, + CanModifyTriggerMetadata, ); } pub mod domain { //! Module with pass conditions for domain related tokens use iroha_executor_data_model::permission::domain::{ - CanRegisterAccountInDomain, CanRegisterAssetDefinitionInDomain, CanRemoveKeyValueInDomain, - CanSetKeyValueInDomain, CanUnregisterDomain, + CanModifyDomainMetadata, CanRegisterDomain, CanUnregisterDomain, }; use iroha_smart_contract::data_model::{ isi::error::InstructionExecutionError, @@ -809,34 +780,16 @@ pub mod domain { } } - impl ValidateGrantRevoke for CanUnregisterDomain { + impl ValidateGrantRevoke for CanRegisterDomain { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - } - - impl ValidateGrantRevoke for CanSetKeyValueInDomain { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) - } - } - - impl ValidateGrantRevoke for CanRemoveKeyValueInDomain { - fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + OnlyGenesis::from(self).validate(authority, block_height) } fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { - Owner::from(self).validate(authority, block_height) + OnlyGenesis::from(self).validate(authority, block_height) } } - impl ValidateGrantRevoke for CanRegisterAccountInDomain { + impl ValidateGrantRevoke for CanUnregisterDomain { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -845,7 +798,7 @@ pub mod domain { } } - impl ValidateGrantRevoke for CanRegisterAssetDefinitionInDomain { + impl ValidateGrantRevoke for CanModifyDomainMetadata { fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { Owner::from(self).validate(authority, block_height) } @@ -866,10 +819,9 @@ pub mod domain { impl_froms!( CanUnregisterDomain, - CanSetKeyValueInDomain, - CanRemoveKeyValueInDomain, - CanRegisterAccountInDomain, - CanRegisterAssetDefinitionInDomain, + CanModifyDomainMetadata, + iroha_executor_data_model::permission::account::CanRegisterAccount, + iroha_executor_data_model::permission::asset_definition::CanRegisterAssetDefinition, ); } @@ -907,8 +859,8 @@ pub(crate) fn accounts_permissions() -> impl Iterator impl Iterator>() .into_iter() - .map(move |token| (role.id().clone(), token)) + .map(move |permission| (role.id().clone(), permission)) }) } diff --git a/crates/iroha_executor_data_model/src/permission.rs b/crates/iroha_executor_data_model/src/permission.rs index 64b2f97dde9..7c100eb9824 100644 --- a/crates/iroha_executor_data_model/src/permission.rs +++ b/crates/iroha_executor_data_model/src/permission.rs @@ -37,7 +37,7 @@ pub mod peer { permission! { #[derive(Copy)] - pub struct CanUnregisterAnyPeer; + pub struct CanManagePeers; } } @@ -45,31 +45,18 @@ pub mod domain { use super::*; permission! { - pub struct CanUnregisterDomain { - pub domain: DomainId, - } - } - - permission! { - pub struct CanSetKeyValueInDomain { - pub domain: DomainId, - } - } - - permission! { - pub struct CanRemoveKeyValueInDomain { - pub domain: DomainId, - } + #[derive(Copy)] + pub struct CanRegisterDomain; } permission! { - pub struct CanRegisterAccountInDomain { + pub struct CanUnregisterDomain { pub domain: DomainId, } } permission! { - pub struct CanRegisterAssetDefinitionInDomain { + pub struct CanModifyDomainMetadata { pub domain: DomainId, } } @@ -79,19 +66,19 @@ pub mod asset_definition { use super::*; permission! { - pub struct CanUnregisterAssetDefinition { - pub asset_definition: AssetDefinitionId, + pub struct CanRegisterAssetDefinition { + pub domain: DomainId, } } permission! { - pub struct CanSetKeyValueInAssetDefinition { + pub struct CanUnregisterAssetDefinition { pub asset_definition: AssetDefinitionId, } } permission! { - pub struct CanRemoveKeyValueInAssetDefinition { + pub struct CanModifyAssetDefinitionMetadata { pub asset_definition: AssetDefinitionId, } } @@ -101,17 +88,18 @@ pub mod account { use super::*; permission! { - pub struct CanUnregisterAccount { - pub account: AccountId, + pub struct CanRegisterAccount { + pub domain: DomainId, } } + permission! { - pub struct CanSetKeyValueInAccount { + pub struct CanUnregisterAccount { pub account: AccountId, } } permission! { - pub struct CanRemoveKeyValueInAccount { + pub struct CanModifyAccountMetadata { pub account: AccountId, } } @@ -133,121 +121,85 @@ pub mod asset { } permission! { - pub struct CanUnregisterUserAsset { - pub asset: AssetId, - } - } - - permission! { - pub struct CanBurnAssetWithDefinition { - pub asset_definition: AssetDefinitionId, - } - } - - permission! { - pub struct CanBurnUserAsset { - pub asset: AssetId, - } - } - - permission! { - pub struct CanMintAssetWithDefinition { + pub struct CanModifyAssetsWithDefinition { pub asset_definition: AssetDefinitionId, } } permission! { - pub struct CanMintUserAsset { - pub asset: AssetId, - } - } - - permission! { - pub struct CanTransferAssetWithDefinition { - pub asset_definition: AssetDefinitionId, + pub struct CanRegisterAsset { + pub owner: AccountId, } } permission! { - pub struct CanTransferUserAsset { + pub struct CanUnregisterAsset { pub asset: AssetId, } } permission! { - pub struct CanSetKeyValueInUserAsset { + pub struct CanModifyAsset { pub asset: AssetId, } } permission! { - pub struct CanRemoveKeyValueInUserAsset { + pub struct CanModifyAssetMetadata { pub asset: AssetId, } } } -pub mod parameter { - use super::*; - - permission! { - #[derive(Copy)] - pub struct CanSetParameters; - } -} - -pub mod role { - use super::*; - - permission! { - #[derive(Copy)] - pub struct CanUnregisterAnyRole; - } -} - pub mod trigger { use super::*; permission! { - pub struct CanRegisterUserTrigger { - pub account: AccountId, + pub struct CanRegisterTrigger { + pub authority: AccountId, } } permission! { - pub struct CanExecuteUserTrigger { + pub struct CanUnregisterTrigger { pub trigger: TriggerId, } } permission! { - pub struct CanUnregisterUserTrigger { - pub account: AccountId, + pub struct CanModifyTrigger { + pub trigger: TriggerId, } } permission! { - pub struct CanMintUserTrigger { + pub struct CanExecuteTrigger { pub trigger: TriggerId, } } permission! { - pub struct CanBurnUserTrigger { + pub struct CanModifyTriggerMetadata { pub trigger: TriggerId, } } +} + +pub mod parameter { + use super::*; permission! { - pub struct CanSetKeyValueInTrigger { - pub trigger: TriggerId, - } + #[derive(Copy)] + pub struct CanSetParameters; } +} + +pub mod role { + use super::*; permission! { - pub struct CanRemoveKeyValueInTrigger { - pub trigger: TriggerId, - } + #[derive(Copy)] + pub struct CanManageRoles; } } diff --git a/crates/iroha_kagami/src/genesis/generate.rs b/crates/iroha_kagami/src/genesis/generate.rs index 3bc572f78b7..54edb6e4a7b 100644 --- a/crates/iroha_kagami/src/genesis/generate.rs +++ b/crates/iroha_kagami/src/genesis/generate.rs @@ -7,8 +7,7 @@ use clap::{Parser, Subcommand}; use color_eyre::eyre::WrapErr as _; use iroha_data_model::{isi::InstructionBox, parameter::Parameters, prelude::*}; use iroha_executor_data_model::permission::{ - account::{CanRemoveKeyValueInAccount, CanSetKeyValueInAccount}, - parameter::CanSetParameters, + domain::CanRegisterDomain, parameter::CanSetParameters, }; use iroha_genesis::{GenesisBuilder, RawGenesisTransaction, GENESIS_DOMAIN_ID}; use iroha_test_samples::{gen_account_in, ALICE_ID, BOB_ID, CARPENTER_ID}; @@ -117,6 +116,8 @@ pub fn generate_default( ); let grant_permission_to_set_parameters = Grant::account_permission(CanSetParameters, ALICE_ID.clone()); + let grant_permission_to_register_domains = + Grant::account_permission(CanRegisterDomain, ALICE_ID.clone()); let transfer_rose_ownership = Transfer::asset_definition( genesis_account_id.clone(), "rose#wonderland".parse()?, @@ -127,16 +128,6 @@ pub fn generate_default( "wonderland".parse()?, ALICE_ID.clone(), ); - let register_user_metadata_access: InstructionBox = Register::role( - Role::new("ALICE_METADATA_ACCESS".parse()?) - .add_permission(CanSetKeyValueInAccount { - account: ALICE_ID.clone(), - }) - .add_permission(CanRemoveKeyValueInAccount { - account: ALICE_ID.clone(), - }), - ) - .into(); let parameters = Parameters::default(); let parameters = parameters.parameters(); @@ -145,16 +136,16 @@ pub fn generate_default( builder = builder.append_parameter(parameter); } - for isi in [ + let instructions: [InstructionBox; 6] = [ mint.into(), mint_cabbage.into(), transfer_rose_ownership.into(), transfer_wonderland_ownership.into(), grant_permission_to_set_parameters.into(), - ] - .into_iter() - .chain(std::iter::once(register_user_metadata_access)) - { + grant_permission_to_register_domains.into(), + ]; + + for isi in instructions { builder = builder.append_instruction(isi); } diff --git a/crates/iroha_schema_gen/src/lib.rs b/crates/iroha_schema_gen/src/lib.rs index 91b450e1316..1be226e3132 100644 --- a/crates/iroha_schema_gen/src/lib.rs +++ b/crates/iroha_schema_gen/src/lib.rs @@ -64,38 +64,29 @@ pub fn build_schemas() -> MetaMap { MerkleTree, // Default permissions - permission::peer::CanUnregisterAnyPeer, + permission::peer::CanManagePeers, permission::domain::CanUnregisterDomain, - permission::domain::CanSetKeyValueInDomain, - permission::domain::CanRemoveKeyValueInDomain, - permission::domain::CanRegisterAccountInDomain, - permission::domain::CanRegisterAssetDefinitionInDomain, + permission::domain::CanModifyDomainMetadata, + permission::account::CanRegisterAccount, permission::account::CanUnregisterAccount, - permission::account::CanSetKeyValueInAccount, - permission::account::CanRemoveKeyValueInAccount, + permission::account::CanModifyAccountMetadata, + permission::asset_definition::CanRegisterAssetDefinition, permission::asset_definition::CanUnregisterAssetDefinition, - permission::asset_definition::CanSetKeyValueInAssetDefinition, - permission::asset_definition::CanRemoveKeyValueInAssetDefinition, + permission::asset_definition::CanModifyAssetDefinitionMetadata, permission::asset::CanRegisterAssetWithDefinition, permission::asset::CanUnregisterAssetWithDefinition, - permission::asset::CanUnregisterUserAsset, - permission::asset::CanBurnAssetWithDefinition, - permission::asset::CanMintAssetWithDefinition, - permission::asset::CanMintUserAsset, - permission::asset::CanBurnUserAsset, - permission::asset::CanTransferAssetWithDefinition, - permission::asset::CanTransferUserAsset, - permission::asset::CanSetKeyValueInUserAsset, - permission::asset::CanRemoveKeyValueInUserAsset, + permission::asset::CanModifyAssetsWithDefinition, + permission::asset::CanRegisterAsset, + permission::asset::CanUnregisterAsset, + permission::asset::CanModifyAsset, + permission::asset::CanModifyAssetMetadata, permission::parameter::CanSetParameters, - permission::role::CanUnregisterAnyRole, - permission::trigger::CanRegisterUserTrigger, - permission::trigger::CanExecuteUserTrigger, - permission::trigger::CanUnregisterUserTrigger, - permission::trigger::CanMintUserTrigger, - permission::trigger::CanBurnUserTrigger, - permission::trigger::CanSetKeyValueInTrigger, - permission::trigger::CanRemoveKeyValueInTrigger, + permission::role::CanManageRoles, + permission::trigger::CanRegisterTrigger, + permission::trigger::CanExecuteTrigger, + permission::trigger::CanUnregisterTrigger, + permission::trigger::CanModifyTrigger, + permission::trigger::CanModifyTriggerMetadata, permission::executor::CanUpgradeExecutor, // Genesis file - used by SDKs to generate the genesis block @@ -594,75 +585,44 @@ mod tests { insert_into_test_map!(Compact); insert_into_test_map!(Compact); - insert_into_test_map!(iroha_executor_data_model::permission::peer::CanUnregisterAnyPeer); + insert_into_test_map!(iroha_executor_data_model::permission::peer::CanManagePeers); insert_into_test_map!(iroha_executor_data_model::permission::domain::CanUnregisterDomain); insert_into_test_map!( - iroha_executor_data_model::permission::domain::CanSetKeyValueInDomain - ); - insert_into_test_map!( - iroha_executor_data_model::permission::domain::CanRemoveKeyValueInDomain - ); - insert_into_test_map!( - iroha_executor_data_model::permission::domain::CanRegisterAccountInDomain - ); - insert_into_test_map!( - iroha_executor_data_model::permission::domain::CanRegisterAssetDefinitionInDomain + iroha_executor_data_model::permission::domain::CanModifyDomainMetadata ); + insert_into_test_map!(iroha_executor_data_model::permission::account::CanRegisterAccount); insert_into_test_map!(iroha_executor_data_model::permission::account::CanUnregisterAccount); insert_into_test_map!( - iroha_executor_data_model::permission::account::CanSetKeyValueInAccount + iroha_executor_data_model::permission::account::CanModifyAccountMetadata ); insert_into_test_map!( - iroha_executor_data_model::permission::account::CanRemoveKeyValueInAccount + iroha_executor_data_model::permission::asset_definition::CanRegisterAssetDefinition ); insert_into_test_map!( iroha_executor_data_model::permission::asset_definition::CanUnregisterAssetDefinition ); - insert_into_test_map!(iroha_executor_data_model::permission::asset_definition::CanSetKeyValueInAssetDefinition); - insert_into_test_map!(iroha_executor_data_model::permission::asset_definition::CanRemoveKeyValueInAssetDefinition); + insert_into_test_map!(iroha_executor_data_model::permission::asset_definition::CanModifyAssetDefinitionMetadata); insert_into_test_map!( iroha_executor_data_model::permission::asset::CanRegisterAssetWithDefinition ); insert_into_test_map!( iroha_executor_data_model::permission::asset::CanUnregisterAssetWithDefinition ); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanUnregisterUserAsset); - insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanBurnAssetWithDefinition - ); - insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanMintAssetWithDefinition - ); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanMintUserAsset); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanBurnUserAsset); - insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanTransferAssetWithDefinition - ); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanTransferUserAsset); - insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanSetKeyValueInUserAsset - ); insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanRemoveKeyValueInUserAsset + iroha_executor_data_model::permission::asset::CanModifyAssetsWithDefinition ); + insert_into_test_map!(iroha_executor_data_model::permission::asset::CanRegisterAsset); + insert_into_test_map!(iroha_executor_data_model::permission::asset::CanUnregisterAsset); + insert_into_test_map!(iroha_executor_data_model::permission::asset::CanModifyAsset); + insert_into_test_map!(iroha_executor_data_model::permission::asset::CanModifyAssetMetadata); insert_into_test_map!(iroha_executor_data_model::permission::parameter::CanSetParameters); - insert_into_test_map!(iroha_executor_data_model::permission::role::CanUnregisterAnyRole); - insert_into_test_map!( - iroha_executor_data_model::permission::trigger::CanRegisterUserTrigger - ); - insert_into_test_map!( - iroha_executor_data_model::permission::trigger::CanExecuteUserTrigger - ); - insert_into_test_map!( - iroha_executor_data_model::permission::trigger::CanUnregisterUserTrigger - ); - insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanMintUserTrigger); - insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanBurnUserTrigger); - insert_into_test_map!( - iroha_executor_data_model::permission::trigger::CanSetKeyValueInTrigger - ); + insert_into_test_map!(iroha_executor_data_model::permission::role::CanManageRoles); + insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanRegisterTrigger); + insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanExecuteTrigger); + insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanUnregisterTrigger); + insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanModifyTrigger); insert_into_test_map!( - iroha_executor_data_model::permission::trigger::CanRemoveKeyValueInTrigger + iroha_executor_data_model::permission::trigger::CanModifyTriggerMetadata ); insert_into_test_map!(iroha_executor_data_model::permission::executor::CanUpgradeExecutor); diff --git a/crates/iroha_test_network/src/lib.rs b/crates/iroha_test_network/src/lib.rs index 3720fbc621b..8c435a49d7f 100644 --- a/crates/iroha_test_network/src/lib.rs +++ b/crates/iroha_test_network/src/lib.rs @@ -14,11 +14,8 @@ pub use iroha_core::state::StateReadOnly; use iroha_crypto::{ExposedPrivateKey, KeyPair}; use iroha_data_model::{asset::AssetDefinitionId, isi::InstructionBox, ChainId}; use iroha_executor_data_model::permission::{ - asset::{CanBurnAssetWithDefinition, CanMintAssetWithDefinition}, - domain::CanUnregisterDomain, - executor::CanUpgradeExecutor, - peer::CanUnregisterAnyPeer, - role::CanUnregisterAnyRole, + asset::CanModifyAssetsWithDefinition, domain::CanUnregisterDomain, + executor::CanUpgradeExecutor, peer::CanManagePeers, role::CanManageRoles, }; use iroha_futures::supervisor::ShutdownSignal; use iroha_genesis::{GenesisBlock, RawGenesisTransaction}; @@ -99,22 +96,16 @@ impl TestGenesis for GenesisBlock { let rose_definition_id = "rose#wonderland".parse::().unwrap(); - let grant_mint_rose_permission = Grant::account_permission( - CanMintAssetWithDefinition { + let grant_modify_rose_permission = Grant::account_permission( + CanModifyAssetsWithDefinition { asset_definition: rose_definition_id.clone(), }, ALICE_ID.clone(), ); - let grant_burn_rose_permission = Grant::account_permission( - CanBurnAssetWithDefinition { - asset_definition: rose_definition_id, - }, - ALICE_ID.clone(), - ); - let grant_unregister_any_peer_permission = - Grant::account_permission(CanUnregisterAnyPeer, ALICE_ID.clone()); - let grant_unregister_any_role_permission = - Grant::account_permission(CanUnregisterAnyRole, ALICE_ID.clone()); + let grant_manage_peers_permission = + Grant::account_permission(CanManagePeers, ALICE_ID.clone()); + let grant_manage_roles_permission = + Grant::account_permission(CanManageRoles, ALICE_ID.clone()); let grant_unregister_wonderland_domain = Grant::account_permission( CanUnregisterDomain { domain: "wonderland".parse().unwrap(), @@ -124,10 +115,9 @@ impl TestGenesis for GenesisBlock { let grant_upgrade_executor_permission = Grant::account_permission(CanUpgradeExecutor, ALICE_ID.clone()); for isi in [ - grant_mint_rose_permission, - grant_burn_rose_permission, - grant_unregister_any_peer_permission, - grant_unregister_any_role_permission, + grant_modify_rose_permission, + grant_manage_peers_permission, + grant_manage_roles_permission, grant_unregister_wonderland_domain, grant_upgrade_executor_permission, ] { diff --git a/defaults/genesis.json b/defaults/genesis.json index 0144f0eea7e..ad3aff497fe 100644 --- a/defaults/genesis.json +++ b/defaults/genesis.json @@ -140,23 +140,13 @@ } }, { - "Register": { - "Role": { - "id": "ALICE_METADATA_ACCESS", - "permissions": [ - { - "name": "CanRemoveKeyValueInAccount", - "payload": { - "account": "ed0120CE7FA46C9DCE7EA4B125E2E36BDB63EA33073E7590AC92816AE1E861B7048B03@wonderland" - } - }, - { - "name": "CanSetKeyValueInAccount", - "payload": { - "account": "ed0120CE7FA46C9DCE7EA4B125E2E36BDB63EA33073E7590AC92816AE1E861B7048B03@wonderland" - } - } - ] + "Grant": { + "Permission": { + "object": { + "name": "CanRegisterDomain", + "payload": null + }, + "destination": "ed0120CE7FA46C9DCE7EA4B125E2E36BDB63EA33073E7590AC92816AE1E861B7048B03@wonderland" } } } diff --git a/docs/source/references/schema.json b/docs/source/references/schema.json index 6088c45dd7d..e3b144ce0a1 100644 --- a/docs/source/references/schema.json +++ b/docs/source/references/schema.json @@ -802,23 +802,7 @@ } ] }, - "CanBurnAssetWithDefinition": { - "Struct": [ - { - "name": "asset_definition", - "type": "AssetDefinitionId" - } - ] - }, - "CanBurnUserAsset": { - "Struct": [ - { - "name": "asset", - "type": "AssetId" - } - ] - }, - "CanBurnUserTrigger": { + "CanExecuteTrigger": { "Struct": [ { "name": "trigger", @@ -826,23 +810,17 @@ } ] }, - "CanExecuteUserTrigger": { + "CanManagePeers": null, + "CanManageRoles": null, + "CanModifyAccountMetadata": { "Struct": [ { - "name": "trigger", - "type": "TriggerId" - } - ] - }, - "CanMintAssetWithDefinition": { - "Struct": [ - { - "name": "asset_definition", - "type": "AssetDefinitionId" + "name": "account", + "type": "AccountId" } ] }, - "CanMintUserAsset": { + "CanModifyAsset": { "Struct": [ { "name": "asset", @@ -850,31 +828,7 @@ } ] }, - "CanMintUserTrigger": { - "Struct": [ - { - "name": "trigger", - "type": "TriggerId" - } - ] - }, - "CanRegisterAccountInDomain": { - "Struct": [ - { - "name": "domain", - "type": "DomainId" - } - ] - }, - "CanRegisterAssetDefinitionInDomain": { - "Struct": [ - { - "name": "domain", - "type": "DomainId" - } - ] - }, - "CanRegisterAssetWithDefinition": { + "CanModifyAssetDefinitionMetadata": { "Struct": [ { "name": "asset_definition", @@ -882,23 +836,15 @@ } ] }, - "CanRegisterUserTrigger": { - "Struct": [ - { - "name": "account", - "type": "AccountId" - } - ] - }, - "CanRemoveKeyValueInAccount": { + "CanModifyAssetMetadata": { "Struct": [ { - "name": "account", - "type": "AccountId" + "name": "asset", + "type": "AssetId" } ] }, - "CanRemoveKeyValueInAssetDefinition": { + "CanModifyAssetsWithDefinition": { "Struct": [ { "name": "asset_definition", @@ -906,7 +852,7 @@ } ] }, - "CanRemoveKeyValueInDomain": { + "CanModifyDomainMetadata": { "Struct": [ { "name": "domain", @@ -914,7 +860,7 @@ } ] }, - "CanRemoveKeyValueInTrigger": { + "CanModifyTrigger": { "Struct": [ { "name": "trigger", @@ -922,31 +868,31 @@ } ] }, - "CanRemoveKeyValueInUserAsset": { + "CanModifyTriggerMetadata": { "Struct": [ { - "name": "asset", - "type": "AssetId" + "name": "trigger", + "type": "TriggerId" } ] }, - "CanSetKeyValueInAccount": { + "CanRegisterAccount": { "Struct": [ { - "name": "account", - "type": "AccountId" + "name": "domain", + "type": "DomainId" } ] }, - "CanSetKeyValueInAssetDefinition": { + "CanRegisterAsset": { "Struct": [ { - "name": "asset_definition", - "type": "AssetDefinitionId" + "name": "owner", + "type": "AccountId" } ] }, - "CanSetKeyValueInDomain": { + "CanRegisterAssetDefinition": { "Struct": [ { "name": "domain", @@ -954,32 +900,32 @@ } ] }, - "CanSetKeyValueInTrigger": { + "CanRegisterAssetWithDefinition": { "Struct": [ { - "name": "trigger", - "type": "TriggerId" + "name": "asset_definition", + "type": "AssetDefinitionId" } ] }, - "CanSetKeyValueInUserAsset": { + "CanRegisterTrigger": { "Struct": [ { - "name": "asset", - "type": "AssetId" + "name": "authority", + "type": "AccountId" } ] }, "CanSetParameters": null, - "CanTransferAssetWithDefinition": { + "CanUnregisterAccount": { "Struct": [ { - "name": "asset_definition", - "type": "AssetDefinitionId" + "name": "account", + "type": "AccountId" } ] }, - "CanTransferUserAsset": { + "CanUnregisterAsset": { "Struct": [ { "name": "asset", @@ -987,16 +933,6 @@ } ] }, - "CanUnregisterAccount": { - "Struct": [ - { - "name": "account", - "type": "AccountId" - } - ] - }, - "CanUnregisterAnyPeer": null, - "CanUnregisterAnyRole": null, "CanUnregisterAssetDefinition": { "Struct": [ { @@ -1021,19 +957,11 @@ } ] }, - "CanUnregisterUserAsset": { - "Struct": [ - { - "name": "asset", - "type": "AssetId" - } - ] - }, - "CanUnregisterUserTrigger": { + "CanUnregisterTrigger": { "Struct": [ { - "name": "account", - "type": "AccountId" + "name": "trigger", + "type": "TriggerId" } ] }, @@ -2680,6 +2608,18 @@ } ] }, + "NewRole": { + "Struct": [ + { + "name": "inner", + "type": "Role" + }, + { + "name": "grant_to", + "type": "AccountId" + } + ] + }, "NonZero": "u32", "NonZero": "u64", "Numeric": { @@ -3509,7 +3449,7 @@ "Struct": [ { "name": "object", - "type": "Role" + "type": "NewRole" } ] }, diff --git a/wasm_samples/executor_with_custom_permission/src/lib.rs b/wasm_samples/executor_with_custom_permission/src/lib.rs index 9fdf6603c4e..132ddf55b4d 100644 --- a/wasm_samples/executor_with_custom_permission/src/lib.rs +++ b/wasm_samples/executor_with_custom_permission/src/lib.rs @@ -19,7 +19,7 @@ extern crate panic_halt; use dlmalloc::GlobalDlmalloc; use executor_custom_data_model::permissions::CanControlDomainLives; use iroha_executor::{ - data_model::prelude::*, permission::ExecutorPermision as _, prelude::*, smart_contract::query, + data_model::prelude::*, permission::ExecutorPermission as _, prelude::*, smart_contract::query, DataModelBuilder, }; use iroha_executor_data_model::permission::domain::CanUnregisterDomain; diff --git a/wasm_samples/multisig_register/src/lib.rs b/wasm_samples/multisig_register/src/lib.rs index e1f1a7c0488..97782e419db 100644 --- a/wasm_samples/multisig_register/src/lib.rs +++ b/wasm_samples/multisig_register/src/lib.rs @@ -10,7 +10,7 @@ use alloc::format; use dlmalloc::GlobalDlmalloc; use executor_custom_data_model::multisig::MultisigRegisterArgs; -use iroha_executor_data_model::permission::trigger::CanExecuteUserTrigger; +use iroha_executor_data_model::permission::trigger::CanExecuteTrigger; use iroha_trigger::{debug::dbg_panic, prelude::*}; #[global_allocator] @@ -22,7 +22,7 @@ getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); const WASM: &[u8] = core::include_bytes!(concat!(core::env!("OUT_DIR"), "/multisig.wasm")); #[iroha_trigger::main] -fn main(_id: TriggerId, _owner: AccountId, event: EventBox) { +fn main(_id: TriggerId, owner: AccountId, event: EventBox) { let args: MultisigRegisterArgs = match event { EventBox::ExecuteTrigger(event) => event .args() @@ -34,7 +34,7 @@ fn main(_id: TriggerId, _owner: AccountId, event: EventBox) { let account_id = args.account.id().clone(); - Register::account(args.account) + Register::account(args.account.clone()) .execute() .dbg_expect("failed to register multisig account"); @@ -69,14 +69,17 @@ fn main(_id: TriggerId, _owner: AccountId, event: EventBox) { .parse() .dbg_expect("failed to parse role"); - let can_execute_multisig_trigger = CanExecuteUserTrigger { + let can_execute_multisig_trigger = CanExecuteTrigger { trigger: trigger_id.clone(), }; - let role = Role::new(role_id.clone()).add_permission(can_execute_multisig_trigger); - Register::role(role) - .execute() - .dbg_expect("failed to register multisig role"); + Register::role( + // FIX: args.account.id() should be used but I can't + // execute an instruction from a different account + Role::new(role_id.clone(), owner).add_permission(can_execute_multisig_trigger), + ) + .execute() + .dbg_expect("failed to register multisig role"); SetKeyValue::trigger( trigger_id, @@ -87,7 +90,7 @@ fn main(_id: TriggerId, _owner: AccountId, event: EventBox) { .dbg_unwrap(); for signatory in args.signatories { - Grant::role(role_id.clone(), signatory) + Grant::account_role(role_id.clone(), signatory) .execute() .dbg_expect("failed to grant multisig role to account"); }