#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::panic
)]
use webauthn_kit::challenge::ChallengeStore;
use webauthn_kit::policy::{
AttestationConveyance, BackupPolicy, CredentialPolicy, ResidentKeyPolicy,
UserVerificationPolicy,
};
use webauthn_kit::{AttestationPolicy, WebauthnConfig};
fn distinctive_config() -> WebauthnConfig {
WebauthnConfig {
rp_id: "matrix.example.com".to_string(),
rp_name: "Matrix RP".to_string(),
rp_origins: vec!["https://matrix.example.com".to_string()],
allowed_algorithms: vec![-8],
challenge_timeout_secs: 60,
attestation: AttestationPolicy::default(),
credential_policy: CredentialPolicy {
user_verification: UserVerificationPolicy::Required,
backup: BackupPolicy::RequireDeviceBound,
allowed_algorithms: vec![-7],
},
resident_key: ResidentKeyPolicy::Required,
attestation_conveyance: AttestationConveyance::Direct,
}
}
fn options_of(config: &WebauthnConfig) -> webauthn_kit::RegistrationOptions {
let store = ChallengeStore::new();
let (_, options) = store.generate_registration_challenge(config, "alice", "Alice", &[]);
options
}
#[test]
fn knob_rp_id_reaches_registration_options() {
let options = options_of(&distinctive_config());
assert_eq!(options.rp.id, "matrix.example.com");
let options = options_of(&WebauthnConfig::default());
assert_eq!(options.rp.id, "localhost");
assert_ne!(
options_of(&distinctive_config()).rp.id,
options_of(&WebauthnConfig::default()).rp.id
);
}
#[test]
fn knob_rp_name_reaches_registration_options() {
assert_eq!(options_of(&distinctive_config()).rp.name, "Matrix RP");
assert_eq!(
options_of(&WebauthnConfig::default()).rp.name,
"webauthn-kit"
);
}
#[test]
fn knob_rp_origins_carried_without_normalization() {
let config = distinctive_config();
assert_eq!(
config.rp_origins,
vec!["https://matrix.example.com".to_string()]
);
assert_ne!(config.rp_origins, WebauthnConfig::default().rp_origins);
}
#[test]
fn knob_allowed_algorithms_advertised_in_options() {
let algs: Vec<i32> = options_of(&distinctive_config())
.pub_key_cred_params
.iter()
.map(|p| p.alg)
.collect();
assert_eq!(algs, vec![-8], "advertised set must match the config");
let default_algs: Vec<i32> = options_of(&WebauthnConfig::default())
.pub_key_cred_params
.iter()
.map(|p| p.alg)
.collect();
assert_eq!(default_algs, vec![-257, -35, -7]);
let mut sorted = default_algs.clone();
sorted.sort();
assert_eq!(sorted, vec![-257, -35, -7]);
}
#[test]
fn knob_challenge_timeout_reaches_options_in_ms() {
assert_eq!(options_of(&distinctive_config()).timeout, 60_000);
assert_eq!(options_of(&WebauthnConfig::default()).timeout, 300_000);
}
#[test]
fn knob_attestation_default_is_strict() {
let policy = AttestationPolicy::default();
assert!(policy.trust_anchors.is_empty());
assert!(!policy.allow_unknown_formats);
}
#[test]
fn knob_attestation_strict_constructor_matches_default() {
assert_eq!(
format!("{:?}", AttestationPolicy::strict()),
format!("{:?}", AttestationPolicy::default())
);
}
#[test]
fn knob_credential_policy_uv_conveyed_into_options() {
let options = options_of(&distinctive_config());
assert_eq!(
options.authenticator_selection.user_verification,
"required"
);
let options = options_of(&WebauthnConfig::default());
assert_eq!(
options.authenticator_selection.user_verification,
"preferred"
);
}
#[test]
fn knob_credential_policy_strict_preset_differs_from_default() {
let strict = CredentialPolicy::strict();
let permissive = CredentialPolicy::default();
assert_ne!(strict, permissive);
assert_eq!(strict.user_verification, UserVerificationPolicy::Required);
assert_eq!(strict.backup, BackupPolicy::RequireDeviceBound);
assert!(!strict.allowed_algorithms.is_empty());
assert!(permissive.allowed_algorithms.is_empty());
}
#[test]
fn knob_resident_key_conveyed_into_options() {
let options = options_of(&distinctive_config());
assert_eq!(options.authenticator_selection.resident_key, "required");
assert!(options.authenticator_selection.require_resident_key);
let options = options_of(&WebauthnConfig::default());
assert_eq!(options.authenticator_selection.resident_key, "preferred");
}
#[test]
fn knob_attestation_conveyance_conveyed_into_options() {
assert_eq!(options_of(&distinctive_config()).attestation, "direct");
assert_eq!(options_of(&WebauthnConfig::default()).attestation, "none");
}