diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index 1ea7ae1f80d275cc1dfcc51c706ea9600239875a..1ef8df68dba9169eba6d70d3aa47f67416f14fcd 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -17,9 +17,6 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::type_complexity)] -//pub mod traits; -mod types; - #[cfg(test)] mod mock; @@ -30,14 +27,12 @@ mod tests; mod benchmarking;*/ pub use pallet::*; -pub use types::*; use frame_support::dispatch::UnfilteredDispatchable; use frame_support::pallet_prelude::*; use frame_system::RawOrigin; use pallet_certification::traits::SetNextIssuableOn; use pallet_identity::{IdtyEvent, IdtyStatus}; -use sp_membership::traits::IsInPendingMemberships; use sp_runtime::traits::IsMember; type IdtyIndex = u32; @@ -102,32 +97,57 @@ pub mod pallet { impl<AccountId, T: Config<I>, I: 'static> pallet_identity::traits::EnsureIdtyCallAllowed<T> for Pallet<T, I> where - T: frame_system::Config<AccountId = AccountId> - + pallet_membership::Config<I, MetaData = MembershipMetaData<AccountId>>, + T: frame_system::Config<AccountId = AccountId> + pallet_membership::Config<I>, { fn can_create_identity(creator: IdtyIndex) -> bool { - let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator); - cert_meta.received_count >= T::MinCertForCreateIdtyRight::get() - && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number() - && cert_meta.issued_count < T::MaxByIssuer::get() + if !T::IsSubWot::get() { + let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator); + cert_meta.received_count >= T::MinCertForCreateIdtyRight::get() + && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number() + && cert_meta.issued_count < T::MaxByIssuer::get() + } else { + true + } } - fn can_confirm_identity(idty_index: IdtyIndex, owner_key: AccountId) -> bool { - pallet_membership::Pallet::<T, I>::force_request_membership( - RawOrigin::Root.into(), - idty_index, - MembershipMetaData(owner_key), - ) - .is_ok() + fn can_confirm_identity(idty_index: IdtyIndex) -> bool { + if !T::IsSubWot::get() { + pallet_membership::Pallet::<T, I>::force_request_membership( + RawOrigin::Root.into(), + idty_index, + Default::default(), + ) + .is_ok() + } else { + true + } } fn can_validate_identity(idty_index: IdtyIndex) -> bool { - // TODO replace this code by te commented one for distance feature - /*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index); - idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/ - pallet_membership::Pallet::<T, I>::claim_membership( - RawOrigin::Root.into(), - Some(idty_index), - ) - .is_ok() + if !T::IsSubWot::get() { + // TODO replace this code by the commented one for distance feature + /*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index); + idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/ + pallet_membership::Pallet::<T, I>::claim_membership( + RawOrigin::Root.into(), + Some(idty_index), + ) + .is_ok() + } else { + true + } + } + fn can_change_identity_address(idty_index: IdtyIndex) -> bool { + if T::IsSubWot::get() { + !pallet_membership::Pallet::<T, I>::is_member(&idty_index) + } else { + true + } + } + fn can_remove_identity(idty_index: IdtyIndex) -> bool { + if T::IsSubWot::get() { + !pallet_membership::Pallet::<T, I>::is_member(&idty_index) + } else { + true + } } } @@ -141,14 +161,8 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::IsCertAllowed<IdtyI } if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) { match receiver_data.status { - IdtyStatus::ConfirmedByOwner => true, + IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => true, IdtyStatus::Created => false, - IdtyStatus::Validated => { - pallet_membership::Pallet::<T, I>::is_member(&receiver) - || pallet_membership::Pallet::<T, I>::is_in_pending_memberships( - receiver, - ) - } } } else { // Receiver not found diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs index b94c67dd58bfc9acb6831623d0102177194ac8a8..6a0c12c1c8af715dd298872e5b798dc6119976b9 100644 --- a/pallets/duniter-wot/src/mock.rs +++ b/pallets/duniter-wot/src/mock.rs @@ -150,7 +150,7 @@ impl pallet_membership::Config<Instance1> for Test { type IdtyId = IdtyIndex; type IdtyIdOf = IdentityIndexOf<Self>; type MembershipPeriod = MembershipPeriod; - type MetaData = crate::MembershipMetaData<u64>; + type MetaData = (); type OnEvent = DuniterWot; type PendingMembershipPeriod = PendingMembershipPeriod; type RevocationPeriod = RevocationPeriod; @@ -206,7 +206,7 @@ impl pallet_membership::Config<Instance2> for Test { type IdtyId = IdtyIndex; type IdtyIdOf = IdentityIndexOf<Self>; type MembershipPeriod = SmithsMembershipPeriod; - type MetaData = crate::MembershipMetaData<u64>; + type MetaData = (); type OnEvent = SmithsSubWot; type PendingMembershipPeriod = SmithsPendingMembershipPeriod; type RevocationPeriod = SmithsRevocationPeriod; diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs index bd3fb937c79637ed3d2d32f7a61d27cd78b14911..3cb3da2b9eabd3426e6a4100525c4ef4648ff380 100644 --- a/pallets/duniter-wot/src/tests.rs +++ b/pallets/duniter-wot/src/tests.rs @@ -56,10 +56,7 @@ fn test_join_smiths() { run_to_block(2); // Dave shoud be able to request smith membership - assert_ok!(SmithsMembership::request_membership( - Origin::signed(4), - crate::MembershipMetaData(4) - )); + assert_ok!(SmithsMembership::request_membership(Origin::signed(4), ())); System::assert_has_event(Event::SmithsMembership( pallet_membership::Event::MembershipRequested(4), )); @@ -109,16 +106,13 @@ fn test_revoke_smiths_them_rejoin() { // Dave should not be able to re-request membership before the RevocationPeriod end run_to_block(3); assert_noop!( - SmithsMembership::request_membership(Origin::signed(4), crate::MembershipMetaData(4)), + SmithsMembership::request_membership(Origin::signed(4), ()), pallet_membership::Error::<Test, crate::Instance2>::MembershipRevokedRecently ); // At block #6, Dave shoud be able to request smith membership run_to_block(6); - assert_ok!(SmithsMembership::request_membership( - Origin::signed(4), - crate::MembershipMetaData(4) - )); + assert_ok!(SmithsMembership::request_membership(Origin::signed(4), ())); // Then, Alice should be able to send a smith cert to Dave assert_ok!(SmithsCert::add_cert(Origin::signed(1), 1, 4)); diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs deleted file mode 100644 index c70663fb2ed8303898e5d0d07593f37feb8619c6..0000000000000000000000000000000000000000 --- a/pallets/duniter-wot/src/types.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021 Axiom-Team -// -// This file is part of Substrate-Libre-Currency. -// -// Substrate-Libre-Currency is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, version 3 of the License. -// -// Substrate-Libre-Currency is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. - -use crate::IdtyIndex; -use frame_support::pallet_prelude::*; - -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct MembershipMetaData<AccountId>(pub AccountId); -impl<AccountId: Eq> sp_membership::traits::Validate<AccountId> for MembershipMetaData<AccountId> { - fn validate(&self, account_id: &AccountId) -> bool { - &self.0 == account_id - } -} -/*impl From<AccountId> for MembershipMetaData { - fn from(account_id: AccountId) -> Self { - Self(account_id) - } -}*/ -/*impl Into<AccountId> for MembershipMetaData { - fn into(self) -> AccountId { - self.0 - } -}*/ - -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(codec::Decode, codec::Encode, Eq, PartialEq, TypeInfo)] -pub enum WotDiff { - AddNode(IdtyIndex), - AddPendingLink(IdtyIndex, IdtyIndex), - AddLink(IdtyIndex, IdtyIndex), - DelLink(IdtyIndex, IdtyIndex), - DisableNode(IdtyIndex), -} - -impl Default for WotDiff { - fn default() -> Self { - unreachable!() - } -} diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index 77cba1b93f9b73b9a29cfbc3fe717eb5ce09bb2c..feebdbfc7d2252f572b7e7afab7b9f068d41e159 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -70,7 +70,8 @@ pub mod pallet { type ChangeOwnerKeyPeriod: Get<Self::BlockNumber>; /// Because this pallet emits events, it depends on the runtime's definition of an event. type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>; - /// Management of the authorizations of the different calls. (The default implementation only allows root) + /// Management of the authorizations of the different calls. + /// The default implementation allows everything. type EnsureIdtyCallAllowed: EnsureIdtyCallAllowed<Self>; #[pallet::constant] /// Minimum duration between the creation of 2 identities by the same creator @@ -340,7 +341,7 @@ pub mod pallet { if <IdentitiesNames<T>>::contains_key(&idty_name) { return Err(Error::<T>::IdtyNameAlreadyExist.into()); } - if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index, who.clone()) { + if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index) { return Err(Error::<T>::NotAllowedToConfirmIdty.into()); } @@ -415,6 +416,11 @@ pub mod pallet { Error::<T>::OwnerKeyAlreadyUsed ); + ensure!( + T::EnsureIdtyCallAllowed::can_change_identity_address(idty_index), + Error::<T>::NotAllowedToChangeIdtyAddress + ); + let block_number = frame_system::Pallet::<T>::block_number(); let maybe_old_old_owner_key = if let Some((old_owner_key, last_change)) = idty_value.old_owner_key { @@ -497,6 +503,11 @@ pub mod pallet { Error::<T>::InvalidRevocationKey ); + ensure!( + T::EnsureIdtyCallAllowed::can_remove_identity(idty_index), + Error::<T>::NotAllowedToRemoveIdty + ); + let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero()); let revocation_payload = RevocationPayload { genesis_hash, @@ -597,8 +608,12 @@ pub mod pallet { InvalidRevocationKey, /// Revocation payload signature is invalid InvalidRevocationSig, + /// Identity not allowed to change address + NotAllowedToChangeIdtyAddress, /// Not allowed to confirm identity NotAllowedToConfirmIdty, + /// Not allowed to remove identity + NotAllowedToRemoveIdty, /// Not allowed to validate identity NotAllowedToValidateIdty, /// Identity creation period is not respected diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs index 0b492553f7c5942a4bf3bd338486c37789988a07..f196bda373a9229a177b4c806d02e879fb746810 100644 --- a/pallets/identity/src/traits.rs +++ b/pallets/identity/src/traits.rs @@ -21,18 +21,33 @@ use sp_runtime::traits::Saturating; pub trait EnsureIdtyCallAllowed<T: Config> { fn can_create_identity(creator: T::IdtyIndex) -> bool; - fn can_confirm_identity(idty_index: T::IdtyIndex, owner_key: T::AccountId) -> bool; + fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool; fn can_validate_identity(idty_index: T::IdtyIndex) -> bool; + fn can_change_identity_address(idty_index: T::IdtyIndex) -> bool; + fn can_remove_identity(idty_index: T::IdtyIndex) -> bool; } -impl<T: Config> EnsureIdtyCallAllowed<T> for () { - fn can_create_identity(_: T::IdtyIndex) -> bool { +#[impl_for_tuples(5)] +#[allow(clippy::let_and_return)] +impl<T: Config> EnsureIdtyCallAllowed<T> for Tuple { + fn can_create_identity(creator: T::IdtyIndex) -> bool { + for_tuples!( #( if !Tuple::can_create_identity(creator) { return false; } )* ); + true + } + fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool { + for_tuples!( #( if !Tuple::can_confirm_identity(idty_index) { return false; } )* ); + true + } + fn can_validate_identity(idty_index: T::IdtyIndex) -> bool { + for_tuples!( #( if !Tuple::can_validate_identity(idty_index) { return false; } )* ); true } - fn can_confirm_identity(_: T::IdtyIndex, _: T::AccountId) -> bool { + fn can_change_identity_address(idty_index: T::IdtyIndex) -> bool { + for_tuples!( #( if !Tuple::can_change_identity_address(idty_index) { return false; } )* ); true } - fn can_validate_identity(_: T::IdtyIndex) -> bool { + fn can_remove_identity(idty_index: T::IdtyIndex) -> bool { + for_tuples!( #( if !Tuple::can_remove_identity(idty_index) { return false; } )* ); true } } diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index 657c4f152931f7f25280536facf2d465075f6354..93ff97dc6aeb1eda2316f1cfcdf01e17443ae930 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -72,7 +72,7 @@ pub mod pallet { /// Something that give the IdtyId on an account id type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>; /// Optional metadata - type MetaData: Parameter + Validate<Self::AccountId>; + type MetaData: Default + Parameter + Validate<Self::AccountId>; #[pallet::constant] /// Maximum life span of a non-renewable membership (in number of blocks) type MembershipPeriod: Get<Self::BlockNumber>; diff --git a/runtime/common/src/entities.rs b/runtime/common/src/entities.rs index aa91be374f60ac4ff81143ba1eda7713610b59e5..1680f7b16abbfd71ae6bf6aa8bc367730d05805d 100644 --- a/runtime/common/src/entities.rs +++ b/runtime/common/src/entities.rs @@ -106,6 +106,11 @@ pub struct SmithsMembershipMetaData<SessionKeysWrapper> { pub p2p_endpoint: sp_runtime::RuntimeString, pub session_keys: SessionKeysWrapper, } +impl<SessionKeysWrapper> Default for SmithsMembershipMetaData<SessionKeysWrapper> { + fn default() -> Self { + unreachable!() + } +} impl<SessionKeysWrapper> sp_membership::traits::Validate<AccountId> for SmithsMembershipMetaData<SessionKeysWrapper> { diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs index 0ada22e65fa5a5b8c231f4058496fda2bf8592ef..3726d216e102866e745c3845c3a051d64b17b2a0 100644 --- a/runtime/common/src/handlers.rs +++ b/runtime/common/src/handlers.rs @@ -75,18 +75,15 @@ where pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>); -type MembershipMetaData = pallet_duniter_wot::MembershipMetaData<AccountId>; - impl< - Inner: sp_membership::traits::OnEvent<IdtyIndex, MembershipMetaData>, + Inner: sp_membership::traits::OnEvent<IdtyIndex, ()>, Runtime: frame_system::Config<AccountId = AccountId> + pallet_identity::Config<IdtyData = IdtyData, IdtyIndex = IdtyIndex> - + pallet_membership::Config<Instance1, MetaData = MembershipMetaData> + + pallet_membership::Config<Instance1, MetaData = ()> + pallet_universal_dividend::Config, - > sp_membership::traits::OnEvent<IdtyIndex, MembershipMetaData> - for OnMembershipEventHandler<Inner, Runtime> + > sp_membership::traits::OnEvent<IdtyIndex, ()> for OnMembershipEventHandler<Inner, Runtime> { - fn on_event(membership_event: &sp_membership::Event<IdtyIndex, MembershipMetaData>) -> Weight { + fn on_event(membership_event: &sp_membership::Event<IdtyIndex, ()>) -> Weight { (match membership_event { sp_membership::Event::MembershipRevoked(idty_index) => { if let Some(idty_value) = pallet_identity::Identities::<Runtime>::get(idty_index) { diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 45d53fa5437a9741b5b5541c9c9264fec0d5e2df..7bf469f49c270c73f436fb359c13c5891667bafd 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -430,7 +430,7 @@ macro_rules! pallets_config { type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; type ConfirmPeriod = ConfirmPeriod; type Event = Event; - type EnsureIdtyCallAllowed = Wot; + type EnsureIdtyCallAllowed = (Wot, SmithsSubWot); type IdtyCreationPeriod = IdtyCreationPeriod; type IdtyData = IdtyData; type IdtyIndex = IdtyIndex; @@ -451,7 +451,7 @@ macro_rules! pallets_config { type IdtyId = IdtyIndex; type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>; type MembershipPeriod = MembershipPeriod; - type MetaData = pallet_duniter_wot::MembershipMetaData<AccountId>; + type MetaData = (); type OnEvent = OnMembershipEventHandler<Wot, Runtime>; type PendingMembershipPeriod = PendingMembershipPeriod; type RevocationPeriod = frame_support::traits::ConstU32<0>;