flowsurface_data/config/
auth.rs1use exchange::proxy::{Proxy, ProxyAuth};
2
3const PROXY_KEYCHAIN_SERVICE: &str = "flowsurface.proxy";
6
7fn proxy_entry_for(proxy: &Proxy) -> Result<keyring::Entry, keyring::Error> {
8 let key = proxy.to_url_string_no_auth();
9 keyring::Entry::new(PROXY_KEYCHAIN_SERVICE, &key)
10}
11
12pub fn load_proxy_auth(proxy: &Proxy) -> Option<ProxyAuth> {
17 let key = proxy.to_url_string_no_auth();
18
19 let entry = match proxy_entry_for(proxy) {
20 Ok(e) => e,
21 Err(err) => {
22 log::warn!(
23 "Keychain entry init failed for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
24 );
25 return None;
26 }
27 };
28
29 let secret = match entry.get_password() {
30 Ok(s) => s,
31 Err(err) => {
32 log::info!(
33 "No proxy auth in keychain for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
34 );
35 return None;
36 }
37 };
38
39 match serde_json::from_str::<ProxyAuth>(&secret) {
40 Ok(auth) => Some(auth),
41 Err(err) => {
42 log::warn!(
43 "Proxy auth in keychain is invalid JSON for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
44 );
45 None
46 }
47 }
48}
49
50pub fn save_proxy_auth(proxy: &Proxy) {
55 let key = proxy.to_url_string_no_auth();
56
57 let Some(auth) = proxy.auth() else {
58 log::info!(
59 "Not saving proxy auth: auth is None (service={PROXY_KEYCHAIN_SERVICE} key={key})"
60 );
61 return;
62 };
63
64 let entry = match proxy_entry_for(proxy) {
65 Ok(e) => e,
66 Err(err) => {
67 log::warn!(
68 "Keychain entry init failed for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
69 );
70 return;
71 }
72 };
73
74 let secret = match serde_json::to_string(auth) {
75 Ok(s) => s,
76 Err(err) => {
77 log::warn!(
78 "Failed to serialize proxy auth for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
79 );
80 return;
81 }
82 };
83
84 match entry.set_password(&secret) {
85 Ok(()) => {
86 log::info!("Stored proxy auth in keychain (service={PROXY_KEYCHAIN_SERVICE} key={key})")
87 }
88 Err(err) => {
89 log::warn!(
90 "Failed to store proxy auth in keychain (service={PROXY_KEYCHAIN_SERVICE} key={key}): {err}"
91 );
92 }
93 }
94}
95
96pub fn delete_proxy_auth(proxy: &Proxy) {
101 let key = proxy.to_url_string_no_auth();
102 let entry = match proxy_entry_for(proxy) {
103 Ok(e) => e,
104 Err(err) => {
105 log::warn!(
106 "Keychain entry init failed for service={PROXY_KEYCHAIN_SERVICE} key={key}: {err}"
107 );
108 return;
109 }
110 };
111 match entry.delete_credential() {
112 Ok(()) => log::info!(
113 "Deleted proxy auth from keychain (service={PROXY_KEYCHAIN_SERVICE} key={key})"
114 ),
115 Err(keyring::Error::NoEntry) => { }
116 Err(err) => log::warn!(
117 "Failed to delete proxy auth from keychain (service={PROXY_KEYCHAIN_SERVICE} key={key}): {err}"
118 ),
119 }
120}
121
122const SERVER_KEYCHAIN_SERVICE: &str = "flowsurface.server";
125
126fn server_entry_for(url: &str) -> Result<keyring::Entry, keyring::Error> {
127 keyring::Entry::new(SERVER_KEYCHAIN_SERVICE, url)
128}
129
130pub fn load_server_token(url: &str) -> Option<String> {
135 let entry = match server_entry_for(url) {
136 Ok(e) => e,
137 Err(err) => {
138 log::warn!(
139 "Keychain entry init failed for service={SERVER_KEYCHAIN_SERVICE} key={url}: {err}"
140 );
141 return None;
142 }
143 };
144
145 match entry.get_password() {
146 Ok(token) => {
147 log::info!(
148 "Loaded server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url})"
149 );
150 Some(token)
151 }
152 Err(keyring::Error::NoEntry) => {
153 log::info!(
154 "No server auth token in keychain for service={SERVER_KEYCHAIN_SERVICE} key={url}"
155 );
156 None
157 }
158 Err(err) => {
159 log::warn!(
160 "Failed to read server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url}): {err}"
161 );
162 None
163 }
164 }
165}
166
167pub fn save_server_token(url: &str, token: &str) {
171 let entry = match server_entry_for(url) {
172 Ok(e) => e,
173 Err(err) => {
174 log::warn!(
175 "Keychain entry init failed for service={SERVER_KEYCHAIN_SERVICE} key={url}: {err}"
176 );
177 return;
178 }
179 };
180
181 match entry.set_password(token) {
182 Ok(()) => log::info!(
183 "Stored server auth token in keychain (service={SERVER_KEYCHAIN_SERVICE} key={url})"
184 ),
185 Err(err) => log::warn!(
186 "Failed to store server auth token in keychain (service={SERVER_KEYCHAIN_SERVICE} key={url}): {err}"
187 ),
188 }
189}
190
191pub fn delete_server_token(url: &str) {
195 let entry = match server_entry_for(url) {
196 Ok(e) => e,
197 Err(err) => {
198 log::warn!(
199 "Keychain entry init failed for service={SERVER_KEYCHAIN_SERVICE} key={url}: {err}"
200 );
201 return;
202 }
203 };
204 match entry.delete_credential() {
205 Ok(()) => log::info!(
206 "Deleted server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url})"
207 ),
208 Err(keyring::Error::NoEntry) => { }
209 Err(err) => log::warn!(
210 "Failed to delete server auth token from keychain (service={SERVER_KEYCHAIN_SERVICE} key={url}): {err}"
211 ),
212 }
213}