From 59fdd99b635635f4887a49361a754291dabc2ac7 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Mon, 9 Sep 2019 16:39:28 +0200 Subject: net: Introduce enum wkd::Variant. --- net/src/wkd.rs | 72 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 23 deletions(-) (limited to 'net') diff --git a/net/src/wkd.rs b/net/src/wkd.rs index 0f80f937..95d59f42 100644 --- a/net/src/wkd.rs +++ b/net/src/wkd.rs @@ -44,6 +44,29 @@ use crate::openpgp::tpk::TPKParser; use super::{Result, Error}; +/// WKD variants. +/// +/// There are two variants of the URL scheme. `Advanced` should be +/// preferred. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Variant { + /// Advanced variant. + /// + /// This method uses a separate subdomain and is more flexible. + /// This method should be preferred. + Advanced, + /// Direct variant. + /// + /// This method is deprecated. + Direct, +} + +impl Default for Variant { + fn default() -> Self { + Variant::Advanced + } +} + /// Stores the local_part and domain of an email address. pub struct EmailAddress { @@ -118,10 +141,11 @@ impl Url { } /// Returns an URL string from a [`Url`]. - pub fn build(&self, direct_method: T) -> String - where T: Into> { - let direct_method = direct_method.into().unwrap_or(false); - if direct_method { + pub fn build(&self, variant: V) -> String + where V: Into> + { + let variant = variant.into().unwrap_or_default(); + if variant == Variant::Direct { format!("https://{}/.well-known/openpgpkey/hu/{}?l={}", self.domain, self.local_encoded, self.local_part) } else { @@ -132,28 +156,28 @@ impl Url { } /// Returns an [`url::Url`]. - pub fn to_url(&self, direct_method: T) -> Result - where T: Into> { - let url_string = self.build(direct_method); + pub fn to_url(&self, variant: V) -> Result + where V: Into> { + let url_string = self.build(variant); let url_url = url::Url::parse(url_string.as_str())?; Ok(url_url) } /// Returns an [`hyper::Uri`]. - pub fn to_uri(&self, direct_method: T) -> Result - where T: Into> { - let url_string = self.build(direct_method); + pub fn to_uri(&self, variant: V) -> Result + where V: Into> { + let url_string = self.build(variant); let uri = url_string.as_str().parse::()?; Ok(uri) } /// Returns a [`PathBuf`]. - pub fn to_file_path(&self, direct_method: T) -> Result - where T: Into> + pub fn to_file_path(&self, variant: V) -> Result + where V: Into> { // Create the directories string. - let direct_method = direct_method.into().unwrap_or(false); - let url = self.to_url(direct_method)?; + let variant = variant.into().unwrap_or_default(); + let url = self.to_url(variant)?; // Can not create path_buf as: // let path_buf: PathBuf = [url.domain().unwrap(), url.path()] // .iter().collect(); @@ -278,7 +302,8 @@ pub fn get>(email_address: S) let https = HttpsConnector::new(4)?; let client = Client::builder().build::<_, hyper::Body>(https); - Ok((email, client, wkd_url.to_uri(false)?, wkd_url.to_uri(true)?)) + use self::Variant::*; + Ok((email, client, wkd_url.to_uri(Advanced)?, wkd_url.to_uri(Direct)?)) }).and_then(|(email, client, advanced_uri, direct_uri)| { // First, try the Advanced Method. client.get(advanced_uri) @@ -308,16 +333,16 @@ pub fn get>(email_address: S) /// /// If the TPK does not have a well-formed UserID with `domain`, /// `Error::InvalidArgument` is returned. -pub fn insert(base_path: P, domain: S, direct_method: T, +pub fn insert(base_path: P, domain: S, variant: V, tpk: &TPK) -> Result<()> where P: AsRef, S: AsRef, - T: Into> + V: Into> { let base_path = base_path.as_ref(); let domain = domain.as_ref(); - let direct_method = direct_method.into().unwrap_or(false); + let variant = variant.into().unwrap_or_default(); // First, check which UserIDs are in `domain`. let addresses = tpk.userids().filter_map(|uidb| { @@ -341,7 +366,7 @@ pub fn insert(base_path: P, domain: S, direct_method: T, // Finally, create the files. for address in addresses.into_iter() { - let path = base_path.join(address.to_file_path(direct_method)?); + let path = base_path.join(address.to_file_path(variant)?); fs::create_dir_all(path.parent().expect("by construction"))?; let mut keyring = KeyRing::default(); if path.is_file() { @@ -403,6 +428,7 @@ mod tests { use crate::openpgp::tpk::TPKBuilder; use super::*; + use self::Variant::*; #[test] fn encode_local_part_succed() { @@ -439,11 +465,11 @@ mod tests { "https://example.com/\ .well-known/openpgpkey/hu/\ stnkabub89rpcphiz4ppbxixkwyt1pic?l=test1"; - assert_eq!(expected_url, wkd_url.clone().build(true)); + assert_eq!(expected_url, wkd_url.clone().build(Direct)); assert_eq!(url::Url::parse(expected_url).unwrap(), - wkd_url.clone().to_url(true).unwrap()); + wkd_url.clone().to_url(Direct).unwrap()); assert_eq!(expected_url.parse::().unwrap(), - wkd_url.to_uri(true).unwrap()); + wkd_url.to_uri(Direct).unwrap()); } #[test] @@ -463,7 +489,7 @@ mod tests { .well-known/openpgpkey/hu/\ stnkabub89rpcphiz4ppbxixkwyt1pic"; assert_eq!(expected_path, - wkd_url.to_file_path(true).unwrap().to_str().unwrap()); + wkd_url.to_file_path(Direct).unwrap().to_str().unwrap()); } #[test] -- cgit v1.2.3