Skip to content

Commit

Permalink
Lenient shield builder (#315)
Browse files Browse the repository at this point in the history
  • Loading branch information
CyonAlexRDX authored Dec 20, 2024
1 parent 191f729 commit 4870dd8
Show file tree
Hide file tree
Showing 9 changed files with 513 additions and 88 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ struct ShieldTests {
builder.addFactorSourceToPrimaryThreshold(factorSourceId: .sampleDevice)
builder.addFactorSourceToPrimaryThreshold(factorSourceId: .sampleDevice) // did not get added, duplicates are not allowed
#expect(builder.primaryRoleThresholdFactors == [.sampleDevice])
builder.addFactorSourceToPrimaryThreshold(factorSourceId: .sampleDeviceOther)
builder.addFactorSourceToPrimaryThreshold(factorSourceId: .sampleDeviceOther) // actually this is added
#expect(builder.validate() == .PrimaryCannotHaveMultipleDevices)
builder.removeFactorFromPrimary(factorSourceId: .sampleDeviceOther)

#expect(builder.validate() == .RecoveryRoleMustHaveAtLeastOneFactor)
builder.removeFactorFromPrimary(factorSourceId: .sampleDeviceOther)
Expand Down Expand Up @@ -139,22 +141,26 @@ struct ShieldTests {
#expect(builder.confirmationRoleFactors.isEmpty)
}

@Test("Primary can only contain one DeviceFactorSource")
@Test("Primary can contain two DeviceFactorSource while building - but is never valid")
func primaryCanOnlyContainOneDeviceFactorSourceThreshold() throws {
let builder = SecurityShieldBuilder()
let factor = FactorSourceId.sampleDevice
let other = FactorSourceId.sampleDeviceOther
builder.addFactorSourceToPrimaryThreshold(factorSourceId: factor)
builder.addFactorSourceToPrimaryOverride(factorSourceId: other)
#expect(builder.primaryRoleThresholdFactors == [factor])
#expect(builder.primaryRoleOverrideFactors == [])
#expect(builder.primaryRoleOverrideFactors == [other])

builder.removeFactorFromPrimary(factorSourceId: factor)

builder.addFactorSourceToPrimaryOverride(factorSourceId: factor)
builder.addFactorSourceToPrimaryThreshold(factorSourceId: other)
#expect(builder.primaryRoleThresholdFactors == [])
#expect(builder.primaryRoleOverrideFactors == [factor])
#expect(builder.primaryRoleThresholdFactors == [other])
#expect(builder.primaryRoleOverrideFactors == [other, factor])

// But when validated/built is err
#expect(builder.validate() != nil)
#expect((try? builder.build()) == nil)
}

@Test("Primary password never alone")
Expand All @@ -164,7 +170,8 @@ struct ShieldTests {
#expect(builder.primaryRoleOverrideFactors.isEmpty)

builder.addFactorSourceToPrimaryThreshold(factorSourceId: .samplePassword)
#expect(builder.validate() == .PrimaryRoleWithThresholdFactorsCannotHaveAThresholdValueOfZero)
#expect(builder.validate() == .PrimaryRoleWithPasswordInThresholdListMustHaveAnotherFactor)

builder.threshold = 0
#expect(builder.validate() == .PrimaryRoleWithThresholdFactorsCannotHaveAThresholdValueOfZero)
builder.threshold = 1
Expand Down
2 changes: 1 addition & 1 deletion crates/sargon-uniffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "sargon-uniffi"
# Don't forget to update version in crates/sargon/Cargo.toml
version = "1.1.94"
version = "1.1.95"
edition = "2021"
build = "build.rs"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl SecurityShieldBuilder {
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
Arc::new(Self {
wrapped: RwLock::new(sargon::SecurityShieldBuilder::new()),
wrapped: RwLock::new(sargon::SecurityShieldBuilder::lenient()),
})
}
}
Expand Down Expand Up @@ -749,7 +749,7 @@ mod tests {
])
);

assert_ne!(
assert_eq!( // we use lenient builder, so we say state has not changed
sim_prim_threshold,
sut.validation_for_addition_of_factor_source_to_primary_threshold_for_each(
vec![
Expand Down
2 changes: 1 addition & 1 deletion crates/sargon/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "sargon"
# Don't forget to update version in crates/sargon-uniffi/Cargo.toml
version = "1.1.94"
version = "1.1.95"
edition = "2021"
build = "build.rs"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ mod tests {
SecurityStructureOfFactorSourceIDs,
AutoBuildOutcomeForTesting,
)> {
let shield_builder = SecurityShieldBuilder::new();
let shield_builder = SecurityShieldBuilder::default();
shield_builder.set_threshold(pick_primary_role_factors.len() as u8);
pick_primary_role_factors.into_iter().for_each(|f| {
shield_builder.add_factor_source_to_primary_threshold(f);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,64 +90,118 @@ impl MatrixBuilder {
pub fn validation_for_addition_of_factor_source_to_primary_threshold_for_each(
&self,
factor_sources: &IndexSet<FactorSourceID>,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.validation_for_addition_of_factor_source_to_primary_threshold_for_each_with_mode(factor_sources, SecurityShieldBuilderMode::Strict)
}

pub fn validation_for_addition_of_factor_source_to_primary_threshold_for_each_with_mode(
&self,
factor_sources: &IndexSet<FactorSourceID>,
mode: SecurityShieldBuilderMode,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.primary_role
.validation_for_addition_of_factor_source_for_each(
.validation_for_addition_of_factor_source_for_each_with_mode(
FactorListKind::Threshold,
factor_sources,
mode,
)
}

pub fn validation_for_addition_of_factor_source_to_primary_override_for_each(
&self,
factor_sources: &IndexSet<FactorSourceID>,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.validation_for_addition_of_factor_source_to_primary_override_for_each_with_mode(factor_sources, SecurityShieldBuilderMode::Strict)
}

pub fn validation_for_addition_of_factor_source_to_primary_override_for_each_with_mode(
&self,
factor_sources: &IndexSet<FactorSourceID>,
mode: SecurityShieldBuilderMode,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.primary_role
.validation_for_addition_of_factor_source_for_each(
.validation_for_addition_of_factor_source_for_each_with_mode(
FactorListKind::Override,
factor_sources,
mode,
)
}

pub fn validation_for_addition_of_factor_source_of_kind_to_recovery_override(
&self,
factor_source_kind: FactorSourceKind,
) -> RoleBuilderMutateResult {
self.validation_for_addition_of_factor_source_of_kind_to_recovery_override_with_mode(factor_source_kind, SecurityShieldBuilderMode::Strict)
}

pub fn validation_for_addition_of_factor_source_of_kind_to_recovery_override_with_mode(
&self,
factor_source_kind: FactorSourceKind,
mode: SecurityShieldBuilderMode,
) -> RoleBuilderMutateResult {
self.recovery_role
.validation_for_addition_of_factor_source_of_kind_to_override(
.validation_for_addition_of_factor_source_of_kind_to_override_with_mode(
factor_source_kind,
mode
)
}

pub fn validation_for_addition_of_factor_source_to_recovery_override_for_each(
&self,
factor_sources: &IndexSet<FactorSourceID>,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.validation_for_addition_of_factor_source_to_recovery_override_for_each_with_mode(factor_sources, SecurityShieldBuilderMode::Strict)
}

pub fn validation_for_addition_of_factor_source_to_recovery_override_for_each_with_mode(
&self,
factor_sources: &IndexSet<FactorSourceID>,
mode: SecurityShieldBuilderMode,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.recovery_role
.validation_for_addition_of_factor_source_for_each(
.validation_for_addition_of_factor_source_for_each_with_mode(
FactorListKind::Override,
factor_sources,
mode,
)
}

pub fn validation_for_addition_of_factor_source_of_kind_to_confirmation_override(
&self,
factor_source_kind: FactorSourceKind,
) -> RoleBuilderMutateResult {
self.validation_for_addition_of_factor_source_of_kind_to_confirmation_override_with_mode(factor_source_kind, SecurityShieldBuilderMode::Strict)
}

pub fn validation_for_addition_of_factor_source_of_kind_to_confirmation_override_with_mode(
&self,
factor_source_kind: FactorSourceKind,
mode: SecurityShieldBuilderMode,
) -> RoleBuilderMutateResult {
self.confirmation_role
.validation_for_addition_of_factor_source_of_kind_to_override(
.validation_for_addition_of_factor_source_of_kind_to_override_with_mode(
factor_source_kind,
mode
)
}

pub fn validation_for_addition_of_factor_source_to_confirmation_override_for_each(
&self,
factor_sources: &IndexSet<FactorSourceID>,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.validation_for_addition_of_factor_source_to_confirmation_override_for_each_with_mode(factor_sources, SecurityShieldBuilderMode::Strict)
}

pub fn validation_for_addition_of_factor_source_to_confirmation_override_for_each_with_mode(
&self,
factor_sources: &IndexSet<FactorSourceID>,
mode: SecurityShieldBuilderMode,
) -> IndexSet<FactorSourceInRoleBuilderValidationStatus> {
self.confirmation_role
.validation_for_addition_of_factor_source_for_each(
.validation_for_addition_of_factor_source_for_each_with_mode(
FactorListKind::Override,
factor_sources,
mode,
)
}

Expand Down Expand Up @@ -198,9 +252,20 @@ impl MatrixBuilder {
pub fn add_factor_source_to_primary_threshold(
&mut self,
factor_source_id: FactorSourceID,
) -> MatrixBuilderMutateResult {
self.add_factor_source_to_primary_threshold_with_mode(
factor_source_id,
SecurityShieldBuilderMode::Strict,
)
}

pub fn add_factor_source_to_primary_threshold_with_mode(
&mut self,
factor_source_id: FactorSourceID,
mode: SecurityShieldBuilderMode,
) -> MatrixBuilderMutateResult {
self.primary_role
.add_factor_source_to_threshold(factor_source_id)
.add_factor_source_to_threshold_with_mode(factor_source_id, mode)
.into_matrix_err(RoleKind::Primary)
}

Expand All @@ -218,27 +283,61 @@ impl MatrixBuilder {
pub fn add_factor_source_to_primary_override(
&mut self,
factor_source_id: FactorSourceID,
) -> MatrixBuilderMutateResult {
self.add_factor_source_to_primary_override_with_mode(
factor_source_id,
SecurityShieldBuilderMode::Strict,
)
}

/// Adds the factor source to the primary role override list.
pub fn add_factor_source_to_primary_override_with_mode(
&mut self,
factor_source_id: FactorSourceID,
mode: SecurityShieldBuilderMode,
) -> MatrixBuilderMutateResult {
self.primary_role
.add_factor_source_to_override(factor_source_id)
.add_factor_source_to_override_with_mode(factor_source_id, mode)
.into_matrix_err(RoleKind::Primary)
}

pub fn add_factor_source_to_recovery_override(
&mut self,
factor_source_id: FactorSourceID,
) -> MatrixBuilderMutateResult {
self.add_factor_source_to_recovery_override_with_mode(
factor_source_id,
SecurityShieldBuilderMode::Strict,
)
}

pub fn add_factor_source_to_recovery_override_with_mode(
&mut self,
factor_source_id: FactorSourceID,
mode: SecurityShieldBuilderMode,
) -> MatrixBuilderMutateResult {
self.recovery_role
.add_factor_source_to_override(factor_source_id)
.add_factor_source_to_override_with_mode(factor_source_id, mode)
.into_matrix_err(RoleKind::Recovery)
}

pub fn add_factor_source_to_confirmation_override(
&mut self,
factor_source_id: FactorSourceID,
) -> MatrixBuilderMutateResult {
self.add_factor_source_to_confirmation_override_with_mode(
factor_source_id,
SecurityShieldBuilderMode::Strict,
)
}

pub fn add_factor_source_to_confirmation_override_with_mode(
&mut self,
factor_source_id: FactorSourceID,
mode: SecurityShieldBuilderMode,
) -> MatrixBuilderMutateResult {
self.confirmation_role
.add_factor_source_to_override(factor_source_id)
.add_factor_source_to_override_with_mode(factor_source_id, mode)
.into_matrix_err(RoleKind::Confirmation)
}

Expand Down
Loading

0 comments on commit 4870dd8

Please sign in to comment.