mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Start to make dynamic interfaces work
This commit is contained in:
Generated
+15
-16
@@ -437,15 +437,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
@@ -851,9 +842,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
version = "0.2.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -1602,14 +1593,21 @@ dependencies = [
|
||||
name = "unshell-lib"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"unshell-obfuscate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unshell-manager"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"libc",
|
||||
"libloading",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"unshell-lib",
|
||||
"unshell-obfuscate",
|
||||
]
|
||||
|
||||
@@ -1627,7 +1625,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unshell-server"
|
||||
version = "0.1.0"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"axum-extra",
|
||||
@@ -1642,6 +1640,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"toml",
|
||||
"unshell-lib",
|
||||
"unshell-manager",
|
||||
"unshell-obfuscate",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
[package]
|
||||
name = "unshell-server"
|
||||
version = "0.1.0"
|
||||
# version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[features]
|
||||
log_debug = ["unshell-lib/log_debug"]
|
||||
default=["log_debug"]
|
||||
log_debug = ["unshell-lib/log_debug", "unshell-manager/log_debug"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
unshell-lib = {path = "../unshell-lib"}
|
||||
unshell-obfuscate = {path = "../unshell-obfuscate"}
|
||||
unshell-lib = {path = "../unshell-lib", default-featues = false}
|
||||
unshell-obfuscate = {path = "../unshell-obfuscate", default-featues = false}
|
||||
unshell-manager = {path = "../unshell-manager", default-featues = false}
|
||||
|
||||
axum = "0.8.7"
|
||||
axum-extra = {version="0.12.2", features = ["typed-header"]}
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use unshell_lib::{debug, info};
|
||||
use unshell_lib::{ModuleError, Result, debug, info};
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
struct ComponentMetadata {
|
||||
@@ -66,15 +66,18 @@ pub struct ComponentState {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
pub fn load_config(path: &PathBuf) -> Result<Vec<ComponentState>, Box<dyn Error>> {
|
||||
let path_absolute = fs::canonicalize(path.clone())?;
|
||||
pub fn load_config(path: &PathBuf) -> Result<Vec<ComponentState>> {
|
||||
let path_absolute =
|
||||
fs::canonicalize(path.clone()).map_err(|e| ModuleError::Error(e.to_string()))?;
|
||||
debug!("Loading data from path: `{:?}`", path_absolute);
|
||||
|
||||
// Read string as path
|
||||
let config_str = fs::read_to_string(path.clone())?;
|
||||
let config_str =
|
||||
fs::read_to_string(path.clone()).map_err(|e| ModuleError::Error(e.to_string()))?;
|
||||
|
||||
// Load config from String
|
||||
let config = toml::from_str::<ComponentMetadata>(&config_str)?;
|
||||
let config = toml::from_str::<ComponentMetadata>(&config_str)
|
||||
.map_err(|e| ModuleError::Error(e.to_string()))?;
|
||||
|
||||
info!("Loaded component `{}`", config.name);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ mod api;
|
||||
mod auth;
|
||||
mod config;
|
||||
pub mod logger;
|
||||
mod modules;
|
||||
mod server;
|
||||
|
||||
pub use server::Server;
|
||||
@@ -18,7 +17,7 @@ pub static DEFAULT_HOST: String = "localhost".to_string();
|
||||
pub static DATABASE_NAME: String = "database".to_string();
|
||||
|
||||
#[static_init::dynamic]
|
||||
pub static SERVER_CONFIG: unshell_lib::config::PayloadConfig = unshell_lib::config::PayloadConfig {
|
||||
pub static SERVER_CONFIG: unshell_manager::PayloadConfig = unshell_manager::PayloadConfig {
|
||||
id: "Server",
|
||||
components: Vec::new(),
|
||||
runtime_config: Vec::new(),
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
use std::{
|
||||
error::Error,
|
||||
collections::HashMap,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use unshell_lib::module::Manager;
|
||||
|
||||
use crate::server::tree2::{Tree, Tree2Repr};
|
||||
use serde_json::Value;
|
||||
use unshell_lib::{
|
||||
ModuleError,
|
||||
config::{InterfaceData, Tree, TreeMessage, config_struct::ConfigStructField},
|
||||
};
|
||||
use unshell_lib::{Result, config::InterfaceStruct};
|
||||
use unshell_manager::Manager;
|
||||
|
||||
mod blobs;
|
||||
mod database;
|
||||
@@ -22,7 +26,7 @@ pub struct Server {
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn new(config_paths: Vec<PathBuf>, database: String) -> Result<Self, Box<dyn Error>> {
|
||||
pub fn new(config_paths: Vec<PathBuf>, database: String) -> Result<Self> {
|
||||
let mut component_configs: Vec<crate::config::ComponentState> = Vec::new();
|
||||
|
||||
for config in &config_paths {
|
||||
@@ -32,7 +36,7 @@ impl Server {
|
||||
Ok(Self {
|
||||
component_configs,
|
||||
manager: Manager::start(&crate::SERVER_CONFIG, Vec::new()),
|
||||
db: sled::open(database)?,
|
||||
db: sled::open(database).map_err(|e| ModuleError::DatabaseError(e.to_string()))?,
|
||||
// tree: Tree2::default(),
|
||||
// interface: get_test_interface(),
|
||||
})
|
||||
@@ -48,12 +52,18 @@ impl Tree for Server {
|
||||
vec!["connection_count".into()]
|
||||
}
|
||||
|
||||
fn select_child(&self, child: &str) -> Result<Tree2Repr, String> {
|
||||
fn select_child(&self, child: &str, _message: TreeMessage) -> Result<TreeMessage> {
|
||||
match child {
|
||||
"connection_count" => Ok(Tree2Repr::File(format!(
|
||||
"Connection count: {}",
|
||||
self.manager.lock().unwrap().connections.len()
|
||||
))),
|
||||
"connection_count" => {
|
||||
let interface = vec![ConfigStructField::Header(format!("Test Heading!"))];
|
||||
|
||||
let value = vec![Value::Null];
|
||||
|
||||
Ok(TreeMessage::InterfaceAndValue(
|
||||
InterfaceStruct::ConfigStruct(interface),
|
||||
InterfaceData::ConfigStruct(value),
|
||||
))
|
||||
}
|
||||
_ => Err("No such child".into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,63 +2,24 @@ use axum::{
|
||||
Extension, Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use serde_json::Value;
|
||||
use unshell_lib::debug;
|
||||
use unshell_lib::{
|
||||
ModuleError,
|
||||
config::{Tree, TreeMessage},
|
||||
debug,
|
||||
};
|
||||
|
||||
use crate::{Server, auth::structs::CurrentUser};
|
||||
|
||||
pub trait Tree {
|
||||
fn is_folder() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_children_string(&self) -> Vec<String> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn select_child(&self, child: &str) -> Result<Tree2Repr, String>;
|
||||
|
||||
fn get_value(&self) -> String {
|
||||
"DEFAULT".into()
|
||||
}
|
||||
|
||||
fn get_path(&self, elements: &mut Vec<&str>) -> Result<Tree2Repr, String> {
|
||||
if elements.is_empty() {
|
||||
return if Self::is_folder() {
|
||||
Ok(Tree2Repr::Folder(self.get_children_string()))
|
||||
} else {
|
||||
Ok(Tree2Repr::File(self.get_value()))
|
||||
};
|
||||
}
|
||||
|
||||
let child = elements.remove(0);
|
||||
|
||||
if Self::is_folder() {
|
||||
self.select_child(child)
|
||||
} else {
|
||||
Err("This is a folder, not a file".into())
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&self, path: &str) -> Result<Tree2Repr, String> {
|
||||
let mut path = if path.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
path.split("/").collect::<Vec<&str>>()
|
||||
};
|
||||
|
||||
self.get_path(&mut path)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub enum Tree2Repr {
|
||||
File(String),
|
||||
Folder(Vec<String>),
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub async fn get_tree2_root(
|
||||
State(server): State<Server>,
|
||||
Extension(extension): Extension<CurrentUser>,
|
||||
) -> Json<Value> {
|
||||
Self::get_tree2(State(server), Path("".into()), Extension(extension)).await
|
||||
}
|
||||
|
||||
pub async fn get_tree2(
|
||||
State(server): State<Server>,
|
||||
Path(path): Path<String>,
|
||||
@@ -66,18 +27,10 @@ impl Server {
|
||||
) -> Json<Value> {
|
||||
debug!("GET /api/interface/{}", path);
|
||||
|
||||
let result = (|| -> Result<_, String> {
|
||||
let interface = server.get(&path)?;
|
||||
|
||||
Ok(interface)
|
||||
})();
|
||||
let result = server
|
||||
.get(&path, TreeMessage::RequestStructAndValue)
|
||||
.map_err(|e| ModuleError::CryptError(e.to_string()));
|
||||
|
||||
Json(serde_json::to_value(result).unwrap())
|
||||
}
|
||||
pub async fn get_tree2_root(
|
||||
State(server): State<Server>,
|
||||
Extension(extension): Extension<CurrentUser>,
|
||||
) -> Json<Value> {
|
||||
Self::get_tree2(State(server), Path("".into()), Extension(extension)).await
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user