Hand a source a secret
Some sources need a secret the app only gets later: a token after the user
signs in, or a key unlocked from the keyring. Send it to the running source
with Message::Secret, wrapped in a Secret.
Send it
Section titled “Send it”use pito_sync::{Message, Secret};
let token = String::from("from the keyring");asks.send(Message::Secret("feed-token".into(), Secret::new(token)))?;The thread calls the source’s secret(name, value) and then runs a pass at
once, never skipped, so the data shows up as soon as the secret arrives.
Keep it in the source
Section titled “Keep it in the source”Source::secret drops the value by default. A source that wants it
overrides the method and keeps it:
struct Feed { token: Option<Secret>,}
impl Source for Feed { fn secret(&mut self, name: &str, value: Secret) { if name == "feed-token" { self.token = Some(value); } }
fn pass(&mut self, conn: &mut Connection, _id: Option<&str>) -> Result<usize, Failure> { let Some(token) = self.token.as_ref().filter(|t| !t.expose().is_empty()) else { return Err(Failure::new(Fault::NoKey, "sign in first")); }; let posts = fetch(token.expose())?; write(conn, posts) }}name and every are left out here; fetch and write stand for the
source’s own code. Until the token arrives, each pass fails with no_key and the UI can ask the
user to sign in. In the feed example the first pass runs without a token,
the app sends one, and the next pass writes:
feed syncing…feed no key: sign in first (0 posts kept)feed syncing…feed 3 posts, newest "Threads that never block the UI"What Secret guarantees
Section titled “What Secret guarantees”let token = pito_sync::Secret::new(String::from("from the keyring"));println!("{token:?}");Secret(hidden)DebugprintsSecret(hidden), so a secret in a struct that derivesDebugnever reaches a log.- It has no
Cloneand noDisplay. expose()is the only way back to the value, as a&str.- When it drops, its buffer is zeroed, spare capacity included.
Hand Secret::new an owned String, so no other copy of the value is left
behind. The crate writes no secret to the database, a log, an error or
Debug output. Keep it that way in your source: never put a secret in a
Failure, a cursor or a row.