Skip to content

Commit

Permalink
fix validation
Browse files Browse the repository at this point in the history
  • Loading branch information
CyonAlexRDX committed Nov 22, 2024
1 parent f7a6fbd commit 065227f
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 49 deletions.
1 change: 1 addition & 0 deletions crates/rules-uniffi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions crates/rules/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(associated_type_defaults)]
#![allow(incomplete_features)]
#![feature(inherent_associated_types)]

mod rules;
Expand Down
22 changes: 10 additions & 12 deletions crates/rules/src/rules/has_rule_set_for_role.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
use crate::prelude::*;

pub trait HasRuleSetForRole<F: IsFactor>: Sized + IsRole {
pub trait HasRuleSetForRole<F: IsFactor>: Sized + IsRole + Clone {
type Violation;

/// Neither Recovery nor Confirmation roles can have factors added to their threshold
/// factor list. Only Primary supports it.
fn violation_if_adding_factors_to_threshold() -> Option<Self::Violation>;

fn validate_device_in_factors_list_of_kind(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation>;

fn validate_password_in_factors_list_of_kind(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation>;

fn validate_ledger_in_factors_list_of_kind(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation>;

fn _do_validate(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
validation: impl Fn(
&RoleWithFactorsBuilt<FactorSource, Self>,
&RoleWithFactorsBuilt<F, Self>,
FactorListKind,
) -> FactorBuilderResult<Self::Violation>,
) -> FactorBuilderResult<Self::Violation> {
Expand All @@ -37,26 +37,24 @@ pub trait HasRuleSetForRole<F: IsFactor>: Sized + IsRole {
}

fn validate_device(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
) -> FactorBuilderResult<Self::Violation> {
Self::_do_validate(context, Self::validate_device_in_factors_list_of_kind)
}

fn validate_ledger(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
) -> FactorBuilderResult<Self::Violation> {
Self::_do_validate(context, Self::validate_ledger_in_factors_list_of_kind)
}

fn validate_password(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
context: &RoleWithFactorsBuilt<F, Self>,
) -> FactorBuilderResult<Self::Violation> {
Self::_do_validate(context, Self::validate_password_in_factors_list_of_kind)
}

fn validate(
context: &RoleWithFactorsBuilt<FactorSource, Self>,
) -> FactorBuilderResult<Self::Violation> {
fn validate(context: &RoleWithFactorsBuilt<F, Self>) -> FactorBuilderResult<Self::Violation> {
Self::validate_device(context)?;
Self::validate_ledger(context)?;
Self::validate_password(context)?;
Expand Down
2 changes: 1 addition & 1 deletion crates/rules/src/rules/is_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ impl<T: IsRole> IsRoleObjectSafe for T {
fn get_role_kind(&self) -> RoleKind {
T::role_kind()
}
}
}
34 changes: 18 additions & 16 deletions crates/rules/src/rules/primary_role_with_factor_source_rule_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::prelude::*;
pub struct PrimaryRoleWithFactorSourceRuleSet;
impl IsRole for PrimaryRoleWithFactorSourceRuleSet {
fn role_kind() -> RoleKind {
RoleKind::PrimaryRole
RoleKind::Primary
}
}

Expand All @@ -20,7 +20,7 @@ impl HasRuleSetForRole<FactorSource> for PrimaryRoleWithFactorSourceRuleSet {
_list_kind: FactorListKind,
) -> FactorBuilderResult<Self::Violation> {
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,
));
Expand All @@ -34,22 +34,24 @@ impl HasRuleSetForRole<FactorSource> for PrimaryRoleWithFactorSourceRuleSet {
) -> FactorBuilderResult<Self::Violation> {
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(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
);
}
}
23 changes: 18 additions & 5 deletions crates/rules/src/rules/role_builder_or_built.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ impl<A> TyEq<A> for A {}
pub type RoleWithFactorsBuilder<F, R> = RoleBuilderOrBuilt<F, R, RoleWithFactorsBuilt<F, R>>;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RoleBuilderOrBuilt<F: IsFactor, R: IsRoleObjectSafe, B> {
pub struct RoleBuilderOrBuilt<F: IsFactor, R: IsRoleObjectSafe + Clone, B> {
role: PhantomData<R>,
built_type: PhantomData<B>,
pub threshold: u8,
Expand All @@ -19,7 +19,7 @@ pub struct RoleBuilderOrBuilt<F: IsFactor, R: IsRoleObjectSafe, B> {
impl<F, R> RoleWithFactorsBuilder<F, R>
where
F: IsFactor,
R: HasRuleSetForRole<F>,
R: HasRuleSetForRole<F> + Clone,
{
pub fn new() -> Self {
Self {
Expand All @@ -35,6 +35,7 @@ where
pub type BuildResult = Result<Self::Built, R::Violation>;

pub fn build(self) -> Self::BuildResult {
self.validate()?;
Ok(self.snapshot())
}

Expand All @@ -58,7 +59,7 @@ where
}

fn validate(&self) -> FactorBuilderResult<R::Violation> {
Ok(())
R::validate(&self.snapshot())
}

fn violation_if_add_factor_to_list_of_kind(
Expand Down Expand Up @@ -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(())
}
}
Expand All @@ -104,7 +109,7 @@ pub type RoleWithFactorsBuilt<F, R> = RoleBuilderOrBuilt<F, R, ()>;
impl<F, R> RoleWithFactorsBuilt<F, R>
where
F: IsFactor,
R: IsRoleObjectSafe,
R: IsRoleObjectSafe + Clone,
{
pub(super) fn new(threshold: u8, threshold_factors: Vec<F>, override_factors: Vec<F>) -> Self {
Self {
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions crates/rules/src/rules/role_kind.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RoleKind {
PrimaryRole,
RecoveryRole,
ConfirmationRole,
}
Primary,
Recovery,
Confirmation,
}
16 changes: 7 additions & 9 deletions crates/rules/src/rules/role_tags.rs
Original file line number Diff line number Diff line change
@@ -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
}
}

Expand All @@ -16,7 +14,7 @@ pub struct TagConfirmationRole;

impl IsRole for TagConfirmationRole {
fn role_kind() -> RoleKind {
RoleKind::ConfirmationRole
RoleKind::Confirmation
}
}

Expand All @@ -25,7 +23,7 @@ pub struct TagRecoveryRole;

impl IsRole for TagRecoveryRole {
fn role_kind() -> RoleKind {
RoleKind::RecoveryRole
RoleKind::Recovery
}
}

Expand All @@ -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);
}
}
}
2 changes: 1 addition & 1 deletion crates/rules/src/rules/sargon_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
// }

Expand Down

0 comments on commit 065227f

Please sign in to comment.