merge: custom db ids for entities
This commit was merged in pull request #104.
This commit is contained in:
@@ -266,7 +266,7 @@ pub async fn metadata_unchanged_does_not_append_history() {
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
pub async fn metadata_change_appends_history_and_repoints_binding() {
|
||||
pub async fn metadata_frozen_after_approval_ignores_reconnect_changes() {
|
||||
let db = db::create_test_pool().await;
|
||||
let actors = spawn_test_actors(&db).await;
|
||||
let new_key = MlDsa87::key_gen(&mut rand::rng());
|
||||
@@ -287,6 +287,7 @@ pub async fn metadata_change_appends_history_and_repoints_binding() {
|
||||
connect_client(props, &mut server_transport).await;
|
||||
});
|
||||
|
||||
// Reconnect presenting different metadata — must be silently ignored.
|
||||
test_transport
|
||||
.send(auth::Inbound::AuthChallengeRequest {
|
||||
pubkey: verifying_key(&new_key).into(),
|
||||
@@ -313,6 +314,7 @@ pub async fn metadata_change_appends_history_and_repoints_binding() {
|
||||
client_metadata, client_metadata_history, program_client,
|
||||
};
|
||||
let mut conn = db.get().await.unwrap();
|
||||
// Metadata is frozen: no new row, no history entry.
|
||||
let metadata_count: i64 = client_metadata::table
|
||||
.count()
|
||||
.get_result(&mut conn)
|
||||
@@ -338,15 +340,16 @@ pub async fn metadata_change_appends_history_and_repoints_binding() {
|
||||
.first::<(String, Option<String>, Option<String>)>(&mut conn)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(metadata_count, 2);
|
||||
assert_eq!(history_count, 1);
|
||||
assert_eq!(metadata_count, 1, "frozen: no new metadata row on reconnect");
|
||||
assert_eq!(history_count, 0, "frozen: no history entry on reconnect");
|
||||
assert_eq!(
|
||||
current,
|
||||
(
|
||||
"client".to_owned(),
|
||||
Some("new".to_owned()),
|
||||
Some("2.0.0".to_owned())
|
||||
)
|
||||
Some("old".to_owned()),
|
||||
Some("1.0.0".to_owned())
|
||||
),
|
||||
"frozen: original metadata must be preserved"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ pub async fn bootstrap_token_auth() {
|
||||
test_transport
|
||||
.send(auth::Inbound::AuthChallengeRequest {
|
||||
pubkey: verifying_key(&new_key).into(),
|
||||
bootstrap_token: Some(token),
|
||||
bootstrap_token: Some(token.into_bytes()),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -231,7 +231,7 @@ pub async fn bootstrap_invalid_token_auth() {
|
||||
test_transport
|
||||
.send(auth::Inbound::AuthChallengeRequest {
|
||||
pubkey: verifying_key(&new_key).into(),
|
||||
bootstrap_token: Some("invalid_token".to_owned()),
|
||||
bootstrap_token: Some(b"invalid_token".to_vec()),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -400,7 +400,7 @@ pub async fn challenge_auth_rejects_integrity_tag_mismatch_when_unsealed() {
|
||||
let challenge = match response {
|
||||
Ok(resp) => match resp {
|
||||
auth::Outbound::AuthChallenge { challenge } => challenge,
|
||||
other => panic!("Expected AuthChallenge, got {other:?}"),
|
||||
other @ auth::Outbound::AuthSuccess => panic!("Expected AuthChallenge, got {other:?}"),
|
||||
},
|
||||
Err(err) => panic!("Expected Ok response, got Err({err:?})"),
|
||||
};
|
||||
|
||||
@@ -14,6 +14,8 @@ use kameo::actor::{ActorRef, Spawn as _};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use tokio::task::JoinSet;
|
||||
|
||||
const TEST_AAD: &[u8] = b"test-aad";
|
||||
|
||||
async fn write_concurrently(
|
||||
actor: ActorRef<Vault>,
|
||||
prefix: &'static str,
|
||||
@@ -27,6 +29,7 @@ async fn write_concurrently(
|
||||
let id = actor
|
||||
.ask(CreateNew {
|
||||
plaintext: SafeCell::new(plaintext.clone()),
|
||||
aad: TEST_AAD.to_vec(),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -120,7 +123,7 @@ async fn insert_failure_does_not_create_partial_row() {
|
||||
drop(conn);
|
||||
|
||||
let err = actor
|
||||
.create_new(SafeCell::new(b"should fail".to_vec()))
|
||||
.create_new(SafeCell::new(b"should fail".to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, Error::DatabaseTransaction(_)));
|
||||
@@ -171,7 +174,7 @@ async fn decrypt_roundtrip_after_high_concurrency() {
|
||||
.unwrap();
|
||||
|
||||
for (id, plaintext) in expected {
|
||||
let mut decrypted = decryptor.decrypt(id).await.unwrap();
|
||||
let mut decrypted = decryptor.decrypt(id, TEST_AAD.to_vec()).await.unwrap();
|
||||
assert_eq!(*decrypted.read(), plaintext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,11 @@ use arbiter_server::{
|
||||
use diesel::{QueryDsl, SelectableHelper};
|
||||
use diesel_async::RunQueryDsl;
|
||||
|
||||
const TEST_AAD: &[u8] = b"test-aad";
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_bootstrap() {
|
||||
async fn bootstrap() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = Vault::new(db.clone(), GlobalActors::spawn_message_bus())
|
||||
.await
|
||||
@@ -39,7 +41,7 @@ async fn test_bootstrap() {
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_bootstrap_rejects_double() {
|
||||
async fn bootstrap_rejects_double() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
@@ -50,14 +52,14 @@ async fn test_bootstrap_rejects_double() {
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_create_new_before_bootstrap_fails() {
|
||||
async fn create_new_before_bootstrap_fails() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = Vault::new(db, GlobalActors::spawn_message_bus())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let err = actor
|
||||
.create_new(SafeCell::new(b"data".to_vec()))
|
||||
.create_new(SafeCell::new(b"data".to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, Error::NotBootstrapped));
|
||||
@@ -65,19 +67,19 @@ async fn test_create_new_before_bootstrap_fails() {
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_decrypt_before_bootstrap_fails() {
|
||||
async fn decrypt_before_bootstrap_fails() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = Vault::new(db, GlobalActors::spawn_message_bus())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let err = actor.decrypt(1).await.unwrap_err();
|
||||
let err = actor.decrypt(1, TEST_AAD.to_vec()).await.unwrap_err();
|
||||
assert!(matches!(err, Error::NotBootstrapped));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_new_restores_sealed_state() {
|
||||
async fn new_restores_sealed_state() {
|
||||
let db = db::create_test_pool().await;
|
||||
let actor = common::bootstrapped_vault(&db).await;
|
||||
drop(actor);
|
||||
@@ -85,19 +87,19 @@ async fn test_new_restores_sealed_state() {
|
||||
let mut actor2 = Vault::new(db, GlobalActors::spawn_message_bus())
|
||||
.await
|
||||
.unwrap();
|
||||
let err = actor2.decrypt(1).await.unwrap_err();
|
||||
let err = actor2.decrypt(1, TEST_AAD.to_vec()).await.unwrap_err();
|
||||
assert!(matches!(err, Error::Sealed));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_unseal_correct_password() {
|
||||
async fn unseal_correct_password() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
let plaintext = b"survive a restart";
|
||||
let aead_id = actor
|
||||
.create_new(SafeCell::new(plaintext.to_vec()))
|
||||
.create_new(SafeCell::new(plaintext.to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
drop(actor);
|
||||
@@ -108,19 +110,19 @@ async fn test_unseal_correct_password() {
|
||||
let seal_key = SafeCell::new(b"test-seal-key".to_vec());
|
||||
actor.try_unseal(seal_key).await.unwrap();
|
||||
|
||||
let mut decrypted = actor.decrypt(aead_id).await.unwrap();
|
||||
let mut decrypted = actor.decrypt(aead_id, TEST_AAD.to_vec()).await.unwrap();
|
||||
assert_eq!(*decrypted.read(), plaintext);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_unseal_wrong_then_correct_password() {
|
||||
async fn unseal_wrong_then_correct_password() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
let plaintext = b"important data";
|
||||
let aead_id = actor
|
||||
.create_new(SafeCell::new(plaintext.to_vec()))
|
||||
.create_new(SafeCell::new(plaintext.to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
drop(actor);
|
||||
@@ -136,6 +138,6 @@ async fn test_unseal_wrong_then_correct_password() {
|
||||
let good_key = SafeCell::new(b"test-seal-key".to_vec());
|
||||
actor.try_unseal(good_key).await.unwrap();
|
||||
|
||||
let mut decrypted = actor.decrypt(aead_id).await.unwrap();
|
||||
let mut decrypted = actor.decrypt(aead_id, TEST_AAD.to_vec()).await.unwrap();
|
||||
assert_eq!(*decrypted.read(), plaintext);
|
||||
}
|
||||
|
||||
@@ -10,45 +10,47 @@ use diesel::{ExpressionMethods as _, QueryDsl, SelectableHelper, dsl::update};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use std::collections::HashSet;
|
||||
|
||||
const TEST_AAD: &[u8] = b"test-aad";
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_create_decrypt_roundtrip() {
|
||||
async fn create_decrypt_roundtrip() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
let plaintext = b"hello arbiter";
|
||||
let aead_id = actor
|
||||
.create_new(SafeCell::new(plaintext.to_vec()))
|
||||
.create_new(SafeCell::new(plaintext.to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut decrypted = actor.decrypt(aead_id).await.unwrap();
|
||||
let mut decrypted = actor.decrypt(aead_id, TEST_AAD.to_vec()).await.unwrap();
|
||||
assert_eq!(*decrypted.read(), plaintext);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_decrypt_nonexistent_returns_not_found() {
|
||||
async fn decrypt_nonexistent_returns_not_found() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
let err = actor.decrypt(9999).await.unwrap_err();
|
||||
let err = actor.decrypt(9999, TEST_AAD.to_vec()).await.unwrap_err();
|
||||
assert!(matches!(err, Error::NotFound));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_ciphertext_differs_across_entries() {
|
||||
async fn ciphertext_differs_across_entries() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
let plaintext = b"same content";
|
||||
let id1 = actor
|
||||
.create_new(SafeCell::new(plaintext.to_vec()))
|
||||
.create_new(SafeCell::new(plaintext.to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
let id2 = actor
|
||||
.create_new(SafeCell::new(plaintext.to_vec()))
|
||||
.create_new(SafeCell::new(plaintext.to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -68,22 +70,22 @@ async fn test_ciphertext_differs_across_entries() {
|
||||
|
||||
assert_ne!(row1.ciphertext, row2.ciphertext);
|
||||
|
||||
let mut d1 = actor.decrypt(id1).await.unwrap();
|
||||
let mut d2 = actor.decrypt(id2).await.unwrap();
|
||||
let mut d1 = actor.decrypt(id1, TEST_AAD.to_vec()).await.unwrap();
|
||||
let mut d2 = actor.decrypt(id2, TEST_AAD.to_vec()).await.unwrap();
|
||||
assert_eq!(*d1.read(), plaintext);
|
||||
assert_eq!(*d2.read(), plaintext);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[test_log::test]
|
||||
async fn test_nonce_never_reused() {
|
||||
async fn nonce_never_reused() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
|
||||
let n = 5;
|
||||
for i in 0..n {
|
||||
actor
|
||||
.create_new(SafeCell::new(format!("secret {i}").into_bytes()))
|
||||
.create_new(SafeCell::new(format!("secret {i}").into_bytes()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
@@ -137,7 +139,7 @@ async fn broken_db_nonce_format_fails_closed() {
|
||||
drop(conn);
|
||||
|
||||
let err = actor
|
||||
.create_new(SafeCell::new(b"must fail".to_vec()))
|
||||
.create_new(SafeCell::new(b"must fail".to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, Error::BrokenDatabase));
|
||||
@@ -145,7 +147,7 @@ async fn broken_db_nonce_format_fails_closed() {
|
||||
let db = db::create_test_pool().await;
|
||||
let mut actor = common::bootstrapped_vault(&db).await;
|
||||
let id = actor
|
||||
.create_new(SafeCell::new(b"decrypt target".to_vec()))
|
||||
.create_new(SafeCell::new(b"decrypt target".to_vec()), TEST_AAD.to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
let mut conn = db.get().await.unwrap();
|
||||
@@ -156,6 +158,6 @@ async fn broken_db_nonce_format_fails_closed() {
|
||||
.unwrap();
|
||||
drop(conn);
|
||||
|
||||
let err = actor.decrypt(id).await.unwrap_err();
|
||||
let err = actor.decrypt(id, TEST_AAD.to_vec()).await.unwrap_err();
|
||||
assert!(matches!(err, Error::BrokenDatabase));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user