-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
168f63a
commit 9734ea3
Showing
21 changed files
with
697 additions
and
658 deletions.
There are no files selected for viewing
33 changes: 33 additions & 0 deletions
33
.../src/roles/factor_levels/factor_instance_level/confirmation_role_with_factor_instances.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use crate::prelude::*; | ||
|
||
pub(crate) type ConfirmationRoleWithFactorInstances = | ||
RoleWithFactorInstances<{ ROLE_CONFIRMATION }>; | ||
|
||
impl HasSampleValues for ConfirmationRoleWithFactorInstances { | ||
fn sample() -> Self { | ||
MatrixOfFactorInstances::sample().confirmation_role | ||
} | ||
|
||
fn sample_other() -> Self { | ||
MatrixOfFactorInstances::sample_other().confirmation_role | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod confirmation_tests { | ||
use super::*; | ||
|
||
#[allow(clippy::upper_case_acronyms)] | ||
type SUT = ConfirmationRoleWithFactorInstances; | ||
|
||
#[test] | ||
fn equality() { | ||
assert_eq!(SUT::sample(), SUT::sample()); | ||
assert_eq!(SUT::sample_other(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn inequality() { | ||
assert_ne!(SUT::sample(), SUT::sample_other()); | ||
} | ||
} |
File renamed without changes.
11 changes: 11 additions & 0 deletions
11
crates/rules/src/roles/factor_levels/factor_instance_level/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
mod confirmation_role_with_factor_instances; | ||
mod general_role_with_hierarchical_deterministic_factor_instances; | ||
mod primary_role_with_factor_instances; | ||
mod recovery_role_with_factor_instances; | ||
mod role_with_factor_instances; | ||
|
||
pub(crate) use confirmation_role_with_factor_instances::*; | ||
pub use general_role_with_hierarchical_deterministic_factor_instances::*; | ||
pub(crate) use primary_role_with_factor_instances::*; | ||
pub(crate) use recovery_role_with_factor_instances::*; | ||
pub(crate) use role_with_factor_instances::*; |
110 changes: 110 additions & 0 deletions
110
...rules/src/roles/factor_levels/factor_instance_level/primary_role_with_factor_instances.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use crate::prelude::*; | ||
|
||
pub(crate) type PrimaryRoleWithFactorInstances = RoleWithFactorInstances<{ ROLE_PRIMARY }>; | ||
|
||
impl HasSampleValues for PrimaryRoleWithFactorInstances { | ||
fn sample() -> Self { | ||
MatrixOfFactorInstances::sample().primary_role | ||
} | ||
|
||
fn sample_other() -> Self { | ||
MatrixOfFactorInstances::sample_other().primary_role | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[allow(clippy::upper_case_acronyms)] | ||
type SUT = PrimaryRoleWithFactorInstances; | ||
|
||
#[test] | ||
fn equality() { | ||
assert_eq!(SUT::sample(), SUT::sample()); | ||
assert_eq!(SUT::sample_other(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn inequality() { | ||
assert_ne!(SUT::sample(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
#[should_panic] | ||
fn primary_role_non_securified_threshold_instances_is_err() { | ||
let _ = SUT::with_factors( | ||
1, | ||
[ | ||
HierarchicalDeterministicFactorInstance::sample_mainnet_account_device_factor_fs_10_unsecurified_at_index(0).into() | ||
], | ||
[] | ||
); | ||
} | ||
|
||
#[test] | ||
fn assert_json_sample() { | ||
let sut = SUT::sample(); | ||
assert_eq_after_json_roundtrip( | ||
&sut, | ||
r#" | ||
{ | ||
"threshold": 2, | ||
"thresholdFactors": [ | ||
{ | ||
"factorSourceID": { | ||
"discriminator": "fromHash", | ||
"fromHash": { | ||
"kind": "device", | ||
"body": "f1a93d324dd0f2bff89963ab81ed6e0c2ee7e18c0827dc1d3576b2d9f26bbd0a" | ||
} | ||
}, | ||
"badge": { | ||
"discriminator": "virtualSource", | ||
"virtualSource": { | ||
"discriminator": "hierarchicalDeterministicPublicKey", | ||
"hierarchicalDeterministicPublicKey": { | ||
"publicKey": { | ||
"curve": "curve25519", | ||
"compressedData": "427969814e15d74c3ff4d9971465cb709d210c8a7627af9466bdaa67bd0929b7" | ||
}, | ||
"derivationPath": { | ||
"scheme": "cap26", | ||
"path": "m/44H/1022H/1H/525H/1460H/0S" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
"factorSourceID": { | ||
"discriminator": "fromHash", | ||
"fromHash": { | ||
"kind": "ledgerHQHardwareWallet", | ||
"body": "ab59987eedd181fe98e512c1ba0f5ff059f11b5c7c56f15614dcc9fe03fec58b" | ||
} | ||
}, | ||
"badge": { | ||
"discriminator": "virtualSource", | ||
"virtualSource": { | ||
"discriminator": "hierarchicalDeterministicPublicKey", | ||
"hierarchicalDeterministicPublicKey": { | ||
"publicKey": { | ||
"curve": "curve25519", | ||
"compressedData": "92cd6838cd4e7b0523ed93d498e093f71139ffd5d632578189b39a26005be56b" | ||
}, | ||
"derivationPath": { | ||
"scheme": "cap26", | ||
"path": "m/44H/1022H/1H/525H/1460H/0S" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
], | ||
"overrideFactors": [] | ||
} | ||
"#, | ||
); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...ules/src/roles/factor_levels/factor_instance_level/recovery_role_with_factor_instances.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use crate::prelude::*; | ||
|
||
pub(crate) type RecoveryRoleWithFactorInstances = RoleWithFactorInstances<{ ROLE_RECOVERY }>; | ||
|
||
impl HasSampleValues for RecoveryRoleWithFactorInstances { | ||
fn sample() -> Self { | ||
MatrixOfFactorInstances::sample().recovery_role | ||
} | ||
|
||
fn sample_other() -> Self { | ||
MatrixOfFactorInstances::sample_other().recovery_role | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[allow(clippy::upper_case_acronyms)] | ||
type SUT = RecoveryRoleWithFactorInstances; | ||
|
||
#[test] | ||
fn equality() { | ||
assert_eq!(SUT::sample(), SUT::sample()); | ||
assert_eq!(SUT::sample_other(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn inequality() { | ||
assert_ne!(SUT::sample(), SUT::sample_other()); | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
crates/rules/src/roles/factor_levels/factor_instance_level/role_with_factor_instances.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use crate::prelude::*; | ||
|
||
pub(crate) type RoleWithFactorInstances<const R: u8> = | ||
AbstractBuiltRoleWithFactor<R, FactorInstance>; | ||
|
||
impl<const R: u8> RoleWithFactorSources<R> { | ||
fn from<const F: u8>(other: &RoleWithFactorSources<F>) -> Self { | ||
Self::with_factors( | ||
other.get_threshold(), | ||
other.get_threshold_factors().clone(), | ||
other.get_override_factors().clone(), | ||
) | ||
} | ||
} | ||
|
||
impl MatrixOfFactorSources { | ||
pub(crate) fn get_role<const R: u8>(&self) -> RoleWithFactorSources<R> { | ||
match R { | ||
ROLE_PRIMARY => RoleWithFactorSources::from(&self.primary_role), | ||
ROLE_RECOVERY => RoleWithFactorSources::from(&self.recovery_role), | ||
ROLE_CONFIRMATION => RoleWithFactorSources::from(&self.confirmation_role), | ||
_ => panic!("unknown"), | ||
} | ||
} | ||
} | ||
|
||
impl<const R: u8> RoleWithFactorInstances<R> { | ||
pub(crate) fn fulfilling_role_of_factor_sources_with_factor_instances( | ||
consuming_instances: &IndexMap<FactorSourceIDFromHash, FactorInstances>, | ||
matrix_of_factor_sources: &MatrixOfFactorSources, | ||
) -> Result<Self, CommonError> { | ||
let role_kind = RoleKind::from_u8(R).unwrap(); | ||
|
||
let role_of_sources = matrix_of_factor_sources.get_role::<R>(); | ||
assert_eq!(role_of_sources.role(), role_kind); | ||
let threshold: u8 = role_of_sources.get_threshold(); | ||
|
||
// Threshold factors | ||
let threshold_factors = | ||
Self::try_filling_factor_list_of_role_of_factor_sources_with_factor_instances( | ||
consuming_instances, | ||
role_of_sources.get_threshold_factors(), | ||
)?; | ||
|
||
// Override factors | ||
let override_factors = | ||
Self::try_filling_factor_list_of_role_of_factor_sources_with_factor_instances( | ||
consuming_instances, | ||
role_of_sources.get_override_factors(), | ||
)?; | ||
|
||
let role_with_instances = | ||
Self::with_factors(threshold, threshold_factors, override_factors); | ||
|
||
assert_eq!(role_with_instances.role(), role_kind); | ||
Ok(role_with_instances) | ||
} | ||
|
||
fn try_filling_factor_list_of_role_of_factor_sources_with_factor_instances( | ||
instances: &IndexMap<FactorSourceIDFromHash, FactorInstances>, | ||
from: &[FactorSource], | ||
) -> Result<Vec<FactorInstance>, CommonError> { | ||
from.iter() | ||
.map(|f| { | ||
if let Some(existing) = instances.get(&f.id_from_hash()) { | ||
let hd_instance = existing | ||
.first() | ||
.ok_or(CommonError::MissingFactorMappingInstancesIntoRole)?; | ||
let instance = FactorInstance::from(hd_instance); | ||
Ok(instance) | ||
} else { | ||
Err(CommonError::MissingFactorMappingInstancesIntoRole) | ||
} | ||
}) | ||
.collect::<Result<Vec<FactorInstance>, CommonError>>() | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
...rc/roles/factor_levels/factor_source_id_level/confirmation_role_with_factor_source_ids.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use crate::prelude::*; | ||
|
||
pub type ConfirmationRoleWithFactorSourceIds = RoleWithFactorSourceIds<{ ROLE_CONFIRMATION }>; | ||
|
||
impl HasSampleValues for ConfirmationRoleWithFactorSourceIds { | ||
/// Config MFA 1.1 | ||
fn sample() -> Self { | ||
let mut builder = RoleBuilder::new(); | ||
builder | ||
.add_factor_source(FactorSourceID::sample_password()) | ||
.unwrap(); | ||
builder.build().unwrap() | ||
} | ||
|
||
/// Config MFA 2.1 | ||
fn sample_other() -> Self { | ||
let mut builder = RoleBuilder::new(); | ||
builder | ||
.add_factor_source(FactorSourceID::sample_device()) | ||
.unwrap(); | ||
builder.build().unwrap() | ||
} | ||
} | ||
impl HasSampleValues for RecoveryRoleWithFactorSourceIds { | ||
/// Config MFA 1.1 | ||
fn sample() -> Self { | ||
let mut builder = RoleBuilder::new(); | ||
builder | ||
.add_factor_source(FactorSourceID::sample_device()) | ||
.unwrap(); | ||
|
||
builder | ||
.add_factor_source(FactorSourceID::sample_ledger()) | ||
.unwrap(); | ||
builder.build().unwrap() | ||
} | ||
|
||
/// Config MFA 3.3 | ||
fn sample_other() -> Self { | ||
let mut builder = RoleBuilder::new(); | ||
builder | ||
.add_factor_source(FactorSourceID::sample_ledger_other()) | ||
.unwrap(); | ||
|
||
builder.build().unwrap() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
|
||
use super::*; | ||
|
||
#[allow(clippy::upper_case_acronyms)] | ||
type SUT = ConfirmationRoleWithFactorSourceIds; | ||
|
||
#[test] | ||
fn equality() { | ||
assert_eq!(SUT::sample(), SUT::sample()); | ||
assert_eq!(SUT::sample_other(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn inequality() { | ||
assert_ne!(SUT::sample(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn get_all_factors() { | ||
let sut = SUT::sample(); | ||
let factors = sut.all_factors(); | ||
assert_eq!( | ||
factors.len(), | ||
sut.get_override_factors().len() + sut.get_threshold_factors().len() | ||
); | ||
} | ||
|
||
#[test] | ||
fn assert_json() { | ||
let sut = SUT::sample(); | ||
assert_eq_after_json_roundtrip( | ||
&sut, | ||
r#" | ||
{ | ||
"threshold": 0, | ||
"thresholdFactors": [], | ||
"overrideFactors": [ | ||
{ | ||
"discriminator": "fromHash", | ||
"fromHash": { | ||
"kind": "passphrase", | ||
"body": "181ab662e19fac3ad9f08d5c673b286d4a5ed9cd3762356dc9831dc42427c1b9" | ||
} | ||
} | ||
] | ||
} | ||
"#, | ||
); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
crates/rules/src/roles/factor_levels/factor_source_id_level/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
mod confirmation_role_with_factor_source_ids; | ||
mod primary_role_with_factor_source_ids; | ||
mod recovery_role_with_factor_source_ids; | ||
mod roles_with_factor_ids; | ||
|
||
pub use confirmation_role_with_factor_source_ids::*; | ||
pub use primary_role_with_factor_source_ids::*; | ||
pub use recovery_role_with_factor_source_ids::*; | ||
pub use roles_with_factor_ids::*; |
Oops, something went wrong.