#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::indexing_slicing,
reason = "integration test code; a failed unwrap/expect is the test failing"
)]
use koh::transport_iroh::auth::AuthError;
use koh::transport_iroh::{auth, bind_endpoint_local, generate_secret_key, loopback_addr, ALPN};
async fn round(
server_pass: Option<&'static str>,
client_pass: Option<&'static str>,
) -> (Result<(), AuthError>, Result<(), AuthError>) {
let server = bind_endpoint_local(generate_secret_key(), true)
.await
.expect("bind server");
let client = bind_endpoint_local(generate_secret_key(), false)
.await
.expect("bind client");
let server_addr = loopback_addr(&server);
let server_ep = server.clone();
let accept = tokio::spawn(async move {
let incoming = server_ep.accept().await.expect("accept");
incoming.await.expect("server handshake")
});
let client_conn = client.connect(server_addr, ALPN).await.expect("connect");
let server_conn = accept.await.expect("accept join");
let result = tokio::join!(
auth::handshake_server(&server_conn, server_pass),
auth::handshake_client(&client_conn, client_pass),
);
drop((server, client));
result
}
#[tokio::test]
async fn passphrase_handshake_over_iroh() {
let (sr, cr) = round(None, None).await;
assert!(sr.is_ok(), "no-passphrase server: {sr:?}");
assert!(cr.is_ok(), "no-passphrase client: {cr:?}");
let (sr, _cr) = round(Some("hunter2"), Some("hunter2")).await;
assert!(sr.is_ok(), "matching passphrase should pass, got {sr:?}");
let (sr, _cr) = round(Some("hunter2"), Some("nope")).await;
assert!(
matches!(sr, Err(AuthError::ChallengeFailed)),
"wrong passphrase must be rejected server-side as ChallengeFailed, got {sr:?}"
);
}