Skip to content
Snippets Groups Projects

feat(identity): explicit revocation

Merged Pascal Engélibert requested to merge idty_revoke into master
5 files
+ 165
20
Compare changes
  • Side-by-side
  • Inline
Files
5
+ 86
19
@@ -36,7 +36,7 @@ use crate::traits::*;
use codec::Codec;
use frame_support::dispatch::Weight;
use frame_system::RawOrigin;
use sp_runtime::traits::{AtLeast32BitUnsigned, One, Saturating, Zero};
use sp_runtime::traits::{AtLeast32BitUnsigned, IdentifyAccount, One, Saturating, Zero};
use sp_std::fmt::Debug;
use sp_std::prelude::*;
@@ -47,6 +47,7 @@ pub mod pallet {
use frame_support::traits::StorageVersion;
use frame_system::pallet_prelude::*;
use sp_membership::traits::MembershipAction as _;
use sp_runtime::traits::Verify;
/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
@@ -102,6 +103,10 @@ pub mod pallet {
type MaxNoRightPeriod: Get<Self::BlockNumber>;
///
type Membership: sp_membership::traits::MembershipAction<Self::IdtyIndex, Self::Origin>;
/// Signing key of revocation payload
type RevocationSigner: IdentifyAccount<AccountId = Self::AccountId>;
/// Signature of revocation payload
type RevocationSignature: Parameter + Verify<Signer = Self::RevocationSigner>;
}
// GENESIS STUFF //
@@ -510,15 +515,13 @@ pub mod pallet {
.rights
.binary_search_by(|(right_, _)| right_.cmp(&right))
{
let name = idty_value.name.clone();
let old_key_opt = if let Some(ref subkey) = idty_value.rights[index].1 {
Some(subkey.clone())
} else if right.allow_owner_key() {
Some(idty_value.owner_key.clone())
} else {
None
};
idty_value.rights.remove(index);
<Pallet<T>>::do_del_right(
idty_index,
idty_value.name.clone(),
&idty_value.owner_key,
right,
idty_value.rights.remove(index).1,
);
if idty_value.rights.is_empty() {
let block_number = frame_system::pallet::Pallet::<T>::block_number();
@@ -531,15 +534,6 @@ pub mod pallet {
}
<Identities<T>>::insert(idty_index, idty_value);
Self::deposit_event(Event::<T>::IdtyLostRight(name, right));
if old_key_opt.is_some() {
T::OnRightKeyChange::on_right_key_change(
idty_index,
right,
old_key_opt,
None,
);
}
Ok(().into())
} else {
Err(Error::<T>::RightNotExist.into())
@@ -549,6 +543,55 @@ pub mod pallet {
}
}
#[pallet::weight(0)]
pub fn revoke_identity(
origin: OriginFor<T>,
payload: RevocationPayload<T::AccountId, T::IdtyIndex, 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());
}
let idty_index = payload.idty;
if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) {
if idty_value.owner_key != payload.owner_key {
return Err(Error::<T>::RequireToBeOwner.into());
}
if idty_value.status != IdtyStatus::Validated {
return Err(Error::<T>::IdtyNotValidated.into());
}
let idty_name = idty_value.name.clone();
idty_value.rights.drain(..).for_each(|(right, subkey_opt)| {
<Pallet<T>>::do_del_right(
idty_index,
idty_name.clone(),
&payload.owner_key,
right,
subkey_opt,
)
});
let block_number = frame_system::pallet::Pallet::<T>::block_number();
let removable_on = block_number + T::MaxNoRightPeriod::get();
idty_value.removable_on = removable_on;
<IdentitiesRemovableOn<T>>::append(
removable_on,
(idty_index, IdtyStatus::Validated),
);
<Identities<T>>::insert(idty_index, idty_value);
Ok(().into())
} else {
Err(Error::<T>::IdtyNotFound.into())
}
}
#[pallet::weight(0)]
pub fn set_right_subkey(
origin: OriginFor<T>,
idty_index: T::IdtyIndex,
@@ -608,6 +651,10 @@ pub mod pallet {
#[pallet::error]
pub enum Error<T> {
/// Genesis hash does not match
BadGenesisHash,
/// Signature is invalid
BadProof,
/// Creator not exist
CreatorNotExist,
/// Creator not allowed to create identities
@@ -727,6 +774,26 @@ pub mod pallet {
total_weight
}
pub(super) fn do_del_right(
idty_index: T::IdtyIndex,
idty_name: IdtyName,
owner_key: &T::AccountId,
right: T::IdtyRight,
subkey_opt: Option<T::AccountId>,
) {
let old_key_opt = if let Some(ref subkey) = subkey_opt {
Some(subkey.clone())
} else if right.allow_owner_key() {
Some(owner_key.clone())
} else {
None
};
Self::deposit_event(Event::<T>::IdtyLostRight(idty_name, right));
if old_key_opt.is_some() {
T::OnRightKeyChange::on_right_key_change(idty_index, right, old_key_opt, None);
}
}
}
}
Loading