mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 18:21:02 +00:00
frame-support: Introduce EnsureOriginOrHigherPrivilege (#12844)
* frame-support: Introduce `EnsureOriginOrHigherPrivilege` This adds a new `EnsureOrigin` implementation that checks if a given origin matches or if the origin is has a higher or equal origin matches or if the origin is has a higher or equal privilege. * FMT
This commit is contained in:
@@ -99,8 +99,8 @@ mod dispatch;
|
|||||||
pub use dispatch::EnsureOneOf;
|
pub use dispatch::EnsureOneOf;
|
||||||
pub use dispatch::{
|
pub use dispatch::{
|
||||||
AsEnsureOriginWithArg, CallerTrait, EitherOf, EitherOfDiverse, EnsureOrigin,
|
AsEnsureOriginWithArg, CallerTrait, EitherOf, EitherOfDiverse, EnsureOrigin,
|
||||||
EnsureOriginWithArg, MapSuccess, NeverEnsureOrigin, OriginTrait, TryMapSuccess,
|
EnsureOriginEqualOrHigherPrivilege, EnsureOriginWithArg, MapSuccess, NeverEnsureOrigin,
|
||||||
UnfilteredDispatchable,
|
OriginTrait, TryMapSuccess, UnfilteredDispatchable,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod voting;
|
mod voting;
|
||||||
|
|||||||
@@ -20,10 +20,12 @@
|
|||||||
use crate::dispatch::{DispatchResultWithPostInfo, Parameter, RawOrigin};
|
use crate::dispatch::{DispatchResultWithPostInfo, Parameter, RawOrigin};
|
||||||
use codec::MaxEncodedLen;
|
use codec::MaxEncodedLen;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{BadOrigin, Member, Morph, TryMorph},
|
traits::{BadOrigin, Get, Member, Morph, TryMorph},
|
||||||
Either,
|
Either,
|
||||||
};
|
};
|
||||||
use sp_std::marker::PhantomData;
|
use sp_std::{cmp::Ordering, marker::PhantomData};
|
||||||
|
|
||||||
|
use super::misc;
|
||||||
|
|
||||||
/// Some sort of check on the origin is performed by this object.
|
/// Some sort of check on the origin is performed by this object.
|
||||||
pub trait EnsureOrigin<OuterOrigin> {
|
pub trait EnsureOrigin<OuterOrigin> {
|
||||||
@@ -59,7 +61,7 @@ pub trait EnsureOrigin<OuterOrigin> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `EnsureOrigin` implementation that always fails.
|
/// [`EnsureOrigin`] implementation that always fails.
|
||||||
pub struct NeverEnsureOrigin<Success>(sp_std::marker::PhantomData<Success>);
|
pub struct NeverEnsureOrigin<Success>(sp_std::marker::PhantomData<Success>);
|
||||||
impl<OO, Success> EnsureOrigin<OO> for NeverEnsureOrigin<Success> {
|
impl<OO, Success> EnsureOrigin<OO> for NeverEnsureOrigin<Success> {
|
||||||
type Success = Success;
|
type Success = Success;
|
||||||
@@ -72,6 +74,90 @@ impl<OO, Success> EnsureOrigin<OO> for NeverEnsureOrigin<Success> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`EnsureOrigin`] implementation that checks that an origin has equal or higher privilege
|
||||||
|
/// compared to the expected `Origin`.
|
||||||
|
///
|
||||||
|
/// It will take the shortcut of comparing the incoming origin with the expected `Origin` and if
|
||||||
|
/// both are the same the origin is accepted.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use frame_support::traits::{EnsureOriginEqualOrHigherPrivilege, PrivilegeCmp, EnsureOrigin as _};
|
||||||
|
/// # use sp_runtime::traits::{parameter_types, Get};
|
||||||
|
/// # use sp_std::cmp::Ordering;
|
||||||
|
///
|
||||||
|
/// #[derive(Eq, PartialEq, Debug)]
|
||||||
|
/// pub enum Origin {
|
||||||
|
/// Root,
|
||||||
|
/// SomethingBelowRoot,
|
||||||
|
/// NormalUser,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// struct OriginPrivilegeCmp;
|
||||||
|
///
|
||||||
|
/// impl PrivilegeCmp<Origin> for OriginPrivilegeCmp {
|
||||||
|
/// fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering> {
|
||||||
|
/// match (left, right) {
|
||||||
|
/// (Origin::Root, Origin::Root) => Some(Ordering::Equal),
|
||||||
|
/// (Origin::Root, _) => Some(Ordering::Greater),
|
||||||
|
/// (Origin::SomethingBelowRoot, Origin::SomethingBelowRoot) => Some(Ordering::Equal),
|
||||||
|
/// (Origin::SomethingBelowRoot, Origin::Root) => Some(Ordering::Less),
|
||||||
|
/// (Origin::SomethingBelowRoot, Origin::NormalUser) => Some(Ordering::Greater),
|
||||||
|
/// (Origin::NormalUser, Origin::NormalUser) => Some(Ordering::Equal),
|
||||||
|
/// (Origin::NormalUser, _) => Some(Ordering::Less),
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// parameter_types! {
|
||||||
|
/// pub const ExpectedOrigin: Origin = Origin::SomethingBelowRoot;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// type EnsureOrigin = EnsureOriginEqualOrHigherPrivilege<ExpectedOrigin, OriginPrivilegeCmp>;
|
||||||
|
///
|
||||||
|
/// // `Root` has an higher privilege as our expected origin.
|
||||||
|
/// assert!(EnsureOrigin::ensure_origin(Origin::Root).is_ok());
|
||||||
|
/// // `SomethingBelowRoot` is exactly the expected origin.
|
||||||
|
/// assert!(EnsureOrigin::ensure_origin(Origin::SomethingBelowRoot).is_ok());
|
||||||
|
/// // The `NormalUser` origin is not allowed.
|
||||||
|
/// assert!(EnsureOrigin::ensure_origin(Origin::NormalUser).is_err());
|
||||||
|
/// ```
|
||||||
|
pub struct EnsureOriginEqualOrHigherPrivilege<Origin, PrivilegeCmp>(
|
||||||
|
sp_std::marker::PhantomData<(Origin, PrivilegeCmp)>,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl<OuterOrigin, Origin, PrivilegeCmp> EnsureOrigin<OuterOrigin>
|
||||||
|
for EnsureOriginEqualOrHigherPrivilege<Origin, PrivilegeCmp>
|
||||||
|
where
|
||||||
|
Origin: Get<OuterOrigin>,
|
||||||
|
OuterOrigin: Eq,
|
||||||
|
PrivilegeCmp: misc::PrivilegeCmp<OuterOrigin>,
|
||||||
|
{
|
||||||
|
type Success = ();
|
||||||
|
|
||||||
|
fn try_origin(o: OuterOrigin) -> Result<Self::Success, OuterOrigin> {
|
||||||
|
let expected_origin = Origin::get();
|
||||||
|
|
||||||
|
// If this is the expected origin, it has the same privilege.
|
||||||
|
if o == expected_origin {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
let cmp = PrivilegeCmp::cmp_privilege(&o, &expected_origin);
|
||||||
|
|
||||||
|
match cmp {
|
||||||
|
Some(Ordering::Equal) | Some(Ordering::Greater) => Ok(()),
|
||||||
|
None | Some(Ordering::Less) => Err(o),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
fn try_successful_origin() -> Result<OuterOrigin, ()> {
|
||||||
|
Ok(Origin::get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Some sort of check on the origin is performed by this object.
|
/// Some sort of check on the origin is performed by this object.
|
||||||
pub trait EnsureOriginWithArg<OuterOrigin, Argument> {
|
pub trait EnsureOriginWithArg<OuterOrigin, Argument> {
|
||||||
/// A return type.
|
/// A return type.
|
||||||
|
|||||||
Reference in New Issue
Block a user