Skip to content

Commit 4c519b2

Browse files
server/collection: Add item creation tests
1 parent 9449951 commit 4c519b2

2 files changed

Lines changed: 184 additions & 3 deletions

File tree

server/src/collection.rs

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,182 @@ impl Collection {
336336
Ok(())
337337
}
338338
}
339+
340+
#[cfg(test)]
341+
mod tests {
342+
use std::sync::Arc;
343+
344+
use oo7::dbus;
345+
346+
use super::*;
347+
348+
/// Helper to create a peer-to-peer connection pair using Unix socket
349+
async fn create_p2p_connection() -> (zbus::Connection, zbus::Connection) {
350+
let guid = zbus::Guid::generate();
351+
let (p0, p1) = tokio::net::UnixStream::pair().unwrap();
352+
353+
let (client_conn, server_conn) = tokio::try_join!(
354+
zbus::connection::Builder::unix_stream(p0).p2p().build(),
355+
zbus::connection::Builder::unix_stream(p1)
356+
.server(guid)
357+
.unwrap()
358+
.p2p()
359+
.build(),
360+
)
361+
.unwrap();
362+
363+
(server_conn, client_conn)
364+
}
365+
366+
#[tokio::test]
367+
async fn create_item_plain() {
368+
let (server_conn, client_conn) = create_p2p_connection().await;
369+
370+
let _server = Service::run_with_connection(
371+
server_conn,
372+
Some(oo7::Secret::from("test-password-long-enough")),
373+
)
374+
.await
375+
.unwrap();
376+
377+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
378+
379+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
380+
381+
// Open plain session
382+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
383+
384+
// Get default collection
385+
let collections = service_api.collections().await.unwrap();
386+
387+
// Create an item using the proper API
388+
let secret = oo7::Secret::text("my-secret-password");
389+
let attributes = &[("application", "test-app"), ("type", "password")];
390+
let dbus_secret = dbus::api::DBusSecret::new(Arc::new(session), secret.clone());
391+
392+
let item = collections[0]
393+
.create_item("Test Item", attributes, &dbus_secret, false, None)
394+
.await
395+
.unwrap();
396+
397+
// Verify item exists in collection
398+
let items = collections[0].items().await.unwrap();
399+
assert_eq!(items.len(), 1, "Collection should have one item");
400+
assert_eq!(items[0].inner().path(), item.inner().path());
401+
402+
// Verify item label
403+
let label = item.label().await.unwrap();
404+
assert_eq!(label, "Test Item");
405+
}
406+
407+
#[tokio::test]
408+
async fn create_item_encrypted() {
409+
let (server_conn, client_conn) = create_p2p_connection().await;
410+
411+
let _server = Service::run_with_connection(
412+
server_conn,
413+
Some(oo7::Secret::from("test-password-long-enough")),
414+
)
415+
.await
416+
.unwrap();
417+
418+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
419+
420+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
421+
422+
// Open encrypted session
423+
let client_private_key = oo7::Key::generate_private_key().unwrap();
424+
let client_public_key = oo7::Key::generate_public_key(&client_private_key).unwrap();
425+
426+
let (server_public_key_opt, session) = service_api
427+
.open_session(Some(client_public_key))
428+
.await
429+
.unwrap();
430+
431+
let server_public_key = server_public_key_opt.unwrap();
432+
let aes_key = oo7::Key::generate_aes_key(&client_private_key, &server_public_key).unwrap();
433+
434+
// Get default collection
435+
let collections = service_api.collections().await.unwrap();
436+
437+
// Create an encrypted item using the proper API
438+
let secret = oo7::Secret::text("my-encrypted-secret");
439+
let attributes = &[("application", "test-app"), ("type", "encrypted-password")];
440+
let dbus_secret =
441+
dbus::api::DBusSecret::new_encrypted(Arc::new(session), secret, &aes_key).unwrap();
442+
443+
let item = collections[0]
444+
.create_item("Test Encrypted Item", attributes, &dbus_secret, false, None)
445+
.await
446+
.unwrap();
447+
448+
// Verify item exists
449+
let items = collections[0].items().await.unwrap();
450+
assert_eq!(items.len(), 1, "Collection should have one item");
451+
assert_eq!(items[0].inner().path(), item.inner().path());
452+
}
453+
454+
#[tokio::test]
455+
async fn search_items_after_creation() {
456+
let (server_conn, client_conn) = create_p2p_connection().await;
457+
458+
let _server = Service::run_with_connection(
459+
server_conn,
460+
Some(oo7::Secret::from("test-password-long-enough")),
461+
)
462+
.await
463+
.unwrap();
464+
465+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
466+
467+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
468+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
469+
let session = Arc::new(session);
470+
471+
let collections = service_api.collections().await.unwrap();
472+
473+
// Create two items with different attributes
474+
let secret1 = oo7::Secret::text("password1");
475+
let attributes1 = &[("application", "firefox"), ("username", "user1")];
476+
let dbus_secret1 = dbus::api::DBusSecret::new(Arc::clone(&session), secret1);
477+
478+
collections[0]
479+
.create_item("Firefox Password", attributes1, &dbus_secret1, false, None)
480+
.await
481+
.unwrap();
482+
483+
let secret2 = oo7::Secret::text("password2");
484+
let attributes2 = &[("application", "chrome"), ("username", "user2")];
485+
let dbus_secret2 = dbus::api::DBusSecret::new(Arc::clone(&session), secret2);
486+
487+
collections[0]
488+
.create_item("Chrome Password", attributes2, &dbus_secret2, false, None)
489+
.await
490+
.unwrap();
491+
492+
// Search for firefox item
493+
let firefox_attrs = &[("application", "firefox")];
494+
let firefox_items = collections[0].search_items(firefox_attrs).await.unwrap();
495+
496+
assert_eq!(firefox_items.len(), 1, "Should find one firefox item");
497+
498+
// Search for chrome item
499+
let chrome_attrs = &[("application", "chrome")];
500+
let chrome_items = collections[0].search_items(chrome_attrs).await.unwrap();
501+
502+
assert_eq!(chrome_items.len(), 1, "Should find one chrome item");
503+
504+
// Search for non-existent item
505+
let nonexistent_attrs = &[("application", "nonexistent")];
506+
let nonexistent_items = collections[0]
507+
.search_items(nonexistent_attrs)
508+
.await
509+
.unwrap();
510+
511+
assert_eq!(
512+
nonexistent_items.len(),
513+
0,
514+
"Should find no nonexistent items"
515+
);
516+
}
517+
}

server/src/item.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,13 @@ mod tests {
440440

441441
// Retrieve secret
442442
let retrieved_secret = item.secret(&session).await.unwrap();
443+
// TODO: ensure the server implementation stores the content-type attribute
443444
assert_eq!(
444445
retrieved_secret
445-
.decrypt(Some(&Arc::new(client_private_key)))
446-
.unwrap(),
447-
secret
446+
.decrypt(Some(&Arc::new(aes_key)))
447+
.unwrap()
448+
.as_bytes(),
449+
secret.as_bytes()
448450
);
449451
}
450452

0 commit comments

Comments
 (0)