Add some more api entries

This commit is contained in:
Alexander Rosenberg 2024-01-25 00:26:15 -08:00
parent dbdf66012d
commit f73eff2bc7
Signed by: Zander671
GPG Key ID: 5FD0394ADBD72730

View File

@ -85,6 +85,104 @@ pub struct Stats {
pub nb_reply: u32, pub nb_reply: u32,
} }
#[derive(Debug, Deserialize)]
pub struct AliasOptionsSuffix {
pub signed_suffix: String,
pub suffix: String,
pub is_custom: bool,
pub is_premium: bool,
}
#[derive(Debug, Deserialize)]
pub struct AliasOptionsRecommendation {
pub alias: String,
pub hostname: String,
}
#[derive(Debug, Deserialize)]
pub struct AliasOptions {
pub can_create: bool,
pub prefix_suggestion: String,
pub suffixes: Vec<AliasOptionsSuffix>,
pub recommendation: Option<AliasOptionsRecommendation>,
}
#[derive(Debug, Deserialize)]
pub struct AliasMailbox {
pub email: String,
pub id: u64,
}
#[derive(Debug, Deserialize)]
pub struct AliasContact {
pub email: String,
pub name: Option<String>,
pub reverse_alias: String,
}
#[derive(Debug, Deserialize)]
pub struct AliasActivity {
pub action: String,
pub contact: AliasContact,
pub timestamp: u64,
}
#[derive(Debug, Deserialize)]
pub struct Alias {
pub creation_date: String,
pub creation_timestamp: u64,
pub email: String,
pub name: Option<String>,
pub enabled: bool,
pub pinned: bool,
pub note: Option<String>,
pub id: u64,
pub mailbox: AliasMailbox,
pub mailboxes: Vec<AliasMailbox>,
pub nb_block: u64,
pub nb_forward: u64,
pub nb_reply: u64,
pub support_pgp: bool,
pub disable_pgp: bool,
pub latest_activity: Option<AliasActivity>,
}
#[derive(Serialize)]
pub struct NewCustomAliasRequest<'a> {
pub alias_prefix: &'a str,
pub signed_suffix: &'a str,
pub mailbox_ids: &'a [u64],
pub note: &'a Option<&'a str>,
pub name: &'a Option<&'a str>,
}
#[derive(Debug, Deserialize)]
pub struct AliasListResponse {
pub aliases: Vec<Alias>,
}
pub enum NewRandomAliasMode {
UUID, WORD,
}
pub enum AliasListMode {
ALL,
PINNED,
DISABLED,
ENABLED,
}
impl AliasListMode {
pub fn param_name(&self) -> Option<&str> {
match self {
Self::ALL => None,
Self::PINNED => Some("pinned"),
Self::DISABLED => Some("disabled"),
Self::ENABLED => Some("enabled"),
}
}
}
pub enum ErrorKind { pub enum ErrorKind {
State, State,
Json, Json,
@ -192,9 +290,14 @@ impl Context {
} }
async fn get_request( async fn get_request(
&mut self, endpoint: &str, headers: &[(&str, &str)] &mut self, endpoint: &str, params: &[(&str, &str)], headers: &[(&str, &str)],
) -> Result<String, Error> { ) -> Result<String, Error> {
let mut builder = self.client.get(self.url.to_owned() + endpoint); let base_url = self.url.to_owned() + endpoint;
let mut builder = self.client.get(
reqwest::Url::parse_with_params(base_url.as_str(), params)
.map_err(|_| {
Error::new(ErrorKind::Http, "Url parse error")
})?);
for header in headers { for header in headers {
builder = builder.header(header.0, header.1); builder = builder.header(header.0, header.1);
} }
@ -202,11 +305,19 @@ impl Context {
} }
async fn post_request( async fn post_request(
&mut self, endpoint: &str, body: &str &mut self, endpoint: &str, params: &[(&str, &str)],
headers: &[(&str, &str)], body: &str
) -> Result<String, Error> { ) -> Result<String, Error> {
Self::perform_request(self.client.post(self.url.to_owned() + endpoint) let base_url = self.url.to_owned() + endpoint;
.header("Content-Type", "application/json") let mut builder = self.client.post(
.body(body.to_owned())).await reqwest::Url::parse_with_params(base_url.as_str(), params).map_err(|_| {
Error::new(ErrorKind::Http, "Url parse error")
})?).header("Content-Type", "application/json")
.body(body.to_owned());
for header in headers {
builder = builder.header(header.0, header.1);
}
Self::perform_request(builder).await
} }
async fn patch_request( async fn patch_request(
@ -247,7 +358,7 @@ impl Context {
device: &str device: &str
) -> Result<bool, Error> { ) -> Result<bool, Error> {
let req_body = LoginRequest {email, password, device}; let req_body = LoginRequest {email, password, device};
let body = self.post_request("api/auth/login", let body = self.post_request("api/auth/login", &[], &[],
Self::obj_to_json(&req_body)?.as_str()).await?; Self::obj_to_json(&req_body)?.as_str()).await?;
let resp_obj: LoginResponse = Self::json_to_obj(body.as_str())?; let resp_obj: LoginResponse = Self::json_to_obj(body.as_str())?;
if resp_obj.mfa_enabled { if resp_obj.mfa_enabled {
@ -275,7 +386,7 @@ impl Context {
mfa_key: self.mfa_key.as_ref().unwrap().as_str(), mfa_key: self.mfa_key.as_ref().unwrap().as_str(),
device: self.device.as_ref().unwrap().as_str(), device: self.device.as_ref().unwrap().as_str(),
})?; })?;
let body = self.post_request("api/auth/mfa", req_json.as_str()).await?; let body = self.post_request("api/auth/mfa", &[], &[], req_json.as_str()).await?;
let resp_obj: MfaResponse = Self::json_to_obj(body.as_str())?; let resp_obj: MfaResponse = Self::json_to_obj(body.as_str())?;
self.api_key = Some(resp_obj.api_key); self.api_key = Some(resp_obj.api_key);
self.device = None; self.device = None;
@ -289,7 +400,7 @@ impl Context {
pub async fn logout(&mut self) -> Result<(), Error> { pub async fn logout(&mut self) -> Result<(), Error> {
match self.api_key.as_ref() { match self.api_key.as_ref() {
Some(api_key) => { Some(api_key) => {
self.get_request("api/logout", self.get_request("api/logout", &[],
&[("Authentication", api_key.clone().as_str())]).await?; &[("Authentication", api_key.clone().as_str())]).await?;
self.api_key = None; self.api_key = None;
Ok(()) Ok(())
@ -301,7 +412,7 @@ impl Context {
pub async fn get_user_info(&mut self) -> Result<UserInfo, Error> { pub async fn get_user_info(&mut self) -> Result<UserInfo, Error> {
match self.api_key.as_ref() { match self.api_key.as_ref() {
Some(api_key) => { Some(api_key) => {
let res = self.get_request("api/user_info", let res = self.get_request("api/user_info", &[],
&[("Authentication", api_key.clone().as_str())]).await?; &[("Authentication", api_key.clone().as_str())]).await?;
Ok(Self::json_to_obj(&res)?) Ok(Self::json_to_obj(&res)?)
}, },
@ -327,7 +438,112 @@ impl Context {
pub async fn stats(&mut self) -> Result<Stats, Error> { pub async fn stats(&mut self) -> Result<Stats, Error> {
match self.api_key.as_ref() { match self.api_key.as_ref() {
Some(api_key) => { Some(api_key) => {
let res = self.get_request("api/stats", let res = self.get_request("api/stats", &[],
&[("Authentication", api_key.clone().as_str())]).await?;
Ok(Self::json_to_obj(&res)?)
},
None => Err(Error::new(ErrorKind::State, "Not logged in")),
}
}
pub async fn alias_options(&mut self, hostname: Option<&str>) -> Result<AliasOptions, Error> {
match self.api_key.as_ref() {
Some(api_key) => {
let params: Vec<(&str, &str)> = match hostname {
Some(hn) => vec![("hostname", hn)],
None => vec![],
};
let res = self.get_request("api/v5/alias/options", &params,
&[("Authentication", api_key.clone().as_str())]).await?;
Ok(Self::json_to_obj(&res)?)
},
None => Err(Error::new(ErrorKind::State, "Not logged in")),
}
}
pub async fn new_custom_alias(
&mut self, hostname: Option<&str>, alias_prefix: &str,
signed_suffix: &str, mailbox_ids: &[u64], note: Option<&str>,
name: Option<&str>
) -> Result<Alias, Error> {
match self.api_key.as_ref() {
Some(api_key) => {
let params: Vec<(&str, &str)> = match hostname {
Some(hn) => vec![("hostname", hn)],
None => vec![],
};
let req_json = Self::obj_to_json(&NewCustomAliasRequest {
alias_prefix, signed_suffix, mailbox_ids,
name: &note, note: &name})?;
let res = self.post_request("api/v3/alias/custom/new", &params,
&[("Authentication", api_key.clone().as_str())],
req_json.as_str()).await?;
Ok(Self::json_to_obj(&res)?)
},
None => Err(Error::new(ErrorKind::State, "Not logged in")),
}
}
pub async fn new_random_alias(
&mut self, hostname: Option<&str>,
mode: Option<NewRandomAliasMode>, note: &str
) -> Result<Alias, Error> {
match self.api_key.as_ref() {
Some(api_key) => {
let mut params = vec![];
if let Some(hn) = hostname {
params.push(("hostname", hn));
}
if let Some(md) = mode {
params.push(("mode", match md {
NewRandomAliasMode::UUID => "uuid",
NewRandomAliasMode::WORD => "word",
}));
}
let req_json = serde_json::json!({"note": note});
let res = self.post_request("api/alias/random/new", &params,
&[("Authentication", api_key.clone().as_str())],
req_json.as_str().unwrap()).await?;
Ok(Self::json_to_obj(&res)?)
},
None => Err(Error::new(ErrorKind::State, "Not logged in")),
}
}
pub async fn list_aliases(
&mut self, page_id: u64, mode: AliasListMode, query: Option<&str>
) -> Result<Vec<Alias>, Error> {
match self.api_key.as_ref() {
Some(api_key) => {
let page_id_str = u64::to_string(&page_id);
let params = match mode.param_name() {
Some(name) => vec![(name, "true"),
("page_id", page_id_str.as_str())],
None => vec![("page_id", page_id_str.as_str())],
};
let res = match query {
Some(q) => {
let req_json = serde_json::json!({"query": q});
self.post_request("api/v2/aliases", &params,
&[("Authentication", api_key.clone().as_str())],
req_json.as_str().unwrap()).await?
},
None => self.get_request("api/v2/aliases", &params,
&[("Authentication", api_key.clone().as_str())]).await?,
};
Ok(Self::json_to_obj::<AliasListResponse>(&res)?.aliases)
},
None => Err(Error::new(ErrorKind::State, "Not logged in")),
}
}
pub async fn get_alias(
&mut self, alias_id: u64
) -> Result<Alias, Error> {
let endpoint = format!("api/aliases/{alias_id}");
match self.api_key.as_ref() {
Some(api_key) => {
let res = self.get_request(endpoint.as_str(), &[],
&[("Authentication", api_key.clone().as_str())]).await?; &[("Authentication", api_key.clone().as_str())]).await?;
Ok(Self::json_to_obj(&res)?) Ok(Self::json_to_obj(&res)?)
}, },