Skip to content

Commit

Permalink
[feature] #1179: Add revoke-permission-or-role instruction
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksandr <a-p-petrosyan@yandex.ru>

[feature] #1179: Add revoke instruction.

Signed-off-by: Aleksandr <a-p-petrosyan@yandex.ru>
  • Loading branch information
appetrosyan committed Jan 12, 2022
1 parent 79d0df6 commit b5e6efe
Show file tree
Hide file tree
Showing 18 changed files with 2,725 additions and 2,461 deletions.
46 changes: 45 additions & 1 deletion core/src/smartcontracts/isi/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::prelude::*;
/// - minting/burning signature condition check
/// - update metadata
/// - grant permissions and roles
/// - TODO Revoke permissions or roles
/// - Revoke permissions or roles
pub mod isi {
use super::{super::prelude::*, *};

Expand Down Expand Up @@ -142,6 +142,25 @@ pub mod isi {
}
}

impl<W: WorldTrait> Execute<W> for Revoke<Account, PermissionToken> {
type Error = Error;
type Diff = DataEvent;

#[metrics(+"revoke_account_permission_token")]
fn execute(
self,
_authority: <Account as Identifiable>::Id,
wsv: &WorldStateView<W>,
) -> Result<Self::Diff, Self::Error> {
let id = self.destination_id.clone();
wsv.modify_account(&id, |account| {
let _ = account.permission_tokens.remove(&self.object);
Ok(())
})?;
Ok(self.into())
}
}

#[cfg(feature = "roles")]
impl<W: WorldTrait> Execute<W> for Grant<Account, RoleId> {
type Error = Error;
Expand All @@ -166,6 +185,31 @@ pub mod isi {
Ok(self.into())
}
}

#[cfg(feature = "roles")]
impl<W: WorldTrait> Execute<W> for Revoke<Account, RoleId> {
type Error = Error;
type Diff = DataEvent;

#[metrics(+"revoke_account_role")]
fn execute(
self,
_authority: <Account as Identifiable>::Id,
wsv: &WorldStateView<W>,
) -> Result<Self::Diff, Self::Error> {
wsv.world()
.roles
.get(&self.object)
.ok_or_else(|| FindError::Role(self.object.clone()))?;

let id = self.destination_id.clone();
wsv.modify_account(&id, |account| {
let _ = account.roles.remove(&self.object);
Ok(())
})?;
Ok(self.into())
}
}
}

/// Account-related [`Query`] instructions.
Expand Down
39 changes: 35 additions & 4 deletions core/src/smartcontracts/isi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ pub mod error {
/// Register.
Register,
/// Set key-value pair.
SetKV,
SetKeyValue,
/// Remove key-value pair.
RemKV,
RemoveKeyValue,
/// Grant
Grant,
/// Transfer
Expand All @@ -116,6 +116,8 @@ pub mod error {
Burn,
/// Un-register.
Unregister,
/// Revoke
Revoke,
}

impl std::fmt::Display for InstructionType {
Expand Down Expand Up @@ -290,6 +292,7 @@ impl<W: WorldTrait> Execute<W> for Instruction {
Ok(remove_key_value.execute(authority, wsv)?.into())
}
Grant(grant_box) => Ok(grant_box.execute(authority, wsv)?.into()),
Revoke(revoke_box) => Ok(revoke_box.execute(authority, wsv)?.into()),
}
}
}
Expand Down Expand Up @@ -472,7 +475,7 @@ impl<W: WorldTrait> Execute<W> for SetKeyValueBox {
IdBox::DomainId(id) => {
SetKeyValue::<Domain, Name, Value>::new(id, key, value).execute(authority, wsv)
}
_ => Err(Error::Unsupported(InstructionType::SetKV)),
_ => Err(Error::Unsupported(InstructionType::SetKeyValue)),
}
}
}
Expand Down Expand Up @@ -500,7 +503,7 @@ impl<W: WorldTrait> Execute<W> for RemoveKeyValueBox {
IdBox::AccountId(account_id) => {
RemoveKeyValue::<Account, Name>::new(account_id, key).execute(authority, wsv)
}
_ => Err(Error::Unsupported(InstructionType::RemKV)),
_ => Err(Error::Unsupported(InstructionType::RemoveKeyValue)),
}
}
}
Expand Down Expand Up @@ -602,6 +605,34 @@ impl<W: WorldTrait> Execute<W> for GrantBox {
}
}

impl<W: WorldTrait> Execute<W> for RevokeBox {
type Error = Error;
type Diff = DataEvent;

#[log]
fn execute(
self,
authority: <Account as Identifiable>::Id,
wsv: &WorldStateView<W>,
) -> Result<Self::Diff, Self::Error> {
let context = Context::new();
match (
self.destination_id.evaluate(wsv, &context)?,
self.object.evaluate(wsv, &context)?,
) {
(IdBox::AccountId(account_id), Value::PermissionToken(permission_token)) => {
Revoke::<Account, PermissionToken>::new(permission_token, account_id)
.execute(authority, wsv)
}
#[cfg(feature = "roles")]
(IdBox::AccountId(account_id), Value::Id(IdBox::RoleId(role_id))) => {
Revoke::<Account, RoleId>::new(role_id, account_id).execute(authority, wsv)
}
_ => Err(Error::Unsupported(InstructionType::Revoke)),
}
}
}

pub mod prelude {
//! Re-exports important traits and types. Meant to be glob imported when using `Iroha`.
pub use super::{account::isi::*, asset::isi::*, domain::isi::*, world::isi::*, *};
Expand Down
Loading

0 comments on commit b5e6efe

Please sign in to comment.