mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-30 01:19:34 +00:00
fix(agent): block thread_id-based context pollution across users (#760)
* fix(agent): prevent forged thread UUID context/write contamination * fix(agent): close thread_id race and reject forged UUID hydration * fix(ci): satisfy clippy and fmt checks after rebase
This commit is contained in:
+56
-6
@@ -641,14 +641,20 @@ mod tests {
|
||||
let conv_id = uuid::Uuid::new_v4();
|
||||
|
||||
// ensure_conversation should create the row.
|
||||
db.ensure_conversation(conv_id, "web", "carol", None)
|
||||
.await
|
||||
.expect("ensure first");
|
||||
assert!(
|
||||
db.ensure_conversation(conv_id, "web", "carol", None)
|
||||
.await
|
||||
.expect("ensure first"),
|
||||
"first ensure_conversation should create the row"
|
||||
);
|
||||
|
||||
// Calling again with the same ID should not error.
|
||||
db.ensure_conversation(conv_id, "web", "carol", None)
|
||||
.await
|
||||
.expect("ensure second (idempotent)");
|
||||
assert!(
|
||||
db.ensure_conversation(conv_id, "web", "carol", None)
|
||||
.await
|
||||
.expect("ensure second (idempotent)"),
|
||||
"second ensure_conversation should touch owned row"
|
||||
);
|
||||
|
||||
// Should be able to add messages to it.
|
||||
let msg_id = db
|
||||
@@ -666,6 +672,50 @@ mod tests {
|
||||
assert_eq!(msgs[0].content, "test message");
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsql")]
|
||||
#[tokio::test]
|
||||
async fn test_ensure_conversation_foreign_conflict_does_not_touch_last_activity() {
|
||||
let harness = TestHarnessBuilder::new().build().await;
|
||||
let db = &harness.db;
|
||||
|
||||
let conv_id = db
|
||||
.create_conversation("web", "alice", None)
|
||||
.await
|
||||
.expect("create conversation");
|
||||
|
||||
let before = db
|
||||
.list_conversations_all_channels("alice", 10)
|
||||
.await
|
||||
.expect("list conversations before foreign ensure")
|
||||
.into_iter()
|
||||
.find(|c| c.id == conv_id)
|
||||
.expect("conversation must exist before foreign ensure")
|
||||
.last_activity;
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_millis(25)).await;
|
||||
|
||||
assert!(
|
||||
!db.ensure_conversation(conv_id, "web", "mallory", None)
|
||||
.await
|
||||
.expect("foreign ensure should not error"),
|
||||
"foreign ensure_conversation should report not ensured"
|
||||
);
|
||||
|
||||
let after = db
|
||||
.list_conversations_all_channels("alice", 10)
|
||||
.await
|
||||
.expect("list conversations after foreign ensure")
|
||||
.into_iter()
|
||||
.find(|c| c.id == conv_id)
|
||||
.expect("conversation must still exist after foreign ensure")
|
||||
.last_activity;
|
||||
|
||||
assert_eq!(
|
||||
after, before,
|
||||
"foreign ensure_conversation should not mutate last_activity"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsql")]
|
||||
#[tokio::test]
|
||||
async fn test_paginated_messages() {
|
||||
|
||||
Reference in New Issue
Block a user