98 lines
2.8 KiB
Rust
98 lines
2.8 KiB
Rust
//! `brokerd`'s side of one `gateway.sock` connection, for tests: ask, read what comes back,
|
|
//! answer with an outcome, or close. Do not edit.
|
|
|
|
#![allow(dead_code)] // each test file uses a different part of this module
|
|
|
|
use std::os::unix::net::UnixStream;
|
|
use std::path::Path;
|
|
use std::time::Duration;
|
|
|
|
use proto::{
|
|
ApprovalOutcome, ApprovalReply, ApprovalRequest, CallId, DataClass, Envelope, GatewayOutcome,
|
|
Message, PROTOCOL_VERSION, PendingApproval, SessionId, Timestamp, read_frame, write_frame,
|
|
};
|
|
|
|
pub struct Asking {
|
|
stream: UnixStream,
|
|
pub posts: Vec<String>,
|
|
}
|
|
|
|
/// An approval of `session`, with these arguments.
|
|
pub fn pending(approval: u64, session: &str, arguments: &str) -> PendingApproval {
|
|
PendingApproval {
|
|
approval,
|
|
session: SessionId::new(session).unwrap(),
|
|
call: CallId(3),
|
|
tool: "read_file".to_string(),
|
|
arguments: arguments.to_string(),
|
|
grant: "notes".to_string(),
|
|
taint: DataClass::Private,
|
|
created: Timestamp::parse("2026-09-24T08:05:00.000Z").unwrap(),
|
|
expires: Timestamp::parse("2026-09-24T08:20:00.000Z").unwrap(),
|
|
}
|
|
}
|
|
|
|
fn frame(id: u64, last: bool, msg: Message) -> Envelope {
|
|
Envelope {
|
|
v: PROTOCOL_VERSION,
|
|
id,
|
|
r#final: last,
|
|
msg,
|
|
}
|
|
}
|
|
|
|
/// Connect and ask; `Ok` with the posts, or `Err` with gatewayd's error detail.
|
|
pub fn ask(socket: &Path, info: PendingApproval) -> Result<Asking, String> {
|
|
let mut stream = UnixStream::connect(socket).map_err(|e| e.to_string())?;
|
|
stream
|
|
.set_read_timeout(Some(Duration::from_secs(10)))
|
|
.unwrap();
|
|
write_frame(
|
|
&mut stream,
|
|
&frame(
|
|
1,
|
|
true,
|
|
Message::ApprovalRequest(ApprovalRequest { approval: info }),
|
|
),
|
|
)
|
|
.unwrap();
|
|
match read_frame(&mut stream).map_err(|e| e.to_string())?.msg {
|
|
Message::ApprovalPosted(p) => Ok(Asking {
|
|
stream,
|
|
posts: p.posts,
|
|
}),
|
|
Message::Error(e) => Err(e.detail),
|
|
other => panic!("{other:?}"),
|
|
}
|
|
}
|
|
|
|
impl Asking {
|
|
/// The answer, within `wait`, or `None`.
|
|
pub fn answer(&mut self, wait: Duration) -> Option<ApprovalReply> {
|
|
self.stream.set_read_timeout(Some(wait)).unwrap();
|
|
match read_frame(&mut self.stream) {
|
|
Ok(Envelope {
|
|
msg: Message::ApprovalReply(r),
|
|
..
|
|
}) => Some(r),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn outcome(&mut self, outcome: GatewayOutcome) {
|
|
write_frame(
|
|
&mut self.stream,
|
|
&frame(
|
|
2,
|
|
true,
|
|
Message::ApprovalOutcome(ApprovalOutcome { outcome }),
|
|
),
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
pub fn close(self) {
|
|
let _ = self.stream.shutdown(std::net::Shutdown::Both);
|
|
}
|
|
}
|