add pc boot support, update cargo.lock
All checks were successful
build docker container automatically / build (push) Successful in 7m7s
All checks were successful
build docker container automatically / build (push) Successful in 7m7s
This commit is contained in:
1293
Cargo.lock
generated
1293
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ dioxus-asset-resolver = "0.7.4"
|
||||
dioxus-html = "0.7.3"
|
||||
dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false }
|
||||
futures = "0.3.32"
|
||||
pbkdf2 = { version = "0.13.0", features = ["sha2", "password-hash", "mcf", "alloc"] }
|
||||
random-string = "1.1.0"
|
||||
reqwest = { version = "0.13.2", features = ["stream"] }
|
||||
serde = "1.0.228"
|
||||
|
||||
10
gen_pass.py
Normal file
10
gen_pass.py
Normal file
@ -0,0 +1,10 @@
|
||||
from passlib.hash import pbkdf2_sha512
|
||||
|
||||
def pbkdf2_sha512_mcf(password: str) -> str:
|
||||
return pbkdf2_sha512.using(
|
||||
rounds=100_000,
|
||||
salt_size=16,
|
||||
).hash(password)
|
||||
|
||||
p = input("pass (will echo) :")
|
||||
print(pbkdf2_sha512_mcf(p))
|
||||
87
src/api/boot.rs
Normal file
87
src/api/boot.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use httpserver::config::ServerConfig;
|
||||
|
||||
use pbkdf2::{
|
||||
Algorithm::Pbkdf2Sha512, PasswordVerifier, Pbkdf2, mcf::PasswordHash
|
||||
};
|
||||
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use std::error::Error;
|
||||
|
||||
static COMMANDS: [(&str, u8); 3] = [("start", 0x1) , ("stop", 0x2), ("reboot", 0x3)];
|
||||
|
||||
#[post("/api/pc/boot")]
|
||||
async fn pc_boot(command: String, pass: String) -> Result<String, HttpError> {
|
||||
let conf = ServerConfig::load();
|
||||
|
||||
let pbkdf_conf = pbkdf2::Params::new(10000).expect("invalid pdkdf2 iterations number");
|
||||
let hash = Pbkdf2::new(Pbkdf2Sha512, pbkdf_conf); //iterations ignored on verify
|
||||
|
||||
let ref_pass = PasswordHash::new(&conf.pc_boot_pass_hash).expect("invalid password set");
|
||||
let pass_bytes = pass.as_bytes();
|
||||
|
||||
if let Err(e) = hash.verify_password(&pass_bytes, &ref_pass)
|
||||
{
|
||||
println!("invalid password : {}", e);
|
||||
return HttpError::forbidden("Invalid password provided");
|
||||
}
|
||||
|
||||
|
||||
let found_command = COMMANDS.iter().find(|&x| x.0 == command.to_lowercase());
|
||||
if found_command == None {
|
||||
return HttpError::bad_request("Invalid command")
|
||||
}
|
||||
|
||||
let res = match esp_boot_request(found_command.unwrap().1).await {
|
||||
Ok(r) => r,
|
||||
Err(_) => { return HttpError::internal_server_error("esp unavailable"); }
|
||||
};
|
||||
|
||||
match res {
|
||||
0 => { return Ok("Success".to_string()) },
|
||||
1 => { return Ok("Failed".to_string()) },
|
||||
_ => { return Ok("Invalid response".to_string()) }
|
||||
}
|
||||
|
||||
Ok("Hello".to_string())
|
||||
}
|
||||
|
||||
#[get("/api/pc/status")]
|
||||
async fn pc_status() -> Result<i32, HttpError> {
|
||||
let res = match esp_boot_request(0x00).await {
|
||||
Ok(r) => r,
|
||||
Err(_) => { return HttpError::internal_server_error("esp unavailable"); }
|
||||
};
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
async fn esp_boot_request(command: u8) -> Result<i32, tokio::io::Error> {
|
||||
let mut stream = None;
|
||||
let mut retry = 3;
|
||||
|
||||
println!("send request to esp");
|
||||
loop {
|
||||
if retry == 0 {
|
||||
return Err(tokio::io::ErrorKind::ConnectionRefused.into());
|
||||
}
|
||||
|
||||
if let Ok(strm) = TcpStream::connect("192.168.1.40:80").await {
|
||||
stream = Some(strm);
|
||||
break;
|
||||
};
|
||||
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
let mut buf = [command ;1];
|
||||
stream.as_mut().unwrap().write_all(&buf).await?;
|
||||
let read_bytes = stream.as_mut().unwrap().read(&mut buf).await?;
|
||||
if read_bytes != 1 {
|
||||
panic!("invalid response");
|
||||
}
|
||||
Ok(buf[0].into())
|
||||
}
|
||||
1
src/api/mod.rs
Normal file
1
src/api/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod boot;
|
||||
@ -5,6 +5,8 @@ pub struct ServerConfig {
|
||||
|
||||
pub upload_storage_limit_soft: u64,
|
||||
pub upload_storage_limit_hard: u64,
|
||||
|
||||
pub pc_boot_pass_hash: String,
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
@ -14,6 +16,8 @@ impl ServerConfig {
|
||||
upload_folder: "./uploads/".to_string(),
|
||||
db_url: std::env::var("HTTPSERVER_DATABASE_URL").expect("missing HTTPSERVER_DATABASE_URL"),
|
||||
|
||||
pc_boot_pass_hash: std::env::var("PC_BOOT_PASS_HASH").expect("missing PC_BOOT_PASS_HASH env var"),
|
||||
|
||||
upload_storage_limit_soft: 1024 * 1024 * 1024 * 200,
|
||||
upload_storage_limit_hard: 1024 * 1024 * 1024 * 300,
|
||||
}
|
||||
|
||||
@ -31,6 +31,9 @@ use tasks::scheduled_tasks_loop;
|
||||
mod components;
|
||||
mod views;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
mod api;
|
||||
|
||||
#[derive(Debug, Clone, Routable, PartialEq)]
|
||||
#[rustfmt::skip]
|
||||
enum Route {
|
||||
|
||||
Reference in New Issue
Block a user