tuta_poll/
types.rs

1use crate::crypto;
2use crate::serialize::*;
3use num_enum::{IntoPrimitive, TryFromPrimitive};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7pub type Id = String;
8pub type IdTuple = (Id, Id);
9pub type Base64 = Vec<u8>;
10pub type Aes128Key = [u8; 16];
11
12#[derive(Debug, Deserialize)]
13pub struct Session {
14    #[serde(with = "serde_format")]
15    _format: (),
16    #[serde(rename = "accessToken")]
17    pub access_token: String,
18    pub user: Id,
19}
20
21#[derive(Debug, Deserialize, Clone, Default)]
22pub struct User {
23    #[serde(with = "serde_format")]
24    _format: (),
25    #[serde(rename = "_id")]
26    pub id: Id,
27    pub memberships: Vec<Membership>,
28    #[serde(rename = "userGroup")]
29    pub user_group: UserGroup,
30
31    #[serde(skip)]
32    group_keys: HashMap<Id, Aes128Key>,
33}
34
35impl User {
36    pub fn has_group(&self, group_id: &Id) -> bool {
37        return self.user_group.group == *group_id
38            || self.memberships.iter().any(|m| m.group == *group_id);
39    }
40
41    pub fn unlock_group_keys(&mut self, user_passphrase_key: &Aes128Key) {
42        let user_group_key =
43            crypto::decrypt_key(&user_passphrase_key, &self.user_group.sym_enc_g_key);
44
45        self.group_keys
46            .insert(self.user_group.group.clone(), user_group_key.clone());
47
48        for member in &self.memberships {
49            if let Some(sym) = member.sym_enc_g_key {
50                self.group_keys.insert(
51                    member.group.clone(),
52                    crypto::decrypt_key(&user_group_key, &sym),
53                );
54            }
55        }
56    }
57
58    pub fn get_group_key(&self, group_id: &Id) -> Option<Aes128Key> {
59        self.group_keys.get(group_id).copied()
60    }
61
62    pub fn get_user_group_key(&self) -> Aes128Key {
63        self.group_keys
64            .get(&self.user_group.group)
65            .copied()
66            .unwrap()
67    }
68}
69
70#[derive(Debug, Deserialize, Clone)]
71#[serde(rename_all = "camelCase")]
72pub struct Membership {
73    pub group: Id,
74    #[serde(with = "string_to_enum")]
75    pub group_type: GroupType,
76    #[serde(with = "serde_option_base64_16")]
77    pub sym_enc_g_key: Option<Aes128Key>,
78}
79
80#[derive(Debug, Deserialize, Clone, Default)]
81#[serde(rename_all = "camelCase")]
82pub struct UserGroup {
83    pub group: Id,
84    pub group_info: IdTuple,
85    #[serde(with = "serde_base64_16")]
86    pub sym_enc_g_key: Aes128Key,
87}
88
89pub struct Credentials {
90    pub login: String,
91    pub access_token: String,
92    pub user_id: Id,
93}
94
95#[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
96#[repr(u8)]
97pub enum GroupType {
98    User,
99    Admin,
100    MailingList,
101    Customer,
102    External,
103    Mail,
104    Contact,
105    File,
106    LocalAdmin,
107    Calendar,
108    Template,
109    ContactList,
110}
111
112#[derive(Debug, Deserialize)]
113pub struct GroupInfo {
114    #[serde(with = "serde_base64_16", rename = "_ownerEncSessionKey")]
115    pub owner_enc_session_key: Aes128Key,
116    #[serde(rename = "_ownerGroup")]
117    pub owner_group: Id,
118    #[serde(rename = "_permissions")]
119    pub permissions: Id,
120}
121
122#[derive(Debug, Deserialize, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
123#[repr(u8)]
124pub enum MailFolderType {
125    Custom,
126    Inbox,
127    Sent,
128    Trash,
129    Archive,
130    Spam,
131    Draft,
132}
133
134#[derive(Debug, Deserialize)]
135pub struct Folder {
136    #[serde(with = "serde_format")]
137    _format: (),
138    #[serde(with = "string_to_enum", rename = "folderType")]
139    pub folder_type: MailFolderType,
140    #[serde(rename = "_id")]
141    pub id: (String, String),
142    pub mails: String,
143    #[serde(with = "serde_base64")]
144    pub name: Base64,
145    #[serde(with = "serde_base64_16", rename = "_ownerEncSessionKey")]
146    pub owner_enc_session_key: Aes128Key,
147}
148
149#[derive(Debug, Deserialize, Serialize)]
150#[serde(deny_unknown_fields, rename_all = "camelCase")]
151pub struct Mail {
152    #[serde(with = "serde_format", rename = "_format")]
153    format: (),
154    pub auth_status: String,
155    pub attachments: Vec<(String, String)>,
156    // was not needed yet
157    pub bucket_key: (),
158    pub body: String,
159    pub bcc_recipients: Vec<Sender>,
160    pub cc_recipients: Vec<Sender>,
161    #[serde(with = "serde_base64")]
162    pub confidential: Base64,
163    pub conversation_entry: (String, String),
164    pub different_envelope_sender: Option<String>,
165    pub first_recipient: Sender,
166    pub headers: Option<String>,
167    #[serde(rename = "_id")]
168    pub id: (String, String),
169    #[serde(with = "serde_base64")]
170    pub list_unsubscribe: Base64,
171    pub mail_details: (),
172    pub mail_details_draft: (),
173    #[serde(with = "serde_base64")]
174    pub method: Base64,
175    pub moved_time: String,
176    #[serde(with = "serde_option_base64_16", rename = "_ownerEncSessionKey")]
177    pub owner_enc_session_key: Option<Aes128Key>,
178    #[serde(rename = "_ownerGroup")]
179    pub owner_group: String,
180    #[serde(rename = "_permissions")]
181    pub permissions: Id,
182    pub phishing_status: String,
183    pub received_date: String,
184    pub recipient_count: String,
185    pub reply_tos: Vec<Sender>,
186    pub reply_type: String,
187    pub sent_date: String,
188    pub sender: Sender,
189    pub state: String,
190    #[serde(with = "serde_base64")]
191    pub subject: Base64,
192    pub to_recipients: Vec<Sender>,
193    #[serde(with = "string_to_enum", rename = "unread")]
194    pub read_status: ReadStatus,
195}
196
197#[derive(Debug, Deserialize, Serialize)]
198#[serde(deny_unknown_fields)]
199pub struct Sender {
200    pub address: String,
201    pub contact: (),
202    #[serde(rename = "_id")]
203    pub id: String,
204    #[serde(with = "serde_base64")]
205    pub name: Base64,
206}
207
208#[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
209#[repr(u8)]
210pub enum ReadStatus {
211    Read = 0,
212    Unread = 1,
213}
214
215#[derive(Debug, Deserialize, Serialize)]
216#[serde(rename_all = "camelCase")]
217pub struct Permission {
218    #[serde(with = "serde_format", rename = "_format")]
219    _format: (),
220    #[serde(with = "string_to_enum", rename = "type")]
221    pub permission_type: PermissionType,
222    #[serde(with = "serde_option_base64_16")]
223    pub bucket_enc_session_key: Option<Aes128Key>,
224    #[serde(rename = "_ownerEncSessionKey")]
225    pub owner_enc_session_key: Option<Aes128Key>,
226    #[serde(rename = "_ownerGroup")]
227    pub owner_group: Option<Id>,
228    pub bucket: Option<Bucket>,
229}
230
231#[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
232#[repr(u8)]
233pub enum PermissionType {
234    Public,
235    Symmetric,
236    PublicSymmetric,
237    Unencrypted,
238    External,
239    OwnerList,
240}
241
242#[derive(Debug, Deserialize, Serialize, Clone)]
243#[serde(rename_all = "camelCase")]
244pub struct Bucket {
245    pub bucket_permissions: Id,
246}
247
248#[derive(Debug, Deserialize, Serialize)]
249#[serde(rename_all = "camelCase")]
250pub struct BucketPermission {
251    #[serde(with = "serde_format", rename = "_format")]
252    _format: (),
253    #[serde(with = "string_to_enum", rename = "type")]
254    pub permission_type: BucketPermissionType,
255    #[serde(rename = "_ownerGroup")]
256    pub owner_group: Option<Id>,
257    #[serde(with = "serde_option_base64_16")]
258    pub owner_enc_bucket_key: Option<Aes128Key>,
259    #[serde(with = "serde_option_base64")]
260    pub pub_enc_bucket_key: Option<Base64>,
261    #[serde(with = "serde_option_base64_16")]
262    pub sym_enc_bucket_key: Option<Aes128Key>,
263    pub group: Id,
264}
265
266#[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
267#[repr(u8)]
268pub enum BucketPermissionType {
269    Public = 2,
270    External = 3,
271}
272
273#[derive(Debug, Deserialize, Serialize)]
274#[serde(rename_all = "camelCase")]
275pub struct Group {
276    #[serde(rename = "_id")]
277    pub id: String,
278    pub keys: Vec<KeyPair>,
279}
280
281#[derive(Debug, Deserialize, Serialize)]
282#[serde(rename_all = "camelCase")]
283pub struct KeyPair {
284    #[serde(with = "serde_base64")]
285    pub sym_enc_priv_key: Base64,
286}
287
288#[derive(Debug, Deserialize)]
289#[serde(rename_all = "camelCase")]
290pub struct EntityUpdate {
291    pub event_batch: Vec<Event>,
292}
293
294#[derive(Debug, Deserialize)]
295#[serde(rename_all = "camelCase")]
296pub struct Event {
297    pub instance_id: String,
298    pub instance_list_id: String,
299    #[serde(with = "string_to_enum")]
300    pub operation: OperationType,
301    #[serde(rename = "type")]
302    pub event_type: String, // yes this is really a string
303}
304
305#[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
306#[repr(u8)]
307pub enum OperationType {
308    Create,
309    Update,
310    Delete,
311}