From 065227f5075572cb229dc43c89a1847c278ba136 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Fri, 22 Nov 2024 15:26:57 +0100 Subject: [PATCH] fix validation --- crates/rules-uniffi/src/lib.rs | 1 + crates/rules/src/lib.rs | 1 + .../rules/src/rules/has_rule_set_for_role.rs | 22 ++++++------ crates/rules/src/rules/is_role.rs | 2 +- ...rimary_role_with_factor_source_rule_set.rs | 34 ++++++++++--------- ...rimary_role_with_factor_sources_builder.rs | 4 ++- .../rules/src/rules/role_builder_or_built.rs | 23 ++++++++++--- crates/rules/src/rules/role_kind.rs | 8 ++--- crates/rules/src/rules/role_tags.rs | 16 ++++----- crates/rules/src/rules/sargon_types.rs | 2 +- 10 files changed, 64 insertions(+), 49 deletions(-) diff --git a/crates/rules-uniffi/src/lib.rs b/crates/rules-uniffi/src/lib.rs index e69de29b..8b137891 100644 --- a/crates/rules-uniffi/src/lib.rs +++ b/crates/rules-uniffi/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/rules/src/lib.rs b/crates/rules/src/lib.rs index 637be208..7a222667 100644 --- a/crates/rules/src/lib.rs +++ b/crates/rules/src/lib.rs @@ -1,4 +1,5 @@ #![feature(associated_type_defaults)] +#![allow(incomplete_features)] #![feature(inherent_associated_types)] mod rules; diff --git a/crates/rules/src/rules/has_rule_set_for_role.rs b/crates/rules/src/rules/has_rule_set_for_role.rs index 8ac75ec1..bdf63110 100644 --- a/crates/rules/src/rules/has_rule_set_for_role.rs +++ b/crates/rules/src/rules/has_rule_set_for_role.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -pub trait HasRuleSetForRole: Sized + IsRole { +pub trait HasRuleSetForRole: Sized + IsRole + Clone { type Violation; /// Neither Recovery nor Confirmation roles can have factors added to their threshold @@ -8,24 +8,24 @@ pub trait HasRuleSetForRole: Sized + IsRole { fn violation_if_adding_factors_to_threshold() -> Option; fn validate_device_in_factors_list_of_kind( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, list_kind: FactorListKind, ) -> FactorBuilderResult; fn validate_password_in_factors_list_of_kind( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, list_kind: FactorListKind, ) -> FactorBuilderResult; fn validate_ledger_in_factors_list_of_kind( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, list_kind: FactorListKind, ) -> FactorBuilderResult; fn _do_validate( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, validation: impl Fn( - &RoleWithFactorsBuilt, + &RoleWithFactorsBuilt, FactorListKind, ) -> FactorBuilderResult, ) -> FactorBuilderResult { @@ -37,26 +37,24 @@ pub trait HasRuleSetForRole: Sized + IsRole { } fn validate_device( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, ) -> FactorBuilderResult { Self::_do_validate(context, Self::validate_device_in_factors_list_of_kind) } fn validate_ledger( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, ) -> FactorBuilderResult { Self::_do_validate(context, Self::validate_ledger_in_factors_list_of_kind) } fn validate_password( - context: &RoleWithFactorsBuilt, + context: &RoleWithFactorsBuilt, ) -> FactorBuilderResult { Self::_do_validate(context, Self::validate_password_in_factors_list_of_kind) } - fn validate( - context: &RoleWithFactorsBuilt, - ) -> FactorBuilderResult { + fn validate(context: &RoleWithFactorsBuilt) -> FactorBuilderResult { Self::validate_device(context)?; Self::validate_ledger(context)?; Self::validate_password(context)?; diff --git a/crates/rules/src/rules/is_role.rs b/crates/rules/src/rules/is_role.rs index c18170e6..10d77620 100644 --- a/crates/rules/src/rules/is_role.rs +++ b/crates/rules/src/rules/is_role.rs @@ -12,4 +12,4 @@ impl IsRoleObjectSafe for T { fn get_role_kind(&self) -> RoleKind { T::role_kind() } -} \ No newline at end of file +} diff --git a/crates/rules/src/rules/primary_role_with_factor_source_rule_set.rs b/crates/rules/src/rules/primary_role_with_factor_source_rule_set.rs index 3af61d32..73832999 100644 --- a/crates/rules/src/rules/primary_role_with_factor_source_rule_set.rs +++ b/crates/rules/src/rules/primary_role_with_factor_source_rule_set.rs @@ -4,7 +4,7 @@ use crate::prelude::*; pub struct PrimaryRoleWithFactorSourceRuleSet; impl IsRole for PrimaryRoleWithFactorSourceRuleSet { fn role_kind() -> RoleKind { - RoleKind::PrimaryRole + RoleKind::Primary } } @@ -20,7 +20,7 @@ impl HasRuleSetForRole for PrimaryRoleWithFactorSourceRuleSet { _list_kind: FactorListKind, ) -> FactorBuilderResult { let kind = FactorSourceKind::Device; - if context.has_factor_of_kind_in_any_list(kind) { + if context.count_factors_of_kind_in_any_list(kind) > 1 { return Err(FactorRulesViolation::ForeverInvalid( Self::Violation::MoreThanOneDeviceFactorIsNotSupported, )); @@ -34,22 +34,24 @@ impl HasRuleSetForRole for PrimaryRoleWithFactorSourceRuleSet { ) -> FactorBuilderResult { let kind = FactorSourceKind::Password; - if list_kind == FactorListKind::Override { - return FactorBuilderResult::not_yet_valid( - PrimaryRoleViolation::PasswordNotAllowedInOverrideListSinceItWouldBeAlone, - ); - } + if context.has_factor_of_kind_in_list_of_kind(kind, list_kind) { + if list_kind == FactorListKind::Override { + return FactorBuilderResult::not_yet_valid( + PrimaryRoleViolation::PasswordNotAllowedInOverrideListSinceItWouldBeAlone, + ); + } - if !context.has_factor_not_of_kind_in_list_of_kind(kind, list_kind) { - return FactorBuilderResult::not_yet_valid( - PrimaryRoleViolation::PasswordMustNotBeAlone, - ); - } + 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, - ); + if list_kind == FactorListKind::Threshold && context.threshold < 2 { + return FactorBuilderResult::not_yet_valid( + PrimaryRoleViolation::PasswordRequiresThresholdOfAtLeastTwo, + ); + } } Ok(()) diff --git a/crates/rules/src/rules/primary_role_with_factor_sources_builder.rs b/crates/rules/src/rules/primary_role_with_factor_sources_builder.rs index c2c233f5..96053d66 100644 --- a/crates/rules/src/rules/primary_role_with_factor_sources_builder.rs +++ b/crates/rules/src/rules/primary_role_with_factor_sources_builder.rs @@ -33,7 +33,9 @@ mod tests { sut.add_to_override(&f).unwrap(); assert_eq!( sut.build(), - Result::not_yet_valid(PrimaryRoleViolation::PasswordMustNotBeAlone) + Result::not_yet_valid( + PrimaryRoleViolation::PasswordNotAllowedInOverrideListSinceItWouldBeAlone + ) ); } } diff --git a/crates/rules/src/rules/role_builder_or_built.rs b/crates/rules/src/rules/role_builder_or_built.rs index ac761a87..eae976fc 100644 --- a/crates/rules/src/rules/role_builder_or_built.rs +++ b/crates/rules/src/rules/role_builder_or_built.rs @@ -8,7 +8,7 @@ impl TyEq for A {} pub type RoleWithFactorsBuilder = RoleBuilderOrBuilt>; #[derive(Clone, Debug, PartialEq, Eq)] -pub struct RoleBuilderOrBuilt { +pub struct RoleBuilderOrBuilt { role: PhantomData, built_type: PhantomData, pub threshold: u8, @@ -19,7 +19,7 @@ pub struct RoleBuilderOrBuilt { impl RoleWithFactorsBuilder where F: IsFactor, - R: HasRuleSetForRole, + R: HasRuleSetForRole + Clone, { pub fn new() -> Self { Self { @@ -35,6 +35,7 @@ where pub type BuildResult = Result; pub fn build(self) -> Self::BuildResult { + self.validate()?; Ok(self.snapshot()) } @@ -58,7 +59,7 @@ where } fn validate(&self) -> FactorBuilderResult { - Ok(()) + R::validate(&self.snapshot()) } fn violation_if_add_factor_to_list_of_kind( @@ -94,7 +95,11 @@ where } Ok(_) => {} } - self.threshold_factors.push(factor.clone()); + let factor = factor.clone(); + match list_kind { + FactorListKind::Override => self.override_factors.push(factor), + FactorListKind::Threshold => self.threshold_factors.push(factor), + } FactorBuilderResult::Ok(()) } } @@ -104,7 +109,7 @@ pub type RoleWithFactorsBuilt = RoleBuilderOrBuilt; impl RoleWithFactorsBuilt where F: IsFactor, - R: IsRoleObjectSafe, + R: IsRoleObjectSafe + Clone, { pub(super) fn new(threshold: u8, threshold_factors: Vec, override_factors: Vec) -> Self { Self { @@ -167,6 +172,14 @@ where .len() } + pub(crate) fn count_factors_of_kind_in_any_list( + &self, + factor_source_kind: FactorSourceKind, + ) -> usize { + self.factors_of_kind_in_list_of_kind(factor_source_kind, None) + .len() + } + pub(crate) fn count_factors_not_of_kind_in_list_of_kind( &self, factor_source_kind: FactorSourceKind, diff --git a/crates/rules/src/rules/role_kind.rs b/crates/rules/src/rules/role_kind.rs index dbc1fe9d..ce44acc3 100644 --- a/crates/rules/src/rules/role_kind.rs +++ b/crates/rules/src/rules/role_kind.rs @@ -1,6 +1,6 @@ #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RoleKind { - PrimaryRole, - RecoveryRole, - ConfirmationRole, -} \ No newline at end of file + Primary, + Recovery, + Confirmation, +} diff --git a/crates/rules/src/rules/role_tags.rs b/crates/rules/src/rules/role_tags.rs index df74d86a..5ba4d7c1 100644 --- a/crates/rules/src/rules/role_tags.rs +++ b/crates/rules/src/rules/role_tags.rs @@ -1,13 +1,11 @@ use crate::prelude::*; - - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct TagPrimaryRole; impl IsRole for TagPrimaryRole { fn role_kind() -> RoleKind { - RoleKind::PrimaryRole + RoleKind::Primary } } @@ -16,7 +14,7 @@ pub struct TagConfirmationRole; impl IsRole for TagConfirmationRole { fn role_kind() -> RoleKind { - RoleKind::ConfirmationRole + RoleKind::Confirmation } } @@ -25,7 +23,7 @@ pub struct TagRecoveryRole; impl IsRole for TagRecoveryRole { fn role_kind() -> RoleKind { - RoleKind::RecoveryRole + RoleKind::Recovery } } @@ -35,16 +33,16 @@ mod tests { #[test] fn is_primary_role() { - assert_eq!(TagPrimaryRole::role_kind(), RoleKind::PrimaryRole); + assert_eq!(TagPrimaryRole::role_kind(), RoleKind::Primary); } #[test] fn is_recovery_role() { - assert_eq!(TagRecoveryRole::role_kind(), RoleKind::RecoveryRole); + assert_eq!(TagRecoveryRole::role_kind(), RoleKind::Recovery); } #[test] fn is_confirmation_role() { - assert_eq!(TagConfirmationRole::role_kind(), RoleKind::ConfirmationRole); + assert_eq!(TagConfirmationRole::role_kind(), RoleKind::Confirmation); } -} \ No newline at end of file +} diff --git a/crates/rules/src/rules/sargon_types.rs b/crates/rules/src/rules/sargon_types.rs index 347149eb..908477ad 100644 --- a/crates/rules/src/rules/sargon_types.rs +++ b/crates/rules/src/rules/sargon_types.rs @@ -120,7 +120,7 @@ impl FactorSource { Self::other(FactorSourceKind::Password) } - // pub fn sample_off_device_mnemonic() -> Self { + // pub fn sample_off_device_mnemonic() -> Self { // Self::new(FactorSourceKind::OffDeviceMnemonic) // }