From abda2133bf0c50fcb3195b66d0c95f8803c164af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Wed, 9 Oct 2019 23:29:31 +0200 Subject: [PATCH] format code, version bump --- Cargo.toml | 2 +- src/digest.rs | 157 ++++++++++++++++++++++++++++---------------------- 2 files changed, 90 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d221a49..97deced 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "digest_auth" -version = "0.2.0" +version = "0.2.1" authors = ["Ondřej Hruška "] edition = "2018" description = "Implementation of the Digest Auth algorithm as defined in IETF RFC 2069, 2617, and 7616, intended for HTTP clients" diff --git a/src/digest.rs b/src/digest.rs index 5ae2362..3f1b4ae 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -32,7 +32,7 @@ impl QuoteForDigest for String { } /// Join a Vec of Display items using a separator -fn join_vec(vec : &Vec, sep : &str) -> String { +fn join_vec(vec: &Vec, sep: &str) -> String { vec.iter() .map(ToString::to_string) .collect::>() @@ -41,7 +41,7 @@ fn join_vec(vec : &Vec, sep : &str) -> String { enum NamedTag<'a> { Quoted(&'a str, Cow<'a, str>), - Plain(&'a str, Cow<'a, str>) + Plain(&'a str, Cow<'a, str>), } impl Display for NamedTag<'_> { @@ -50,14 +50,11 @@ impl Display for NamedTag<'_> { NamedTag::Quoted(name, content) => { write!(f, "{}=\"{}\"", name, content.quote_for_digest()) } - NamedTag::Plain(name, content) => { - write!(f, "{}={}", name, content) - } + NamedTag::Plain(name, content) => write!(f, "{}={}", name, content), } } } - /// Helper func that parses the key-value string received from server fn parse_header_map(input: &str) -> Result> { #[derive(Debug)] @@ -148,7 +145,6 @@ fn parse_header_map(input: &str) -> Result> { Ok(parsed) } - /// Login attempt context /// /// All fields are borrowed to reduce runtime overhead; this struct should not be stored anywhere, @@ -174,25 +170,28 @@ impl<'a> AuthContext<'a> { /// Construct a new context with the GET verb and no payload body. /// See the other constructors if this does not fit your situation. pub fn new(username: UN, password: PW, uri: UR) -> Self - where UN: Into>, - PW: Into>, - UR: Into> + where + UN: Into>, + PW: Into>, + UR: Into>, { - Self::new_with_method(username, password, uri, Option::<&'a[u8]>::None, HttpMethod::GET) + Self::new_with_method( + username, + password, + uri, + Option::<&'a [u8]>::None, + HttpMethod::GET, + ) } /// Construct a new context with the POST verb and a payload body (may be None). /// See the other constructors if this does not fit your situation. - pub fn new_post( - username: UN, - password: PW, - uri: UR, - body: Option, - ) -> Self - where UN: Into>, - PW: Into>, - UR: Into>, - BD: Into>, + pub fn new_post(username: UN, password: PW, uri: UR, body: Option) -> Self + where + UN: Into>, + PW: Into>, + UR: Into>, + BD: Into>, { Self::new_with_method(username, password, uri, body, HttpMethod::POST) } @@ -205,16 +204,17 @@ impl<'a> AuthContext<'a> { body: Option, method: HttpMethod, ) -> Self - where UN: Into>, - PW: Into>, - UR: Into>, - BD: Into> + where + UN: Into>, + PW: Into>, + UR: Into>, + BD: Into>, { Self { - username : username.into(), - password : password.into(), - uri : uri.into(), - body : body.map(Into::into), + username: username.into(), + password: password.into(), + uri: uri.into(), + body: body.map(Into::into), method, cnonce: None, } @@ -223,7 +223,7 @@ impl<'a> AuthContext<'a> { /// Set cnonce to the given value pub fn set_custom_cnonce(&mut self, cnonce: CN) where - CN: Into> + CN: Into>, { self.cnonce = Some(cnonce.into()); } @@ -269,10 +269,7 @@ impl FromStr for WwwAuthenticateHeader { impl WwwAuthenticateHeader { /// Generate an [`AuthorizationHeader`](struct.AuthorizationHeader.html) to be sent to the server in a new request. /// The [`self.nc`](struct.AuthorizationHeader.html#structfield.nc) field is incremented. - pub fn respond( - &mut self, - secrets: &AuthContext, - ) -> Result { + pub fn respond(&mut self, secrets: &AuthContext) -> Result { AuthorizationHeader::from_prompt(self, secrets) } @@ -357,7 +354,10 @@ impl Display for WwwAuthenticateHeader { entries.push(NamedTag::Plain("stale", "true".into())); } - entries.push(NamedTag::Plain("algorithm", self.algorithm.to_string().into())); + entries.push(NamedTag::Plain( + "algorithm", + self.algorithm.to_string().into(), + )); entries.push(NamedTag::Quoted("nonce", (&self.nonce).into())); if let Some(ref opaque) = self.opaque { entries.push(NamedTag::Quoted("opaque", (opaque).into())); @@ -369,7 +369,9 @@ impl Display for WwwAuthenticateHeader { } for (i, e) in entries.iter().enumerate() { - if i > 0 { f.write_str(", ")?; } + if i > 0 { + f.write_str(", ")?; + } f.write_str(&e.to_string())?; } @@ -385,15 +387,15 @@ impl Display for WwwAuthenticateHeader { #[derive(Debug, PartialEq, Clone)] pub struct AuthorizationHeader { /// Authorization realm - pub realm : String, + pub realm: String, /// Server nonce pub nonce: String, /// Server opaque pub opaque: Option, /// Flag that userhash was used - pub userhash : bool, + pub userhash: bool, /// Hash algorithm - pub algorithm : Algorithm, + pub algorithm: Algorithm, /// Computed digest pub response: String, /// Username or hash (owned because of the computed hash) @@ -428,7 +430,6 @@ impl AuthorizationHeader { prompt: &mut WwwAuthenticateHeader, context: &AuthContext, ) -> Result { - let qop = match &prompt.qop { None => None, Some(vec) => { @@ -453,11 +454,15 @@ impl AuthorizationHeader { opaque: prompt.opaque.clone(), userhash: prompt.userhash, algorithm: prompt.algorithm, - response : String::default(), - username : String::default(), + response: String::default(), + username: String::default(), uri: context.uri.as_ref().into(), qop, - cnonce: context.cnonce.as_ref().map(AsRef::as_ref).map(ToOwned::to_owned), // Will be generated if needed, if build_hash is set and this is None + cnonce: context + .cnonce + .as_ref() + .map(AsRef::as_ref) + .map(ToOwned::to_owned), // Will be generated if needed, if build_hash is set and this is None nc: prompt.nc, }; @@ -479,8 +484,7 @@ impl AuthorizationHeader { /// - cnonce (if it was None before) /// - username copied from context /// - response - pub fn digest(&mut self, context : &AuthContext) - { + pub fn digest(&mut self, context: &AuthContext) { // figure out which QOP option to use let qop_algo = match self.qop { None => QopAlgo::NONE, @@ -492,9 +496,7 @@ impl AuthorizationHeader { QopAlgo::AUTH } } - Some(Qop::AUTH) => { - QopAlgo::AUTH - } + Some(Qop::AUTH) => QopAlgo::AUTH, }; let h = &self.algorithm; @@ -554,7 +556,7 @@ impl AuthorizationHeader { username = context.username, realm = self.realm ) - .as_bytes(), + .as_bytes(), ) } else { context.username.as_ref().to_owned() @@ -653,7 +655,7 @@ impl AuthorizationHeader { if auth.qop.is_some() { if !auth.cnonce.is_some() { - return Err(MissingRequired("cnonce", input.into())) + return Err(MissingRequired("cnonce", input.into())); } } else { // cnonce must not be set if qop is not given, clear it. @@ -676,9 +678,15 @@ impl Display for AuthorizationHeader { entries.push(NamedTag::Quoted("uri", (&self.uri).into())); if self.qop.is_some() && self.cnonce.is_some() { - entries.push(NamedTag::Plain("qop", self.qop.as_ref().unwrap().to_string().into())); + entries.push(NamedTag::Plain( + "qop", + self.qop.as_ref().unwrap().to_string().into(), + )); entries.push(NamedTag::Plain("nc", format!("{:08x}", self.nc).into())); - entries.push(NamedTag::Quoted("cnonce", self.cnonce.as_ref().unwrap().into())); + entries.push(NamedTag::Quoted( + "cnonce", + self.cnonce.as_ref().unwrap().into(), + )); } entries.push(NamedTag::Quoted("response", (&self.response).into())); @@ -689,7 +697,10 @@ impl Display for AuthorizationHeader { // algorithm can be omitted if it is the default value (or in legacy compat mode) if self.qop.is_some() || self.algorithm.algo != AlgorithmType::MD5 { - entries.push(NamedTag::Plain("algorithm", self.algorithm.to_string().into())); + entries.push(NamedTag::Plain( + "algorithm", + self.algorithm.to_string().into(), + )); } if self.userhash { @@ -697,7 +708,9 @@ impl Display for AuthorizationHeader { } for (i, e) in entries.iter().enumerate() { - if i > 0 { f.write_str(", ")?; } + if i > 0 { + f.write_str(", ")?; + } f.write_str(&e.to_string())?; } @@ -756,8 +769,7 @@ mod tests { } #[test] - fn test_parse_header_map2() - { + fn test_parse_header_map2() { let src = r#"realm="api@example.org""#; let map = parse_header_map(src).unwrap(); assert_eq!(map.get("realm").unwrap(), "api@example.org"); @@ -836,38 +848,47 @@ mod tests { }; assert_eq!( -r#"Digest realm="api@example.org", + r#"Digest realm="api@example.org", qop="auth", domain="/my/nice/url /login /logout", algorithm=SHA-512-256, nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK", opaque="HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS", charset=UTF-8, - userhash=true"#.replace(",\n ", ", "), hdr.to_string()); + userhash=true"# + .replace(",\n ", ", "), + hdr.to_string() + ); - hdr.stale=true; - hdr.userhash=false; + hdr.stale = true; + hdr.userhash = false; hdr.opaque = None; hdr.qop = None; assert_eq!( -r#"Digest realm="api@example.org", + r#"Digest realm="api@example.org", domain="/my/nice/url /login /logout", stale=true, algorithm=SHA-512-256, nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK", - charset=UTF-8"#.replace(",\n ", ", "), hdr.to_string()); + charset=UTF-8"# + .replace(",\n ", ", "), + hdr.to_string() + ); hdr.qop = Some(vec![Qop::AUTH, Qop::AUTH_INT]); assert_eq!( -r#"Digest realm="api@example.org", + r#"Digest realm="api@example.org", qop="auth, auth-int", domain="/my/nice/url /login /logout", stale=true, algorithm=SHA-512-256, nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK", - charset=UTF-8"#.replace(",\n ", ", "), hdr.to_string()); + charset=UTF-8"# + .replace(",\n ", ", "), + hdr.to_string() + ); } #[test] @@ -949,7 +970,7 @@ Digest username="Mufasa", response="1949323746fe6a43ef61f9606e7febea", opaque="5ccc069c403ebaf9f0171e9517f40e41" "# - .trim() + .trim() ); // Try round trip @@ -992,7 +1013,7 @@ Digest username="Mufasa", opaque="5ccc069c403ebaf9f0171e9517f40e41", algorithm=MD5 "# - .trim() + .trim() ); // Try round trip @@ -1033,7 +1054,7 @@ Digest username="Mufasa", opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS", algorithm=MD5 "# - .trim() + .trim() ); // Try round trip @@ -1085,7 +1106,7 @@ Digest username="Mufasa", opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS", algorithm=SHA-256 "# - .trim() + .trim() ); // Try round trip