#![allow(unused_crate_dependencies)]
use async_trait::async_trait;
use eyre::Report;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use volli_core::Message;
use volli_transport::Transport;
#[derive(Clone)]
struct VecTransport {
sent: Arc<Mutex<Vec<String>>>,
recv: Arc<Mutex<VecDeque<Message>>>,
}
impl VecTransport {
fn new(msgs: Vec<Message>) -> Self {
Self {
sent: Arc::new(Mutex::new(Vec::new())),
recv: Arc::new(Mutex::new(msgs.into())),
}
}
}
#[async_trait]
impl Transport for VecTransport {
async fn send(&mut self, msg: &Message) -> Result<(), Report> {
let kind = match msg {
Message::Ping => "Ping",
Message::Pong { .. } => "Pong",
Message::Auth { .. } => "Auth",
Message::AuthOk => "AuthOk",
Message::AuthErr => "AuthErr",
_ => "Other",
};
self.sent.lock().unwrap().push(kind.to_string());
Ok(())
}
async fn recv(&mut self) -> Result<Option<Message>, Report> {
Ok(self.recv.lock().unwrap().pop_front())
}
}
async fn auth_once(mut tr: VecTransport, csk: [u8; 32], agent_id: String) -> Vec<String> {
if let Some(Message::Auth { token }) = tr.recv().await.unwrap() {
let tok = volli_core::token::decode_token(&token).unwrap();
if volli_core::token::verify_token(&tok, &csk).is_ok() && tok.payload.agent_id == agent_id {
tr.send(&Message::AuthOk).await.unwrap();
} else {
tr.send(&Message::AuthErr).await.unwrap();
}
} else {
tr.send(&Message::AuthErr).await.unwrap();
}
tr.sent.lock().unwrap().clone()
}
#[tokio::test]
async fn auth_success() {
let mut csk = [0u8; 32];
getrandom::getrandom(&mut csk).unwrap();
let token = volli_core::token::issue_token(&csk, "t", "c", "aid", 60).unwrap();
let encoded = volli_core::token::encode_token(&token).unwrap();
let tr = VecTransport::new(vec![Message::Auth { token: encoded }]);
let sent = auth_once(tr, csk, "aid".to_string()).await;
assert_eq!(sent, vec!["AuthOk"]);
}
#[tokio::test]
async fn auth_bad_key() {
let mut csk = [0u8; 32];
let mut wrong = [0u8; 32];
getrandom::getrandom(&mut csk).unwrap();
getrandom::getrandom(&mut wrong).unwrap();
let token = volli_core::token::issue_token(&csk, "t", "c", "aid", 60).unwrap();
let encoded = volli_core::token::encode_token(&token).unwrap();
let tr = VecTransport::new(vec![Message::Auth { token: encoded }]);
let sent = auth_once(tr, wrong, "aid".to_string()).await;
assert_eq!(sent, vec!["AuthErr"]);
}
#[tokio::test]
async fn auth_bad_agent_id() {
let mut csk = [0u8; 32];
getrandom::getrandom(&mut csk).unwrap();
let token = volli_core::token::issue_token(&csk, "t", "c", "other", 60).unwrap();
let encoded = volli_core::token::encode_token(&token).unwrap();
let tr = VecTransport::new(vec![Message::Auth { token: encoded }]);
let sent = auth_once(tr, csk, "aid".to_string()).await;
assert_eq!(sent, vec!["AuthErr"]);
}