Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions context/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ jupiter = { workspace = true }
vault = { workspace = true }

gemini = { workspace = true, optional = true }
tokio = "1.45.1"
13 changes: 12 additions & 1 deletion context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,17 @@ pub struct AppContext {
impl AppContext {
/// Creates a new application context with the given configuration.
pub async fn new(config: common::config::Config) -> Self {

let config = Arc::new(config);

let storage = jupiter::storage::Storage::new(config.clone()).await;
let vault = vault::integration::vault_core::VaultCore::new(storage.clone());

let storage_for_vault = storage.clone();
let vault = tokio::task::spawn_blocking(move || {
vault::integration::vault_core::VaultCore::new(storage_for_vault)
}).await.expect("VaultCore::new panicked");


#[cfg(feature = "p2p")]
let client = gemini::p2p::client::P2PClient::new(storage.clone(), vault.clone());

Expand All @@ -41,9 +49,12 @@ impl AppContext {
#[cfg(feature = "p2p")]
client,
}


}

pub fn wrapped_context(&self) -> Arc<Self> {
Arc::new(self.clone())
}
}

1 change: 1 addition & 0 deletions monobean/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ vault = { path = "../vault" }
gateway = { path = "../gateway" }
ceres = { path = "../ceres" }
mercury = { path = "../mercury" }
context = {path = "../context"}

thiserror = { version = "2.0.11", features = ["default"] }
tracing-subscriber = { version = "0.3.19", features = ["default", "env-filter"] }
Expand Down
2 changes: 1 addition & 1 deletion monobean/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ impl MonobeanApplication {
glib::LogLevel::Debug => tracing::Level::DEBUG,
};

println!("{}: {}", level, fields);
println!("{level}: {fields}");
},
);
}
Expand Down
4 changes: 2 additions & 2 deletions monobean/src/components/hello_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ impl HelloPage {
fn setup_logo(&self) {
let logo = self.imp().logo.clone();
let id = random_int_range(1, 6);
logo.set_icon_name(Some(format!("walrus-{}", id).as_str()));
logo.set_icon_name(Some(format!("walrus-{id}").as_str()));

let gesture = gtk::GestureClick::new();
gesture.connect_pressed(clone!(
#[weak]
logo,
move |_, _, _, _| {
let id = random_int_range(1, 6);
logo.set_icon_name(Some(format!("walrus-{}", id).as_str()));
logo.set_icon_name(Some(format!("walrus-{id}").as_str()));
}
));
logo.add_controller(gesture);
Expand Down
4 changes: 2 additions & 2 deletions monobean/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ macro_rules! get_setting {
pub fn monobean_base() -> PathBuf {
// Get the base directory from the environment variable or use the default
std::env::var("MONOBEAN_BASE_DIR")
.map(|inner| PathBuf::from(inner))
.map(PathBuf::from)
.unwrap_or_else(|_| common::config::mega_base().join("monobean"))
}

Expand All @@ -119,7 +119,7 @@ pub fn monobean_base() -> PathBuf {
pub fn monobean_cache() -> PathBuf {
// Get the cache directory from the environment variable or use the default
std::env::var("MONOBEAN_CACHE_DIR")
.map(|inner| PathBuf::from(inner))
.map(PathBuf::from)
.unwrap_or_else(|_| common::config::mega_cache().join("monobean"))
}

Expand Down
71 changes: 50 additions & 21 deletions monobean/src/core/mega_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ceres::api_service::ApiHandler;
use ceres::protocol::repo::Repo;
use common::config::Config;
use common::model::P2pOptions;
use jupiter::context::Context as MegaContext;
use context::AppContext as MegaContext;
use mercury::internal::object::tree::Tree;
use std::fmt;
use std::fmt::{Debug, Formatter};
Expand All @@ -18,6 +18,7 @@ use std::path::{Component, Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use tokio::sync::{oneshot, OnceCell, RwLock};
use vault::integration::vault_core::VaultCore;
use vault::pgp::{SignedPublicKey, SignedSecretKey};

pub struct MegaCore {
Expand Down Expand Up @@ -146,19 +147,28 @@ impl MegaCore {
return;
}

if let Some(pk) = vault::pgp::load_pub_key().await {
let sk = vault::pgp::load_sec_key().await.unwrap();
let guard = self.running_context.read().await;
let vault_core = if let Some(ctx) = guard.as_ref() {
&ctx.vault
} else {
let err_msg = "Mega core is not running, failed to get vault core";
tracing::error!(err_msg);
return;
};

if let Some(pk) = vault_core.load_pub_key() {
let sk = vault_core.load_sec_key().await.unwrap();
chan.send(Ok(())).unwrap();
self.pgp.set((pk, sk)).unwrap();
} else {
let uid = format!("{} <{}>", user_name, user_email);
let params = vault::pgp::params(
let uid = format!("{user_name} <{user_email}>");
let params = VaultCore::params(
vault::pgp::KeyType::Rsa(2048),
passwd.clone(),
uid.as_ref(),
);
let (pk, sk) = vault::pgp::gen_pgp_keypair(params, passwd);
vault::pgp::save_keys(pk.clone(), sk.clone()).await;
let (pk, sk) = vault_core.gen_pgp_keypair(params, passwd);
vault_core.save_keys(pk.clone(), sk.clone());
chan.send(Ok(())).unwrap();
self.pgp.set((pk, sk)).unwrap();
}
Expand Down Expand Up @@ -190,9 +200,18 @@ impl MegaCore {
self.initialized.store(true, Ordering::Release);
}

let guard = self.running_context.read().await;
let vault_core = if let Some(ctx) = guard.as_ref() {
&ctx.vault
} else {
let err_msg = "Mega core is not running, failed to get vault core";
tracing::error!(err_msg);
return;
};

// Try to load pgp keys from vault.
if let Some(pk) = vault::pgp::load_pub_key().await {
let sk = vault::pgp::load_sec_key().await.unwrap();
if let Some(pk) = vault_core.load_pub_key() {
let sk = vault_core.load_sec_key().await.unwrap();
self.pgp.set((pk, sk)).unwrap();
tracing::debug!("Loaded pgp keys from vault");
}
Expand All @@ -211,13 +230,9 @@ impl MegaCore {
return Err(MonoBeanError::MegaCoreError(err.to_string()));
}

let config: Arc<Config> = self.config.read().await.clone().into();
let config = self.config.read().await.clone();

let inner = MegaContext::new(config.clone()).await;
inner
.services
.mono_storage
.init_monorepo(&config.monorepo)
.await;

let http_ctx = inner.clone();
*self.http_options.write().await = http_addr
Expand Down Expand Up @@ -281,21 +296,23 @@ impl MegaCore {

if path.as_ref().starts_with(&import_dir) && path.as_ref() != import_dir {
if let Some(model) = ctx
.storage
.services
.as_ref()
.git_db_storage
.find_git_repo_like_path(path.as_ref().to_string_lossy().as_ref())
.await
.unwrap()
{
let repo: Repo = model.into();
return Ok(Box::new(ImportApiService {
context: ctx.clone(),
storage: ctx.storage.clone(),
repo,
}));
}
}
let ret: Box<dyn ApiHandler> = Box::new(MonoApiService {
context: ctx.clone(),
storage: ctx.storage.clone(),
});

// Rust-analyzer cannot infer the type of `ret` correctly and always reports an error.
Expand All @@ -319,7 +336,7 @@ impl MegaCore {
match tree {
Ok(Some(tree)) => Ok(tree),
_ => {
let err_msg = format!("Failed to load tree: {:?}", path);
let err_msg = format!("Failed to load tree: {path:?}");
tracing::error!(err_msg);
Err(MonoBeanError::MegaCoreError(err_msg))
}
Expand All @@ -328,7 +345,9 @@ impl MegaCore {

async fn load_blob(&self, id: impl AsRef<str>) -> MonoBeanResult<String> {
let ctx = self.running_context.read().await.clone().unwrap();
let mono = MonoApiService { context: ctx };
let mono = MonoApiService {
storage: ctx.storage,
};
let raw = mono
.get_raw_blob_by_hash(id.as_ref())
.await
Expand All @@ -338,7 +357,7 @@ impl MegaCore {
Some(data) => match String::from_utf8(data) {
Ok(string) => Ok(string),
Err(err) => {
let err_msg = format!("Invalid UTF-8 data: {}", err);
let err_msg = format!("Invalid UTF-8 data: {err}");
tracing::error!(err_msg);
Err(MonoBeanError::MegaCoreError(err_msg))
}
Expand Down Expand Up @@ -500,7 +519,14 @@ mod tests {
#[tokio::test]
async fn test_launch_http() {
let temp_base = TempDir::new().unwrap();

// 设置环境变量,让 mega_base() 返回临时目录
unsafe {
std::env::set_var("MEGA_BASE_DIR", temp_base.path());
}

let core = test_core(&temp_base).await;

core.process_command(MegaCommands::MegaStart(
Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8080)),
None,
Expand All @@ -515,9 +541,12 @@ mod tests {
assert!(core.ssh_options.read().await.is_none());
}

#[tokio::test]
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_launch_ssh() {
let temp_base = TempDir::new().unwrap();
unsafe {
std::env::set_var("MEGA_BASE_DIR", temp_base.path());
}
let core = test_core(&temp_base).await;
core.process_command(MegaCommands::MegaStart(
None,
Expand Down
8 changes: 4 additions & 4 deletions monobean/src/core/servers.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::error::MonoBeanResult;
use bytes::BytesMut;
use common::model::P2pOptions;
use context::AppContext as MegaContext;
use gateway::https_server::{app, check_run_with_p2p};
use jupiter::context::Context as MegaContext;
use mono::git_protocol::ssh::SshServer;
use russh::server::Server;
use std::collections::HashMap;
Expand Down Expand Up @@ -31,7 +31,7 @@ impl HttpOptions {

pub async fn run_server(&self, mega_ctx: MegaContext) -> MonoBeanResult<()> {
let app = app(
mega_ctx.clone(),
mega_ctx.storage.clone(),
self.addr.ip().to_string(),
self.addr.port(),
self.p2p.clone(),
Expand Down Expand Up @@ -88,7 +88,7 @@ impl SshOptions {
// Use rusty vault configurations...
let (tx, mut rx) = mpsc::channel::<()>(1);
self.abort.set(tx).unwrap();
let key = mono::server::ssh_server::load_key().await;
let key = mono::server::ssh_server::load_key(mega_ctx.clone());
let ssh_config = russh::server::Config {
auth_rejection_time: std::time::Duration::from_secs(3),
keys: vec![key],
Expand All @@ -100,7 +100,7 @@ impl SshOptions {
let mut ssh_server = SshServer {
clients: Arc::new(Mutex::new(HashMap::new())),
id: 0,
context: mega_ctx,
storage: mega_ctx.storage.clone(),
smart_protocol: None,
data_combined: BytesMut::new(),
};
Expand Down
2 changes: 1 addition & 1 deletion monobean/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ fn load_css() {
.into_iter()
.map(|f| {
let provider = CssProvider::new();
provider.load_from_resource(&format!("{}/css/{}", PREFIX, f));
provider.load_from_resource(&format!("{PREFIX}/css/{f}"));
style_context_add_provider_for_display(
&gtk::gdk::Display::default().expect("Could not connect to a display."),
&provider,
Expand Down
25 changes: 14 additions & 11 deletions vault/src/integration/vault_core.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use std::{
path::PathBuf,
sync::{Arc, RwLock},
};

use std::{path::PathBuf, sync::{Arc, RwLock}};
use crate::integration::jupiter_backend::JupiterBackend;
use common::errors::MegaError;
use jupiter::storage::Storage;
Expand All @@ -18,6 +14,8 @@ use tracing::log;

const CORE_KEY_FILE: &str = "core_key.json"; // where the core key is stored, like `root_token`



#[derive(Debug, Clone, Serialize, Deserialize)]
struct CoreKey {
secret_shares: Vec<Vec<u8>>,
Expand Down Expand Up @@ -51,9 +49,10 @@ impl VaultCore {
pub fn new(ctx: Storage) -> Self {
let dir = common::config::mega_base().join("vault");
let key_path = dir.join(CORE_KEY_FILE);

println!("{:?}", key_path);

Copilot AI Jul 1, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a logging framework (e.g., tracing::debug) instead of println to ensure consistent logging across the application.

Suggested change
println!("{:?}", key_path);
tracing::debug!("Vault key path: {:?}", key_path);

Copilot uses AI. Check for mistakes.
std::fs::create_dir_all(&dir).expect("Failed to create vault directory");
Self::config(ctx, key_path)
let result = Self::config(ctx.clone(), key_path);
result
}

fn config(ctx: Storage, key_path: PathBuf) -> Self {
Expand All @@ -71,23 +70,26 @@ impl VaultCore {
};
let core = Arc::new(RwLock::new(core));


let key = {
let mut managed_core = core.write().unwrap();
managed_core
.config(core.clone(), None)
.expect("Failed to configure vault core");

let core_key = if !key_path.exists() {


let result = managed_core
.init(&seal_config)
.expect("Failed to initialize vault");
let core_key = CoreKey {
secret_shares: Vec::from(&result.secret_shares[..]),
root_token: result.root_token,
};
let file = std::fs::File::create(key_path).unwrap();
println!("[vault] Creating new core_key.json at: {}", key_path.display());
let file = std::fs::File::create(&key_path).unwrap();
serde_json::to_writer_pretty(file, &core_key).unwrap();

core_key
} else {
println!("Using existing vault core key file: {}", key_path.display());
Expand All @@ -110,7 +112,6 @@ impl VaultCore {

core_key.into()
};

Self { core, key }
}
}
Expand Down Expand Up @@ -187,6 +188,7 @@ mod tests {
async fn test_vault_core_initialization() {
let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
let key_path = temp_dir.path().join(CORE_KEY_FILE);
println!("Key path: {:?}", key_path);
let storage = test_storage(temp_dir.path()).await;
let vault_core = VaultCore::config(storage, key_path);

Expand All @@ -199,7 +201,8 @@ mod tests {
"Vault core should be initialized"
);
}



#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_vault_api() {
let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
Expand Down
Loading