Skip to content

Commit

Permalink
fix(fc-pallet-pass): revive tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pandres95 committed Sep 27, 2024
1 parent cf067c8 commit 9077ddf
Show file tree
Hide file tree
Showing 3 changed files with 465 additions and 380 deletions.
147 changes: 13 additions & 134 deletions pallets/pass/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! Test environment for pallet pass.
use crate::{self as pallet_pass, Config};
pub use authenticators::*;
use codec::{Decode, Encode, MaxEncodedLen};
use fc_traits_authn::Challenger;
use fc_traits_authn::{composite_authenticators, util::AuthorityFromPalletId, Challenger};
use frame_support::{
derive_impl, parameter_types,
traits::{ConstU32, ConstU64, EqualPrivilegeOnly, OnInitialize, Randomness},
traits::{ConstU32, ConstU64, EqualPrivilegeOnly, OnInitialize},
weights::Weight,
DebugNoBound, EqNoBound, PalletId,
};
Expand All @@ -14,11 +15,12 @@ use scale_info::TypeInfo;
use sp_core::{blake2_256, H256};
use sp_io::TestExternalities;
use sp_runtime::{
str_array as s,
traits::{IdentifyAccount, IdentityLookup, Verify},
MultiSignature,
};

mod authenticators;

pub type Block = frame_system::mocking::MockBlock<Test>;

pub type AccountPublic = <MultiSignature as Verify>::Signer;
Expand Down Expand Up @@ -78,144 +80,21 @@ impl pallet_scheduler::Config for Test {
type WeightInfo = ();
}

pub struct RandomnessFromBlockNumber;
impl frame_support::traits::Randomness<H256, u64> for RandomnessFromBlockNumber {
fn random(subject: &[u8]) -> (H256, u64) {
let block_number = System::block_number();
let block_number_as_bytes = block_number.to_le_bytes();
(
H256(blake2_256(
&vec![block_number_as_bytes.to_vec(), subject.to_vec()].concat()[..],
)),
block_number,
)
}
}

#[derive(TypeInfo, MaxEncodedLen, DebugNoBound, EqNoBound, PartialEq, Clone, Encode, Decode)]
pub struct MockDeviceAttestation {
pub(crate) context: (),
pub(crate) user_id: fc_traits_authn::HashedUserId,
pub(crate) challenge: fc_traits_authn::Challenge,
pub(crate) device_id: fc_traits_authn::DeviceId,
}

impl fc_traits_authn::ChallengeResponse<()> for MockDeviceAttestation {
fn is_valid(&self) -> bool {
self.challenge == MockChallenger::generate(&self.context)
}

fn used_challenge(&self) -> ((), fc_traits_authn::Challenge) {
((), MockChallenger::generate(&self.context))
}

fn authority(&self) -> fc_traits_authn::AuthorityId {
s("DummyAuthenticator")
}
}

impl fc_traits_authn::UserAuthenticator for MockDeviceAttestation {
const AUTHORITY: fc_traits_authn::AuthorityId = s("MockDevice");
type Challenger = MockChallenger;
type Credential = Self;

fn device_id(&self) -> fc_traits_authn::DeviceId {
todo!()
}
}

impl fc_traits_authn::DeviceChallengeResponse<()> for MockDeviceAttestation {
fn device_id(&self) -> fc_traits_authn::DeviceId {
self.device_id
}
}

impl fc_traits_authn::UserChallengeResponse<()> for MockDeviceAttestation {
fn user_id(&self) -> fc_traits_authn::HashedUserId {
self.user_id
}
}

pub struct MockChallenger;
impl fc_traits_authn::Challenger for MockChallenger {
type Context = ();

fn generate(_: &Self::Context) -> fc_traits_authn::Challenge {
let (hash, _) = RandomnessFromBlockNumber::random_seed();
hash.0
}
}

pub struct InvalidAuthenticator;
impl fc_traits_authn::Authenticator for InvalidAuthenticator {
const AUTHORITY: fc_traits_authn::AuthorityId = s("InvalidAuthenticator");
type Challenger = MockChallenger;
type DeviceAttestation = MockDeviceAttestation;
type Device = MockDevice;

fn verify_device(&self, _: &Self::DeviceAttestation) -> Option<Self::Device> {
None
}

fn unpack_device(&self, _: &Self::DeviceAttestation) -> Self::Device {
()
}
}

pub struct DummyAuthenticator;
impl fc_traits_authn::Authenticator for DummyAuthenticator {
const AUTHORITY: fc_traits_authn::AuthorityId = s("DummyAuthenticator");
type Challenger = MockChallenger;
type DeviceAttestation = MockDeviceAttestation;
type Device = MockDeviceAttestation;

fn unpack_device(&self, verification: &Self::DeviceAttestation) -> Self::Device {
todo!()
}
// fn get_device_id(&self, device: Vec<u8>) -> Option<pallet_pass::DeviceId> {
// let len = device.len();
// Some([(len as u8) + 1; 32])
// }

// fn authenticate(
// &self,
// _device: Vec<u8>,
// challenge: &[u8],
// payload: &[u8],
// ) -> Result<(), fc_traits_authn::AuthenticateError> {
// ensure!(
// challenge == payload,
// fc_traits_authn::AuthenticateError::ChallengeFailed
// );
// Ok(())
// }
}

#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Debug, Clone, Eq, PartialEq)]
pub enum MockAuthenticationMethods {
InvalidAuthenticationMethod,
DummyAuthenticationMethod,
}

impl Into<Box<dyn fc_traits_authn::Authenticator>> for MockAuthenticationMethods {
fn into(self) -> Box<dyn fc_traits_authn::Authenticator> {
match self {
MockAuthenticationMethods::InvalidAuthenticationMethod => {
Box::new(InvalidAuthenticator)
}
MockAuthenticationMethods::DummyAuthenticationMethod => Box::new(DummyAuthenticator),
}
}
}

parameter_types! {
pub PassPalletId: PalletId = PalletId(*b"py/pass_");
}

composite_authenticators! {
pub Pass = {
AuthenticatorA,
AuthenticatorB,
};
}

impl Config for Test {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Authenticator = MockAuthenticationMethods;
type Authenticator = PassAuthenticator<AuthorityFromPalletId<Self::PalletId>>;
type RegisterOrigin = EnsureSigned<Self::AccountId>;
type RuntimeCall = RuntimeCall;
type PalletId = PassPalletId;
Expand Down
210 changes: 210 additions & 0 deletions pallets/pass/src/mock/authenticators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
use super::*;
use fc_traits_authn::{util::AuthorityFromPalletId, *};
use frame_support::traits::Randomness;
use sp_core::Get;

pub use authenticator_a::AuthenticatorA;
pub use authenticator_b::AuthenticatorB;

pub struct RandomnessFromBlockNumber;
impl Randomness<H256, u64> for RandomnessFromBlockNumber {
fn random(subject: &[u8]) -> (H256, u64) {
let block_number = System::block_number();
let block_number_as_bytes = block_number.to_le_bytes();
(
H256(blake2_256(
&vec![block_number_as_bytes.to_vec(), subject.to_vec()].concat()[..],
)),
block_number,
)
}
}

pub(self) type PassAuthorityId = AuthorityFromPalletId<PassPalletId>;

pub mod authenticator_a {
use super::*;

pub struct AuthenticatorA;

#[derive(TypeInfo, DebugNoBound, EqNoBound, PartialEq, Clone, Encode, Decode)]
pub struct DeviceAttestation {
pub(crate) device_id: DeviceId,
pub(crate) challenge: Challenge,
}

#[derive(TypeInfo, Encode, Decode, MaxEncodedLen)]
pub struct Device {
pub(crate) device_id: DeviceId,
}

#[derive(
TypeInfo, DebugNoBound, EqNoBound, PartialEq, Clone, Encode, Decode, MaxEncodedLen,
)]
pub struct Credential {
pub(crate) user_id: HashedUserId,
pub(crate) challenge: Challenge,
}

impl Authenticator for AuthenticatorA {
type Authority = PassAuthorityId;
type Challenger = Self;
type DeviceAttestation = DeviceAttestation;
type Device = Device;

fn unpack_device(attestation: Self::DeviceAttestation) -> Self::Device {
Device {
device_id: attestation.device_id,
}
}
}

impl Challenger for AuthenticatorA {
type Context = ();

fn generate(_: &Self::Context) -> Challenge {
let (hash, _) = RandomnessFromBlockNumber::random_seed();
hash.0
}
}

impl UserAuthenticator for Device {
type Authority = PassAuthorityId;
type Challenger = AuthenticatorA;
type Credential = Credential;

fn device_id(&self) -> &DeviceId {
&self.device_id
}
}

impl DeviceChallengeResponse<()> for DeviceAttestation {
fn is_valid(&self) -> bool {
true
}

fn used_challenge(&self) -> ((), Challenge) {
((), self.challenge)
}

fn authority(&self) -> AuthorityId {
PassAuthorityId::get()
}

fn device_id(&self) -> &DeviceId {
&self.device_id
}
}

impl UserChallengeResponse<()> for Credential {
fn is_valid(&self) -> bool {
true
}

fn used_challenge(&self) -> ((), Challenge) {
((), self.challenge)
}

fn authority(&self) -> AuthorityId {
PassAuthorityId::get()
}

fn user_id(&self) -> HashedUserId {
self.user_id
}
}
}

pub mod authenticator_b {
use super::*;

pub struct AuthenticatorB;

#[derive(TypeInfo, DebugNoBound, EqNoBound, PartialEq, Clone, Encode, Decode)]
pub struct DeviceAttestation {
pub(crate) device_id: DeviceId,
pub(crate) challenge: Challenge,
}

#[derive(TypeInfo, Encode, Decode, MaxEncodedLen)]
pub struct Device {
pub(crate) device_id: DeviceId,
}

#[derive(
TypeInfo, DebugNoBound, EqNoBound, PartialEq, Clone, Encode, Decode, MaxEncodedLen,
)]
pub struct Credential {
pub(crate) device_id: DeviceId,
pub(crate) user_id: HashedUserId,
pub(crate) challenge: Challenge,
}

impl Authenticator for AuthenticatorB {
type Authority = PassAuthorityId;
type Challenger = Self;
type DeviceAttestation = DeviceAttestation;
type Device = Device;

fn unpack_device(attestation: Self::DeviceAttestation) -> Self::Device {
Device {
device_id: attestation.device_id,
}
}
}

impl Challenger for AuthenticatorB {
type Context = DeviceId;

fn generate(context: &Self::Context) -> Challenge {
let (hash, _) = RandomnessFromBlockNumber::random(context);
hash.0
}
}

impl UserAuthenticator for Device {
type Authority = PassAuthorityId;
type Challenger = AuthenticatorB;
type Credential = Credential;

fn device_id(&self) -> &DeviceId {
&self.device_id
}
}

impl DeviceChallengeResponse<DeviceId> for DeviceAttestation {
fn is_valid(&self) -> bool {
true
}

fn used_challenge(&self) -> (DeviceId, Challenge) {
(self.device_id, self.challenge)
}

fn authority(&self) -> AuthorityId {
PassAuthorityId::get()
}

fn device_id(&self) -> &DeviceId {
&self.device_id
}
}

impl UserChallengeResponse<DeviceId> for Credential {
fn is_valid(&self) -> bool {
true
}

fn used_challenge(&self) -> (DeviceId, Challenge) {
(self.device_id, self.challenge)
}

fn authority(&self) -> AuthorityId {
PassAuthorityId::get()
}

fn user_id(&self) -> HashedUserId {
self.user_id
}
}
}
Loading

0 comments on commit 9077ddf

Please sign in to comment.