1use std::fmt;
4use std::net::Ipv4Addr;
5
6use crate::AUTH_KEY_SIZE;
7
8const DC_ADDRESSES: [(i32, Ipv4Addr, u16); 5] = [
10 (1, Ipv4Addr::new(149, 154, 175, 53), 443),
11 (2, Ipv4Addr::new(149, 154, 167, 51), 443),
12 (3, Ipv4Addr::new(149, 154, 175, 100), 443),
13 (4, Ipv4Addr::new(149, 154, 167, 91), 443),
14 (5, Ipv4Addr::new(91, 108, 56, 130), 443),
15];
16
17pub struct Account {
19 index: i32,
21 dc_id: i32,
23 user_id: i64,
25 auth_key: [u8; AUTH_KEY_SIZE],
27}
28
29impl fmt::Debug for Account {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.debug_struct("Account")
32 .field("index", &self.index)
33 .field("dc_id", &self.dc_id)
34 .field("user_id", &"<redacted>")
35 .field("auth_key", &"<redacted>")
36 .finish()
37 }
38}
39
40impl Account {
41 pub(crate) fn new(index: i32, dc_id: i32, user_id: i64, auth_key: [u8; AUTH_KEY_SIZE]) -> Self {
43 Self {
44 index,
45 dc_id,
46 user_id,
47 auth_key,
48 }
49 }
50
51 pub fn index(&self) -> i32 {
53 self.index
54 }
55
56 pub fn dc_id(&self) -> i32 {
58 self.dc_id
59 }
60
61 pub fn user_id(&self) -> i64 {
65 self.user_id
66 }
67
68 pub fn auth_key_bytes(&self) -> &[u8; AUTH_KEY_SIZE] {
72 &self.auth_key
73 }
74
75 pub fn to_grammers_session_data(&self) -> grammers_session::SessionData {
80 use grammers_session::{types::DcOption, SessionData};
81 use std::net::{SocketAddrV4, SocketAddrV6};
82
83 let (ip, port) = DC_ADDRESSES
85 .iter()
86 .find(|(id, _, _)| *id == self.dc_id)
87 .map(|(_, ip, port)| (*ip, *port))
88 .unwrap_or((Ipv4Addr::new(149, 154, 167, 51), 443));
89
90 let ipv4 = ip;
91 let ipv6 = ipv4.to_ipv6_mapped();
92
93 let mut session_data = SessionData {
94 home_dc: self.dc_id,
95 ..SessionData::default()
96 };
97
98 if let Some(dc_option) = session_data.dc_options.get_mut(&self.dc_id) {
100 dc_option.auth_key = Some(self.auth_key);
101 } else {
102 session_data.dc_options.insert(
103 self.dc_id,
104 DcOption {
105 id: self.dc_id,
106 ipv4: SocketAddrV4::new(ipv4, port),
107 ipv6: SocketAddrV6::new(ipv6, port, 0, 0),
108 auth_key: Some(self.auth_key),
109 },
110 );
111 }
112
113 session_data
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_account_creation() {
123 let auth_key = [0xAB; AUTH_KEY_SIZE];
124 let account = Account::new(0, 2, 12345678, auth_key);
125
126 assert_eq!(account.index(), 0);
127 assert_eq!(account.dc_id(), 2);
128 assert_eq!(account.user_id(), 12345678);
129 assert_eq!(account.auth_key_bytes(), &auth_key);
130 }
131
132 #[test]
133 fn debug_redacts_account_identity_and_auth_key() {
134 let account = Account::new(0, 2, 12_345_678, [0xAB; AUTH_KEY_SIZE]);
135 let debug = format!("{account:?}");
136
137 assert!(debug.contains("<redacted>"));
138 assert!(!debug.contains("12345678"));
139 assert!(!debug.contains("171, 171"));
140 }
141}