Skip to content
This repository was archived by the owner on Feb 4, 2025. It is now read-only.

Commit

Permalink
[no ci] wip
Browse files Browse the repository at this point in the history
  • Loading branch information
CyonAlexRDX committed Nov 22, 2024
1 parent 065227f commit 67c2fa5
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 92 deletions.
41 changes: 35 additions & 6 deletions crates/rules/src/rules/has_rule_set_for_role.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
use crate::prelude::*;

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FactorRulesFailure<E: std::fmt::Debug> {
Specific(E),

Basic(FactorRulesFailureBasic),
}

#[derive(Clone, Debug, PartialEq, Eq, ThisError)]
pub enum FactorRulesFailureBasic {
#[error("Threshold may not be larger than the number of factors in the threshold list")]
ThresholdTooLarge,
}

pub trait HasRuleSetForRole<F: IsFactor>: Sized + IsRole + Clone {
type Violation;
type Violation: std::fmt::Debug;
type Failure = FactorRulesFailure<Self::Violation>;
type Result = std::result::Result<(), Self::Failure>;

/// Neither Recovery nor Confirmation roles can have factors added to their threshold
/// factor list. Only Primary supports it.
Expand Down Expand Up @@ -54,10 +69,24 @@ pub trait HasRuleSetForRole<F: IsFactor>: Sized + IsRole + Clone {
Self::_do_validate(context, Self::validate_password_in_factors_list_of_kind)
}

fn validate(context: &RoleWithFactorsBuilt<F, Self>) -> FactorBuilderResult<Self::Violation> {
Self::validate_device(context)?;
Self::validate_ledger(context)?;
Self::validate_password(context)?;
Ok(())
fn validate(context: &RoleWithFactorsBuilt<F, Self>) -> Self::Result {
if context.threshold > context.threshold_factors.len() as u8 {
// return FactorBuilderResult::not_yet_valid(
// Self::violation_if_adding_factors_to_threshold().unwrap(),
// );
// return Self::Result::Err(Self::Failure::Basic(
// FactorRulesFailureBasic::ThresholdTooLarge,
// ));
let basic: FactorBuilderResult<>
let failure: Self::Failure =
Self::Failure::Basic(FactorRulesFailureBasic::ThresholdTooLarge);
let res: Self::Result = Self::Result::Err(failure);
return res;
}

// Self::validate_device(context)?;
// Self::validate_ledger(context)?;
// Self::validate_password(context)?;
Self::Result::Ok(())
}
}
2 changes: 0 additions & 2 deletions crates/rules/src/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ mod factor_rules_violation;
mod has_rule_set_for_role;
mod is_role;
// mod matrix;
mod primary_role_with_factor_source_rule_set;
mod primary_role_with_factor_sources_builder;
mod role_builder_or_built;
mod role_kind;
Expand All @@ -15,7 +14,6 @@ pub use factor_rules_violation::*;
pub use has_rule_set_for_role::*;
pub use is_role::*;
// pub use matrix::*;
pub use primary_role_with_factor_source_rule_set::*;

#[allow(unused_imports)]
pub use primary_role_with_factor_sources_builder::*;
Expand Down
68 changes: 0 additions & 68 deletions crates/rules/src/rules/primary_role_with_factor_source_rule_set.rs

This file was deleted.

87 changes: 82 additions & 5 deletions crates/rules/src/rules/primary_role_with_factor_sources_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,70 @@

use crate::prelude::*;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PrimaryRoleWithFactorSourceRuleSet;
impl IsRole for PrimaryRoleWithFactorSourceRuleSet {
fn role_kind() -> RoleKind {
RoleKind::Primary
}
}

impl HasRuleSetForRole<FactorSource> for PrimaryRoleWithFactorSourceRuleSet {
type Violation = PrimaryRoleViolation;

fn violation_if_adding_factors_to_threshold() -> Option<Self::Violation> {
None
}

fn validate_device_in_factors_list_of_kind(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
_list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation> {
let kind = FactorSourceKind::Device;
if context.count_factors_of_kind_in_any_list(kind) > 1 {
return Err(FactorRulesViolation::ForeverInvalid(
Self::Violation::MoreThanOneDeviceFactorIsNotSupported,
));
}
Ok(())
}

fn validate_password_in_factors_list_of_kind(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation> {
let kind = FactorSourceKind::Password;

if context.has_factor_of_kind_in_list_of_kind(kind, list_kind) {
if list_kind == FactorListKind::Override {
return FactorBuilderResult::forever_invalid(
PrimaryRoleViolation::PasswordNotAllowedInOverrideListSinceItWouldBeAlone,
);
}

if !context.has_factor_not_of_kind_in_list_of_kind(kind, list_kind) {
return FactorBuilderResult::not_yet_valid(
PrimaryRoleViolation::PasswordMustNotBeAlone,
);
}

if list_kind == FactorListKind::Threshold && context.threshold < 2 {
return FactorBuilderResult::not_yet_valid(
PrimaryRoleViolation::PasswordRequiresThresholdOfAtLeastTwo,
);
}
}
Ok(())
}

fn validate_ledger_in_factors_list_of_kind(
_context: &RoleWithFactorsBuilt<FactorSource, Self>,
_list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation> {
Ok(()) // No restrictions
}
}

pub type PrimaryRoleWithFactorSourcesBuilder =
RoleWithFactorsBuilder<FactorSource, PrimaryRoleWithFactorSourceRuleSet>;

Expand All @@ -10,30 +74,43 @@ mod tests {
use super::*;

#[test]
fn add_device_to_threshold_then_build() {
fn single_device_in_threshold_is_ok() {
type F = FactorSource;
type SUT = PrimaryRoleWithFactorSourcesBuilder;
let mut sut = SUT::new();

let f = F::sample_device();
sut.add_to_threshold(&f).unwrap();
let built = sut.build().unwrap();
assert_eq!(built.threshold_factors, vec![f])
}

#[test]
fn threshold_cannot_be_larger_than_threshold_factor_count() {
type F = FactorSource;
type SUT = PrimaryRoleWithFactorSourcesBuilder;
let mut sut = SUT::new();

let f = F::sample_device();
sut.add_to_threshold(&f).unwrap();
sut.set_threshold(2);
let built = sut.build().unwrap();
assert_eq!(built.threshold_factors, vec![f])
}


#[test]
fn add_password_to_override_then_build() {
type F = FactorSource;
type SUT = PrimaryRoleWithFactorSourcesBuilder;
type Result = SUT::BuildResult;
type MutResult = SUT::MutateResult;

let mut sut = SUT::new();

let f = F::sample_password();
sut.add_to_override(&f).unwrap();
assert_eq!(
sut.build(),
Result::not_yet_valid(
sut.add_to_override(&f),
MutResult::forever_invalid(
PrimaryRoleViolation::PasswordNotAllowedInOverrideListSinceItWouldBeAlone
)
);
Expand Down
27 changes: 16 additions & 11 deletions crates/rules/src/rules/role_builder_or_built.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ where
}

pub type Built = RoleWithFactorsBuilt<F, R>;
pub type MutateResult = FactorBuilderResult<R::Violation>;
pub type BuildResult = Result<Self::Built, R::Violation>;

pub fn build(self) -> Self::BuildResult {
Expand All @@ -47,28 +48,32 @@ where
)
}

pub fn add_to_override(&mut self, factor: impl Borrow<F>) -> FactorBuilderResult<R::Violation> {
pub fn add_to_override(&mut self, factor: impl Borrow<F>) -> Self::MutateResult {
self.add_to_list(factor, FactorListKind::Override)
}

pub fn add_to_threshold(
&mut self,
factor: impl Borrow<F>,
) -> FactorBuilderResult<R::Violation> {
pub fn add_to_threshold(&mut self, factor: impl Borrow<F>) -> Self::MutateResult {
self.add_to_list(factor, FactorListKind::Threshold)
}

fn validate(&self) -> FactorBuilderResult<R::Violation> {
R::validate(&self.snapshot())
pub fn set_threshold(&mut self, threshold: u8) -> Self::MutateResult {
let mut simulation = self.clone();
simulation.threshold = threshold;
simulation.validate()
}

fn validate(&self) -> Self::MutateResult {
// R::validate(&self.snapshot())
todo!()
}

fn violation_if_add_factor_to_list_of_kind(
&self,
factor: &F,
list_kind: FactorListKind,
) -> FactorBuilderResult<R::Violation> {
) -> Self::MutateResult {
if let Some(violation) = R::violation_if_adding_factors_to_threshold() {
return FactorBuilderResult::Err(FactorRulesViolation::ForeverInvalid(violation));
return Self::MutateResult::Err(FactorRulesViolation::ForeverInvalid(violation));
}

let factor = factor.clone();
Expand All @@ -85,7 +90,7 @@ where
&mut self,
factor: impl Borrow<F>,
list_kind: FactorListKind,
) -> FactorBuilderResult<R::Violation> {
) -> Self::MutateResult {
let factor = factor.borrow();
let outcome = self.violation_if_add_factor_to_list_of_kind(factor, list_kind);
match outcome.as_ref() {
Expand All @@ -100,7 +105,7 @@ where
FactorListKind::Override => self.override_factors.push(factor),
FactorListKind::Threshold => self.threshold_factors.push(factor),
}
FactorBuilderResult::Ok(())
Self::MutateResult::Ok(())
}
}

Expand Down

0 comments on commit 67c2fa5

Please sign in to comment.