bkbh/src-tauri/src/data_door.rs
Bianca Fürstenau bd40e5c8d8 Refactor
2025-02-10 18:39:06 +01:00

91 lines
2.5 KiB
Rust

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<u8>, Vec<u8>, usize);
impl easy::Handler for Collector {
fn write(&mut self, data: &[u8]) -> Result<usize, easy::WriteError> {
self.0.extend_from_slice(data);
Ok(data.len())
}
fn read(&mut self, data: &mut [u8]) -> Result<usize, easy::ReadError> {
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<Easy2<Collector>, ()> {
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<AppState>>) -> Result<String, ()> {
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<AppState>>) -> Result<String, ()> {
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())
}