v0.5.2-pre.006-fix-010
This commit is contained in:
90
ks-wallet-demo-scenarios/tests/password_lifecycle.rs
Normal file
90
ks-wallet-demo-scenarios/tests/password_lifecycle.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
// file: ks-wallet-demo-scenarios/tests/password_lifecycle.rs
|
||||
// version: 1
|
||||
|
||||
//! External ordered password lifecycle scenario.
|
||||
|
||||
const PASSWORD_A: &str = "ks-wallet-demo-password-A";
|
||||
const PASSWORD_B: &str = "ks-wallet-demo-password-B";
|
||||
const CHALLENGE_B: &[u8] = b"ks-wallet-demo-scenarios password-B signing proof";
|
||||
const CHALLENGE_A_RESTORED: &[u8] = b"ks-wallet-demo-scenarios restored password-A signing proof";
|
||||
|
||||
fn make_directory_private(path: &std::path::Path) {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt; // rust-rules: trait-import
|
||||
std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o700)).unwrap_or_else(
|
||||
|error| panic!("wallet scenario directory permissions must be set: {error}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn password(value: &str) -> ks_wallet::WalletPassword {
|
||||
return ks_wallet::WalletPassword::new(value.to_owned())
|
||||
.unwrap_or_else(|error| panic!("scenario password must be accepted: {error}"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn password_rotation_runs_a_to_b_rejects_a_then_restores_a() {
|
||||
let directory = tempfile::tempdir()
|
||||
.unwrap_or_else(|error| panic!("temporary scenario directory must exist: {error}"));
|
||||
make_directory_private(directory.path());
|
||||
let manager = ks_wallet::WalletManager::new(directory.path())
|
||||
.unwrap_or_else(|error| panic!("wallet manager must be created: {error}"));
|
||||
let alias = ks_wallet::WalletAlias::parse("password-lifecycle")
|
||||
.unwrap_or_else(|error| panic!("scenario alias must be valid: {error}"));
|
||||
let created = manager
|
||||
.create(alias.clone(), password(PASSWORD_A))
|
||||
.await
|
||||
.unwrap_or_else(|error| panic!("scenario wallet creation must succeed: {error}"));
|
||||
let initial_public_key = created.public_key();
|
||||
created.lock();
|
||||
let rotated_to_b = ks_wallet_demo_scenarios::rotate_wallet_password(
|
||||
&manager,
|
||||
&alias,
|
||||
password(PASSWORD_A),
|
||||
password(PASSWORD_B),
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|error| panic!("password A to B rotation must succeed: {error}"));
|
||||
assert_eq!(rotated_to_b.identity.public_key, initial_public_key);
|
||||
let rejected_a = ks_wallet_demo_scenarios::expect_wallet_password_rejected(
|
||||
&manager,
|
||||
&alias,
|
||||
password(PASSWORD_A),
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|error| panic!("old password A must be rejected: {error}"));
|
||||
assert_eq!(rejected_a.identity.public_key, initial_public_key);
|
||||
assert_eq!(rejected_a.rejection_code, "wallet_native_authentication_failed");
|
||||
let signed_with_b = ks_wallet_demo_scenarios::unlock_and_sign_wallet(
|
||||
&manager,
|
||||
&alias,
|
||||
password(PASSWORD_B),
|
||||
CHALLENGE_B,
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|error| panic!("password B must unlock and sign: {error}"));
|
||||
assert_eq!(signed_with_b.identity.public_key, initial_public_key);
|
||||
assert_eq!(signed_with_b.message_length, CHALLENGE_B.len());
|
||||
assert!(!signed_with_b.signature.is_empty());
|
||||
let restored_to_a = ks_wallet_demo_scenarios::rotate_wallet_password(
|
||||
&manager,
|
||||
&alias,
|
||||
password(PASSWORD_B),
|
||||
password(PASSWORD_A),
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|error| panic!("password B to A restoration must succeed: {error}"));
|
||||
assert_eq!(restored_to_a.identity.public_key, initial_public_key);
|
||||
let signed_with_restored_a = ks_wallet_demo_scenarios::unlock_and_sign_wallet(
|
||||
&manager,
|
||||
&alias,
|
||||
password(PASSWORD_A),
|
||||
CHALLENGE_A_RESTORED,
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|error| panic!("restored password A must unlock and sign: {error}"));
|
||||
assert_eq!(signed_with_restored_a.identity.public_key, initial_public_key);
|
||||
assert_eq!(signed_with_restored_a.message_length, CHALLENGE_A_RESTORED.len());
|
||||
assert!(!signed_with_restored_a.signature.is_empty());
|
||||
}
|
||||
Reference in New Issue
Block a user