Complete authenticated interactive prompt routing
This commit is contained in:
parent
6816f0632e
commit
46b52b4b43
1 changed files with 595 additions and 96 deletions
|
|
@ -3,7 +3,8 @@ use std::fs::File;
|
|||
use std::io;
|
||||
|
||||
use lazaret_client::terminal::{
|
||||
HostTerminal, HostTerminalEvent, InteractiveSessionTransport, run_interactive_session,
|
||||
HostTerminal, HostTerminalEvent, InteractiveSessionTransport, PromptOutcome,
|
||||
run_interactive_session,
|
||||
};
|
||||
use lazaret_client::{ClientError, ClientSessionIdentity};
|
||||
use lazaret_core::identity::{
|
||||
|
|
@ -106,11 +107,21 @@ impl HostTerminal for PtyTerminal {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn prompt(&mut self, prompt: &TerminalPrompt) -> io::Result<DeveloperDecisionKind> {
|
||||
fn prompt(&mut self, prompt: &TerminalPrompt) -> io::Result<PromptOutcome> {
|
||||
assert_eq!(prompt.agent_profile, "trusted");
|
||||
assert_eq!(prompt.command_argv, [b"/usr/bin/tool".to_vec()]);
|
||||
assert_eq!(prompt.justification, "update host metadata");
|
||||
Ok(self.decision)
|
||||
let resumed_size = if matches!(self.events.front(), Some(HostTerminalEvent::LocalSuspend)) {
|
||||
self.events.pop_front();
|
||||
self.suspend_and_resume()?;
|
||||
Some(self.size(prompt.session_id)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(PromptOutcome {
|
||||
decision: self.decision,
|
||||
resumed_size,
|
||||
})
|
||||
}
|
||||
|
||||
fn suspend_and_resume(&mut self) -> io::Result<()> {
|
||||
|
|
@ -132,6 +143,7 @@ struct FixtureTransport {
|
|||
prompt_sent: bool,
|
||||
failure: Option<TransportFailure>,
|
||||
signed_decision: Option<Vec<u8>>,
|
||||
prompt_after_events: usize,
|
||||
}
|
||||
|
||||
impl FixtureTransport {
|
||||
|
|
@ -142,6 +154,7 @@ impl FixtureTransport {
|
|||
prompt_sent: false,
|
||||
failure: None,
|
||||
signed_decision: None,
|
||||
prompt_after_events: 5,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -188,7 +201,7 @@ impl InteractiveSessionTransport for FixtureTransport {
|
|||
)],
|
||||
));
|
||||
}
|
||||
if !self.prompt_sent && self.events.len() >= 5 {
|
||||
if !self.prompt_sent && self.events.len() >= self.prompt_after_events {
|
||||
self.prompt_sent = true;
|
||||
return Ok(batch(
|
||||
self.session_id,
|
||||
|
|
@ -206,6 +219,39 @@ impl InteractiveSessionTransport for FixtureTransport {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_suspend_sends_resumed_size_before_decision() {
|
||||
let identity = ClientSessionIdentity::generate::<std::convert::Infallible>().unwrap();
|
||||
let binding = binding(&identity);
|
||||
let mut terminal = PtyTerminal::new([HostTerminalEvent::Idle, HostTerminalEvent::LocalSuspend]);
|
||||
let mut transport = FixtureTransport::successful(identity.session_id());
|
||||
transport.prompt_after_events = 1;
|
||||
|
||||
assert_eq!(
|
||||
run_interactive_session(
|
||||
&mut transport,
|
||||
&mut terminal,
|
||||
&identity,
|
||||
&binding,
|
||||
&[b"/bin/sh".to_vec()],
|
||||
)
|
||||
.unwrap(),
|
||||
23
|
||||
);
|
||||
|
||||
assert_eq!(terminal.suspend_count, 1);
|
||||
assert!(matches!(
|
||||
transport.events.as_slice(),
|
||||
[
|
||||
InteractiveSessionEvent::Poll { .. },
|
||||
InteractiveSessionEvent::Terminal(lazaret_core::records::SessionTerminalEvent::Resize(
|
||||
_
|
||||
)),
|
||||
InteractiveSessionEvent::PromptDecision { .. }
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn terminal_fixture_routes_resize_signals_suspend_prompt_and_nonzero_exit() {
|
||||
let identity = ClientSessionIdentity::generate::<std::convert::Infallible>().unwrap();
|
||||
|
|
|
|||
Loading…
Reference in a new issue