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 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, }
304
305#[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive, Clone)]
306#[repr(u8)]
307pub enum OperationType {
308 Create,
309 Update,
310 Delete,
311}