citadel_types/proto/
mod.rs

1use crate::crypto::{CryptoParameters, SecrecyMode, SecurityLevel};
2use crate::prelude::HeaderObfuscatorSettings;
3use crate::utils;
4use serde::{Deserialize, Serialize};
5use std::fmt::{Debug, Display, Formatter};
6use std::path::PathBuf;
7use uuid::Uuid;
8
9#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
10/// If force_login is true, the protocol will disconnect any previously existent sessions in the session manager attributed to the account logging-in (so long as login succeeds)
11/// The default is a Standard login that will with force_login set to false
12pub enum ConnectMode {
13    Standard { force_login: bool },
14    Fetch { force_login: bool },
15}
16
17impl Default for ConnectMode {
18    fn default() -> Self {
19        Self::Standard { force_login: false }
20    }
21}
22
23#[derive(Serialize, Deserialize, Debug, Clone)]
24pub struct VirtualObjectMetadata {
25    pub name: String,
26    pub date_created: String,
27    pub author: String,
28    pub plaintext_length: usize,
29    pub group_count: usize,
30    pub object_id: ObjectId,
31    pub cid: u64,
32    pub transfer_type: TransferType,
33}
34
35#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
36#[repr(transparent)]
37pub struct ObjectId(pub u128);
38
39impl Debug for ObjectId {
40    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41        write!(f, "{}", self.0)
42    }
43}
44
45impl Display for ObjectId {
46    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
47        Debug::fmt(self, f)
48    }
49}
50
51impl ObjectId {
52    pub fn random() -> Self {
53        Uuid::new_v4().as_u128().into()
54    }
55
56    pub const fn zero() -> Self {
57        Self(0)
58    }
59}
60
61impl From<u128> for ObjectId {
62    fn from(value: u128) -> Self {
63        Self(value)
64    }
65}
66
67impl VirtualObjectMetadata {
68    pub fn serialize(&self) -> Vec<u8> {
69        bincode::serialize(self).unwrap()
70    }
71
72    pub fn deserialize_from<'a, T: AsRef<[u8]> + 'a>(input: T) -> Option<Self> {
73        bincode::deserialize(input.as_ref()).ok()
74    }
75
76    pub fn get_security_level(&self) -> Option<SecurityLevel> {
77        match &self.transfer_type {
78            TransferType::FileTransfer => None,
79            TransferType::RemoteEncryptedVirtualFilesystem { security_level, .. } => {
80                Some(*security_level)
81            }
82        }
83    }
84}
85
86#[derive(Debug, Clone, Copy, Eq, PartialEq)]
87pub enum ObjectTransferOrientation {
88    Receiver { is_revfs_pull: bool },
89    Sender,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[allow(variant_size_differences)]
94pub enum ObjectTransferStatus {
95    TransferBeginning,
96    ReceptionBeginning(PathBuf, VirtualObjectMetadata),
97    // relative group_id, total groups, Mb/s
98    TransferTick(usize, usize, f32),
99    ReceptionTick(usize, usize, f32),
100    TransferComplete,
101    ReceptionComplete,
102    Fail(String),
103}
104
105impl ObjectTransferStatus {
106    pub fn is_tick_type(&self) -> bool {
107        matches!(
108            self,
109            ObjectTransferStatus::TransferTick(_, _, _)
110                | ObjectTransferStatus::ReceptionTick(_, _, _)
111        )
112    }
113
114    /// Even if an error, returns true if the file transfer is done
115    pub fn is_finished_type(&self) -> bool {
116        matches!(
117            self,
118            ObjectTransferStatus::TransferComplete
119                | ObjectTransferStatus::ReceptionComplete
120                | ObjectTransferStatus::Fail(_)
121        )
122    }
123}
124
125impl std::fmt::Display for ObjectTransferStatus {
126    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
127        match self {
128            ObjectTransferStatus::TransferBeginning => {
129                write!(f, "Transfer beginning")
130            }
131
132            ObjectTransferStatus::ReceptionBeginning(_, vfm) => {
133                write!(f, "Download for object {vfm:?} beginning")
134            }
135
136            ObjectTransferStatus::TransferTick(relative_group_id, total_groups, transfer_rate) => {
137                utils::print_tick(f, *relative_group_id, *total_groups, *transfer_rate)
138            }
139
140            ObjectTransferStatus::ReceptionTick(relative_group_id, total_groups, transfer_rate) => {
141                utils::print_tick(f, *relative_group_id, *total_groups, *transfer_rate)
142            }
143
144            ObjectTransferStatus::TransferComplete => {
145                write!(f, "Transfer complete")
146            }
147
148            ObjectTransferStatus::ReceptionComplete => {
149                write!(f, "Download complete")
150            }
151
152            ObjectTransferStatus::Fail(reason) => {
153                write!(f, "Failure. Reason: {reason}")
154            }
155        }
156    }
157}
158
159#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
160pub struct SessionSecuritySettings {
161    pub security_level: SecurityLevel,
162    pub secrecy_mode: SecrecyMode,
163    pub crypto_params: CryptoParameters,
164    pub header_obfuscator_settings: HeaderObfuscatorSettings,
165}
166
167#[derive(Debug, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Default)]
168pub enum UdpMode {
169    Enabled,
170    #[default]
171    Disabled,
172}
173
174#[derive(Clone, Debug, Serialize, Deserialize)]
175pub enum MemberState {
176    EnteredGroup { cids: Vec<u64> },
177    LeftGroup { cids: Vec<u64> },
178}
179
180#[derive(Copy, Clone, Debug, PartialEq)]
181pub enum GroupMemberAlterMode {
182    Leave,
183    Kick,
184}
185
186#[derive(Serialize, Deserialize, Debug, Clone)]
187/// Options for creating message groups
188pub struct MessageGroupOptions {
189    pub group_type: GroupType,
190    pub id: u128,
191}
192
193impl Default for MessageGroupOptions {
194    fn default() -> Self {
195        Self {
196            group_type: GroupType::Private,
197            id: Uuid::new_v4().as_u128(),
198        }
199    }
200}
201
202#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)]
203pub enum GroupType {
204    /// A public group is a group where any user registered to the owner can join
205    Public,
206    /// A private group is a group where the group can only be joined when the owner
207    /// sends out Invitation requests to mutually-registered peers
208    Private,
209}
210
211#[derive(Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
212pub struct MessageGroupKey {
213    pub cid: u64,
214    pub mgid: u128,
215}
216
217impl MessageGroupKey {
218    pub fn new(cid: u64, mgid: u128) -> Self {
219        Self { cid, mgid }
220    }
221}
222
223impl std::fmt::Debug for MessageGroupKey {
224    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
225        write!(f, "{self}")
226    }
227}
228
229impl std::fmt::Display for MessageGroupKey {
230    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
231        write!(f, "[{}:{}]", self.cid, self.mgid)
232    }
233}
234
235#[derive(Clone, Debug, Serialize, Deserialize)]
236pub enum TransferType {
237    FileTransfer,
238    RemoteEncryptedVirtualFilesystem {
239        virtual_path: PathBuf,
240        security_level: SecurityLevel,
241    },
242}