files_sdk/users/
public_keys.rs1use crate::{FilesClient, PaginationInfo, Result};
10use serde::{Deserialize, Serialize};
11use serde_json::json;
12
13#[derive(Debug, Serialize, Deserialize, Clone)]
15pub struct PublicKeyEntity {
16 pub id: Option<i64>,
18
19 pub title: Option<String>,
21
22 pub user_id: Option<i64>,
24
25 pub username: Option<String>,
27
28 pub fingerprint: Option<String>,
30
31 pub fingerprint_sha256: Option<String>,
33
34 pub created_at: Option<String>,
36
37 pub last_login_at: Option<String>,
39
40 pub status: Option<String>,
42
43 pub generated_private_key: Option<String>,
45
46 pub generated_public_key: Option<String>,
48}
49
50#[derive(Debug, Clone)]
52pub struct PublicKeyHandler {
53 client: FilesClient,
54}
55
56impl PublicKeyHandler {
57 pub fn new(client: FilesClient) -> Self {
59 Self { client }
60 }
61
62 pub async fn list(
88 &self,
89 user_id: Option<i64>,
90 cursor: Option<String>,
91 per_page: Option<i64>,
92 ) -> Result<(Vec<PublicKeyEntity>, PaginationInfo)> {
93 let mut endpoint = "/public_keys".to_string();
94 let mut query_params = Vec::new();
95
96 if let Some(user_id) = user_id {
97 query_params.push(format!("user_id={}", user_id));
98 }
99
100 if let Some(cursor) = cursor {
101 query_params.push(format!("cursor={}", cursor));
102 }
103
104 if let Some(per_page) = per_page {
105 query_params.push(format!("per_page={}", per_page));
106 }
107
108 if !query_params.is_empty() {
109 endpoint.push('?');
110 endpoint.push_str(&query_params.join("&"));
111 }
112
113 let url = format!("{}{}", self.client.inner.base_url, endpoint);
114 let response = reqwest::Client::new()
115 .get(&url)
116 .header("X-FilesAPI-Key", &self.client.inner.api_key)
117 .send()
118 .await?;
119
120 let headers = response.headers().clone();
121 let pagination = PaginationInfo::from_headers(&headers);
122
123 let status = response.status();
124 if !status.is_success() {
125 return Err(crate::FilesError::ApiError {
126 endpoint: None,
127 code: status.as_u16(),
128 message: response.text().await.unwrap_or_default(),
129 });
130 }
131
132 let keys: Vec<PublicKeyEntity> = response.json().await?;
133 Ok((keys, pagination))
134 }
135
136 pub async fn get(&self, id: i64) -> Result<PublicKeyEntity> {
142 let endpoint = format!("/public_keys/{}", id);
143 let response = self.client.get_raw(&endpoint).await?;
144 Ok(serde_json::from_value(response)?)
145 }
146
147 pub async fn create(
155 &self,
156 user_id: i64,
157 title: &str,
158 public_key: &str,
159 ) -> Result<PublicKeyEntity> {
160 let body = json!({
161 "user_id": user_id,
162 "title": title,
163 "public_key": public_key,
164 });
165
166 let response = self.client.post_raw("/public_keys", body).await?;
167 Ok(serde_json::from_value(response)?)
168 }
169
170 pub async fn generate(
180 &self,
181 user_id: i64,
182 title: &str,
183 algorithm: &str,
184 length: Option<i64>,
185 password: Option<&str>,
186 ) -> Result<PublicKeyEntity> {
187 let mut body = json!({
188 "user_id": user_id,
189 "title": title,
190 "generate_keypair": true,
191 "generate_algorithm": algorithm,
192 });
193
194 if let Some(length) = length {
195 body["generate_length"] = json!(length);
196 }
197
198 if let Some(password) = password {
199 body["generate_private_key_password"] = json!(password);
200 }
201
202 let response = self.client.post_raw("/public_keys", body).await?;
203 Ok(serde_json::from_value(response)?)
204 }
205
206 pub async fn update(&self, id: i64, title: &str) -> Result<PublicKeyEntity> {
213 let body = json!({
214 "title": title,
215 });
216
217 let endpoint = format!("/public_keys/{}", id);
218 let response = self.client.patch_raw(&endpoint, body).await?;
219 Ok(serde_json::from_value(response)?)
220 }
221
222 pub async fn delete(&self, id: i64) -> Result<()> {
228 let endpoint = format!("/public_keys/{}", id);
229 self.client.delete_raw(&endpoint).await?;
230 Ok(())
231 }
232}
233
234#[cfg(test)]
235mod tests {
236 use super::*;
237
238 #[test]
239 fn test_handler_creation() {
240 let client = FilesClient::builder().api_key("test-key").build().unwrap();
241 let _handler = PublicKeyHandler::new(client);
242 }
243}