test(credentials): 完成 B-03 生命周期验收
This commit is contained in:
@@ -1118,4 +1118,40 @@ mod tests {
|
||||
assert!(broker.unlock(password()).is_err());
|
||||
assert_eq!(fs::read(path).unwrap(), b"corrupt");
|
||||
}
|
||||
#[test]
|
||||
fn b03_unrecoverable_store_does_not_block_local_editing() {
|
||||
let temp = tempfile::tempdir().unwrap();
|
||||
let path = temp.path().join("credentials.v1");
|
||||
fs::write(&path, b"unrecoverable-credential-store").unwrap();
|
||||
let mut broker = CredentialBroker::new(path.clone());
|
||||
assert_eq!(
|
||||
broker.unlock(password()).unwrap_err(),
|
||||
"SCHEMA_INCOMPATIBLE"
|
||||
);
|
||||
assert!(broker.is_locked());
|
||||
assert_eq!(fs::read(&path).unwrap(), b"unrecoverable-credential-store");
|
||||
|
||||
let vault = tempfile::tempdir().unwrap();
|
||||
let mut workspace = crate::workspace::Workspace::open(vault.path()).unwrap();
|
||||
let saved = workspace
|
||||
.write(
|
||||
"still-editable.md",
|
||||
"",
|
||||
b"local notes remain available",
|
||||
"local",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
workspace.read("still-editable.md").unwrap().content,
|
||||
"local notes remain available"
|
||||
);
|
||||
assert_eq!(
|
||||
fs::read(vault.path().join("still-editable.md")).unwrap(),
|
||||
b"local notes remain available"
|
||||
);
|
||||
assert_eq!(
|
||||
saved.hash,
|
||||
crate::workspace::hash(b"local notes remain available")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1081,7 +1081,7 @@ mod lifecycle_tests {
|
||||
let worker = scope.spawn(|| host.lock_credentials());
|
||||
let start = std::time::Instant::now();
|
||||
while credentials.load(Ordering::SeqCst) == 0
|
||||
&& start.elapsed() < Duration::from_secs(2)
|
||||
&& start.elapsed() < Duration::from_secs(1)
|
||||
{
|
||||
std::thread::sleep(Duration::from_millis(1));
|
||||
}
|
||||
@@ -1092,6 +1092,7 @@ mod lifecycle_tests {
|
||||
worker.join().unwrap().unwrap();
|
||||
assert!(observed > 0);
|
||||
assert!(revoked > 0);
|
||||
assert!(start.elapsed() < Duration::from_secs(1));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,13 @@ impl Drop for SessionMonitor {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::credentials::{CredentialBroker, CredentialId, Scope};
|
||||
use std::time::{Duration, Instant};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
fn password() -> Zeroizing<Vec<u8>> {
|
||||
Zeroizing::new(b"b03-test-password-123".to_vec())
|
||||
}
|
||||
#[test]
|
||||
fn native_message_revokes_without_unlocking_on_session_return() {
|
||||
let signal = Arc::new(AtomicU64::new(0));
|
||||
@@ -166,6 +173,39 @@ mod tests {
|
||||
assert_eq!(signal.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
#[test]
|
||||
fn b03_native_and_manual_lock_reject_new_resolves_within_one_second() {
|
||||
let temp = tempfile::tempdir().unwrap();
|
||||
let mut broker = CredentialBroker::new(temp.path().join("credentials.v1"));
|
||||
broker.unlock(password()).unwrap();
|
||||
let id = CredentialId::legacy("b03-provider");
|
||||
broker
|
||||
.put(&id, Zeroizing::new(b"b03-lock-fixture".to_vec()))
|
||||
.unwrap();
|
||||
let signal = broker.lock_signal();
|
||||
let monitor = SessionMonitor::start(signal).unwrap();
|
||||
|
||||
let started = Instant::now();
|
||||
unsafe {
|
||||
SendMessageW(
|
||||
monitor.window as HWND,
|
||||
WM_WTSSESSION_CHANGE,
|
||||
WTS_SESSION_LOCK as usize,
|
||||
0,
|
||||
);
|
||||
}
|
||||
let error = broker.resolve(&Scope::Provider, &id).unwrap_err();
|
||||
assert_eq!(error, "CREDENTIALS_LOCKED");
|
||||
assert!(started.elapsed() < Duration::from_secs(1));
|
||||
|
||||
broker.unlock(password()).unwrap();
|
||||
let started = Instant::now();
|
||||
broker.lock();
|
||||
let error = broker.resolve(&Scope::Provider, &id).unwrap_err();
|
||||
assert_eq!(error, "CREDENTIALS_LOCKED");
|
||||
assert!(started.elapsed() < Duration::from_secs(1));
|
||||
drop(monitor);
|
||||
}
|
||||
#[test]
|
||||
fn native_lock_logoff_and_disconnect_revoke_every_bound_domain() {
|
||||
let credential = Arc::new(AtomicU64::new(0));
|
||||
let extension = Arc::new(AtomicU64::new(0));
|
||||
|
||||
Reference in New Issue
Block a user