Skip to content

Commit

Permalink
feat: removed password error for safe password (#58)
Browse files Browse the repository at this point in the history
- Removed PasswordError and opted to use `String` for the error type in
`impl FromStr for SafePassword`. This was needed to ensure
`SafePassword` can be used with `serde` and `clap`.
- Added a unit test to ensure `serde` and `clap` will work properly.
  • Loading branch information
hansieodendaal committed Jul 20, 2023
1 parent 468db3e commit c067263
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ subtle = {version= "2.4", default-features =false, optional = true}

[dev-dependencies]
rand = "0.8.0"
clap = { version = "3.2", features = ["derive", "env"] }

[features]
default = ["serialize", "std", "zero"]
Expand Down
2 changes: 1 addition & 1 deletion rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ imports_layout = "HorizontalVertical"
imports_granularity = "Crate"
match_block_trailing_comma = true
max_width = 120
newline_style = "Unix"
newline_style = "Native"
normalize_comments = true
reorder_imports = true
reorder_modules = true
Expand Down
53 changes: 41 additions & 12 deletions src/password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

//! A type for handling a passphrase safely.
use alloc::{string::String, vec::Vec};
use core::{fmt::Display, str::FromStr};
use core::str::FromStr;

#[cfg(feature = "serde")]
use serde::{ser::SerializeSeq, Serialize, Serializer};
Expand Down Expand Up @@ -67,18 +67,8 @@ impl SafePassword {
}
}

/// An error for parsing a password from a string
#[derive(Debug)]
pub struct PasswordError;

impl Display for PasswordError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "PasswordError")
}
}

impl FromStr for SafePassword {
type Err = PasswordError;
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self {
Expand Down Expand Up @@ -134,4 +124,43 @@ mod tests {

assert_eq!(safe_password.reveal(), deser.reveal());
}

#[test]
// If the error type in `impl FromStr for SafePassword` is wrong, this test will fail to compile
fn use_with_clap_and_serde() {
use alloc::string::String;

use clap::Parser;
use serde::{Deserialize, Serialize};

fn deserialize_safe_password_option<'de, D>(deserializer: D) -> Result<Option<SafePassword>, D::Error>
where D: serde::Deserializer<'de> {
let password: Option<String> = Deserialize::deserialize(deserializer)?;
println!("Password: {:?}", password);
Ok(password.map(SafePassword::from))
}

#[derive(Parser, Serialize, Deserialize, Debug)]
#[clap(author, version, about, long_about = None)]
#[clap(propagate_version = true)]
struct Cli {
#[serde(deserialize_with = "deserialize_safe_password_option")]
#[clap(long, env = "MY_PASSWORD", hide_env_values = true)]
pub password: Option<SafePassword>,
}

let hex_password = "48656c6c6f20576f726c64";
let input = serde_json::json!({
"password": hex_password,
});

// Deserialize the JSON input into the Cli struct
let cli: Cli = serde_json::from_value(input).unwrap();

// Access the SafePassword field
if let Some(password) = cli.password {
let password_reveal = String::from_utf8(password.reveal().clone()).unwrap();
assert_eq!(hex_password.to_string(), password_reveal);
}
}
}

0 comments on commit c067263

Please sign in to comment.