Skip to content
Snippets Groups Projects
Verified Commit 1eb76a83 authored by Pascal Engélibert's avatar Pascal Engélibert :bicyclist:
Browse files

feat(identity): revoke_identity

parent 3cb4c309
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !12. Comments created here will be created in the context of that merge request.
...@@ -275,7 +275,16 @@ impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pall ...@@ -275,7 +275,16 @@ impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pall
} }
IdtyEvent::Confirmed => {} IdtyEvent::Confirmed => {}
IdtyEvent::Validated => {} IdtyEvent::Validated => {}
IdtyEvent::Removed => {} IdtyEvent::Removed => {
if let Err(e) = pallet_membership::Pallet::<T, I>::revoke_membership(
RawOrigin::Root.into(),
Some(idty_index),
) {
sp_std::if_std! {
println!("fail to revoke membership: {:?}", e)
}
}
}
} }
0 0
} }
......
...@@ -20,7 +20,7 @@ use frame_support::{parameter_types, traits::Everything}; ...@@ -20,7 +20,7 @@ use frame_support::{parameter_types, traits::Everything};
use frame_system as system; use frame_system as system;
use sp_core::H256; use sp_core::H256;
use sp_runtime::{ use sp_runtime::{
testing::Header, testing::{Header, TestSignature, UintAuthorityId},
traits::{BlakeTwo256, IdentityLookup}, traits::{BlakeTwo256, IdentityLookup},
}; };
use std::collections::BTreeMap; use std::collections::BTreeMap;
...@@ -118,6 +118,8 @@ impl pallet_identity::Config for Test { ...@@ -118,6 +118,8 @@ impl pallet_identity::Config for Test {
type OnIdtyChange = DuniterWot; type OnIdtyChange = DuniterWot;
type MaxDisabledPeriod = MaxDisabledPeriod; type MaxDisabledPeriod = MaxDisabledPeriod;
type RemoveIdentityConsumers = (); type RemoveIdentityConsumers = ();
type RevocationSigner = UintAuthorityId;
type RevocationSignature = TestSignature;
} }
// Membership // Membership
......
...@@ -35,7 +35,7 @@ pub use types::*; ...@@ -35,7 +35,7 @@ pub use types::*;
use crate::traits::*; use crate::traits::*;
use codec::Codec; use codec::Codec;
use frame_support::dispatch::Weight; use frame_support::dispatch::Weight;
use sp_runtime::traits::{AtLeast32BitUnsigned, One, Saturating, Zero}; use sp_runtime::traits::{AtLeast32BitUnsigned, IdentifyAccount, One, Saturating, Verify, Zero};
use sp_std::fmt::Debug; use sp_std::fmt::Debug;
use sp_std::prelude::*; use sp_std::prelude::*;
...@@ -93,6 +93,10 @@ pub mod pallet { ...@@ -93,6 +93,10 @@ pub mod pallet {
/// Handle the logic that remove all identity consumers. /// Handle the logic that remove all identity consumers.
/// "identity consumers" mean all things that rely on the existence of the identity. /// "identity consumers" mean all things that rely on the existence of the identity.
type RemoveIdentityConsumers: RemoveIdentityConsumers<Self::IdtyIndex>; type RemoveIdentityConsumers: RemoveIdentityConsumers<Self::IdtyIndex>;
/// Signing key of revocation payload
type RevocationSigner: IdentifyAccount<AccountId = Self::AccountId>;
/// Signature of revocation payload
type RevocationSignature: Parameter + Verify<Signer = Self::RevocationSigner>;
} }
// GENESIS STUFF // // GENESIS STUFF //
...@@ -362,6 +366,28 @@ pub mod pallet { ...@@ -362,6 +366,28 @@ pub mod pallet {
Ok(().into()) Ok(().into())
} }
#[pallet::weight(0)]
pub fn revoke_identity(
origin: OriginFor<T>,
payload: RevocationPayload<T::AccountId, T::Hash>,
payload_sig: T::RevocationSignature,
) -> DispatchResultWithPostInfo {
let _ = ensure_signed(origin)?;
if payload.genesis_hash != frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero())
{
return Err(Error::<T>::BadGenesisHash.into());
}
if !payload.using_encoded(|bytes| payload_sig.verify(bytes, &payload.owner_key)) {
return Err(Error::<T>::BadProof.into());
}
if let Some(idty_index) = <IdentityIndexOf<T>>::take(payload.owner_key) {
Self::do_remove_identity(idty_index);
Ok(().into())
} else {
Err(Error::<T>::IdtyNotFound.into())
}
}
#[pallet::weight(0)] #[pallet::weight(0)]
pub fn remove_identity( pub fn remove_identity(
origin: OriginFor<T>, origin: OriginFor<T>,
...@@ -418,6 +444,10 @@ pub mod pallet { ...@@ -418,6 +444,10 @@ pub mod pallet {
#[pallet::error] #[pallet::error]
pub enum Error<T> { pub enum Error<T> {
/// Genesis hash does not match
BadGenesisHash,
/// Signature is invalid
BadProof,
/// Creator not allowed to create identities /// Creator not allowed to create identities
CreatorNotAllowedToCreateIdty, CreatorNotAllowedToCreateIdty,
/// Identity already confirmed /// Identity already confirmed
......
...@@ -23,7 +23,7 @@ use frame_support::{ ...@@ -23,7 +23,7 @@ use frame_support::{
use frame_system as system; use frame_system as system;
use sp_core::H256; use sp_core::H256;
use sp_runtime::{ use sp_runtime::{
testing::Header, testing::{Header, TestSignature, UintAuthorityId},
traits::{BlakeTwo256, IdentityLookup, IsMember}, traits::{BlakeTwo256, IdentityLookup, IsMember},
}; };
...@@ -110,6 +110,8 @@ impl pallet_identity::Config for Test { ...@@ -110,6 +110,8 @@ impl pallet_identity::Config for Test {
type OnIdtyChange = (); type OnIdtyChange = ();
type MaxDisabledPeriod = MaxDisabledPeriod; type MaxDisabledPeriod = MaxDisabledPeriod;
type RemoveIdentityConsumers = (); type RemoveIdentityConsumers = ();
type RevocationSigner = UintAuthorityId;
type RevocationSignature = TestSignature;
} }
// Build genesis storage according to the mock runtime. // Build genesis storage according to the mock runtime.
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use crate::mock::*; use crate::mock::*;
use crate::{Error, GenesisIdty, IdtyName, IdtyValue}; use crate::{Error, GenesisIdty, IdtyName, IdtyValue, RevocationPayload};
use codec::Encode;
//use frame_support::assert_err; //use frame_support::assert_err;
use frame_support::assert_ok; use frame_support::assert_ok;
use frame_system::{EventRecord, Phase}; use frame_system::{EventRecord, Phase};
use sp_runtime::testing::TestSignature;
type IdtyVal = IdtyValue<u64, u64>; type IdtyVal = IdtyValue<u64, u64>;
...@@ -123,3 +125,47 @@ fn test_idty_creation_period() { ...@@ -123,3 +125,47 @@ fn test_idty_creation_period() {
); );
}); });
} }
#[test]
fn test_idty_revocation() {
new_test_ext(IdentityConfig {
identities: vec![alice()],
})
.execute_with(|| {
// We need to initialize at least one block before any call
run_to_block(1);
let revocation_payload = RevocationPayload {
owner_key: 1,
genesis_hash: System::block_hash(0),
};
// Payload must be signed by the right identity
assert_eq!(
Identity::revoke_identity(
Origin::signed(1),
revocation_payload.clone(),
TestSignature(42, revocation_payload.encode())
),
Err(Error::<Test>::BadProof.into())
);
// Anyone can submit a revocation payload
assert_ok!(Identity::revoke_identity(
Origin::signed(42),
revocation_payload.clone(),
TestSignature(1, revocation_payload.encode())
));
let events = System::events();
assert_eq!(events.len(), 1);
assert_eq!(
events[0],
EventRecord {
phase: Phase::Initialization,
event: Event::Identity(crate::Event::IdtyRemoved { idty_index: 1 }),
topics: vec![],
}
);
});
}
...@@ -85,3 +85,10 @@ pub struct IdtyValue<BlockNumber, AccountId> { ...@@ -85,3 +85,10 @@ pub struct IdtyValue<BlockNumber, AccountId> {
pub removable_on: BlockNumber, pub removable_on: BlockNumber,
pub status: IdtyStatus, pub status: IdtyStatus,
} }
#[derive(Clone, Encode, Decode, PartialEq, Eq, TypeInfo, RuntimeDebug)]
pub struct RevocationPayload<AccountId, Hash> {
pub owner_key: AccountId,
// Avoid replay attack between blockchains
pub genesis_hash: Hash,
}
...@@ -367,6 +367,8 @@ macro_rules! pallets_config { ...@@ -367,6 +367,8 @@ macro_rules! pallets_config {
type OnIdtyChange = Wot; type OnIdtyChange = Wot;
type MaxDisabledPeriod = MaxDisabledPeriod; type MaxDisabledPeriod = MaxDisabledPeriod;
type RemoveIdentityConsumers = RemoveIdentityConsumersImpl<Self>; type RemoveIdentityConsumers = RemoveIdentityConsumersImpl<Self>;
type RevocationSigner = <Signature as sp_runtime::traits::Verify>::Signer;
type RevocationSignature = Signature;
} }
impl pallet_membership::Config<frame_support::instances::Instance1> for Runtime { impl pallet_membership::Config<frame_support::instances::Instance1> for Runtime {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment