Skip to content

Commit

Permalink
refactor(types): renamed types
Browse files Browse the repository at this point in the history
  • Loading branch information
Guusvanmeerveld committed Aug 10, 2023
1 parent 948cead commit e080593
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 137 deletions.
90 changes: 31 additions & 59 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use crate::{
error::{ErrorKind, Result},
failed,
http::{BasicCredentials, Http},
types::{candidate::CandidateType, AutodiscoverResponse, ConfigResult, RedirectType},
types::{
request::AutodiscoverRequest,
response::{AutodiscoverResponse, AutodiscoverResult, RedirectType},
},
};

pub struct Client {
Expand All @@ -16,30 +19,6 @@ pub struct Client {
dns: Dns,
}

pub struct AutodiscoverRequest {
use_auth: bool,
url: String,
email: String,
}

impl AutodiscoverRequest {
pub fn new<U: Into<String>, E: Into<String>>(url: U, email: E, use_auth: bool) -> Self {
Self {
url: url.into(),
email: email.into(),
use_auth,
}
}

pub fn set_url(&mut self, url: String) {
self.url = url;
}

pub fn set_email(&mut self, email: String) {
self.email = email;
}
}

impl Client {
pub fn new<B: Into<BasicCredentials>>(creds: B) -> Result<Self> {
let http = Http::new()?;
Expand All @@ -56,27 +35,27 @@ impl Client {

async fn handle_config_result(
&self,
result: ConfigResult,
result: AutodiscoverResult,
mut request: AutodiscoverRequest,
) -> Result<AutodiscoverResponse> {
match result {
ConfigResult::Ok(config) => Ok(config),
ConfigResult::Error(error) => failed!(
AutodiscoverResult::Ok(config) => Ok(config),
AutodiscoverResult::Error(error) => failed!(
ErrorKind::InvalidConfig,
"The received config is invalid: {}",
error.message(),
),
ConfigResult::Redirect(redirect_type) => {
AutodiscoverResult::Redirect(redirect_type) => {
match redirect_type {
RedirectType::Email(email_addr) => {
if email_addr == request.email {
if email_addr == request.email() {
failed!(ErrorKind::InvalidConfig, "The returned config redirects us to the same email address that we are already requesting");
}

request.set_email(email_addr);
}
RedirectType::Url(url) => {
if url == request.url {
if url == request.url() {
failed!(ErrorKind::InvalidConfig, "The returned config redirects us to the same url that we are already requesting");
}

Expand All @@ -97,41 +76,34 @@ impl Client {
) -> Result<AutodiscoverResponse> {
let request: AutodiscoverRequest = request.into();

let url = &request.url;
let email = &request.email;
let url = request.url();
let payload = request.payload()?;

if let Some(candidate_type) = CandidateType::from_url(url) {
let body = candidate_type.create_request_body(email)?;
let method = if request.auth_required() {
Method::POST
} else {
Method::GET
};

let method = if request.use_auth {
Method::POST
} else {
Method::GET
};
let creds = if request.auth_required() {
Some(&self.creds)
} else {
None
};

let creds = if request.use_auth {
Some(&self.creds)
} else {
None
};
match self.http.fetch_xml(url, method, payload, creds).await {
Ok(bytes) => {
let request_protocol = request.protocol()?;

match self.http.fetch_xml(url, method, body, creds).await {
Ok(bytes) => {
let config_result = candidate_type.parse_config(bytes)?;
let config_result = request_protocol.parse_response(bytes)?;

let config = self.handle_config_result(config_result, request).await?;
let config = self.handle_config_result(config_result, request).await?;

return Ok(config);
}
Err(err) => {
failed!(ErrorKind::HttpRequest, "Error fetching {}: {:?}", url, err)
}
return Ok(config);
}
Err(err) => {
failed!(ErrorKind::HttpRequest, "Error fetching {}: {:?}", url, err)
}
} else {
failed!(
ErrorKind::InvalidRequestUrl,
"The request url does not have a valid extension"
)
}
}

Expand Down
16 changes: 9 additions & 7 deletions src/email.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use log::warn;
use validator::validate_email;

use crate::{
client::{AutodiscoverRequest, Client},
client::Client,
// ldap::Ldap,
error::{ErrorKind, Result},
failed,
types::{candidate::CandidateType, AutodiscoverResponse},
types::{protocol::Protocol, request::AutodiscoverRequest, response::AutodiscoverResponse},
};

const INVALID_EMAIL_MESSAGE: &str = "The given email address is invalid";
Expand Down Expand Up @@ -61,12 +61,12 @@ pub async fn from_email<E: AsRef<str>, P: AsRef<str>, U: AsRef<str>>(
format!(
"https://autodiscover.{}/autodiscover/autodiscover.{}",
domain,
CandidateType::POX
Protocol::POX
),
format!(
"https://{}/autodiscover/autodiscover.{}",
domain,
CandidateType::POX
Protocol::POX
),
];

Expand Down Expand Up @@ -111,7 +111,7 @@ pub async fn from_email<E: AsRef<str>, P: AsRef<str>, U: AsRef<str>>(
let candidate = format!(
"http://autodiscover.{}/autodiscover/autodiscover.{}",
domain,
CandidateType::POX
Protocol::POX
);

let request = AutodiscoverRequest::new(candidate, email.as_ref(), false);
Expand All @@ -133,7 +133,7 @@ pub async fn from_email<E: AsRef<str>, P: AsRef<str>, U: AsRef<str>>(
"https://{}:{}/autodiscover/autodiscover.{}",
autodiscover_domain,
autodiscover_port,
CandidateType::POX
Protocol::POX
);

let request = AutodiscoverRequest::new(candidate, email.as_ref(), true);
Expand Down Expand Up @@ -182,12 +182,14 @@ mod test {
env_logger::init();
dotenv::dotenv().unwrap();

from_email(
let config = from_email(
env::var("EMAIL").unwrap(),
env::var("PASSWORD").ok(),
env::var("USERNAME").ok(),
)
.await
.unwrap();

println!("{:?}", config)
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ mod email;
mod error;
mod http;
mod ldap;
mod types;
pub mod types;

pub use email::from_email;
43 changes: 3 additions & 40 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,4 @@
pub mod candidate;
pub mod pox;
// mod soap;

// pub use soap::SoapConfig;
pub use pox::Autodiscover as PoxAutodiscover;
use pox::Response as PoxResponse;

pub enum ConfigResult {
Ok(AutodiscoverResponse),
Redirect(RedirectType),
Error(Error),
}

impl ConfigResult {
pub fn error<M: Into<String>>(message: M) -> Self {
ConfigResult::Error(Error {
message: message.into(),
})
}
}

pub enum RedirectType {
Url(String),
Email(String),
}

pub struct Error {
message: String,
}

impl Error {
pub fn message(&self) -> &str {
self.message.as_ref()
}
}

#[derive(Debug)]
pub enum AutodiscoverResponse {
Pox(PoxResponse),
}
pub mod protocol;
pub mod request;
pub mod response;
18 changes: 8 additions & 10 deletions src/types/pox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::io::Read;

use serde::{Deserialize, Serialize};

use super::{AutodiscoverResponse, ConfigResult, RedirectType};
use super::response::{AutodiscoverResponse, AutodiscoverResult, RedirectType};

use crate::{
constants::{DEFAULT_MICROSOFT_REQUEST_SCHEMA, DEFAULT_MICROSOFT_RESPONSE_SCHEMA},
Expand Down Expand Up @@ -345,24 +345,24 @@ pub struct NetworkRequirements {
ipv6_end: String,
}

impl Into<ConfigResult> for Autodiscover {
fn into(self) -> ConfigResult {
impl Into<AutodiscoverResult> for Autodiscover {
fn into(self) -> AutodiscoverResult {
if let Some(response) = self.into_response() {
if let Some(account) = response.account() {
if let Some(action_type) = account.action_type() {
let redirect_type = match action_type {
Action::RedirectAddr => match account.redirect_addr() {
Some(addr) => Some(RedirectType::Email(addr.to_string())),
None => {
return ConfigResult::error(
return AutodiscoverResult::error(
"Missing redirect address when it should be available",
)
}
},
Action::RedirectUrl => match account.redirect_url() {
Some(url) => Some(RedirectType::Url(url.to_string())),
None => {
return ConfigResult::error(
return AutodiscoverResult::error(
"Missing redirect url when it should be available",
)
}
Expand All @@ -371,16 +371,14 @@ impl Into<ConfigResult> for Autodiscover {
};

if let Some(redirect) = redirect_type {
return ConfigResult::Redirect(redirect);
return AutodiscoverResult::Redirect(redirect);
}
}
}

return ConfigResult::Ok(AutodiscoverResponse::Pox(response));
return AutodiscoverResult::Ok(AutodiscoverResponse::Pox(response));
}

ConfigResult::Error(super::Error {
message: String::new(),
})
AutodiscoverResult::error("Config did not contain a response value")
}
}
30 changes: 10 additions & 20 deletions src/types/candidate.rs → src/types/protocol.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
use std::{
fmt::Display,
io::{self},
path::Path,
};
use std::{fmt::Display, io, path::Path};

use bytes::Bytes;
use log::debug;
use reqwest::IntoUrl;

use crate::{
error::Result,
types::{
// SoapConfig
ConfigResult,
PoxAutodiscover,
},
};
use super::{pox::Autodiscover as PoxAutodiscover, response::AutodiscoverResult};
use crate::error::Result;

pub enum CandidateType {
pub enum Protocol {
// SOAP,
POX,
}

impl Display for CandidateType {
impl Display for Protocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.file_extension())
}
}

impl CandidateType {
impl Protocol {
/// Create the corresponding file extension for the current protocol.
pub fn file_extension(&self) -> String {
let ext = match self {
CandidateType::POX => "xml",
Protocol::POX => "xml",
// CandidateType::SOAP => "svc",
};

Expand Down Expand Up @@ -64,7 +54,7 @@ impl CandidateType {

pub fn create_request_body<E: AsRef<str>>(&self, email_address: E) -> Result<Bytes> {
match &self {
CandidateType::POX => {
Protocol::POX => {
let request_config = PoxAutodiscover::create_request(email_address.as_ref());

let config_string = serde_xml_rs::to_string(&request_config)?;
Expand All @@ -76,11 +66,11 @@ impl CandidateType {
}
}

pub fn parse_config<B: AsRef<[u8]>>(&self, bytes: B) -> Result<ConfigResult> {
pub fn parse_response<B: AsRef<[u8]>>(&self, bytes: B) -> Result<AutodiscoverResult> {
let reader = io::Cursor::new(bytes);

match &self {
CandidateType::POX => {
Protocol::POX => {
let config = PoxAutodiscover::from_xml(reader)?;

Ok(config.into())
Expand Down
Loading

0 comments on commit e080593

Please sign in to comment.