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

WIP feat(identity): revoke_identity

parent a90145e5
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.
...@@ -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,33 @@ pub mod pallet { ...@@ -362,6 +366,33 @@ 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) {
if let Ok(_idty_value) = <Identities<T>>::try_get(idty_index) {
T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Removed {});
} else {
panic!("storage corrupted");
}
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 +449,10 @@ pub mod pallet { ...@@ -418,6 +449,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
......
...@@ -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 = ();
type RevocationSignature = ();
} }
// Build genesis storage according to the mock runtime. // Build genesis storage according to the mock runtime.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// 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 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};
...@@ -123,3 +123,34 @@ fn test_idty_creation_period() { ...@@ -123,3 +123,34 @@ 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);
// Alice should be able te create an identity
assert_ok!(Identity::revoke_identity(
Origin::signed(2),
RevocationPayload {
owner_key: 1,
genesis_hash: System::block_hash(0),
},
()
));
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