use chrono::offset::Utc; use curl::{easy, easy::Easy2}; use rand::prelude::*; use ring_compat::signature::ed25519::SigningKey; use tauri::{Manager, State}; use tokio::sync::Mutex; use crate::app_state::AppState; #[derive(Debug)] struct Collector(Vec, Vec, usize); impl easy::Handler for Collector { fn write(&mut self, data: &[u8]) -> Result { self.0.extend_from_slice(data); Ok(data.len()) } fn read(&mut self, data: &mut [u8]) -> Result { let p = self.2; let src: &[u8] = self.1.as_ref(); let n = usize::min(src.len()-p, data.len()); data[..n].copy_from_slice(&src[p..(p+n)]); self.2 = n+p; Ok(n) } fn seek(&mut self, whence: std::io::SeekFrom) -> easy::SeekResult { use std::io::SeekFrom::{Start, End, Current}; match whence { Start(p) => { self.2 = p as usize; easy::SeekResult::Ok }, End(d) => { let p = self.1.len() as i64; if p+d < 0 { easy::SeekResult::Fail } else { self.2 = (p+d) as usize; easy::SeekResult::Ok } }, Current(d) => { let p = self.2 as i64; if p+d < 0 { easy::SeekResult::Fail } else { self.2 = (p+d) as usize; easy::SeekResult::Ok } }, } } } pub fn data_client(file: &str) -> Result, ()> { let mut client = Easy2::new(Collector(Vec::new(), Vec::new(), 0)); let url = format!("https://cloud.seebruecke.org/public.php/webdav/data/{}", file); client.url(&url) .map_err(|_| ())?; client.username(include_str!("cloud_user.txt")).map_err(|_| ())?; client.http_auth(easy::Auth::new().auto(true)).map_err(|_| ())?; client.ssl_cainfo_blob(include_bytes!("isrg-root-x1.pem")) .map_err(|_| ())?; Ok(client) } #[tauri::command] pub async fn pull_data(state: State<'_, Mutex>) -> Result { let mut client = data_client("")?; client.custom_request("PROPFIND").map_err(|_| ())?; client.perform().map_err(|_| ())?; let content = &client.get_ref().0; Ok(String::from_utf8_lossy(content).to_string()) } #[tauri::command] pub async fn push_data(state: State<'_, Mutex>) -> Result { let state = state.lock().await; let key_file = format!("{:016X}.key", state.id); let mut client = data_client(&key_file)?; client.put(true).map_err(|_| ())?; let v_key = state.key.verifying_key(); client.get_mut().1.extend_from_slice(v_key.as_ref()); client.in_filesize(v_key.as_ref().len() as u64); client.upload(true); let perf = client.perform().map_err(|_| ())?; let content = &client.get_ref().0; Ok(String::from_utf8_lossy(content).to_string()) }