Something went wrong. Try again.
Identities for entities did.bot
agent llm did
Something went wrong. Try again.
3.0 kB · 83 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384//! Handing a code to a client that is listening on this machine.//!//! The last step of every authorization this daemon completes is a `GET` of//! a redirect the server built. The server cannot make it: `plan/node.md`//! puts the daemon on the agent host and the authorization server somewhere//! else, and the client's callback listens on loopback here. So the daemon//! fetches it.//!//! That is a request whose target came from a process the model started, so//! it is bounded twice: loopback only, and no chains. Both bounds live here//! rather than at the call site, so that a second caller cannot acquire a//! weaker copy of them. Loopback is what [`didbot_http::is_loopback`] says.
use url::Url;
/// Why a code did not reach its client.#[derive(Debug, thiserror::Error)]pub enum Trouble { /// The redirect pointed somewhere that is not this machine. #[error("{0}")] Elsewhere(String), /// The client did not answer, or the URL was not one. #[error("{0}")] Failed(String),}
/// Fetches `redirect`, which is the act of delivering the code in it.////// An error names the target without its query, which carries the code.////// `http` is expected to be built with redirects turned off; this does not/// build its own client, because the callers already hold one and a second/// would be a second set of timeouts to keep in step.pub async fn deliver(http: &reqwest::Client, redirect: &str) -> Result<(), Trouble> { let target = Url::parse(redirect) .map_err(|err| Trouble::Failed(format!("the redirect is unusable: {err}")))?; if !didbot_http::is_loopback(&target) { let mut shown = target; shown.set_query(None); shown.set_fragment(None); return Err(Trouble::Elsewhere(format!( "the client asked for its code at {shown}, which is not loopback" ))); } http.get(target).send().await.map_err(|err| { Trouble::Failed(format!( "the client did not take its code: {}", err.without_url() )) })?; Ok(())}
#[cfg(test)]mod tests { use super::*;
/// Both refusals are logged, so neither may carry the code. #[tokio::test] async fn a_refusal_does_not_repeat_the_code() { let http = didbot_http::client(); let elsewhere = deliver(&http, "https://example.invalid/cb?code=do-not-log") .await .unwrap_err() .to_string(); assert!(!elsewhere.contains("do-not-log"), "{elsewhere}");
// A loopback port nobody is listening on. let port = std::net::TcpListener::bind("127.0.0.1:0") .unwrap() .local_addr() .unwrap() .port(); let unanswered = deliver( &http, &format!("http://127.0.0.1:{port}/cb?code=do-not-log"), ) .await .unwrap_err() .to_string(); assert!(!unanswered.contains("do-not-log"), "{unanswered}"); }}