Skip to content

Commit

Permalink
Merge pull request #15 from KILTprotocol/feature/bk_revoke_delegations
Browse files Browse the repository at this point in the history
feat: revoke delegations
  • Loading branch information
foby authored Mar 15, 2019
2 parents 15f6e35 + e8fa392 commit f0023a2
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 10 deletions.
43 changes: 37 additions & 6 deletions runtime/src/attestation.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

use rstd::result;
use rstd::prelude::*;
use support::{dispatch::Result, StorageMap, decl_module, decl_storage};
use {system, super::delegation, super::ctype, system::ensure_signed};
Expand All @@ -19,13 +21,13 @@ decl_module! {
let delegation = <delegation::Delegations<T>>::get(d.clone());
if delegation.4 {
return Err("delegation revoked")
} else if delegation.2 != sender {
} else if !delegation.2.eq(&sender) {
return Err("not delegated to attester")
} else if delegation.3 & delegation::Permissions::ATTEST != delegation::Permissions::ATTEST {
} else if (delegation.3 & delegation::Permissions::ATTEST) != delegation::Permissions::ATTEST {
return Err("delegation not authorized to attest")
} else {
let root = <delegation::Root<T>>::get(delegation.0.clone());
if root.0 != ctype_hash {
if !root.0.eq(&ctype_hash) {
return Err("CTYPE of delegation does not match")
}
}
Expand All @@ -47,6 +49,14 @@ decl_module! {
::runtime_io::print("insert Attestation");
existing_attestations_for_claim.push((ctype_hash.clone(), sender.clone(), delegation_id.clone(), false));
<Attestations<T>>::insert(claim_hash.clone(), existing_attestations_for_claim);
match delegation_id {
Some(d) => {
let mut delegated_attestations = <DelegatedAttestations<T>>::get(d);
delegated_attestations.push(claim_hash.clone());
<DelegatedAttestations<T>>::insert(d.clone(), delegated_attestations);
},
None => {}
}
Ok(())
},
}
Expand All @@ -58,9 +68,22 @@ decl_module! {
let mut last_attested : bool = false;
let mut existing_attestations_for_claim = <Attestations<T>>::get(claim_hash.clone());
for v in existing_attestations_for_claim.iter_mut() {
if v.1.eq(&sender) && !v.3 {
last_attested = true;
v.3 = true;
if !v.3 {
if v.1.eq(&sender) {
last_attested = true;
v.3 = true;
} else {
// check delegator in case of delegation
match v.2 {
Some(d) => {
if Self::is_delegating(&sender, &d)? {
last_attested = true;
v.3 = true;
}
},
None => {}
}
}
}
}
if last_attested {
Expand All @@ -73,10 +96,18 @@ decl_module! {
}
}

impl<T: Trait> Module<T> {
fn is_delegating(account: &T::AccountId, delegation: &T::DelegationNodeId) -> result::Result<bool, &'static str> {
<delegation::Module<T>>::is_delegating(account, delegation)
}
}

decl_storage! {
trait Store for Module<T: Trait> as Attestation {
// Attestations: claim-hash -> [(ctype-hash, account, delegation-id?, revoked)]
Attestations get(attestations): map T::Hash => Vec<(T::Hash,T::AccountId,Option<T::DelegationNodeId>,bool)>;
// DelegatedAttestations: delegation-id -> [claim-hash]
DelegatedAttestations get(delegated_attestations): map T::DelegationNodeId => Vec<T::Hash>;
}
}

Expand Down
84 changes: 80 additions & 4 deletions runtime/src/delegation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

use rstd::result;
use rstd::prelude::*;
use runtime_primitives::traits::{Hash, CheckEqual, SimpleBitOps, Member, Verify, MaybeDisplay};
use support::{dispatch::Result, StorageMap, Parameter, decl_module, decl_storage};
Expand Down Expand Up @@ -89,32 +90,107 @@ decl_module! {
Some(p) => {
if <Delegations<T>>::exists(p) {
let parent = <Delegations<T>>::get(p.clone());
if parent.2 != sender {
if !parent.2.eq(&sender) {
return Err("not owner of parent")
} else if parent.3 & Permissions::DELEGATE != Permissions::DELEGATE {
} else if (parent.3 & Permissions::DELEGATE) != Permissions::DELEGATE {
return Err("not authorized to delegate")
} else {
// TODO: check for cycles
// TODO: check for cycles?
::runtime_io::print("insert Delegation with parent");
<Delegations<T>>::insert(delegation_id.clone(), (root_id.clone(), Some(p.clone()), delegate, permissions, false));
Self::add_child(delegation_id.clone(), p.clone());
}
} else {
return Err("parent not found")
}
},
None => {
if root.1 != sender {
if !root.1.eq(&sender) {
return Err("not owner of root")
}
::runtime_io::print("insert Delegation without parent");
<Delegations<T>>::insert(delegation_id.clone(), (root_id.clone(), None, delegate, permissions, false));
Self::add_child(delegation_id.clone(), root_id.clone());
}
}
} else {
return Err("root not found")
}
return Ok(());
}

pub fn revoke_root(origin, root_id: T::DelegationNodeId) -> Result {
let sender = ensure_signed(origin)?;
if !<Root<T>>::exists(root_id) {
return Err("root not found")
}
let mut r = <Root<T>>::get(root_id.clone());
if !r.1.eq(&sender) {
return Err("not permitted to revoke")
}
if !r.2 {
r.2 = true;
<Root<T>>::insert(root_id.clone(), r);
Self::revoke_children(&root_id);
}

return Ok(());
}

pub fn revoke_delegation(origin, delegation_id: T::DelegationNodeId) -> Result {
let sender = ensure_signed(origin)?;
if !Self::is_delegating(&sender, &delegation_id)? {
return Err("not permitted to revoke")
}
Self::revoke(&delegation_id);
return Ok(());
}
}
}

impl<T: Trait> Module<T> {
pub fn is_delegating(account: &T::AccountId, delegation: &T::DelegationNodeId) -> result::Result<bool, &'static str> {
if !<Delegations<T>>::exists(delegation) {
return Err("delegation not found")
}
let d = <Delegations<T>>::get(delegation);
if d.2.eq(account) {
Ok(true)
} else {
match d.1 {
None => {
let r = <Root<T>>::get(d.0.clone());
Ok(r.1.eq(account))
},
Some(p) => {
return Self::is_delegating(account, &p)
}
}
}
}

fn revoke(delegation: &T::DelegationNodeId) {
let mut d = <Delegations<T>>::get(delegation.clone());
if !d.4 {
d.4 = true;
<Delegations<T>>::insert(delegation.clone(), d);
Self::revoke_children(delegation);
}
}

fn revoke_children(delegation: &T::DelegationNodeId) {
if <Children<T>>::exists(delegation) {
let children = <Children<T>>::get(delegation);
for child in children {
Self::revoke(&child);
}
}
}

fn add_child(child: T::DelegationNodeId, parent: T::DelegationNodeId) {
let mut children = <Children<T>>::get(parent.clone());
children.push(child);
<Children<T>>::insert(parent, children);
}
}

Expand Down
6 changes: 6 additions & 0 deletions runtime/src/did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ decl_module! {
<DID<T>>::insert(sender.clone(), (sign_key, box_key, doc_ref));
Ok(())
}

pub fn remove(origin) -> Result {
let sender = ensure_signed(origin)?;
<DID<T>>::remove(sender.clone());
Ok(())
}
}
}

Expand Down

0 comments on commit f0023a2

Please sign in to comment.