20230220 passkey cleanup (#1396)

* Migrate from cred to passkey
* Start to cleanup for removal of the legacy passkey type
This commit is contained in:
Firstyear 2023-02-20 17:50:49 +10:00 committed by GitHub
parent cd5daf2f1c
commit 8ce3e81123
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 14 deletions

View file

@ -565,7 +565,7 @@ pub const JSON_SYSTEM_INFO_V1: &str = r#"{
"class": ["object", "system_info", "system"], "class": ["object", "system_info", "system"],
"uuid": ["00000000-0000-0000-0000-ffffff000001"], "uuid": ["00000000-0000-0000-0000-ffffff000001"],
"description": ["System (local) info and metadata object."], "description": ["System (local) info and metadata object."],
"version": ["10"] "version": ["11"]
} }
}"#; }"#;

View file

@ -918,16 +918,6 @@ impl Credential {
Password::new(policy, cleartext).map(Self::new_from_generatedpassword) Password::new(policy, cleartext).map(Self::new_from_generatedpassword)
} }
/// Create a new credential that contains a CredentialType::Webauthn
pub fn new_passkey_only(label: String, cred: Passkey) -> Self {
let mut webauthn_map = Map::new();
webauthn_map.insert(label, cred);
Credential {
type_: CredentialType::Webauthn(webauthn_map),
uuid: Uuid::new_v4(),
}
}
/// Update the state of the Password on this credential, if a password is present. If possible /// Update the state of the Password on this credential, if a password is present. If possible
/// this will convert the credential to a PasswordMFA in some cases, or fail in others. /// this will convert the credential to a PasswordMFA in some cases, or fail in others.
pub fn set_password( pub fn set_password(

View file

@ -1584,8 +1584,7 @@ mod tests {
let jws_signer = create_jwt_signer(); let jws_signer = create_jwt_signer();
// Now create the credential for the account. // Now create the credential for the account.
let cred = Credential::new_passkey_only("soft".to_string(), wan_cred); account.passkeys = btreemap![(Uuid::new_v4(), ("soft".to_string(), wan_cred))];
account.primary = Some(cred);
// now check correct mech was offered. // now check correct mech was offered.

View file

@ -92,6 +92,10 @@ impl QueryServer {
if system_info_version < 10 { if system_info_version < 10 {
migrate_txn.migrate_9_to_10()?; migrate_txn.migrate_9_to_10()?;
} }
if system_info_version < 11 {
migrate_txn.migrate_10_to_11()?;
}
} }
migrate_txn.commit()?; migrate_txn.commit()?;
@ -279,6 +283,55 @@ impl<'a> QueryServerWriteTransaction<'a> {
// Complete // Complete
} }
/// Migrate 10 to 11
///
/// This forces a load of all credentials, and then examines if any are "passkey" capable. If they
/// are, they are migrated to the passkey type, allowing us to deprecate and remove the older
/// credential behaviour.
///
#[instrument(level = "debug", skip_all)]
pub fn migrate_10_to_11(&mut self) -> Result<(), OperationError> {
admin_warn!("starting 9 to 10 migration.");
let filter = filter!(f_pres("primary_credential"));
let pre_candidates = self.internal_search(filter).map_err(|e| {
admin_error!(err = ?e, "migrate_10_to_11 internal search failure");
e
})?;
// First, filter based on if any credentials present actually are the legacy
// webauthn type.
let modset: Vec<_> = pre_candidates
.into_iter()
.filter_map(|ent| {
ent.get_ava_single_credential("primary_credential")
.and_then(|cred| cred.passkey_ref().ok())
.map(|pk_map| {
let modlist = pk_map
.iter()
.map(|(t, k)| {
Modify::Present(
"passkeys".into(),
Value::Passkey(Uuid::new_v4(), t.clone(), k.clone()),
)
})
.chain(std::iter::once(m_purge("primary_credential")))
.collect();
(ent.get_uuid(), ModifyList::new_list(modlist))
})
})
.collect();
// If there is nothing, we don't need to do anything.
if modset.is_empty() {
admin_info!("migrate_10_to_11 no entries to migrate, complete");
return Ok(());
}
// Apply the batch mod.
self.internal_batch_modify(modset.into_iter())
}
#[instrument(level = "info", skip_all)] #[instrument(level = "info", skip_all)]
pub fn initialise_schema_core(&mut self) -> Result<(), OperationError> { pub fn initialise_schema_core(&mut self) -> Result<(), OperationError> {
admin_debug!("initialise_schema_core -> start ..."); admin_debug!("initialise_schema_core -> start ...");

View file

@ -61,7 +61,9 @@ pub fn apply_profile() {
match profile_cfg.cpu_flags { match profile_cfg.cpu_flags {
CpuOptLevel::none => {} CpuOptLevel::none => {}
CpuOptLevel::native => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-cpu=native"), CpuOptLevel::native => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-cpu=native"),
CpuOptLevel::neon_v8 => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-features=+neon,+fp-armv8"), CpuOptLevel::neon_v8 => {
println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-features=+neon,+fp-armv8")
}
CpuOptLevel::x86_64_v2 => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-cpu=x86-64-v2"), CpuOptLevel::x86_64_v2 => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-cpu=x86-64-v2"),
CpuOptLevel::x86_64_v3 => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-cpu=x86-64-v3"), CpuOptLevel::x86_64_v3 => println!("cargo:rustc-env=RUSTFLAGS=-Ctarget-cpu=x86-64-v3"),
} }