1use anyhow::Error;
2use serde::{Deserialize, Serialize};
3
4use crate::{http, MAIL_API_URL};
5use crate::http::Client;
6use crate::user::User;
7
8#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Account {
11 pub address: String,
12 pub password: Option<String>,
13 pub quota: i64,
14 pub used: i64,
15 #[serde(rename = "isDisabled")]
16 pub is_disabled: bool,
17 #[serde(rename = "createdAt")]
18 pub created_at: serde_json::Value,
19 #[serde(rename = "updatedAt")]
20 pub updated_at: ::serde_json::Value,
21 #[serde(rename = "@context")]
23 pub context: Option<String>,
24 #[serde(rename = "@id")]
25 pub at_id: Option<String>,
26 #[serde(rename = "@type")]
27 pub type_field: Option<String>,
28 #[serde(rename = "id")]
29 pub id: Option<String>,
30}
31
32impl Account {
33 fn from_user(user: &User) -> Account {
34 Account {
35 address: format!("{}@{}", user.id, user.domain),
36 password: Some(user.password.clone()),
37 quota: 0,
38 used: 0,
39 is_disabled: false,
40 created_at: Default::default(),
41 updated_at: Default::default(),
42 context: None,
43 at_id: None,
44 type_field: None,
45 id: None,
46 }
47 }
48}
49
50pub(crate) async fn create(user: &User) -> Result<Account, Error> {
51 let client = Client::new()?.build()?;
52
53 log::debug!("Creating account for user {:?}", user);
54
55 let json = serde_json::json!(Account::from_user(user));
56 let json_str = json.to_string();
57 let response = client
58 .post(format!("{}/accounts", MAIL_API_URL).as_str())
59 .body(json_str)
60 .send()
61 .await?;
62
63 let code = response.status();
64
65 let response = response
66 .text()
67 .await?;
68
69 http::check_response_status(&code, &response).await?;
70
71 log::trace!("Created account: {}", response);
72 Ok(serde_json::from_str(&response)?)
73}
74
75pub(crate) async fn get(token: &str, id: &str) -> Result<Account, Error> {
76 let client = Client::new()?.with_auth(&token)?.build()?;
77
78 log::debug!("Searching for account with id {}", id);
79
80 let response = client
81 .get(&format!("{}/accounts/{}", MAIL_API_URL, id))
82 .send()
83 .await?;
84
85 let code = response.status();
86
87 let response = response
88 .text()
89 .await?;
90
91 http::check_response_status(&code, &response).await?;
92
93 log::trace!("Retrieved a user: {}", response);
94 Ok(serde_json::from_str(&response)?)
95}
96
97pub(crate) async fn delete(token: &str, id: &str) -> Result<(), Error> {
98 let client = Client::new()?.with_auth(&token)?.build()?;
99
100 log::debug!("Searching for account with id {}", id);
101
102
103 let response = client
104 .delete(&format!("{}/accounts/{}", MAIL_API_URL, id))
105 .send()
106 .await?;
107
108 let code = response.status();
109
110 http::check_response_status(&code, "").await?;
111
112 log::trace!("Deleted user with id {}", id);
113 Ok(())
114}
115
116pub(crate) async fn me(token: &str) -> Result<Account, Error> {
117 let client = Client::new()?.with_auth(&token)?.build()?;
118
119 log::debug!("Getting me");
120
121 let builder = client
122 .get(&format!("{}/me", MAIL_API_URL));
123
124 let response = builder
125 .send()
126 .await?;
127
128 let code = response.status();
129
130 let response = response
131 .text()
132 .await?;
133
134 http::check_response_status(&code, &response).await?;
135
136 log::trace!("Retrieved me: {}", response);
137 Ok(serde_json::from_str(&response)?)
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143 use crate::token;
144
145 #[tokio::test]
146 async fn test_accounts_create() -> Result<(), Error> {
147 pretty_env_logger::try_init().ok();
148
149 let user = User::default().with_domain(&crate::domains::domains().await?.any().domain);
150 assert_eq!(
151 create(&user)
152 .await?
153 .address
154 .as_str()
155 .is_empty(),
156 false
157 );
158 Ok(())
159 }
160
161 #[tokio::test]
162 async fn test_accounts() -> Result<(), Error> {
163 pretty_env_logger::try_init().ok();
164 let user = User::default().with_domain(&crate::domains::domains().await?.any().domain);
165
166 let create = create(&user).await.unwrap();
167
168 let token = token(&user).await.unwrap();
169
170
171 assert_eq!(
172 create
173 .address
174 .as_str()
175 .is_empty(),
176 false
177 );
178
179 let id = create.id.unwrap();
180
181 let get = get(&token.token, &id).await?;
182
183 assert_eq!(get.id.unwrap(), id.clone());
184
185 let me = me(&token.token).await?;
186
187 assert_eq!(me.id.unwrap(), id.clone());
188
189 delete(&token.token, &id).await.unwrap();
190
191 Ok(())
192 }
193}