diff --git a/Cargo.lock b/Cargo.lock index 7c80b6a..01284f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,6 +195,7 @@ dependencies = [ "mockall", "rand 0.7.3", "rpassword", + "secrecy", "serde", "sha1", "termion", diff --git a/Cargo.toml b/Cargo.toml index bad1f69..56fd62f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ aes-gcm = "0.10.3" base64 = "0.21.7" sha1 = "0.10.6" itertools = "0.12.1" +secrecy = "0.8.0" [dev-dependencies] mockall = "^0.9" diff --git a/src/command.rs b/src/command.rs index 3d4774f..653733e 100644 --- a/src/command.rs +++ b/src/command.rs @@ -275,13 +275,13 @@ macro_rules! build_subcommand_map( #[macro_export] macro_rules! parse_command_args( ($aparte:ident, $command:ident, $index:ident, {}) => (); - ($aparte:ident, $command:ident, $index:ident, { $arg:ident: Password<$type:ty> }) => ( + ($aparte:ident, $command:ident, $index:ident, { $arg:ident: Password }) => ( if $command.args.len() <= $index { $aparte.schedule(Event::ReadPassword($command.clone())); return Ok(()) } - let $arg: Password<$type> = Password::from_str(&$command.args[$index])?; + let $arg: Password = Password::from_str(&$command.args[$index])?; $index += 1; ); @@ -669,7 +669,10 @@ mod tests_command_parser { "/test \"command with arg".to_string(), ); assert!(command.is_err()); - assert_eq!(format!("{}", command.err().unwrap()), "Missing closing quote"); + assert_eq!( + format!("{}", command.err().unwrap()), + "Missing closing quote" + ); } #[test] diff --git a/src/core.rs b/src/core.rs index 4c0bd07..35a3313 100644 --- a/src/core.rs +++ b/src/core.rs @@ -17,6 +17,7 @@ use chrono::{DateTime, FixedOffset, Local as LocalTz}; use futures::sink::SinkExt; use futures::stream::StreamExt; use rand::Rng; +use secrecy::{ExposeSecret, Secret}; use termion::event::Key; use tokio::runtime::Runtime as TokioRuntime; use tokio::signal::unix; @@ -64,7 +65,7 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); #[derive(Debug, Clone)] pub enum Event { Start, - Connect(ConnectionInfo, Password), + Connect(ConnectionInfo, Password), Connected(Account, Jid), Disconnected(Account, String), AuthError(Account, String), @@ -370,19 +371,7 @@ impl Display for Mod { } } -#[derive(Debug, Clone)] -pub struct Password(pub T); - -impl FromStr for Password { - type Err = T::Err; - - fn from_str(s: &str) -> Result { - match T::from_str(s) { - Err(e) => Err(e), - Ok(inner) => Ok(Password(inner)), - } - } -} +pub type Password = Secret; pub struct Connection { pub sink: mpsc::UnboundedSender, @@ -409,7 +398,7 @@ Examples: aparte.config.accounts.keys().cloned().collect() }) }, - password: Password + password: Password }, |aparte, _command| { let account = { @@ -1119,7 +1108,7 @@ impl Aparte { } } - pub fn connect(&mut self, connection_info: &ConnectionInfo, password: Password) { + pub fn connect(&mut self, connection_info: &ConnectionInfo, password: Password) { let account: Account = match Jid::from_str(&connection_info.jid) { Ok(Jid::Full(jid)) => jid, Ok(Jid::Bare(jid)) => { @@ -1143,7 +1132,7 @@ impl Aparte { self.log(format!("Connecting as {account}")); let config = tokio_xmpp::AsyncConfig { jid: Jid::from(account.clone()), - password: password.0, + password: password.expose_secret().clone(), server: match (&connection_info.server, &connection_info.port) { (Some(server), Some(port)) => tokio_xmpp::starttls::ServerConfig::Manual { host: server.clone(),